Swing - Thread.sleep() stop JTextField.setText() working [duplicate]

你离开我真会死。 提交于 2019-11-26 19:10:06

When you use Thread.sleep() you're doing it on the main thread. This freezes the gui for five seconds then it updates the outputField. When that happens, it uses the last set text which is blank.

It's much better to use Swing Timers and here's an example that does what you're trying to accomplish:

if (match) {
    // Another class calculates
} else {
    outputField.setText("INPUT ERROR");
    ActionListener listener = new ActionListener(){
        public void actionPerformed(ActionEvent event){
            outputField.setText("");
        }
    };
    Timer timer = new Timer(5000, listener);
    timer.setRepeats(false);
    timer.start();
}

As Philip Whitehouse states in his answer, you are blocking the swing Event Dispatch Thread with the Thread.sleep(...) call.

Given that you've taken the time to set up an ActionListener already, it would probably be easiest to use a javax.swing.Timer to control clearing the text. To do this, you could add a field to your GUI class:

    private Timer clearTimer = new Timer(5000, this);

In the constructor for GUI, turn off the repeats feature, as you really only need a one-shot:

    public GUI() {
        clearTimer.setRepeats(false);
        createFrame();
    }

Then, actionPerformed can be modified to use this to start the timer/clear the field:

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == equals) {
            inputField.setText(inputField.getText().replaceAll("\\s", ""));
            String text = inputField.getText();
            System.out.println(text);
            Pattern equationPattern = Pattern.compile("[\\d(][\\d-+*/()]+[)\\d]");
            boolean match = equationPattern.matcher(text).matches();
            System.out.println(match);
            if (match) {
                // Another class calculates
            } else {
                clearTimer.restart();
                outputField.setText("INPUT ERROR"); // This doesn't appear
            }
        } else if (e.getSource() == clearTimer) {
            outputField.setText("");
        }
    }

You're doing a Thread.sleep() in the Swing main thread. This is NOT good practice. You need to use a SwingWorker thread at best.

What's happening is that it's running the first line, hitting Thread.sleep().

This prevents the (main) EDT thread from doing any of the repaints (as well as preventing the next line executing).

You should use a javax.swing.Timer to setup the delayed reaction and not put sleep() calls in the main thread.

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