Dispose a frame inside a listener after 3 secs

僤鯓⒐⒋嵵緔 提交于 2019-12-13 08:26:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!