Swing - Thread.sleep()停止JTextField.setText()工作 [英] Swing - Thread.sleep() stop JTextField.setText() working

查看:106
本文介绍了Swing - Thread.sleep()停止JTextField.setText()工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

对单个线程使用sleep()

使用Thread.sleep()时,我遇到了JTextField.setText()的问题。这是我正在制作的基本计算器。当输入字段中的输入格式不正确时,我希望INPUT ERROR出现在输出字段中5秒钟,然后清除它。当我将文本设置为INPUT ERROR时,setText()方法 工作并且通过在其间打印文本我发现它确实与它和setText()一起工作在另一个之后。当我在它们之间放置Thread.sleep()时会出现问题。
这是代码的SSCCE版本:

I'm having issues with JTextField.setText() when using Thread.sleep(). This is for a basic calculator I'm making. When the input in the input field is not of the correct format I want "INPUT ERROR" to appear in the output field for 5 seconds and then for it to be cleared. The setText() method did work when I just set the text once to "INPUT ERROR" and by printing out the text in between I found it does work with both that and the setText("") one after the other. The problem arises when I put the Thread.sleep() between them. Here's a SSCCE version of the code:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.regex.Pattern;
import javax.swing.*;

public class Calc {
    static Calc calc = new Calc();

    public static void main(String args[]) {
        GUI gui = calc.new GUI();
    }

    public class GUI implements ActionListener {

        private JButton equals;

        private JTextField inputField, outputField;

        public GUI() {
            createFrame();
        }

        public void createFrame() {
            JFrame baseFrame = new JFrame("Calculator");
            baseFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel contentPane = new JPanel();
            BoxLayout layout = new BoxLayout(contentPane, BoxLayout.Y_AXIS);
            contentPane.setLayout(layout);
            baseFrame.setContentPane(contentPane);
            baseFrame.setSize(320, 100);

            equals = new JButton("=");
            equals.addActionListener(this);

            inputField = new JTextField(16);
            inputField.setHorizontalAlignment(JTextField.TRAILING);
            outputField = new JTextField(16);
            outputField.setHorizontalAlignment(JTextField.TRAILING);
            outputField.setEditable(false);

            contentPane.add(inputField);
            contentPane.add(outputField);
            contentPane.add(equals);

            contentPane.getRootPane().setDefaultButton(equals);
            baseFrame.setResizable(false);
            baseFrame.setLocation(100, 100);

            baseFrame.setVisible(true);
        }

        /**
         * When an action event takes place, the source is identified and the
         * appropriate action is taken.
         */

        @Override
        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 {
                    try {
                        outputField.setText("INPUT ERROR"); // This doesn't appear
                        Thread.sleep(5000);
                        outputField.setText("");
                    } catch (InterruptedException e1) {
                    }
                }
            }
        }
    }
}

我实际上并没有使用嵌套类,但我希望它能够包含在一个类中。抱歉GUI看起来如何,但这又是为了减少代码。重要部分( if(e.getSource()== equals))与我的代码保持不变。提供错误输入的最简单方法是使用字母。

I'm not actually using a nested class but I wanted it to be able to be contained in one class for you. Sorry about how the GUI looks but again this was to cut down the code. The the important section (if (e.getSource() == equals)) remains unchanged from my code. The simplest way to give an incorrect input is to use letters.

推荐答案

当您使用 Thread.sleep时()你是在主线程上做的。这会冻结gui五秒钟,然后更新 outputField 。当发生这种情况时,它使用最后设置的文本为空白。

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.

使用 Swing Timers 和这里有一个例子来说明你想要完成的事情:

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

这篇关于Swing - Thread.sleep()停止JTextField.setText()工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆