我创建了一个在钢琴上播放一系列音符的程序,然后确定用户在钢琴上的点击是否与刚播放的内容相匹配。我让程序使用Swing计时器自动播放一系列音符,但我需要等到序列完成播放才能继续播放。这是我现在所拥有的简化示例:
import java.awt.event.*;
import javax.swing.*;
public class myProgram {
Timer timer = new Timer(1000, new AutoPlay());
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myProgram myProgram = new myProgram();
System.out.println("Computer plays notes.");
myProgram.compTurn();
System.out.println("Your turn.");
}
});
}
class AutoPlay implements ActionListener {
int i = 0;
public void actionPerformed(ActionEvent e) {
System.out.println("Auto-played note.");
i++;
if (i == 2) timer.stop();
}
}
// TODO - Play a melody for the user to repeat
public void compTurn() {
timer.start();
}
}
"轮到你"打印太快了。如果它有帮助,计时器的目的是让程序触发音频笔记,更新钢琴图形,这样你就可以看到按下的音符,加载下一个要播放的音符,然后重复直到序列完成。
答案 0 :(得分:1)
使用观察者模式的变体来通知计时器何时完成。例如,PropertyChangeListener可以很好地工作。例如......
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
public class MyProg2 extends JPanel {
public static final String TIMER_COMPLETE = "timer complete";
private static final int TIMER_DELAY = 1000;
private Timer timer;
public MyProg2() {
// TODO create GUI
}
public void playNotes() {
if (timer != null && timer.isRunning()) {
return;
}
timer = new Timer(TIMER_DELAY, new TimerListener());
timer.start();
}
private class TimerListener implements ActionListener {
private int i = 0;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Auto-played note.");
i++;
if (i == 2) {
timer.stop();
firePropertyChange(TIMER_COMPLETE, false, true);
}
}
}
private static void createAndShowGui() {
System.out.println("Starting program");
MyProg2 mainPanel = new MyProg2();
mainPanel.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (MyProg2.TIMER_COMPLETE.equals(pcEvt.getPropertyName()) && pcEvt.getNewValue() == Boolean.TRUE) {
System.out.println("Your turn");
}
}
});
mainPanel.playNotes();
JFrame frame = new JFrame("MyProg2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案 1 :(得分:1)
计算机开始播放时禁用用户输入选项。当用户转向时启用它们。永远不要禁用edt。