マイペースなプログラミング日記

x86エミュレータやFPGA、WebGLにお熱なd-kamiがマイペースに書くブログ

なんとなく定期的にバスドラムを鳴らしてみる

JavaFXのタイマ使って8回バスドラムを鳴らしてみます。
参考↓
JavaFX 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.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;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        receiver = MidiSystem.getReceiver();

        Button button = createDrumButton("ドラム!");
        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);
        
        button.setOnAction( e -> {
            Timeline timer = new Timeline(new KeyFrame(Duration.millis(250), event -> {
                try{
                    ShortMessage message = new ShortMessage();
                    message.setMessage(ShortMessage.NOTE_ON, 9, 36, 100);
                    receiver.send(message, -1);
                }catch(InvalidMidiDataException ex){
                    ex.printStackTrace();
                }
            }));

            timer.setCycleCount(8);
            timer.play();
        });

        return button;
    }
}