Java - задержка между событиями после ввода значения в JTextArea - PullRequest
1 голос
/ 09 января 2020

Я подготовил простую форму (javax.swing.JFrame), в которой находится JTextArea. После ввода значения «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);
    }
}

Основной класс:

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);
            }
        }
        );
    }
}

Как получить эффект отображения панели в форме в течение нескольких секунд после нажатия кнопки «TAB» в TextArea?

1 Ответ

2 голосов
/ 09 января 2020

Не блокируйте поток обработки событий 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. Иногда я забываю, что по умолчанию это будет повторяться , что могло бы сбить с толку.)

...