选择状态时,框架的内容窗格会删除其组件。然后,根据您选择的状态,另一个类将获取内容窗格并添加到其上。执行此操作后,框架将被打包以相应地调整大小。
我想要自由控制框架中的什么,例如能够将面板并排放置在彼此之上,等等......所以我真的不想使用CardLayout。 (我更倾向于让1个面板处理loginscreen和chat。然后,能够显示另一个面板旁边的那个面板。)
我在我的登录和聊天屏幕上使用JFrame的内容窗格,但是当我运行我的代码时,我得到一个小框架(有一些尺寸,但几乎没有)里面是白色的。
请告诉我我做错了什么,并指导我朝着正确的方向前进。 PS:没有错误
编辑:我唯一能想到的是,因为我通过方法传递frame.getContentPane()
,并且方法是按值传递的,所以对frame.getContentPane()
的实际引用可能不会注意到我要求的变化。但后来我不知道为什么框架的内部是白色的(好像我的JTextArea尝试渲染),并且在框架的内部有填充,所以必须发生一些事情......
Main.java:
package main;
import ui.Frame;
public class Main {
public static Frame frame = new Frame();
public static void main(String[] args) {
frame.show();
frame.switchState(State.chat);
}
public static enum State {
login, chat;
}
}
Frame.java:
package ui;
import main.Main.State;
import javax.swing.JFrame;
public class Frame {
private Panel currentpanel; //from package ui, not AWT
private ChatPanel chatpanel = new ChatPanel();
private JFrame frame;
public Frame() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
}
public void show() {
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void switchState(State state) {
frame.removeAll();
switch(state) {
case chat:
currentpanel = chatpanel;
currentpanel.addComponentsTo(frame.getContentPane());
break;
}
frame.pack();
frame.revalidate();
}
}
Panel.java:
package ui;
import java.awt.Container;
public interface Panel {
public void addComponentsTo(Container pane);
}
ChatPanel.java:
package ui;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JTextArea;
public class ChatPanel implements Panel {
private JTextArea toparea = new JTextArea();
private JTextArea bottomarea = new JTextArea();
@Override
public void addComponentsTo(Container pane) {
pane.setPreferredSize(new Dimension(500, 500));
pane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.gridx = 0;
gbc.ipadx = 450;
gbc.ipady = 350;
pane.add(toparea, gbc);
gbc.gridy = 1;
gbc.ipady = 100;
pane.add(bottomarea);
}
}
答案 0 :(得分:0)
我知道这可能非常令人沮丧。
你尝试过调用吗?pack(); or repaint();
答案 1 :(得分:0)
我发现了问题。在向其添加任何内容之前,它正在调用frame.removeAll();
。
当我尝试if(frame.getComponents().length > 0)
时,它仍会触发removeAll()
,但问题并未解决。看到我还没有添加任何内容,我检查了组件是什么(通过打印出对象),它是JRootPane
。
之后,我尝试打印frame.getContentPane().getComponents().length
,它按预期给了我0。
长话短说:这就是switchPanel(State state)
看起来的样子:
public void switchState(State state) {
if(frame.getContentPane().getComponents().length > 0)
frame.removeAll();
switch(state) {
case chat:
currentpanel = chatpanel;
currentpanel.addComponentsTo(frame.getContentPane());
break;
}
frame.pack();
frame.revalidate();
}
答案 2 :(得分:0)
注意:我仍然推荐CardLayout,但是如果你坚持动态设置框架的内容窗格就在这里。
框架类
public class SwitchingFrame extends JFrame {
public static enum State {ONE, TWO}
private PanelONE panel1 = new PanelONE();
private PanelTWO panel2 = new PanelTWO();
public SwitchingFrame() {
getContentPane().setLayout(new BorderLayout());
pack();
setVisible(true);
}
public void switchState(State state) {
setVisible(false);
getContentPane().removeAll();
if (state.equals(State.ONE))
getContentPane().add(panel1, BorderLayout.CENTER);
else
getContentPane().add(panel2, BorderLayout.CENTER);
pack();
setVisible(true);
}
}
切换的两个面板类
public class PanelONE extends JPanel {
public PanelONE() {
add(new JLabel("ONE"));
}
}
public class PanelONE extends JPanel {
public PanelTWO() {
add(new JLabel("TWO"));
}
}
主要方法,包括模拟更改面板的按钮
public class TestSwitchingFrame {
public static void main(String[] args) {
final SwitchingFrame sframe = new SwitchingFrame();
JFrame frame = new JFrame();
JButton b1 = new JButton("ONE");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sframe.switchState(SwitchingFrame.State.ONE);
}
});
JButton b2 = new JButton("TWO");
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sframe.switchState(SwitchingFrame.State.TWO);
}
});
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(b1);
frame.getContentPane().add(b2);
frame.pack();
frame.setVisible(true);
}
}
您不需要(不应该)编写自己的界面(Panel)。您的两个面板应该扩展JPanel并在框架内容窗格中设置。你的框架应该扩展JFrame,不需要覆盖它的show
方法(让Swing为你做)。 switchState
函数的具体实现最终取决于您想要的最终结果。有类似的方法可以实现几乎相同的结果。