简体   繁体   English

Swing GUI不更新

[英]Swing GUI not updating

I'm writing an application that reads in audio, analyses this data and then displays the results in realtime. 我正在编写一个应用程序,它可以读取音频,分析这些数据,然后实时显示结果。 Currently I am using a SwingWorker to run the loop that initiates the background analysis and calling the SwingUtilities.invokeLater method inside the loop to update the GUI components each time analysis has completed. 当前,我正在使用SwingWorker运行启动后台分析的循环,并在每次分析完成时在循环内调用SwingUtilities.invokeLater方法以更新GUI组件。 At the moment, the GUI seems to be updating randomly, and occasionally not at all. 目前,GUI似乎是随机更新的,偶尔根本没有更新。

The following code shows how I'm trying to accomplish this. 以下代码显示了我如何尝试完成此任务。 The TunerListener is an inner class of a JPanel subclass. TunerListener是JPanel子类的内部类。 PrevNote, nextNote, frequency, and the light variables are all components in the JPanel subclass that I want to update: 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);
            }
        }

    }
}

Edit I notice when I use the debugger that I sometimes get to a point where it tells me the source could not be found and in the debugging window it says something about a FutureTask$Sync.innerRun. 编辑我注意到,当我使用调试器时,有时会告诉我找不到源,并且在调试窗口中,它显示了有关FutureTask $ Sync.innerRun的内容。 Does this narrow it down at all? 这会缩小范围吗?

As an alternative, use an instance of javax.swing.Timer , illustrated here , to Start and Stop the playing of a selected Note , shown here . 作为替代方案,使用的实例javax.swing.Timer所示, 在这里 ,以启动停止选定的播放Note ,出在这里 The play() method feeds a SourceDataLine , which operates asynchronously, and the enum Note makes constructing a JComboBox particularly easy. 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM