ボタンを押すたびによくあるドラムの8ビートパターンを鳴らすようにしてみました。今回はボタンを押すたびにタイマを毎回生成しない仕様。しかもちゃんとタイマの状態をチェックしているので途中でパターンがおかしくなることもないと思われる
import javafx.stage.Stage; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.animation.Animation; import javafx.util.Duration; import javax.sound.midi.Receiver; import javax.sound.midi.MidiSystem; import javax.sound.midi.ShortMessage; import javax.sound.midi.InvalidMidiDataException; public class DrumTest extends Application { private Receiver receiver; private Timeline timer; private String pattern = "B-S-BBS-"; private int patternIndex = 0; public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { receiver = MidiSystem.getReceiver(); Button button = createDrumButton("8ビート!"); BorderPane pane = new BorderPane(); pane.setCenter(button); Scene scene = new Scene(pane, 320, 120); stage.setScene(scene); stage.show(); } private Button createDrumButton(String text){ Button button = new Button(text); timer = new Timeline(new KeyFrame(Duration.millis(250), event -> { try{ if(pattern.charAt(patternIndex) == 'B'){ noteBassDrum(); }else if(pattern.charAt(patternIndex) == 'S'){ noteSnareDrum(); } }catch(InvalidMidiDataException ex){ ex.printStackTrace(); } patternIndex = (patternIndex + 1) % 8; })); button.setOnAction( e -> { if(timer.getStatus() == Animation.Status.STOPPED){ timer.setCycleCount(16); timer.play(); } }); return button; } private void noteBassDrum() throws InvalidMidiDataException{ ShortMessage message = new ShortMessage(); message.setMessage(ShortMessage.NOTE_ON, 9, 36, 100); receiver.send(message, -1); } private void noteSnareDrum() throws InvalidMidiDataException{ ShortMessage message = new ShortMessage(); message.setMessage(ShortMessage.NOTE_ON, 9, 38, 100); receiver.send(message, -1); } }