Java - 将值输入 JTextArea 后事件之间的延迟

Java - delay between events after entering the value into JTextArea

我准备了一个 JTextArea 所在的简单表单 (javax.swing.JFrame)。 输入 "TAB" 值后,我希望在窗体上看到一个可见的 JPanel 几秒钟。不幸的是,当我遇到以下事件时:

 <br>
JPanel.setVisible (true); <br>
TimeUnit.SECONDS.sleep (3); <br>
JPanel.setVisible (false); <br>
in keyPressed for JTextArea.KeyListener ()

他们不会一个接一个地执行 - 首先我睡觉,然后 JPanel.setVisible (true) 和 JPanel.setVisible (false)

public class Form1 extends JFrame {

    JTextArea txt1 = new JTextArea();
    JPanel pnl2 = new JPanel();

    public Form1() {

        txt1.setLocation(10, 10);
        txt1.setSize(100, 30);
        txt1.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e
            ) {
                if (e.getKeyCode() == KeyEvent.VK_TAB) {
                    e.consume();

                    pnl2.setVisible(true);
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Form1.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    pnl2.setVisible(false);
                }
            }

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent e
            ) {
            }
        });
        add(txt1);

        pnl2.setLayout(null);
        pnl2.setLocation(10, 150);
        pnl2.setSize(100, 100);
        pnl2.setBorder(BorderFactory.createEtchedBorder());
        pnl2.setVisible(false);
        add(pnl2);
    }
}

主要class:

public class Main {

    public static void main(String[] args)  {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Form1 f = new Form1()
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setSize(500, 400);
                f.setLocationRelativeTo(null);
                f.setResizable(false);
                f.setLayout(null);
                f.setVisible(true);
            }
        }
        );
    }
}

如何实现在TextArea上输入"TAB"按钮后在窗体上显示面板几秒的效果?

不要阻塞 AWT 事件调度线程 (EDT)。

相反,设置一个 javax.swing.Timer(获取正确的包 - 而不是另一个!)。 Swing Timer 可能会创建另一个线程来进行计时,但会通过 EDT(通过 java.awt.EventQueue.invokeLater 或类似方式)将事件发回。 sleep 之后执行的代码应该移至动作侦听器。

                pnl2.setVisible(true);
                javax.swing.Timer timer =
                    new javax.swing.Timer(3000, event -> {
                        pnl2.setVisible(false);
                    });
                timer.setRepeats(false);
                timer.start();

(为了强调正确Timer,我使用了完全限定名。有时我忘记了默认情况下它会重复,这会造成混淆。)