Swing GUI 不更新
Posted
技术标签:
【中文标题】Swing GUI 不更新【英文标题】:Swing GUI not updating 【发布时间】:2012-05-05 14:26:37 【问题描述】:我正在编写一个应用程序,它可以读取音频,分析这些数据,然后实时显示结果。目前,我正在使用 SwingWorker 运行启动后台分析的循环,并在每次分析完成时调用循环内的 SwingUtilities.invokeLater 方法来更新 GUI 组件。目前,GUI 似乎在随机更新,有时根本不更新。
以下代码显示了我是如何尝试完成此任务的。 TunerListener 是 JPanel 子类的内部类。 PrevNote、nextNote、frequency、light 变量都是我要更新的 JPanel 子类中的组件:
private class TunerListener implements ActionListener
private boolean firstUpdate = true;
private boolean executing = false;
private TunerWorker tunerWorker = null;
private final class TunerWorker extends SwingWorker<Void, Void>
@Override
protected Void doInBackground()
while (!this.isCancelled())
// Audio analysis in worker thread
model.update(firstUpdate);
// Update components in EDT
if (!this.isCancelled())
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
prevNote.setText(model.getPrev());
currentNote.setText(model.getNote());
nextNote.setText(model.getNext());
frequency.setText("Frequency: "
+ model.getFrequency());
switch (model.getOffset())
case -2:
light_2.setIcon(onRed);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case -1:
light_2.setIcon(off);
light_1.setIcon(onRed);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case 0:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(onGreen);
light1.setIcon(off);
light2.setIcon(off);
break;
case 1:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(onRed);
light2.setIcon(off);
break;
case 2:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(onRed);
break;
firstUpdate = false;
);
return null;
@Override
protected void done()
;
@Override
public void actionPerformed(ActionEvent ae)
if (ae.getActionCommand().equals("tune"))
if (!executing)
executing = true;
firstUpdate = true;
tune.setText("Stop Tuning");
tunerWorker = new TunerWorker();
tunerWorker.execute();
else
tune.setText("Start Tuning");
executing = false;
tunerWorker.cancel(true);
编辑 我注意到,当我使用调试器时,有时我会告诉我找不到源,并且在调试窗口中它会显示有关 FutureTask$Sync.innerRun 的信息。这会缩小范围吗?
【问题讨论】:
您是否尝试过 GUI 组件或框架的 validate() 和 repaint() 方法? 我认为您不需要将代码放入SwingUtilities.invokeLater(...)
thingy,这是 SwingWorker。此外,因为在我看来,您尝试更新的内容都是String
(如果我没记错的话),那么您可以简单地调用publish()
,这反过来又会调用process(...)
,如果总是在EDT .我猜你的SwingWorker<Void, String>
的第二个参数应该是String
而不是Void
为了更好的帮助,请尽快使用SSCCE编辑您的问题
【参考方案1】:
作为替代方案,使用javax.swing.Timer
的实例(图示为here)开始和停止播放选定的Note
,显示为@987654322 @。 play()
方法提供了一个异步操作的 SourceDataLine
,enum Note
使得构造 JComboBox
变得特别容易。
final JComboBox combo = new JComboBox();
for (Note note : Note.values())
combo.addItem(note);
combo.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
System.out.println(combo.getSelectedItem());
);
this.add(combo);
【讨论】:
以上是关于Swing GUI 不更新的主要内容,如果未能解决你的问题,请参考以下文章
Swing GUI 客户端侦听器未响应远程 RMI 属性的更新