gpt4 book ai didi

java - JTextField 不随 Thread.sleep() 更新

转载 作者:行者123 更新时间:2023-12-01 18:48:04 25 4
gpt4 key购买 nike

我试图找出文本字段未更新的原因。我知道使用 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 = "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。为什么文本字段不更新?难道不应该设置文本,然后线程等待吗?

编辑:根据答案,上述代码已更新。

最佳答案

您正在 EDT 上调用 Thread.sleep(1000);。这意味着当你的方法结束时 - 只有那时 repaint() 才会触发(在稍后的某个时间点)。

在此之前,您的 GUI 会被卡住。

考虑这是在一个线程上进行的(因此处理很简单):

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

这在 Swing 中很难做到,但与动态语言(如 Groovy)相比,它会变得如此简单(您将更好地掌握正在发生的事情):

    edt { 
textField.setText(one)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(two)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(three)
}
}
}
}
}

关于java - JTextField 不随 Thread.sleep() 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16860745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com