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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Objects;
import java.util.Optional;
public final class Main extends Application {
public static final void main(final String... args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final var textArea1 = new TextArea();
textArea1.setEditable(false);
VBox.setVgrow(textArea1, Priority.ALWAYS);
final var textArea2 = new TextArea();
textArea2.setEditable(false);
VBox.setVgrow(textArea2, Priority.ALWAYS);
final var vbox = new VBox();
vbox.getChildren().setAll(new Label("Output"), textArea1, new Label("Error"), textArea2);
final var startButton = new Button("Start");
startButton.setOnAction(event -> startProcessAsync(textArea1, textArea2));
final var stopButton = new Button("Stop");
stopButton.setOnAction(event -> stopProcess());
final var toolBar = new ToolBar();
toolBar.getItems().setAll(startButton, stopButton);
final var root = new BorderPane();
root.setTop(toolBar);
root.setCenter(vbox);
final var scene = new Scene(root, 800, 800);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
private static record ProcessHandle(Process process, StreamConsumer outputConsumer, StreamConsumer errorConsumer) {
public void stop() {
System.out.println("Killing process.");
process.destroy();
outputConsumer.interrupt();
errorConsumer.interrupt();
}
}
private Service<ProcessHandle> backgroundTask;
private void stopProcess() {
Optional.ofNullable(backgroundTask)
.ifPresent(Service::cancel);
}
private void startProcessAsync(final TextArea outputArea, final TextArea errorArea) {
Optional.ofNullable(backgroundTask)
.ifPresent(Service::cancel);
backgroundTask = null;
final var service = new Service<ProcessHandle>() {
@Override
protected Task<ProcessHandle> createTask() {
return new Task<>() {
@Override
protected ProcessHandle call() throws Exception {
System.out.println("Starting process.");
// final var process = new ProcessBuilder("cmd.exe", "/C", "test.bat").start();
// final var process = new ProcessBuilder("ipconfig.exe").start();
final var process = new ProcessBuilder("ping.exe", "-t", "www.google.com").start();
final var t1 = new StreamConsumer(process.getInputStream(), outputArea);
final var t2 = new StreamConsumer(process.getErrorStream(), errorArea);
final var result = new ProcessHandle(process, t1, t2);
updateValue(result);
t1.start();
t2.start();
t1.join();
t2.join();
return result;
}
};
}
};
service.setOnSucceeded(event -> System.out.println("Success"));
service.setOnCancelled(event -> {
System.out.println("Cancelled");
final ProcessHandle processHandler = (ProcessHandle)event.getSource().getValue();
Optional.of(processHandler)
.ifPresent(ProcessHandle::stop);
});
service.setOnFailed(event -> System.out.println("Failed " + event.getSource().getException()));
backgroundTask = service;
backgroundTask.start();
}
private final static class StreamConsumer extends Thread {
private final TextArea textArea;
private final InputStream input;
public StreamConsumer(final InputStream input, final TextArea textArea) {
this.input = input;
this.textArea = textArea;
setPriority(Thread.MIN_PRIORITY);
}
@Override
public void run() {
try (final var reader = new BufferedReader(new InputStreamReader(input))) {
String line = null;
while (!Thread.currentThread().isInterrupted() && (line = reader.readLine()) != null) {
// System.out.println("Error: " + line);
final var text = line;
Platform.runLater(() -> updateConsoleAtFXAppThread(text));
}
} catch (IOException e) {
e.printStackTrace();
}
}
private final void updateConsoleAtFXAppThread(final String line) {
var text = textArea.getText();
text = (Objects.isNull(text) || text.isBlank()) ? line : text + "\n" + line;
textArea.setText(text);
textArea.setScrollTop(Double.MAX_VALUE);
}
}
} |
Partager