问题
I want to dispose the frame 3 seconds after I type a key. Here is my code:
frame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
Timer t = new Timer(3000, null);
t.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test");
frame.dispose();
}
});
t.start();
}
}
I can see from the console the printed string but the frame is not closing. I've seen a similar thread and use the Timer seemed to be the solution but it's not working for me.
回答1:
frame.dispose()
isn't guarenteed to execute immediately. I've found calling frame.setVisible(false)
first helps speed up the disposing process.
EDIT
Also, you might want to look at using Key Bindings instead of key listeners for triggering your event. Key Listeners are complicated and generally not very useful (they require focus on the item you're interacting with, they tend to consume events so you don't see them).
EDIT 2
After further examination of your code, the problem seems to be that you need to set the timer to not repeat (before you call start):
t.setRepeats(false);
This example works for me - let me know if you're still experiencing a problem (and if so, please post a runnable example of the problem you're experiencing - I can only guess at any additional code that could cause problems):
import java.awt.event.*;
import javax.swing.*;
public class QuickTest {
public QuickTest(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
Timer t = new Timer(3000, null);
t.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test");
frame.dispose();
}
});
t.setRepeats(false);
t.start();
}
});
}
public static void main(String[] args){
new QuickTest();
}
}
回答2:
Seems to work fine for me.
Make sure that the setDefaultCloseOperation
is not set to DO_NOTHING
as it will, do nothing
public class TestCloseFrame {
public static void main(String[] args) {
new TestCloseFrame();
}
public TestCloseFrame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
JButton close = new JButton("Close");
close.addActionListener(new CloseAction(frame, close));
frame.add(close);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CloseAction implements ActionListener {
private JButton button;
private JFrame frame;
private int count = 0;
public CloseAction(JFrame frame, JButton button) {
this.button = button;
this.frame = frame;
}
@Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count++;
button.setText(Integer.toString(4 - count));
if (count > 3) {
frame.dispose();
Timer timer = (Timer) e.getSource();
timer.stop();
}
}
});
timer.setInitialDelay(0);
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
}
}
来源:https://stackoverflow.com/questions/13475255/dispose-a-frame-inside-a-listener-after-3-secs