PEl*_*hen 5 java swing jtextfield thread-sleep
可能重复:
对单个线程使用sleep()
使用Thread.sleep()时,我遇到了JTextField.setText()的问题.这是我正在制作的基本计算器.当输入字段中的输入格式不正确时,我希望"INPUT ERROR"在输出字段中出现5秒钟,然后清除它.当我只将文本设置为"INPUT ERROR"并打印出中间的文本时,setText()方法确实有效,我发现它确实可以同时使用它和setText("").当我在它们之间放置Thread.sleep()时会出现问题.这是代码的SSCCE版本:
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) {
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我实际上并没有使用嵌套类,但我希望它能够包含在一个类中.很抱歉GUI看起来如何,但这又是为了减少代码.重要部分(if (e.getSource() == equals))与我的代码保持不变.提供错误输入的最简单方法是使用字母.
aly*_*aly 12
当你使用Thread.sleep()你在主线程上做它.这冻结gui五秒然后它更新了outputField.当发生这种情况时,它使用最后设置的文本,该文本为空白.
使用Swing Timers会更好,这里有一个例子可以完成你想要完成的任务:
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();
}
Run Code Online (Sandbox Code Playgroud)
你Thread.sleep()在Swing主线程中做了一个.这不是一个好习惯.你SwingWorker最多需要使用一个线程.
发生了什么事情,它正在运行第一线,击中Thread.sleep().
这可以防止(主)EDT线程执行任何重绘(以及阻止下一行执行).
您应该使用a javax.swing.Timer来设置延迟反应,而不是sleep()在主线程中调用.
正如菲利普怀特豪斯在他的回答中所述,你正在通过电话阻止摆动事件派遣线程Thread.sleep(...).
鉴于您已经花时间设置了一个ActionListener,最简单的方法是使用a javax.swing.Timer来控制清除文本.为此,您可以向GUI班级添加字段:
private Timer clearTimer = new Timer(5000, this);
Run Code Online (Sandbox Code Playgroud)
在构造函数中GUI,关闭重复功能,因为你真的只需要一次性:
public GUI() {
clearTimer.setRepeats(false);
createFrame();
}
Run Code Online (Sandbox Code Playgroud)
然后,actionPerformed可以修改使用它来启动计时器/清除字段:
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("");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9151 次 |
| 最近记录: |