Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@james-d
Created February 18, 2016 14:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james-d/e9a2f195ffef56e7481f to your computer and use it in GitHub Desktop.
Save james-d/e9a2f195ffef56e7481f to your computer and use it in GitHub Desktop.
Example of showing an alert from background thread using `Platform.runLater(...)`
import static javafx.beans.binding.Bindings.when;
import java.util.Random;
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MockServer extends Application {
@Override
public void start(Stage primaryStage) {
ListView<String> connectedClients = new ListView<>();
Server server = new Server(clientName -> {
connectedClients.getItems().add(clientName);
} , clientName -> {
connectedClients.getItems().remove(clientName);
});
Button startStopButton = new Button();
startStopButton.setOnAction(e -> {
if (server.isRunning()) {
server.cancel();
} else {
server.restart();
}
});
startStopButton.textProperty().bind(
when(server.runningProperty()).
then("Stop Server").
otherwise("Start Server"));
BorderPane.setAlignment(startStopButton, Pos.CENTER);
BorderPane.setMargin(startStopButton, new Insets(10));
BorderPane root = new BorderPane(connectedClients);
root.setTop(startStopButton);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class Server extends Service<Void> {
private final Consumer<String> connectedNotification;
private final Consumer<String> disconnectedNotification;
public Server(Consumer<String> connectedNotification, Consumer<String> disconnectedNotification) {
this.connectedNotification = connectedNotification;
this.disconnectedNotification = disconnectedNotification;
}
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
private int clientCount = 0;
@Override
protected Void call() throws Exception {
Random rng = new Random();
while (!isCancelled()) {
try {
Thread.sleep(rng.nextInt(3000) + 1000);
} catch (InterruptedException exc) {
if (isCancelled()) {
break;
} else {
Thread.currentThread().interrupt();
}
}
final String clientName = "Client " + (++clientCount);
final int connectTime = rng.nextInt(3000) + 4000;
Thread clientThread = new Thread(() -> {
try {
Thread.sleep(connectTime);
} catch (InterruptedException exc) {
exc.printStackTrace();
}
Platform.runLater(() -> {
disconnectedNotification.accept(clientName);
});
});
clientThread.setDaemon(true);
Platform.runLater(() -> {
connectedNotification.accept(clientName);
Alert alert = new Alert(AlertType.INFORMATION);
alert.setContentText(clientName + " connected");
alert.show();
});
clientThread.start();
}
return null;
}
};
}
}
public static void main(String[] args) {
launch(args);
}
}
@OrangoMango
Copy link

Why should I use Platform.runLater()?

@james-d
Copy link
Author

james-d commented Jun 17, 2021

Why should I use Platform.runLater()?

The code inside the Platform.runLater() blocks updates the UI. That can only be done from the FX Application Thread, and Platform.runLater() executes the supplied Runnable on that thread.

@OrangoMango
Copy link

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment