当前位置: 动力学知识库 > 问答 > 编程问答 >

java - JLabel misplaced after adding JPanel

问题描述:

I'm almost blind after reading lots of java swing articles, and still can not get panel to work.

When i add 2 JLabels, they are nicely aligned to left, with 5px padding defined by EmptyBorder, just as i want them to be.

I found that after adding ProgressBar with extra border for padding, does not work as expected, added 1 more panel, where i add ProgressBar. Progress looks good, but all my labels are displaced.

And finally it look like this (RED background is for debug, to see how JPanel draws):



Question1: How to fix this?

Question2: Is it standard approach for swing to place panel inside of other panel with other panels just to get formating i want?



Source:

public class AppInitProgressDialog {

private static final int VIEW_PADDING_VAL = 5;

private static final Border viewPaddingBorder = new EmptyBorder( VIEW_PADDING_VAL, VIEW_PADDING_VAL, VIEW_PADDING_VAL, VIEW_PADDING_VAL );

private JPanel view; // Dialog view

private JPanel panel;

private JPanel progressPanel;

private JLabel title;

private JLabel progressDesc;

private JProgressBar progressBar;

private void initPanel( int w, int h ) {

view = new JPanel();

view.setBorder( BorderFactory.createRaisedSoftBevelBorder() );

view.setBackground( Color.LIGHT_GRAY );

view.setSize( w, h );

view.setLayout( new BorderLayout() );

panel = new JPanel();

panel.setBorder( viewPaddingBorder );

panel.setLayout( new BoxLayout(panel, BoxLayout.PAGE_AXIS) );

//panel.setLayout( new SpringLayout() );

panel.setOpaque( false );

JFrame parent = AppContext.getMe().getAppWindow().getFrame();

int posx = (parent.getWidth() - w)/2;

int posy = (parent.getHeight() - h)/2;

view.add( panel, BorderLayout.CENTER );

view.setLocation( posx, posy );

}

private void initTitle() {

title = new JLabel( "Progress title" );

title.setAlignmentX( JComponent.LEFT_ALIGNMENT );

panel.add(title);

}

private void initProgress() {

progressPanel = new JPanel( new BorderLayout() );

progressPanel.setBackground( Color.LIGHT_GRAY );

progressPanel.setBorder( new EmptyBorder( 15, 30, 15, 30) );

progressPanel.setBackground( Color.RED );

progressBar = new JProgressBar(0, 10000);

progressBar.setStringPainted(true);

progressBar.setAlignmentX( JComponent.LEFT_ALIGNMENT );

progressPanel.add(progressBar);

panel.add( progressPanel );

progressDesc = new JLabel( "Progress description" );

panel.add(progressDesc);

}

public AppInitProgressDialog() {

initPanel( 400, 100 );

initTitle();

initProgress();

}

public JComponent getView() {

return view;

}

}

网友答案:

Alternatively, you can use BorderLayout for panel:

panel = new JPanel(new BorderLayout());
...
panel.add(title, BorderLayout.NORTH);
...
panel.add(progressPanel); // default CENTER
...
panel.add(progressDesc, BorderLayout.SOUTH);

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;

/**
 * @see http://stackoverflow.com/a/16837816/230513
 */
public class Test {

    private JFrame f = new JFrame("Test");

    private void display() {
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new AppInitProgressDialog().getView());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    class AppInitProgressDialog {

        private static final int VIEW_PADDING_VAL = 5;
        private JPanel view;   // Dialog view
        private JPanel panel;
        private JPanel progressPanel;
        private JLabel title;
        private JLabel progressDesc;
        private JProgressBar progressBar;

        private void initPanel(int w, int h) {
            view = new JPanel();
            view.setBorder(BorderFactory.createRaisedBevelBorder());
            view.setBackground(Color.LIGHT_GRAY);
            view.setSize(w, h);
            view.setLayout(new BorderLayout());

            panel = new JPanel(new BorderLayout());
            panel.setBorder(BorderFactory.createLineBorder(Color.blue));
            panel.setOpaque(false);

            view.add(panel, BorderLayout.CENTER);
        }

        private void initTitle() {
            title = new JLabel("Progress title");
            title.setAlignmentX(JComponent.LEFT_ALIGNMENT);
            panel.add(title, BorderLayout.NORTH);
        }

        private void initProgress() {
            progressPanel = new JPanel(new BorderLayout());
            progressPanel.setBackground(Color.LIGHT_GRAY);
            progressPanel.setBorder(new EmptyBorder(15, 30, 15, 30));
            progressPanel.setBackground(Color.RED);

            progressBar = new JProgressBar(0, 10000);
            progressBar.setStringPainted(true);
            progressBar.setAlignmentX(JComponent.LEFT_ALIGNMENT);
            progressPanel.add(progressBar);

            panel.add(progressPanel);
            progressDesc = new JLabel("Progress description");
            panel.add(progressDesc, BorderLayout.SOUTH);
        }

        public AppInitProgressDialog() {
            initPanel(400, 100);
            initTitle();
            initProgress();
        }

        public JComponent getView() {
            return view;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}
网友答案:

Use Layout Managers rather than just adding panels to each other. Specifically in your case I think you can use GridLayout.

panel.setLayout(new GridLayout(1,1,0,0));

Fore more details on layout refer to this tutorial.

分享给朋友:
您可能感兴趣的文章:
随机阅读: