1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| package test.threadmonitor;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import java.util.Optional;
import java.util.function.Function;
public final class Main extends Application {
private Button button;
private Shape led;
@Override
public void start(final Stage stage) throws Exception {
button = new Button("Start");
button.setOnAction(this::onButton);
final var toolbar = new ToolBar();
toolbar.getItems().setAll(button);
led = new Circle(25, Color.TRANSPARENT);
led.setStroke(Color.BLACK);
final var container = new StackPane();
container.getChildren().setAll(led);
final var root = new BorderPane();
root.setTop(toolbar);
root.setCenter(container);
final var scene = new Scene(root);
stage.setTitle("Test");
stage.setWidth(800);
stage.setHeight(600);
stage.setScene(scene);
stage.show();
}
private ThreadMonitor threadMonitor;
private void onButton(final ActionEvent event) {
Optional.ofNullable(threadMonitor)
.ifPresent(ThreadMonitor::cancel);
threadMonitor = null;
button.setDisable(true);
//
final var thread = new Thread(() -> {
System.out.println("Start thread.");
try {
for (int i = 0; i < 2; i++) {
System.out.printf("Sleep %d.\n", i + 1);
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End thread.");
});
final ChangeListener<Thread.State> listener = (value, oldValue, newValue) -> {
System.out.printf("State changed from %s to %s\n", oldValue, newValue);
final var color = STATE_TO_COLOR_CONVERTER.apply(newValue);
led.setFill(color);
if (Thread.State.TERMINATED == newValue) {
threadMonitor.cancel();
}
};
final var monitor = new ThreadMonitor(thread);
monitor.setOnCancelled(anotherEvent -> {
threadMonitor.lastValueProperty().removeListener(listener);
threadMonitor = null;
button.setDisable(false);
});
monitor.lastValueProperty().addListener(listener);
monitor.start();
threadMonitor = monitor;
thread.start();
}
private static final Function<Thread.State, Color> STATE_TO_COLOR_CONVERTER = state -> Optional.ofNullable(state)
.map(val -> switch (val) {
case NEW -> Color.PINK; // Wait to start.
case BLOCKED -> Color.RED; // Blocked by another thread.
case WAITING -> Color.PURPLE; // Wait for another thread.
case RUNNABLE -> Color.GREEN; // Compute.
case TERMINATED -> Color.BLACK; // End.
case TIMED_WAITING -> Color.BLUE; // Sleep.
})
.orElse(Color.TRANSPARENT);
} |
Partager