Merccy Posted August 12, 2015 Share Posted August 12, 2015 (edited) Setting up a JavaFX form + controller is a fucking pain in the ass. Why can it be a pain in the ass?If you use the regular application.launch the standard classloader is not working.If you call Application.launch a second time (even though you've exited the Platform) it will throw an exception and not work.If you do not use setImplicitExit(false) it will exit the platform when you close the stage I have written a class that should be able to be used by any form and controller without modification. How to use: JFXForm<MyController> form = new JFXForm<>("FormTitle", getClass().getClassLoader("package/Form.fxml")); form.launchForm((ex) -> { if (ex == null) { form.openForm(); } }); You can use form.getController(); to get the controller associated with the form. Use Platform.runLater(() -> {}); when you interact with the controller as it will make sure the code will run in the same thread. Class: import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; import java.net.URL; public class JFXForm<T> { public interface JFXFormOnCreate { void callback(IOException exception); } private String formTitle; private URL fxml; private Stage stage; private T controller; public JFXForm(String formTitle, URL fxml) { this.formTitle = formTitle; this.fxml = fxml; } public void launchForm(JFXFormOnCreate done) { // Make sure javafx doesn't exit when the last scene is closed Platform.setImplicitExit(false); // Start JavaFX toolkit new JFXPanel(); // Create new Window on JavaFX thread Platform.runLater(() -> { // Setup FXML view FXMLLoader loader = new FXMLLoader(fxml); loader.setClassLoader(getClass().getClassLoader()); try { Parent view = loader.load(); // Setup controller controller = loader.getController(); // Setup stage stage = new Stage(); stage.setTitle(formTitle); stage.setResizable(false); stage.setScene(new Scene(view)); done.callback(null); } catch (IOException e) { done.callback(e); } }); } public void openForm() { stage.show(); } public void closeForm() { stage.close(); } public T getController() { return controller; } public Stage getStage() { return stage; } } Edited August 13, 2015 by Merccy Quote Link to comment Share on other sites More sharing options...
frozen8 Posted August 12, 2015 Share Posted August 12, 2015 I would rather use a JFrame for this instead of JavaFX. Since JavaFX is not really made for this kind of stuff. Quote Link to comment Share on other sites More sharing options...
Merccy Posted August 13, 2015 Author Share Posted August 13, 2015 I've changed it to a generic class you can easily use for any form + controller. Quote Link to comment Share on other sites More sharing options...
Valkyr Posted August 23, 2015 Share Posted August 23, 2015 (edited) lol controllers lol fxml use swingfxpanel and init your gui using platform.runlater to initialize the toolkit. whack it into a jframe and done. edit: btw for loading the resource, try using getClass.getResource(fileName) edit 2: my bad, I read this as a problem. the point still stands but if your posted code works then fair play :p Applications won't work for script GUIs though. Edited August 23, 2015 by Valkyr Quote Link to comment Share on other sites More sharing options...