JPanel" Loop" / Buttons由" panel.removeAll()重复;"?

时间:2014-07-07 10:19:04

标签: java swing loops jpanel

基本问题: 我用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();}
    }   
}

2 个答案:

答案 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();
    }
}

一些进一步的建议:

  1. 就效率而言,最好重新使用JButton而不是创建它们的多个副本。我想这三个按钮具有非常相似的功能。您可以创建一个JButton并修改其执行的操作。

  2. 您应该避免使用setSizesetMinimumSizesetMaximumSizesetPreferredSize。这些方法旨在由布局管理器负责。您可能有兴趣阅读此问题:Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?此外,您应该熟悉A Visual Guide to Layout Managers中描述的不同布局管理器。

  3. 您不应在Event Dispatch Thread (EDT)之外运行与Swing GUI相关的代码,因为大多数Swing方法都不是线程安全的。

  4. 您应该遵循Java Naming Conventions以更好地保持代码的一致性,并在与其他人共享代码时更加清晰。