【问题标题】:jbutton action, setIcon is being executed at the end of actionjbutton 动作,setIcon 在动作结束时执行
【发布时间】:2011-06-25 22:27:00
【问题描述】:

我正在开发我的第一个 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));

【问题讨论】:

    标签: java awt jbutton actionlistener


    【解决方案1】:

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

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

    【讨论】:

    • 我在一个单独的类中转身,我将使用另一个类来调用主类,然后我将尝试等待和通知方法。我必须了解有关 EventQueue 的更多信息。顺便说一句,非常感谢 Paŭlo Ebermann 的快速回复。
    • 我找到了一个快速修复这个图标刷新的东西“update(getGraphics());”,它对我来说很好,也许它对其他人也有帮助。
    • 不,这不是一个好的解决方案。最好采纳 Paulo 和 Uhlen 的建议(各 1+)
    • @Paŭlo Ebermann 当我使用 SwingUtilities.invokeAndWait 时,代码进入调试模式,显示类 EventDispatchThread.run() 行:172。它锁定了。该程序仍在运行。它出现在相同代码的第二次执行中。所以我把 if (SwingUtilities.isEventDispatchThread( )) 放在相关代码之前,它在第二次执行时进入这个案例。是说主线程还在运行还是我的子线程在运行?我无法从 [link]download.oracle.com/javase/tutorial/uiswing/concurrency/… 清楚地理解
    • andWait 版本一直等到 EDT 有时间执行您的可运行文件,并且只有在您的可运行文件完成后,andWait 方法才会返回。我不知道您在 Runnable 中做了什么(也许将其添加到您的问题中)。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      阅读 Concurrency 上的 Swing 教程部分。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        相关资源
        最近更新 更多