当添加第二个JPanel时,Java CardLayout JPanel向上移动
我是Java新手,主要是CardLayout。我只想切换由JPanels表示的“窗口”。我在什么地方读到了CardLayout的工作。但我的问题是,当当添加第二个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
将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布局实现的。请参见下面我的答案中的编辑。