我正在尝试创建一个小的GUI,它有2个JButton和2个JPanel,每个都有一些绘图动画 . 默认情况下,它必须显示第一个JPanel,并通过单击第二个JButton我想看到我的第二个JPanel . 所以:我创建了JFrame,Panel1和Panel2,在那里我绘制了我的动画,创建了Button1和Button2并添加了ActionListeners . 我还有MainPanel,它有一个字段变量i . 通过更改此“i”我的构造函数将MainPanel添加到Panel1(默认)或Panel2(通过单击JButton2我更改i) . 比我把这个MainPanel添加到我的框架 . 所以我的问题:在类MainPanel中我有refreshMe方法,我应该在那里写什么才能让我的GUI正常工作?谢谢 . 这是我的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GuiTest {
public static void main(String[] args) {
JFrame f = new JFrame();
MainPanel myPanel = new MainPanel();
f.add(myPanel);
Button1 button1 = new Button1();
Button2 button2 = new Button2();
myPanel.add(button1);
myPanel.add(button2);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
class MainPanel extends JPanel {
Panel1 p1 = new Panel1();
Panel2 p2 = new Panel2();
public int i = 1; //this is being changed later by clicking JButton
// I use this setter later in actionPerformed in order to change i
public void setI(int i) {
this.i = i;
}
MainPanel() {
if (i == 1) {
this.add(p1);
}
if (i == 2) {
this.add(p2);
}
}
public void refreshMe() {
// Need some help here:
// I don't know what should I write, how to make a repaint of myPanel?
System.out.println("just test, if the method refreshMe working by clicking some button");
}
}
class Panel1 extends JPanel {
public Panel1() {
this.setBackground(Color.BLUE);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class Panel2 extends JPanel {
public Panel2() {
this.setBackground(Color.GREEN);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class Button1 extends JButton {
MainPanel someObj1 = new MainPanel();
Button1() {
setText("Show Annimation A");
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
someObj1.setI(1);
System.out.println("The variable i is now: " + someObj1.i);
someObj1.refreshMe();
}
});
}
}
class Button2 extends JButton {
MainPanel someObj2 = new MainPanel();
Button2() {
setText("Show Annimation B");
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
someObj2.setI(2);
System.out.println("The variable i is now: " + someObj2.i);
someObj2.refreshMe();
}
});
}
}
2 回答
为了在添加/删除或调整可见容器上的组件后反映更改,在添加/删除或调整组件大小后,在容器实例上调用
revalidate()
和repaint()
.虽然这在你的代码中不起作用,但主要的原因是在JButton类中重新创建
MainPanel
的新实例,而实际上2JButtons
应该共享正在使用的单个实例(你可以将MainPanel实例传递给JButton
的构造函数,但是除非添加自定义功能,否则你不应该真正扩展JButton
:关于您的代码的一些其他建议:
不要不必要地扩展
JButton
类,只需创建JButton
的实例,就像使用JFrame
一样,并在JButton
实例上调用方法 .别忘了在
Event Dispatch Thread
上创建/操作Swing组件,通过SwingUtilities.invokeLater(..)
块,阅读here了解更多信息 .以下是您修复的代码(以上建议已实施):
但是,我建议更简单,幸运的是你有两个选择:
1)使用CardLayout,它允许您在单个
JFrame
/容器上的多个组件之间进行切换 .这是我做的一个例子:
2)使用
removeAll()
技术,即调用frame.getContentPane().removeAll()
,这将删除当前在JFrame
上的所有组件,然后添加新内容并在JFrame
实例上调用revalidate()
和repaint()
(也可能想在其中添加pack()
)以反映更改 . 虽然我推荐CardLayout
.我想你可以使用
CardLayout
来实现你的功能 . 请参考here