我正在为温度计JFreeChart编程,但我不想看到它只显示一个值...我需要将最终值放入JTextField(然后按一个按钮),看看水银是怎么回事从0º到最终值,我想看看水银是如何上升的。
我使用Thread.sleep(500)创建了一个FOR(从0到最终值),然后使用FOR中的索引更新数据集值,但它没有显示转换,它完成FOR并最终返回显示最终值的温度计。我试图刷新图表,但它没有用。
我的按钮中的代码
final JButton btnAccept = new JButton("Accept");
btnAceptar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for(int i = 0; i <= 40; i++) {
try {
Thread.sleep(500);
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
dataset.setValue(i);
}
}
});
panel.add(btnAceptar);
答案 0 :(得分:1)
Swing是一个单线程框架。也就是说,期望对UI的所有交互和修改都在事件调度线程的内容中执行。
阻止此线程的任何操作都将阻止EDT开始处理重绘请求和处理新事件(以及其他事项)。
您遇到的问题是,actionPerformed
事件是在EDT的上下文中触发的。您的for-next
循环现在阻止了EDT,阻止了处理任何绘制请求......
使用javax.swing.Timer
定期触发事件并更新dataset
值,直至达到所需目标,然后停止计时器。
例如......
final JButton btnAccept = new JButton("Accept");
btnAceptar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
dataset.setValue(0);
Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int current = dataset.getValue();
if (current < 40) {
current++;
dataset.setValue(current);
} else {
((Timer)evt.getSource()).stop();
}
}
});
timer.start();
}
});
panel.add(btnAceptar);
使用在其SwingWorker
方法中使用for-next
循环的doInBackground
,发布新值,该值将在process
方法中使用,该方法已执行在美国东部时间的背景下...
例如......
final JButton btnAccept = new JButton("Accept");
btnAceptar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
SwingWorker worker = new SwingWorker<Object, Integer> {
protected Object doInBackground() {
for(int i = 0; i <= 40; i++) {
try {
Thread.sleep(500);
}
catch(InterruptedException ex) {
break;
}
publish(i);
}
}
protected void process(List<Integer> chunks) {
// Only care about the last update...
dataset.setValue(chunks.get(chunks.size() - 1));
}
}
}
});
panel.add(btnAceptar);
滚动您自己的Thread
,这会在for-next
方法中使用run
循环,但您必须使用SwingUtilities.invokeLater
来更新dataset
在EDT的背景下,这是一个混乱和麻烦,特别是与其他两个选项......
查看Concurrency in Swing了解更多详情