我试图创建一个小的图形用户界面,它有2个Jbutton将和2个JPanels与他们每个人的一些绘图动画。 默认情况下,它必须显示第一的JPanel,并通过点击第二的JButton我想看看我的第二个JPanel的。 所以:我创建的JFrame,Panel1的和是Panel2,在那里我有我的画动画,创建Button1的和Button2的,并增加他们的ActionListeners。 我也有mainPanel中其中有一个字段变量i。 通过改变这个“我”我的构造函数添加到mainPanel中任Panel1的(默认)或者是Panel2(通过点击我将jButton2改变我)。 比我这个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();
}
});
}
}
为了反映添加/移除或调整大小部件,其上形成可视容器呼叫之后改变revalidate()
和repaint()
添加/移除或调整所述部件后的容器的实例。
虽然这不会在你的代码工作,主要的理由是一个JButton类中重新创建的新实例MainPanel
的时候,其实2个JButtons
要共享正在使用(你可以传递的mainPanel实例的单个实例JButton
小号构造函数,但你真不该延伸JButton
除非添加自定义功能):
class Button2 extends JButton {
MainPanel someObj2 = new MainPanel();//you create an instance of MainPanel which isnt even showing and than do changes on that, this way you will never see any of the changes
Button2() {
}
}
在你的代码的一些其他建议:
这里是你的代码固定(以上建议ECT实现):
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;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
final MainPanel myPanel = new MainPanel();
f.add(myPanel);
JButton button1 = new JButton("Show Animation A");
JButton button2 = new JButton("Show Animation B");
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myPanel.setI(1);
System.out.println("The variable i is now: " + myPanel.i);
myPanel.refreshMe();
}
});
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myPanel.setI(2);
System.out.println("The variable i is now: " + myPanel.i);
myPanel.refreshMe();
}
});
myPanel.add(button1);
myPanel.add(button2);
myPanel.checkPanel();
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;
}
public void refreshMe() {
checkPanel();
revalidate();
repaint();
// 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");
}
public void checkPanel() {
if (i == 1) {
this.add(p1);
this.remove(p2);//or it will remain there as this is default flowlayout
} else if (i == 2) {
this.add(p2);
this.remove(p1);
}
}
}
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);
}
}
然而编号建议简单的东西,幸好你有2种选择:
1)使用CardLayout
这将允许你在单一的多个部件之间翻转JFrame
/容器。
这里是我做了一个例子:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
private final static String PANEL1 = "panel 1";
private final static String PANEL2 = "panel 2";
public Test() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel1 = new JPanel();
panel1.add(new JLabel("Panel 1"));
JPanel panel2 = new JPanel();
panel2.add(new JLabel("Panel 2"));
//Create the panel that contains the "cards".
final JPanel cards = new JPanel(new CardLayout());
cards.add(panel1, PANEL1);
cards.add(panel2, PANEL2);
//create button to allow chnage to next card
JButton buttonNext = new JButton(">");
buttonNext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
CardLayout cl = (CardLayout) (cards.getLayout());//get cards
cl.next(cards);
}
});
//create button to allow chnage to previous card
JButton buttonPrev = new JButton("<");
buttonPrev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
CardLayout cl = (CardLayout) (cards.getLayout());//get cards
cl.previous(cards);
}
});
//create panel to hold buttons which will allow switching between cards
JPanel buttonPanel = new JPanel();
buttonPanel.add(buttonPrev);
buttonPanel.add(buttonNext);
frame.add(cards);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
2)使用removeAll()
技术,即调用frame.getContentPane().removeAll()
将目前取消对所有组件JFrame
,比添加新的内容,并呼吁revalidate()
和repaint()
也可能要添加pack()
在那里)在JFrame
实例,以反映变化。 虽然编号建议CardLayout
。
我想你可以只使用CardLayout
来实现你的函数。 请参考这里