Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当添加第二个JPanel时,Java CardLayout JPanel向上移动_Java_Swing_Cardlayout - Fatal编程技术网

当添加第二个JPanel时,Java CardLayout JPanel向上移动

当添加第二个JPanel时,Java CardLayout JPanel向上移动,java,swing,cardlayout,Java,Swing,Cardlayout,我是Java新手,主要是CardLayout。我只想切换由JPanels表示的“窗口”。我在什么地方读到了CardLayout的工作。但我的问题是,当将chatPanel添加到主面板(这是CardLayout)时,connectPanel的内容会从中心位置向上移动几个像素。我是否跳过了代码createChatPanel(),它应该在哪里 我有以下代码: package App; import java.awt.CardLayout; import java.awt.Dimension; imp

我是Java新手,主要是CardLayout。我只想切换由JPanels表示的“窗口”。我在什么地方读到了CardLayout的工作。但我的问题是,当
将chatPanel
添加到
主面板(这是CardLayout)时,
connectPanel
的内容会从中心位置向上移动几个像素。我是否跳过了代码
createChatPanel(),
它应该在哪里

我有以下代码:

package App;

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import Validators.*;



public class GUI {

private JFrame mainFrame = null;
private JPanel mainPanel = null;
private CardLayout cl = new CardLayout();

public GUI(){


    try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         } 
         catch (UnsupportedLookAndFeelException e) {
         }
         catch (ClassNotFoundException e) {
         }
         catch (InstantiationException e) {
         }
         catch (IllegalAccessException e) {
         }

    mainFrame = new JFrame("MainChat");
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.setSize(640,480);
    mainFrame.setLocationRelativeTo(null);
    mainFrame.setResizable(false);
    mainFrame.setLayout(new GridBagLayout());

    JMenuBar menuBar = new JMenuBar();

    JMenu menuFile = new JMenu("Soubor");
    JMenu menuHelp = new JMenu("Nápověda");

    menuBar.add(menuFile);
    menuBar.add(menuHelp);

    menuFile.add(new JMenuItem("Nové Připojení"));
    menuFile.add(new JSeparator());
    menuFile.add(new JMenuItem("Konec"));
    menuHelp.add(new JMenuItem("O programu"));
    mainFrame.setJMenuBar(menuBar);


    createMainPanel();
    createConnectPanel();
    createChatPanel();

    mainFrame.setVisible(true);
}

public void createMainPanel() {

    mainPanel = new JPanel(cl);
    mainFrame.add(mainPanel);

}

public void createConnectPanel() {

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

    JTextField ip = new JTextField();
    ip.setDocument(new JTextFieldLimit(15));
    ip.setColumns(11);

    JLabel iplabel = new JLabel("IP:");
    connectPanel.add(iplabel);
    connectPanel.add(ip);

    JButton connect = new JButton("Connect");
    connect.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            cl.show(mainPanel,"chatPanel");

        }
    });
    connectPanel.add(connect);

}

public void createChatPanel(){

    JPanel chatPanel = new JPanel();
    mainPanel.add(chatPanel,"chatPanel");

    JTextArea chatbox = new JTextArea();
    chatbox.setPreferredSize(new Dimension(200,200));
    chatPanel.add(chatbox);

}
}

拜托,我搞砸了什么?谢谢。

因为您要在主JPanel中添加两个JPanel, 这两个面板都需要安装在主面板内

如果一个内板比另一个大得多, 主面板将调整以适应较大的面板

例如,评论这一行:

chatbox.setPreferredSize(new Dimension(200,200));
将导致文本字段保持不变。这是因为 chatbox不会导致容器调整大小

还请注意,主面板最初的大小与您的面板不同 主框架,因为尚未设置主面板的大小

如果要将connectPanel的大小设置为相同的大小 作为主框架,connectPanel不会 在添加chatPanel时自动调整大小(作为 调整主面板大小的后果)

因此,您可以做的是添加中间行:

JPanel connectPanel = new JPanel();
connectPanel.setSize(640, 480);
mainPanel.add(connectPanel, "connectPanel");
,这可能会解决您的问题

虽然这会起作用,但我绝对建议使用 对于 所有的图形用户界面设计。这将节省你大量的时间,如果 你花一个小时来学习它。这也会让你免于 必须手动设置大小(从而避免
每次设计更改都必须重写一半的GUI代码)。

如果您希望一个JPanel集中在另一个JPanel中,请将connectPanel放在另一个充当哑容器的JPanel中,并让该容器使用GridBagLayout。然后,如果将connectPanel添加到没有任何GridBagConstraints的容器中,它将被添加到GridBagLayout的默认位置(居中)。然后,可以使用与connectPanel相同的常量将此容器JPanel添加到主面板

我倾向于让布局决定组件的大小,避免使用setSize,甚至setPreferredSize,并且在将其设置为可见之前,肯定会在JFrame上调用pack()。您肯定不想设置JTextField的大小或preferredSize,而是设置它的列和行并将其放置在JScrollPane中,然后将该JScrollPane添加到视图中

编辑:
下面的示例显示了在小型gui的顶部、中部和底部放置连接面板之类的内容。只需按“下一步”按钮即可了解我的意思:

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);
    }
}

我认为CardLayout使得目前只有一个JPanel,你可以切换它们。所以,不知怎的,我错过了这个概念?CardLayout将其组件像卡片一样存储在彼此的顶部。即使不是“在前线”,他们仍然在那里。这就是为什么使用CardLayout的容器会调整大小,以适合所包含的最大组件。哦,谢谢。有没有类似的方法可以切换JPanel,这样它们就不会相互干扰?如果你避免在设计中硬编码大小和数字,而是尝试用“居中”、“顶部”、“左侧”、“底部”、“对齐”等词语添加组件,你就不必担心这些事情了。这是通过MIG布局实现的。请参见下面我的答案中的编辑。