Java JTextField不';t使用Thread.sleep()更新
我正在试图找出文本字段没有更新的原因。我知道使用SwingWorker可能会解决这个问题,但我不明白为什么它一开始就不起作用Java JTextField不';t使用Thread.sleep()更新,java,multithreading,jtextfield,Java,Multithreading,Jtextfield,我正在试图找出文本字段没有更新的原因。我知道使用SwingWorker可能会解决这个问题,但我不明白为什么它一开始就不起作用 public class waitExample { private JFrame frame; private JTextField txtLeadingText; private String one = "update string 1"; private String two = "update string 2"; private String three =
public class waitExample {
private JFrame frame;
private JTextField txtLeadingText;
private String one = "update string 1";
private String two = "update string 2";
private String three = "update string 3";
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
waitExample window = new waitExample();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public waitExample() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
txtLeadingText = new JTextField();
txtLeadingText.setHorizontalAlignment(SwingConstants.CENTER);
txtLeadingText.setText("leading text");
frame.getContentPane().add(txtLeadingText, BorderLayout.SOUTH);
txtLeadingText.setColumns(10);
JButton btnClickMeTo = new JButton("CLICK ME TO UPDATE TEXT");
btnClickMeTo.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
try {
updateOne();
Thread.sleep(1000);
updateTwo();
Thread.sleep(1000);
updateThree();
Thread.sleep(1000);
updateLast();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
frame.getContentPane().add(btnClickMeTo, BorderLayout.CENTER);
}
private void updateOne() {
txtLeadingText.setText(one);
}
private void updateTwo() {
txtLeadingText.setText(two);
}
private void updateThree() {
txtLeadingText.setText(three);
}
private void updateLast() {
txtLeadingText.setText("default text");
}
}
据我所知,默认线程将阻止任何GUI更新。这不重要,因为我在Thread.sleep之前设置了textField。
为什么文本字段不更新?不应该设置文本,然后线程等待吗
编辑:根据答案,上述代码已更新。GUI事件循环更新屏幕,但在您返回之前无法更新屏幕
我建议您避免在GUI事件线程中执行任何阻塞操作。GUI事件循环会更新屏幕,但在您返回之前它无法更新屏幕
我建议您避免在GUI事件线程中执行任何阻塞操作。您正在调用
thread.sleep(1000)代码>在EDT上。这意味着当您的方法结束时-只有在之后的某个时间点才会触发repaint()
在此之前,您的GUI将被冻结
假设这是在一个线程上进行的(因此处理非常简单):
您正在调用Thread.sleep(1000)代码>在EDT上。这意味着当您的方法结束时-只有在之后的某个时间点才会触发repaint()
在此之前,您的GUI将被冻结
假设这是在一个线程上进行的(因此处理非常简单):
进一步解释:当您调用像txtLeadingText.setText(one)
这样的函数时,GUI上显示的文本不会立即更新。相反,文本字段的内部变量将更改,它还将通知Swing队列需要重新绘制。因为这是通过事件队列进行的,所以它只在函数返回后通过repaint()
运行。@AlexGittemeier根据答案和您的注释,我已经更改了代码(请参阅文章)。更新后的代码反映了我从您的评论中理解的内容,尽管它仍然无法修复错误。如果“重新绘制();”从方法返回后调用,所有内容是否都应正确更新?@Aaron这仍然在同一线程中执行。现在它是这样的:输入mouseClicked()
->输入updateOne()
->退出updateOne()
->输入…
->退出mouseClicked()
->执行重新绘制()
@Xeon所以在退出mouseClicked()之前不会调用“重新绘制()“?进一步解释:当调用像txtLeadingText.setText(one)
这样的函数时,GUI上显示的文本不会立即更新。相反,文本字段的内部变量将更改,它还将通知Swing队列需要重新绘制。因为这是通过事件队列进行的,所以它只在函数返回后通过repaint()
运行。@AlexGittemeier根据答案和您的注释,我已经更改了代码(请参阅文章)。更新后的代码反映了我从您的评论中理解的内容,尽管它仍然无法修复错误。如果“重新绘制();”从方法返回后调用,所有内容是否都应正确更新?@Aaron这仍然在同一线程中执行。现在是这样的:输入mouseClicked()
->输入updateOne()
->退出updateOne()
->输入…
->退出mouseClicked()
->执行重新绘制()
@Xeon所以在退出“mouseClicked()”之前不会调用“重新绘制()”?
txtLeadingText.setText(one);
Thread.sleep(1000);
txtLeadingText.setText(two);
Thread.sleep(1000);
txtLeadingText.setText(three);
Thread.sleep(1000);
...
<returning from updateText()>
<processing other events on button click>
...
// some time later
<Swing finds out that GUI needs repaint: calls rapaint()>
public class MyRunnable implements Runnable {
private List<String> strsToSet;
public MyRunnable(List<String> strsToSet) {
this.strsToSet = strsToSet;
}
@Override
public void run() {
try {
if(strsToSet.size() > 0) {
final String str = strsToSet.get(0);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
txtLeadingText.setText(str);
}
});
Thread.sleep(1000);
List<String> newList = new LinkedList<String>(strsToSet);
newList.remove(0);
new Thread(new MyRunnable(newList)).start();
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
new Thread(new MyRunnable(Arrays.asList(one, two, three))).start();
edt {
textField.setText(one)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(two)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(three)
}
}
}
}
}