2

我正在开发我的第一个awt游戏。我试图在单击按钮时将图标设置为按钮(在某些情况下)。这是代码的相关部分:

if (tileIsMemTile) {
        System.out.println("!!! Right Tile !!!");
        memTile.setBackground(Color.red);
        numberOfMemTilesToGuess -= 1;
        System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess");
    } else {
        System.out.println("!!! Wrong Tile !!!");
        Icon falseTileIcon = new ImageIcon(getClass().getResource("wrong.png"));
        memTile.setIcon(falseTileIcon);
        wrongGuessAction();         
    }

    System.out.println(">>> Action processed >>>");

    if (numberOfMemTilesToGuess == 0) {
        System.out.println("\n END OF THE LEVEL");
        System.out.println("Congratulations, you guessed all the tiles without error !! \n");

        dispose();
        //TODO  !!!! SHOW INTERLEVEL INFORMATION !!!!

        if (memGridDimX != maxDimX && memGridDimY != maxDimY) {
            if (memGridDimX == memGridDimY)
                new Memory(memGridDimX, memGridDimY + 1);
            else
                new Memory(memGridDimX + 1, memGridDimY);
        } else
            System.out.println("You have a really good memory my friend!");
    }
}

private void wrongGuessAction() {
    //TODO !!! FAILED IN LEVEL MESSAGE !!!

    try { Thread.sleep(2000); } catch (Exception e1) {}
    dispose();

    if (memGridDimX == initialDimX && ( memGridDimY == initialDimY || memGridDimY == initialDimY + 1))  
        new Memory(initialDimX, initialDimY);
    else
        new Memory(memGridDimX - 1, memGridDimY - 1);
}

所以在这里我设置了jbutton的图标之后,我想在处理旧的jframe并启动新的jframe之前看到它(游戏中的下一个级别)。但是尽管试图通过以下方式延迟执行dispose()函数:

尝试 { Thread.sleep(2000); } 捕捉(异常 e1){}

以及任何其他延迟功能(例如比较 currenttimemillis(), to-t1),我什至尝试使用;

memTile.setBackground(Color.green);
int i = 0;
do {
System.out.println(i); i++;
} while (!memTile.getIcon().equals(Color.green));

实际上最后一个似乎正在工作,但eclipse毫无例外地跳转到调试模式,即使我关闭框架它也不会终止进程。

所以没有任何效果。在每种情况下,框架都会关闭,我看不到按钮上的图标。如果我评论 dispose 并让它创建下一个框架,旧框架将保留,图标加载到按钮上,并且正在创建新框架。我无法理解 setIcon 方法的执行原理。

提前致谢。

// memTile.setBackground(Color.green); // int i = 0; // 做 { //
// System.out.println(i); 我++;// } while (!memTile.getIcon().equals(Color.green));

4

3 回答 3

2

ActionListenerAWT 事件分派线程上调用。同一个线程还处理任何其他事件,如绘画。因此,只要您的actionPerformed()方法不返回,就不会绘制任何内容(或 GUI 上的任何其他内容都已更改)。

EventQueue.invokeLater您应该在此线程之外执行更长时间运行的操作(即启动一个新线程执行此操作),然后为 GUI 更改稍后使用(或)回调EventQueue.invokeAndWait

于 2011-02-12T01:48:00.577 回答
1

我必须了解有关 EventQueue 的更多信息。

阅读 Swing 教程中关于并发的部分。

也许您的 Thread.sleep(...) 代码应该替换为 Swing Timer。Swing 教程还有一个关于“如何使用 Swing 计时器”的部分。

于 2011-02-12T03:31:31.397 回答
1

Paŭlo Ebermann 给出了正确的答案,但我只想补充一点,不要在事件调度线程上睡觉!那只会让事情变得更糟。Swing 是强大的工具包,但它对错误线程的容忍度(在 EDT 上休眠,在 EDT 之外更新 UI)是恕我直言,人们在使用 Swing 时遇到问题的第一大原因。如果在这种情况下它会因RuntimeException而失败,则会暴露很多错误,因此更容易修复。

于 2011-02-12T01:58:27.860 回答