Jump to content

Setup JavaFX form


Merccy

Recommended Posts

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 by Merccy
Link to comment
Share on other sites

  • 2 weeks later...

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 by Valkyr
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...