我想动态更改面板,正如此answer所示,他们建议使用cardLayout。但是我想更改整个UI(没有旧按钮了),cardLayout似乎不太方便。所以我有以下代码:
JFrame frame = new JFrame ("Key test");
MyDrawPanel1 dp1 = new MyDrawPanel1(frame);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible (true);
JPanel p = new JPanel ();
p.setLayout(new BorderLayout());
p.add(dp1,BorderLayout.CENTER);
frame.getContentPane().add(p);
frame.pack();
frame.setVisible (true);
在MyDrawPanel1中,有一个用于更改面板的按钮:
public MyDrawPanel1(final JFrame frame) {
clickButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
frame.getContentPane().removeAll();
//frame.validate();
frame.getContentPane().add(new MyDrawPanel2());
((JPanel)frame.getContentPane()).revalidate();
}
});
this.add(clickButton);
}
编辑:MyDrawPanel1中的更多代码。
JButton clickButton = new JButton("click");
Image image = new ImageIcon("D:/0.jpg").getImage();
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawImage(image, 3, 40, null);
}
public Dimension getPreferredSize() {
if (image != null) {
return new Dimension(image.getWidth(null), image.getHeight(null));
}
return super.getPreferredSize(); // default
}
但是第一个面板不会消失,我必须最小化它才能刷新它,以便可以看到第二个面板。我的问题是为什么验证不起作用以及是否还有其他选择。谢谢。
编辑:这是我在面板上截取的图片。(第一个面板):
(点击后):
编辑:
madProgrammer和Adarsh Singhal提供了两种方法来解决此问题。第一个是第二个面板,该面板不调用super.paintComponent(),因此添加它即可正常工作(因为此answer说,它是橡皮擦,所以第一个面板不见了)。第二个是调用frame.repaint(),但我不明白为什么?
最佳答案
我们必须使用repaint()来告诉组件自己重新绘制。根据您的情况可视化。而revalidate用于更新布局。因此,每当您动态添加/删除组件时,都需要调用它们。以下编写的代码显示一个设置为CardLayout的JFrame,以在JFrame上完全绘制Red dp1(JPanel)。在dp1上,有一个Jbutton。如果单击该按钮,将删除dp1,并绘制dp2(JPanel)。 dp2为绿色以区分更改。看来您已经忘记了repaint()。
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MyFrame extends JFrame{
JButton button;
private static MyFrame frame;
public MyFrame(){
this.setSize(400, 400);
this.setLayout(new CardLayout());
this.setLocationRelativeTo(null);
JPanel dp1 = new JPanel();
dp1.setBackground(Color.RED);
add(dp1);
button = new JButton("Click me to remove dp1 & draw dp2");
dp1.add (button);
JPanel dp2 = new JPanel ();
dp2.setBackground(Color.GREEN);
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
frame.getContentPane().remove(dp1);
frame.add(dp2);
frame.revalidate();
frame.repaint();
}});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible (true);
}
public static void main(String[] args) {
frame = new MyFrame();
}
}