简体   繁体   中英

Placing of JPanels on the JFrames is not correct

I wrote a program to compose a GUI using swing/awt framework for my assignment. So far, I am able to get the pieces working together, but when I put them all into a JFrame, they are not coming out as expected.

I have recently started working on Java GUI framework, and not sure what is missing in my code. How can I get this working properly?

I am also attaching the screen shots (see at the bottom) of the output I am getting.

public class MainFrame extends JFrame {

    public MainFrame() {
    addComponentsToPane(this.getContentPane());
    }

    private void addComponentsToPane(Container pane) {

        // Set layout
        GridBagConstraints gbc = new GridBagConstraints();
        this.setTitle("Test tool");
        this.setSize(600, 650);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new GridLayout(2, 1));

        // Add video JComponent
        mMainPanel = new MainPanel();
        pane.add(mMainPanel, 0);

        // Add conference screen panel
        mFeedPanel = new FeedPanel();
        pane.add(mFeedPanel, 1);

        // Add a button panel
        mButtonPanel = new ButtonPanel();
        pane.add(mButtonPanel, 2);

        this.setResizable(true);
        this.setVisible(true);
        this.pack();
    }
}

// In actual output, there is 1 screen in this panel. 
// mScreen1 is derived from JComponent object.
public class MainPanel() extends JPanel {

    public MainPanel() {
    addMainPanelComponents();
    }

    private void addMainPanelComponents() {
        this.setSize(352, 240);
        setBackground(Color.yellow);
        setLayout(new GridLayout(1, 2));
        add(mScreen);
        setVisible(true);
    }
}

// In actual output, there are 3 screens in this panel. I have shown code for 1 screen only
// mScreen1 is derived from JComponent object.
public class FeedPanel extends JPanel {

    public FeedPanel() {
    addFeedPanelComponents();
    }

    private void addFeedPanelComponents() {

        String img1 = "images/screen1.png";

        setSize(352, 150);
        setBackground(Color.yellow);
        setLayout(new GridLayout(1, 3));                

        Image image1 = ImageIO.read(new File(img1));
        mScreen1.setImage(image1);
        add(mScreen1);
        setVisible(true);
    }
}

public class ButtonPanel extends JPanel {

    public ButtonPanel() {
    addButtonPanelComponents();
    }

    private void addButtonPanelComponents() {

        this.setSize(352, 150);
        this.setBackground(Color.yellow);
        this.setLayout(new GridLayout(1, 
                                      5));

        // Add Button to panel
        mStartButton = new JButton("Start");
        this.add(mStartButton);
        mStartButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                StartButtonActionListener(ae);
            }
        });

        mStopButton = new JButton("Stop");
        this.add(mStopButton);
        mStopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                StopButtonActionListener(ae);
            }
        });
        setVisible(true);
    }
}

This comes by default on running the code.

在此处输入图片说明

This comes after manually resizing the frame. 在此处输入图片说明

Try this :

    public class Main{

    private JFrame f;
    private JLabel l1, l2, l3,l4;
    private JPanel p1, p2, p3;
    private JButton b1, b2, b3;

    public Main(){

    this.f = new JFrame();
    this.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.f.setLayout(new GridLayout(3,1));

    this.p1 = new JPanel();
    this.p1.setLayout(null)
    this.p1.setSize(yoursize);

    this.l1 = new JLabel();
    this.l1.setBounds(x,y,xspan,yspan);

    this.p1.add(l1);

    this.p2 = new JPanel();
    this.p2.setLayout(new GridLayout(1,3));

    this.l2 = new JLabel();
    this.l3 = new JLabel();
    this.l4 = new JLabel();

    this.p2.add(l2);
    this.p2.add(l3);
    this.p2.add(l4);

    this.p3 = new JPanel();
    this.p3.setLayout(new GridLayout(1,3));

    this.b1 = new JButton();
    this.b2 = new JButton();  
    this.b3 = new JButton();

    this.p3.add(b1);       
    this.p3.add(b2);
    this.p3.add(b3);

    this.f.add(p1);
    this.f.add(p2);
    this.f.add(p3);

    this.f.pack();
    this.f.setResizeable(false)
    }}

Add your video components instead of labels and you can change the color of the components as you wish. Also if you want more control over the size and position of the components, use null layout and place them individually using setBounds() function as once shown in the program above. It is surely time consuming but makes the layout perfect.

The combination of BorderLayout , GirdLayout and BoxLayout can do this for you(Actually it's not the only choice).

Here is the code:

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class GridLayoutTest {
    public void createUI(){
        JFrame frame = new JFrame();

        JPanel topPanel = new TopPanel();
        JPanel buttomPanel = new ButtomPanel();


        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(topPanel,BorderLayout.CENTER);
        mainPanel.add(buttomPanel,BorderLayout.SOUTH);
        frame.add(mainPanel,BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        GridLayoutTest test = new GridLayoutTest();
        test.createUI();
    }

    @SuppressWarnings("serial")
    class TopPanel extends JPanel{
        public TopPanel(){
            setLayout(new GridLayout(2, 3));
            ImageIcon icon = new ImageIcon("capture.png");
            JLabel label1 = new JLabel(icon);
            label1.setVisible(false);
            JLabel label2 = new JLabel(icon);
            JLabel label3 = new JLabel(icon);
            label3.setVisible(false);
            JLabel label4 = new JLabel(icon);
            JLabel label5 = new JLabel(icon);
            JLabel label6 = new JLabel(icon);
            add(label1);
            add(label2);
            add(label3);
            add(label4);
            add(label5);
            add(label6);
        }
    }

    @SuppressWarnings("serial")
    class ButtomPanel extends JPanel{
        public ButtomPanel(){
            JButton startButton = new JButton("start");
            JButton stopButton = new JButton("stop");
            JButton recordButton = new JButton("record");

            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            add(Box.createHorizontalGlue());
            add(startButton);
            add(Box.createHorizontalStrut(10));
            add(stopButton);
            add(Box.createHorizontalStrut(10));
            add(recordButton);
            add(Box.createHorizontalGlue());
        }
    }
}

BoxLayout is so good too provide white space and help you to center the component.

    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    add(Box.createHorizontalGlue());
    add(startButton);
    add(Box.createHorizontalStrut(10));
    add(stopButton);
    add(Box.createHorizontalStrut(10));
    add(recordButton);
    add(Box.createHorizontalGlue());

Add Glue before the first component and after the last component will help you too center the component and add strut can help you to provide white space you want. you can refer to https://stackoverflow.com/a/22525005/3378204 for more details.

Here is the effect:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

The BoxLayout won't affect your component's size. Hope it can help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM