Java 在JFrame上动态更改JPanel的问题
我有一个JFrame,它使用BorderLayout作为布局管理器。 我也有两个面板在这个JFrame上,在中间和南部的位置。 在某些用户操作中(实际上,当用户按下底部面板上的“下一步”时),面板的中心位置会动态更改 守则如下:Java 在JFrame上动态更改JPanel的问题,java,swing,jframe,Java,Swing,Jframe,我有一个JFrame,它使用BorderLayout作为布局管理器。 我也有两个面板在这个JFrame上,在中间和南部的位置。 在某些用户操作中(实际上,当用户按下底部面板上的“下一步”时),面板的中心位置会动态更改 守则如下: private void switchToPanelByState(State state) { this.getContentPane().removeAll(); JPanel panel = _panels.get(state); thi
private void switchToPanelByState(State state)
{
this.getContentPane().removeAll();
JPanel panel = _panels.get(state);
this.getContentPane().add(panel, BorderLayout.CENTER);
this.getContentPane().add(_controlPanel, BorderLayout.SOUTH);
this.pack();
}
问题是,在对面板进行一些更改之后,“旧”(来自以前的面板)GUI元素的部分将出现在当前面板上
我还不时看到以下例外情况:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
但我不知道这是否与问题有关
这些问题的可能根源是什么?
任何建议都将不胜感激。只接受中央区域的一个,那么就没有理由删除()/removeAll()
;您的代码应如下所示:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1L;
public MyFrame() {
final JPanel parentPanel = new JPanel();
parentPanel.setLayout(new BorderLayout(10, 10));
JButton myButton = new JButton("Add Component ");
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JPanel childPanel1 = new JPanel();
childPanel1.setBackground(Color.red);
childPanel1.setPreferredSize(new Dimension(300, 40));
JPanel childPanel2 = new JPanel();
childPanel2.setBackground(Color.blue);
childPanel2.setPreferredSize(new Dimension(800, 600));
parentPanel.add(childPanel1, BorderLayout.NORTH);
parentPanel.add(childPanel2, BorderLayout.CENTER);
parentPanel.revalidate();
parentPanel.repaint();
pack();
}
});
setTitle("My Empty Frame");
setLocation(10, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
parentPanel.add(myButton, BorderLayout.SOUTH);
add(parentPanel);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyFrame myFrame = new MyFrame();
}
});
}
}
或者直接
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel childPanel1 = new JPanel();
private JPanel childPanel2 = new JPanel();
private JPanel childPanel3 = new JPanel();
public MyFrame() {
childPanel1.setBackground(Color.red);
childPanel1.setPreferredSize(new Dimension(300, 40));
childPanel2.setBackground(Color.blue);
childPanel2.setPreferredSize(new Dimension(300, 40));
childPanel3.setBackground(Color.yellow);
childPanel3.setPreferredSize(new Dimension(300, 40));
JButton myButton = new JButton("Add Component ");
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
add(childPanel2, BorderLayout.CENTER);
pack();
}
});
setTitle("My Empty Frame");
setLocation(10, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(childPanel3, BorderLayout.CENTER);
add(myButton, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyFrame myFrame = new MyFrame();
}
});
}
}
2) 没有人知道参数状态是什么,如果不知道,就不可能回答这个问题
3) 我可以模拟RepaitManager的异常,当CustomPaint比本机OS的延迟快时mKorbel,谢谢你的回答。不幸的是,JFrame(this)和容器(contentpane)都没有方法revalidate。至于“状态”-它只是在HashMap中找到正确面板的一个键。这个答案是错误的-正确的是BorderLayout只显示最后添加的组件(在其每个约束区域中),但是:所有以前添加的具有相同约束的组件仍然是容器的子组件。顺便说一句:请不要在答案中乱扔只是略有不同的变量-选择一个(最简单的,这里是第二个,只有两个childPanel字段)并坚持它。每当我看到removeAll()方法时,首先想到的是你应该使用一个。