Swing GUI没有更新

时间:2012-05-05 14:26:37

标签: java swing user-interface concurrency swingworker

我正在编写一个读取音频的应用程序,分析这些数据,然后实时显示结果。目前我正在使用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的内容。这会缩小它吗?

1 个答案:

答案 0 :(得分:1)

作为替代方案,使用javax.swing.Timer的实例,图示here开始停止播放所选{{1} },显示hereNote方法提供play(),它以异步方式运行,而SourceDataLine则构建enum Note特别容易。

Note

JComboBox