基本问题: 我用3" States"创建了一个游戏,每个状态都由同一个类中的方法启动。 每个方法都调用panel.removeAll();在静态面板上,显示游戏内容,然后我再次添加按钮,背景等面板。在第一个" Loop" (通过"循环"我的意思是所有3个国家的序列相互称呼,一切正常。
当状态3再次调用状态1时,所以当第二个循环启动时会出现以下问题: 当我点击JButton时,动作执行TWICE。在第三个循环中,它执行了三次!
那么我的问题是什么?是这样,我再次通过removeAll()和panel.add(JButton)添加按钮吗?
如果是这样,那么它的方式是什么?我应该创建不同的面板并一次设置一个不可见/可见的面板吗?不会导致沉重的重量"通过让所有图形一直加载在处理器上?
感谢您的帮助!
编辑: 这是一个例子:
package sscc;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class stuff extends JFrame implements ActionListener {
static stuff frame = new stuff();
static JPanel panel = new JPanel();
public static void main(String[] args){
//Setting up the Frame in MainMethod. Is that wrong?
frame.setSize(800, 600);
frame.setResizable(false);
frame.setLocationRelativeTo ( null );
frame.setUndecorated(true);
frame.add(panel); //
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.Phase1();
}
//Each Phase gets a Button to Enter the next one
JButton Next1 = new JButton("Next1");
JButton Next2 = new JButton("Next2");
JButton Next3 = new JButton("Next3");
public void Phase1(){
panel.removeAll();
panel.add(Next1);
Next1.setBounds(200,200,200,200);
Next1.setActionCommand("Phase1");
Next1.addActionListener(this);
}
public void Phase2(){
panel.removeAll();
panel.add(Next2);
Next2.setBounds(200,200,200,200);
Next2.setActionCommand("Phase2");
Next2.addActionListener(this);
}
public void Phase3(){
panel.removeAll();
panel.add(Next3);
Next3.setBounds(200,200,200,200);
Next3.setActionCommand("Phase3");
Next3.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if("Phase1".equals(e.getActionCommand())){System.out.println("Phase1Counter");Phase2();}
if("Phase2".equals(e.getActionCommand())){System.out.println("Phase2Counter");Phase3();}
if("Phase1".equals(e.getActionCommand())){System.out.println("Phase3Counter");Phase1();}
}
}
答案 0 :(得分:1)
对于每个阶段,您将再次将ActionListener添加到按钮。所以它会被多次调用。你的if子句中也有一个拼写错误:你两次检查“Phase1”。
您应该在初始步骤中(例如在main()方法中)将按钮添加到按钮中,而不是在阶段方法中。
答案 1 :(得分:1)
您的动作侦听器意外“触发”的原因是由于您在if
方法中处理actionPerformed
语句的方式。由于您使用三个单独的if
语句来检查操作命令,因此在完成方法之前将检查所有三个条件。
以下是正在发生的事情:第一次按下按钮时,您正在执行第一个if
块,但立即将操作命令更改为"Phase2"
方法中的Phase2
。完成第一个if
块后,到达第二个if
块并确定为真,因为您刚刚将操作命令更改为"Phase2"
!因此,当动作侦听器确实尚未执行时,它似乎再次执行。要纠正此行为,您应该使用if-else
块:
@Override
public void actionPerformed(ActionEvent e) {
if ("Phase1".equals(e.getActionCommand())) {
System.out.println("Phase1Counter");
Phase2();
} else if ("Phase2".equals(e.getActionCommand())) {
System.out.println("Phase2Counter");
Phase3();
} else if ("Phase1".equals(e.getActionCommand())) {
System.out.println("Phase3Counter");
Phase1();
}
}
一些进一步的建议:
就效率而言,最好重新使用JButton
而不是创建它们的多个副本。我想这三个按钮具有非常相似的功能。您可以创建一个JButton
并修改其执行的操作。
您应该避免使用setSize
,setMinimumSize
,setMaximumSize
和setPreferredSize
。这些方法旨在由布局管理器负责。您可能有兴趣阅读此问题:Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?此外,您应该熟悉A Visual Guide to Layout Managers中描述的不同布局管理器。
您不应在Event Dispatch Thread (EDT)之外运行与Swing GUI相关的代码,因为大多数Swing方法都不是线程安全的。
您应该遵循Java Naming Conventions以更好地保持代码的一致性,并在与其他人共享代码时更加清晰。