I have two streams (main and one side). When you click on the button, the side stream is executed, but when you press the error again. Below is the code. It is necessary that you can click on the button to wait until the thread is executed and click again and the stream is executed again.

package application; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.Synthesizer; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; public class Main extends Application { static AffableThread mSecondThread; //ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ public void start(Stage stage) { AnchorPane r1 = new AnchorPane(); //созданиС pane Scene sc1 = new Scene(r1, 600, 400); //созданиС сцСны mSecondThread = new AffableThread(); //Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Button b1 = new Button(); //Ρ‚Π° самая ΠΊΠ½ΠΎΠΏΠΊΠ° b1.setLayoutX(200); b1.setLayoutY(100); b1.setPrefSize(100, 50); r1.getChildren().add(b1); b1.setOnAction(b - > { //ActionListener mSecondThread.start(); //Π½Π°Ρ‡Π°Π»ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° }); stage.setScene(sc1); stage.show(); } public static void main(String[] args) { launch(args); System.out.println("Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΡ‘Π½..."); } class AffableThread extends Thread //Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ класс ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Π·Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ происходит Π² ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ {@ Override public void run() //Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ Π² ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ { System.out.println("ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΈΠ· ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°!"); System.out.println("ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΈΠ· ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°!"); try { Synthesizer s1 = MidiSystem.getSynthesizer(); s1.open(); MidiChannel[] channels = s1.getChannels(); channels[0].programChange(41); channels[0].noteOn(36, 80); Thread.sleep(1000); channels[0].noteOff(36); channels[0].noteOn(38, 80); Thread.sleep(1000); channels[0].noteOff(38); channels[0].noteOn(40, 80); Thread.sleep(1000); channels[0].noteOff(40); channels[0].noteOn(41, 80); Thread.sleep(1000); channels[0].noteOff(41); channels[0].noteOn(43, 80); Thread.sleep(1000); channels[0].noteOff(43); channels[0].noteOn(45, 80); Thread.sleep(1000); channels[0].noteOff(45); channels[0].noteOn(47, 80); Thread.sleep(1000); channels[0].noteOff(47); s1.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 
  • one
    RTFM java.util.concurrent.ExecutorService - Yura Ivanov

1 answer 1

If it’s quite simple, you can create a stream each time you press the button:

 b1.setOnAction(b -> { //ActionListener if ( mSecondThread == null || !mSecondThread.isAlive() ) { mSecondThread = new AffableThread(); //Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° mSecondThread.start(); //Π½Π°Ρ‡Π°Π»ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° } }); 

You can as advised Yura Ivanov:

 import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.Synthesizer; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class Main extends Application { private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private ScheduledFuture future = null; public void start(Stage stage) { AnchorPane r1 = new AnchorPane(); Scene sc1 = new Scene(r1, 600, 400); Button b1 = new Button(); b1.setLayoutX(200); b1.setLayoutY(100); b1.setPrefSize(100, 50); r1.getChildren().add(b1); b1.setOnAction(b -> { if ( future == null || future.isDone() ) { try { future = executor.schedule( runnable, 0, TimeUnit.MILLISECONDS ); } catch( Exception e ) { e.printStackTrace(); } }); stage.setScene(sc1); stage.show(); } public static void main(String[] args) { launch(args); System.out.println("Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΡ‘Π½..."); } private Runnable runnable = () -> { System.out.println("ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΈΠ· ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°!"); System.out.println("ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΈΠ· ΠΏΠΎΠ±ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°!"); try { Synthesizer s1 = MidiSystem.getSynthesizer(); s1.open(); MidiChannel[] channels = s1.getChannels(); channels[0].programChange(41); channels[0].noteOn(36, 80); Thread.sleep(1000); channels[0].noteOff(36); channels[0].noteOn(38, 80); Thread.sleep(1000); channels[0].noteOff(38); channels[0].noteOn(40, 80); Thread.sleep(1000); channels[0].noteOff(40); channels[0].noteOn(41, 80); Thread.sleep(1000); channels[0].noteOff(41); channels[0].noteOn(43, 80); Thread.sleep(1000); channels[0].noteOff(43); channels[0].noteOn(45, 80); Thread.sleep(1000); channels[0].noteOff(45); channels[0].noteOn(47, 80); Thread.sleep(1000); channels[0].noteOff(47); s1.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }; } 

Written is not perfect, but the direction is correct. You can also look in the direction of javafx.concurrent, although in this case it will be superfluous.

  • Excess familiarity with javafx.concurrent just will not. - DimXenon