1

基本上,每次我点击我的一个 JButton 时,它都会锁定。我一直在环顾四周,发现可能是因为无限循环,但我在任何地方都看不到。

一双新鲜的眼睛会派上用场!

无论如何,这里是被声明的 JButtons:

public static JButton textYes = new JButton("Yes");
public static JButton textNo = new JButton("No");

这是我的 main() 方法:

public static void main(String[] args) throws IOException {
    Greed gui = new Greed();
    gui.launchFrame();
    redirectSystemStreams();

    Container contentPane = f.getContentPane();
    contentPane.add(new Greed());

    Scanner is = new Scanner(System.in);
    System.out.println("Welcome to Greed...");
        //do {
    System.out.println("Would you like to play? (yes/no)");
    area = "menu";
    menu = is.next();
}

下面是 Start() 方法:

public static void start(String menu) {
            switch (menu) {
                case "yes":
                    jTextArea1.setText(null);
                    diceOne = 0;
                    diceTwo = 0;
                    diceThree = 0;
                    diceFour = 0;
                    diceFive = 0;
                    System.out.println("Rolling...");
                    Game();

                    break;
                case "no":
                    System.out.println("Goodbye...");
                    System.exit(0);

                    break;
                default:
                    invalidInput();

                    break;
            }
}

这是带有 JButton 侦听器的 actionPerformed() 方法:

public void actionPerformed(ActionEvent e) {
    //jTextArea1.setText(null);
    if (box1.isSelected()) {
        System.out.println("1 is selected");
        willRerollDiceOne = true;
    }
    else {
        //System.out.println("1 not selected");
        willRerollDiceOne = false;
    }
    if (box2.isSelected()) {
        System.out.println("2 is selected");
        willRerollDiceTwo = true;
    }
    else {
        //System.out.println("2 not selected");
        willRerollDiceTwo = false;
    }
    if (box3.isSelected()) {
        System.out.println("3 is selected");
        willRerollDiceThree = true;
    }
    else {
        //System.out.println("3 not selected");
        willRerollDiceThree = false;
    }
    if (box4.isSelected()) {
        System.out.println("4 is selected");
        willRerollDiceFour = true;
    }
    else {
        //System.out.println("4 not selected");
        willRerollDiceFour = false;
    }
    if (box5.isSelected()) {
        System.out.println("5 is selected");
        willRerollDiceFive = true;
    }
    else {
        //System.out.println("5 not selected");
        willRerollDiceFive = false;
    }

    if ("menu".equals(area)) {
        if(e.getSource() == textYes){
            start("yes");
        }
        if(e.getSource() == textNo){
            start("no");
        }
    }
    if ("choiceReroll".equals(area)) {
        if(e.getSource() == textYes){
            choiceReroll = "yes";
        }
        if(e.getSource() == textNo){
            choiceReroll = "no";
        }
    }
}

我认为它以某种方式连接到 JButtons。

让我知道是否需要显示更多代码。

无论如何,任何和所有的帮助表示赞赏!

感谢您的帮助和时间!

编辑:对不起,我忘了显示连接到 JBUttons 的听众:

textYes.addActionListener(this);
textNo.addActionListener(this);

编辑:另外,这里是 Game() 方法:

public static void Game() {
    rollDiceOne();
    rollDiceTwo();
    rollDiceThree();
    rollDiceFour();
    rollDiceFive();

    displayDiceValues();
    f.validate();
    f.repaint();

    choiceRerollDice();
}

还有 rollDice# 方法:

public static void rollDiceOne() {
    diceOne = 1 + (int)(Math.random()*6);
}
public static void rollDiceTwo() {
    diceTwo = 1 + (int)(Math.random()*6);
}
public static void rollDiceThree() {
    diceThree = 1 + (int)(Math.random()*6);
}
public static void rollDiceFour() {
    diceFour = 1 + (int)(Math.random()*6);
}
public static void rollDiceFive() {
    diceFive = 1 + (int)(Math.random()*6);
}
4

3 回答 3

3

问题是您ActionListener在不使用新线程的情况下执行所有操作。这意味着您正在冻结 UI 线程,这基本上会阻止 UI 刷新。

您可以做的是ThreadactionPerformed方法中使用 a 。

public void actionPerformed(final ActionEvent e) {
    Thread t = new Thread() {
        public void run() {
            //jTextArea1.setText(null);
            if (box1.isSelected()) {
                System.out.println("1 is selected");
                willRerollDiceOne = true;
            }
            else {
                //System.out.println("1 not selected");
                willRerollDiceOne = false;
            }
            if (box2.isSelected()) {
                System.out.println("2 is selected");
                willRerollDiceTwo = true;
            }
            else {
                //System.out.println("2 not selected");
                willRerollDiceTwo = false;
            }
            if (box3.isSelected()) {
                System.out.println("3 is selected");
                willRerollDiceThree = true;
            }
            else {
                //System.out.println("3 not selected");
                willRerollDiceThree = false;
            }
            if (box4.isSelected()) {
                System.out.println("4 is selected");
                willRerollDiceFour = true;
            }
            else {
                //System.out.println("4 not selected");
                willRerollDiceFour = false;
            }
            if (box5.isSelected()) {
                System.out.println("5 is selected");
                willRerollDiceFive = true;
            }
            else {
                //System.out.println("5 not selected");
                willRerollDiceFive = false;
            }

            if ("menu".equals(area)) {
                if(e.getSource() == textYes){
                    start("yes");
                }
                if(e.getSource() == textNo){
                    start("no");
                }
            }
            if ("choiceReroll".equals(area)) {
                if(e.getSource() == textYes){
                    choiceReroll = "yes";
                }
                if(e.getSource() == textNo){
                    choiceReroll = "no";
                }
            }
        }
    };
    t.start();

}

使用线程将防止 UI 冻结

更新

正如 MadProgrammer 所说,在这种情况下,最好使用SwingWorker而不是 Thread

于 2013-06-20T19:58:16.873 回答
2

我怀疑它choiceRerollDice正在使用扫描仪来读取用户的输入,这会阻塞事件调度线程,从而阻止它被重新绘制。

您将 CLI 范式与 GUI 范式混合在一起,这又提出了一个问题,为什么?

使用图形界面时不应使用 CLI 样式输入(即Scanner),而应使用可用的图形控件,例如按钮或文本字段

于 2013-06-20T21:42:03.903 回答
1

看起来您从未将任何侦听器附加到按钮,而是尝试从 System.in 中读取。如果这是真的,那么程序将挂起,等待来自 System.in 的输入。

而不是拥有

Scanner is = new Scanner(System.in);
...
area = "menu";
menu = is.next();

在按钮上使用 actionListeners,与

textYes.addActionListener(/*Your Action Listener*/);
...

编辑 - 即使附加了 ActionListeners,它也会挂在 Scanner 行上,试图从输入流中读取。删除这些行应该可以解决它。

于 2013-06-20T19:50:19.670 回答