我有一个带有一些 JButtons
的 JFrame
。 “更新”按钮(名为JButton1
)执行许多填充表单的查询。
现在我希望另一个 JButton
成为“自动更新”(名为 JButton2
),因此我希望它在 JButton1ActionPerformed
内循环方法,直到不再选择 JButton2
。
当我按下 JButton2
时,窗口卡住。
我的代码正确吗?您认为我需要一个停止按钮吗?
private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) {
long start = System.currentTimeMillis();
if(jToggleButton2.isSelected()){
start = System.currentTimeMillis();
do{
do{
jButton1ActionPerformed(evt);
}
while(System.currentTimeMillis()-start>3000);
}
while(jToggleButton2.isSelected());
}
if(jToggleButton2.isSelected()){
jToggleButton2.setSelected(false);
}
}
最佳答案
Swing 是:
- 单线程;这意味着您不应在事件调度线程的上下文中执行任何长时间运行或阻塞的操作
- 不是线程安全的;这意味着您不应在 EDT 之外更新 UI 或 UI 可能依赖的任何内容。尝试在 EDT 之外处理 UI 元素也是有风险的,因为线程模型可能返回错误值
如果没有更多的背景信息来解决您的问题,我可能建议使用 Swing Timer
。两个主要原因:
ActionListener
在 EDT 上下文中调用,从而可以安全地从内部更新 UI- 您可以指定更新之间的延迟,这可以降低 EDT 过载而导致性能问题的风险
例如...
private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) {
long start = System.currentTimeMillis();
if (jToggleButton2.isSelected()) {
// You could use an instance field instead and determine
// if the Timer is already running or not
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!jToggleButton2.isSelected()) {
((Timer) e.getSource()).stop();
return;
}
jButton1ActionPerformed(evt);
}
});
timer.start();
// Just want to point out that this doesn't make sense
// As if the button was selected, you'd still be in
// your previous loop
//if (jToggleButton2.isSelected()) {
// jToggleButton2.setSelected(false);
//}
}
}
另一个解决方案可能是使用 SwingWorker
,它为您提供了一种在 EDT 之外执行长时间运行或阻塞操作的方法,但它还提供了从 EDT 内安全更新 UI 的功能.
看一下:
了解更多详情
关于java - While 循环重复 JButton 的 actionPerformed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47357803/