我正在尝试组装一个 MIDI 序列的图形表示,并且我想要一条垂直线在序列播放时在面板上水平移动,以反射(reflect)序列中的实际位置。我知道我应该使用 getTickPosition()
之类的东西来提供垂直线的位置。
但是我如何触发这些事件,以便垂直线知道自己重绘呢?我是否创建了一个特殊的监听器,滴答声以某种方式触发?
最佳答案
建立一个 Swing Timer
以每 NN 毫秒检查和更新一次刻度位置。
So, there's not any kind of built-in timer in the MidiSystem?
当然有。但重点是所有 GUI 更新都应该在 EDT 上进行。通过从 Swing Timer
调用它们,它们是。此外,MIDI 定时器是供 MIDI API/系统使用的,让它不受干扰地做它做的事情,并在从 Swing Timer
中检查时报告相关信息。
此外,考虑到 UI 组件的性质,请查看此 GUI 右上角的 JProgressBar
。
更新
我改编了在 Java Sound WIKI 上看到的源代码进入这种方法的 SSCCE。
import javax.sound.midi.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.URL;
class PlayMidi {
public static void main(String[] args) throws Exception {
URL url = new URL("http://pscode.org/media/EverLove.mid");
Sequence sequence = MidiSystem.getSequence(url);
final Sequencer sequencer = MidiSystem.getSequencer();
sequencer.open();
sequencer.setSequence(sequence);
Runnable r = new Runnable() {
public void run() {
final JProgressBar progress = new JProgressBar(0,(int)sequencer.getMicrosecondLength());
ActionListener updateListener = new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
progress.setValue((int)sequencer.getMicrosecondPosition());
}
};
Timer timer = new Timer(40,updateListener);
sequencer.start();
timer.start();
JOptionPane.showMessageDialog(null, progress);
sequencer.close();
timer.stop();
}
};
SwingUtilities.invokeLater(r);
}
}
关于java - 使用 MIDI 节拍位置控制序列中图形标记的移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13169941/