2

オーディオを読み取り、このデータを分析して、結果をリアルタイムで表示するアプリケーションを作成しています。現在、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 に関するメッセージが表示されることがあります。これで全然絞れますか?

4

1 に答える 1

1

javax.swing.Timer別の方法として、ここに示されている のインスタンスを使用して、ここに示されている選択された を再生Startます。このメソッドは、非同期で動作する をフィードします。これにより、 の構築が特に簡単になります。StopNoteplay()SourceDataLineenum NoteJComboBox

ノート

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);
于 2012-05-05T19:18:34.877 に答える