实现这一目的的正确方法是什么?

时间:2014-05-12 14:14:10

标签: java multithreading swing user-interface while-loop

我像这样开始我的GUI,这似乎是正确的。

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame gui = new JFrame();
            gui.setExtendedState(JFrame.MAXIMIZED_BOTH);
            gui.setVisible(true);
        }
    });

在应用程序的某个时刻,playTurn()方法被触发。 for循环全部在列表中转动。

 for (String turn : controller.getTurns()) {
                playTurn(turn);
            }

我现在用我的CardLayout加载正确的面板,效果很好。然后我不得不编写playTurn()方法。所以playTurn()被调用。它应该根据一些变量做某些事情。但是在禁用某些按钮之前不应该返回。这是我无法实现的,程序停止工作。我可以猜测它是在线程等的方向..但似乎无法弄明白。提前谢谢。

public void playTurn(String turn) {
    if (controller.givePlayers().contains(turn)) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                while (!turnFinished) {
                    if (!button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled()) {
                        turnFinished = true;
                    }
                }
            }
        });
    } else {
        deletePlayer(turn);
    }
}

抱歉格式不正确。无法找到。

编辑: GUI停止响应。也无法关闭程序。 我尝试使用SwingWorker for while,它不会阻止GUI,但仍会返回playTurn()。

我甚至尝试过创建一个我调用该方法的新线程。不会被阻止,但方法仍然会返回。

Thread one = new Thread() {
                    public void run() {
                        playTurn(turn);
                    }
                };

FIXED:将可运行的内容放在堆栈中更高的位置;

1 个答案:

答案 0 :(得分:3)

您的playTurn方法运行EDT上的代码,导致此行javax.swing.SwingUtilities.invokeLater(new Runnable() {,这会使您的应用程序GUI无响应,因为通常必须在{{ 1}}。由于您的按钮不会从GUI更改,因此一旦循环开始,它可能会永远循环。

通过在另一个EDT中运行代码,您不会冻结GUI。我猜,因为你没有提供关于其余代码的大量信息,所以你可能必须改变循环完成后处理事物的方式。

根据评论进行修改:由于您不希望Thread返回,请不要在其中使用线程,并确保playTurn未在playTurn上运行}。在创建并EDT运行代码后,您的playTurn方法将会返回。

你可能想尝试像这样:

Thread

确保您不在Runnable code = new Runnable() { @Override public void run() { for (String turn : controller.getTurns()) { playTurn(turn); } } }; if (!SwingUtilities.isEventDispatchThread()) { code.run(); } else { new Thread(code).start(); } 上运行代码。这样,EDT在满足循环条件之前不会返回,playTurn保持响应。

GUI

执行此操作可能会让您更改一些内容。

我们的想法是拨打新的public void playTurn(String turn) { if (controller.givePlayers().contains(turn)) { while (!turnFinished) { if (!button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled()) { turnFinished = true; } } } else { deletePlayer(turn); } } ,您不希望它/需要它等待新Thread中运行的代码结束以继续。