I am trying to get and destroy an external process I\'ve created via ProcessBuilder in my FXML application close, but it\'s not working. This is based on the helpful advice
The approach is right, but there are few problems.
You've created the FXMLLoader
named fxmlLoader
but then you call FXMLLoader.load()
which is static method and is not connected with instance you've created before.
Also using static method to intercommunication is not very good (imagine you'll want to have several processes). Better store myController
to a field and call it in the stop()
method.
Even better would be to add corresponding utility method to Controller and call it from main app, because main app doesn't seem to use Process
itself.
Here goes short app to demonstrate all described:
public class DoTextAreaLog extends Application {
private LoggController controller;
@Override
public void start(Stage stage) throws IOException{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("logg.fxml"));
VBox root = (VBox)fxmlLoader.load();
controller = (LoggController) fxmlLoader.getController();
stage.setScene(new Scene(root, 400, 300));
stage.show();
}
@Override
public void stop() throws Exception {
super.stop();
controller.destroy();
}
public static void main(String[] args) { launch(); }
}
Controller:
public class LoggController implements Initializable {
@FXML private TextArea textarea;
@FXML private void onAction(ActionEvent event) {
destroy();
}
private Process p;
public void destroy() {
if (p != null) {
p.destroy();
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
try {
p = new ProcessBuilder("ping", "stackoverflow.com", "-n", "100").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
try (BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = bri.readLine()) != null) {
log(line);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}).start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void log(final String st) {
Platform.runLater(new Runnable() {
@Override
public void run() {
textarea.setText(st + "\n" + textarea.getText());
}
});
}
}
logg.fxml:
<VBox id="root" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="fxml.LoggController">
<TextArea fx:id="textarea"/>
<Button text="Stop The Madness!" onAction="#onAction"/>
</VBox>