为什么我的 Thread.sleep() 没有按预期工作?

Owe*_*ish 2 java sleep

我的代码目前看起来像这样,我想在发布代码发生之后、游戏开始之前延迟该过程,但目前看起来好像发布代码根本没有发生。看起来好像在延迟之后,立即开始,这是我不希望的。如果有人可以帮忙,谢谢。

这是我的代码。

startButton.addMouseListener(new MouseListener() {
    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // Press
        startButton.setPreferredSize(new Dimension(240, 240));
        startButton.setIcon(startButtonHover);
        FRAME.pack();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // Release
        // NOT TRIGGERING AT ALL
        startButton.setPreferredSize(new Dimension(256, 256));
        startButton.setIcon(startButtonImage);
        FRAME.pack();

        try {
            Thread.sleep(400);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
        }

        // Game Start
        FRAME.remove(menuPanel);
        FRAME.revalidate();
        FRAME.repaint();

    }

});
Run Code Online (Sandbox Code Playgroud)

rzw*_*oot 7

几乎所有 UI 系统(Swing(您在这里使用的)就是其中之一)都有一个称为“事件调度程序线程”(Event Dispatcher Thread)或 EDT 的概念。

EDT 有很多属性:

  • 这样的线程只有一个。
  • 与 UI 的任何交互(例如jLabel.setText("Hello")删除或添加小部件、更改某些内容的颜色等)都必须从 EDT 完成。如果你从任何其他线程执行此操作,就会发生奇怪的事情。
  • 所有事件处理程序(例如,鼠标单击代码等)都在 EDT 内运行。
  • 您绝不能阻止 EDT。EDT 是负责确保您的程序在用户在应用程序窗口上拖动另一个窗口时重新绘制自身的线程(操作系统不记得这些像素!操作系统只是要求应用程序重新绘制自身;有时鼠标指针是不是硬件精灵并在其尾迹中留下“踪迹”)。EDT 也是负责处理的线程,例如,如果用户按下按钮但没有放开,则该按钮将被重新绘制为“现在已按下”的外观。

您是否见过这样的 napp 崩溃,即使按下按钮也不会执行任何操作,或者一旦隐藏并重新显示它,甚至拖动任何窗口越过它,它就会变成暗灰色?

那将是一个违反该规则的应用程序。

在这里,您正在美国东部时间 (EDT) 睡觉。这是禁止的

阻止行为:

  • 与数据库对话
  • 打开文件
  • 与网络上的任何事物交互
  • 等待一个线程。
  • 任何synchronized东西。
  • Thread.sleep
  • 还有很多很多。任何会导致线程休眠的事情,因为它无法继续,直到发生某些事件(磁盘已准备好字节,一段时间过去,锁变为空闲,等等)。

解决方案不是休眠 400 毫秒然后采取行动。解决方案是创建一个等待 400 毫秒的新线程,然后将删除、重新验证和重新绘制的代码注入 EDT(毕竟,该线程不是 EDT,因此您可以在其中等待 400 毫秒) ,但您无法对 UI 进行操作,因为您只能在 EDT 中执行此操作)。

这很烦人,但有点常见,所以 swing 有一个专门的东西:SwingTimer