I prepared a simple form (javax.swing.JFrame) on which JTextArea is located. After entering the "TAB" value, I would like to see a visible JPanel on the form for a few seconds. Unfortunately, when I have the following events:
<br>
JPanel.setVisible (true); <br>
TimeUnit.SECONDS.sleep (3); <br>
JPanel.setVisible (false); <br>
in keyPressed for JTextArea.KeyListener ()
they don't execute one after another - first I get sleep, then JPanel.setVisible (true) and 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);
}
}
Main 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);
}
}
);
}
}
How can I get the effect of showing the panel on the form for a few seconds after entering the "TAB" button on TextArea?
Don't block the AWT Event Dispatch Thread (EDT).
Instead, set a javax.swing.Timer
(get the package right - not the other one!). The Swing Timer
may create another thread to do the timing, but posts the event back through the EDT (via java.awt.EventQueue.invokeLater
or similar). The code executed after the sleep
should be move to an action listener.
pnl2.setVisible(true);
javax.swing.Timer timer =
new javax.swing.Timer(3000, event -> {
pnl2.setVisible(false);
});
timer.setRepeats(false);
timer.start();
(I have used the fully qualified name to emphasize the right Timer
. Sometimes I forget that by default it will repeat, which would be confusing.)