Java CardLayout JPanel moves up, when second JPanel added

半城伤御伤魂 提交于 2019-11-28 14:14:07

Since you are adding two JPanels to your main JPanel, these two panels both need to fit within the main panel.

If one of the inner panels is much larger than the other one, the main panel will adjust to fit the larger one.

E.g. commenting this line:

chatbox.setPreferredSize(new Dimension(200,200));

would cause your text field to stay put. This is because the chatbox would not cause the container to resize.

Also note that the main panel is not initially the same size as your main frame, since you have not set the size of the main panel.

If you would set the size of the connectPanel to the same size as your main frame, the connectPanel would not be automatically resized when adding the chatPanel (as a consequence of the mainPanel being resized)

So what you could do is add the middle line in:

JPanel connectPanel = new JPanel();
connectPanel.setSize(640, 480);
mainPanel.add(connectPanel, "connectPanel");

, which probably would solve your problem.

Although this would work, I definitely recommend using MIG Layout for all your GUI designing. It will save you plenty of time if you take an hour to learn it. It will also save you from having to set sizes manually (and thereby saving you from having to rewrite half your GUI code with every design change).

If you want a JPanel centered in another, place your connectPanel in another JPanel that acts as a dumb container, and have this container use GridBagLayout. Then if you add the connectPanel to the container without any GridBagConstraints, it will be added to the default position for GridBagLayout which is centered. You can then add this container JPanel to your mainPanel using the same constant that you would have used for your connectPanel.

I would tend to let the layouts determine the size of components and avoid using setSize and even setPreferredSize, and would definitely call pack() on my JFrame prior to setting it visible. You definitely don't want to set the size or preferredSize of your JTextField, but rather set its columns and rows and place it in a JScrollPane, and then add that JScrollPane to the view.

Edit:
Here's an example that shows placement of something like your connect panel at the top, middle and bottom of a small gui. Just press the "Next" button to see what I mean:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class GUI2 extends JPanel {
    public static final String CONNECT_NORTH = "connect north";
    public static final String CONNECT_CENTER = "connect center";
    private static final String CONNECT_SOUTH = "connect south";
    private static final String CHAT_PANEL = "chat panel";
    private CardLayout cardlayout = new CardLayout();

    public GUI2() {
        setLayout(cardlayout);
        add(createConnectPanel(BorderLayout.NORTH), CONNECT_NORTH);
        add(createConnectPanel(BorderLayout.CENTER), CONNECT_CENTER);
        add(createConnectPanel(BorderLayout.SOUTH), CONNECT_SOUTH);
        add(createChatPanel(), CHAT_PANEL);
    }

    public void nextPanel() {
        cardlayout.next(this);
    }


    private JPanel createConnectPanel(String borderlayoutLocation) {
        JPanel innerPanel = new JPanel();
        innerPanel.add(new JLabel("IP:"));
        innerPanel.add(Box.createHorizontalStrut(5));
        innerPanel.add(new JTextField(11));
        innerPanel.add(Box.createHorizontalStrut(5));
        innerPanel.add(new JButton(new AbstractAction("Next") {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                GUI2.this.nextPanel();
            }
        }));

        JPanel innerPanel2 = new JPanel(new GridBagLayout());
        innerPanel2.add(innerPanel);
        JPanel connectPanel = new JPanel(new BorderLayout());
        connectPanel.add(innerPanel2, borderlayoutLocation);
        return connectPanel;
    }

    private JPanel createChatPanel() {
        JPanel chatPanel = new JPanel(new BorderLayout(5, 5));
        chatPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        chatPanel.add(new JScrollPane(new JTextArea(15, 30)), BorderLayout.CENTER);
        chatPanel.add(new JTextField(), BorderLayout.SOUTH);

        return chatPanel;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGui();
            }
        });
    }

    private static void createGui() {
        JFrame frame = new JFrame("App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new GUI2());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!