Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Buy OSRS Gold

Sell OSRS Gold
wastedbro

JavaFX GuiBuilder

Recommended Posts

Here is a simple snippet for launching a JavaFX GUI in only a few lines of code.

Controller

package scripts.wastedbro.api.misc.gui;

import javafx.fxml.Initializable;
import javafx.stage.Stage;

/**
 * @author Wastedbro
 */
public abstract class Controller implements Initializable
{
    private Stage hostStage;
    private boolean isDone = false, wasCancelled = true;

    public boolean isDone()
    {
        return isDone;
    }
    public boolean wasCancelled()
    {
        return wasCancelled;
    }

    public Stage getHostStage()
    {
        return hostStage;
    }

    public void setHostStage(Stage hostStage)
    {
        this.hostStage = hostStage;
    }


    public void setDone(boolean done)
    {
        isDone = done;
    }

    public void setWasCancelled(boolean wasCancelled)
    {
        this.wasCancelled = wasCancelled;
    }
}

 

GuiBuilder

package scripts.wastedbro.api.misc.gui;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.apache.commons.io.FileUtils;
import org.tribot.api.General;
import org.tribot.api.Timing;
import org.tribot.util.Util;

import javax.swing.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URL;
import java.nio.charset.Charset;

/**
 *
 */
public class GuiLoader
{
    private String fxmlString,
        frameTitle = "";

    private URL styleSheetUrl = null;

    private Controller controller;
    private Stage parent;

    private boolean isDecorated = false, isModal = false;

    public boolean loadGui()
    {
        SwingUtilities.invokeLater(() ->
        {
            new JFXPanel();
            Platform.runLater(() ->
            {
                new JFXPanel();
                try
                {
                    Stage stage = new Stage();

                    if(!isDecorated)
                        stage.initStyle(StageStyle.UNDECORATED);

                    stage.setTitle(frameTitle);
                    stage.setResizable(false);

                    if(isModal)
                    {
                        stage.initOwner(parent);
                        stage.initModality(Modality.APPLICATION_MODAL);
                    }

                    controller.setHostStage(stage);
                    Platform.setImplicitExit(false);

                    FXMLLoader loader = new FXMLLoader();
                    loader.setController(controller);
                    Scene scene = new Scene(loader.load(new ByteArrayInputStream(fxmlString.getBytes())));

                    if(styleSheetUrl != null)
                        scene.getStylesheets().add(styleSheetUrl.toExternalForm());

                    stage.setScene(scene);
                    stage.showAndWait();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            });
        });

        if(!isModal)
        {
            while (!controller.isDone())
                General.sleep(500, 1000);
        }

        return !controller.wasCancelled();
    }

    //region Getters and Setters

    public String getFxmlString()
    {
        return fxmlString;
    }

    public void setFxmlString(String fxmlString)
    {
        this.fxmlString = fxmlString;
    }

    public String getFrameTitle()
    {
        return frameTitle;
    }

    public void setFrameTitle(String frameTitle)
    {
        this.frameTitle = frameTitle;
    }

    public URL getStyleSheetUrl()
    {
        return styleSheetUrl;
    }

    public void setStyleSheetUrl(URL styleSheetUrl)
    {
        this.styleSheetUrl = styleSheetUrl;
    }

    public Controller getController()
    {
        return controller;
    }

    public void setController(Controller controller)
    {
        this.controller = controller;
    }

    public Stage getParent()
    {
        return parent;
    }

    public void setParent(Stage parent)
    {
        this.parent = parent;
    }

    public boolean isDecorated()
    {
        return isDecorated;
    }

    public void setDecorated(boolean decorated)
    {
        isDecorated = decorated;
    }

    public boolean isModal()
    {
        return isModal;
    }

    public void setModal(boolean modal)
    {
        isModal = modal;
    }

    //endregion


    public static class Builder
    {
        private GuiLoader guiLoader = new GuiLoader();

        public Builder setFxmlString(String fxmlString)
        {
            guiLoader.setFxmlString(fxmlString);
            return this;
        }

        public Builder setFxmlURL(String url)
        {
            guiLoader.setFxmlString(HostedFxmlLoader.getFxml(url));
            return this;
        }

        public Builder setFrameTitle(String frameTitle)
        {
            guiLoader.setFrameTitle(frameTitle);
            guiLoader.setDecorated(true);
            return this;
        }

        public Builder setStyleSheetString(String cssString)
        {
            try
            {
                File themeFile = new File(Util.getWorkingDirectory() + File.separator + "wbTemp" + File.separator + "theme.css");
                themeFile.delete();

                FileUtils.writeStringToFile(themeFile, cssString, Charset.forName("UTF-8"));
                Timing.waitCondition(()-> themeFile.exists(), 10000);

                guiLoader.setStyleSheetUrl(themeFile.toURI().toURL());

                return this;
            }
            catch (Exception e)
            {
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
        public Builder setStyleSheetUrl(URL styleSheetUrl)
        {
            guiLoader.setStyleSheetUrl(styleSheetUrl);
            return this;
        }

        public Builder setController(Controller controller)
        {
            guiLoader.setController(controller);
            return this;
        }

        public Builder setParent(Stage parent)
        {
            guiLoader.setParent(parent);
            guiLoader.setModal(true);
            return this;
        }

        public GuiLoader build()
        {
            return this.guiLoader;
        }
    }
}

 

 

Example Usage:

GuiLoader guiLoader = new GuiLoader.Builder()
  .setFxmlString("FXML Code")
  .setController(controller)
  .setStyleSheetString("CSS Code")
  .build();

if (guiLoader.loadGui())
{
  // Run script. I usually pull the user settings out of the controller object
}
else
{
  General.println("GUI Cancelled");
}

 

In order for this to work properly, you have to accurately set the controller to "closed" and "cancelled" properly. For example, in your controller:

/**
* Runs when the user starts the script
*/
@FXML
void onStartButtonAction(ActionEvent event)
{
  this.setWasCancelled(cancelled);
  this.setDone(true);

  if(getHostStage() != null)
    getHostStage().close();
}

 

  • Like 2

Share this post


Link to post
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.


  • Our picks

    • Over the past few months, I’ve been working diligently on a new project - TRiBot X. Everything has been written from the ground up, with all of the best practices of software engineering. Every aspect of TRiBot has been re-imagined to support three main goals: flexibility, useability, and reliability.
      • 31 replies
    • Come give us feedback on the next version of TRiBot!
      • 74 replies
    • TRiBot is looking to improve a lot of its customer relationship management, customer on boarding process, customer experience, design elements, community engagement and pretty much everything else you can imagine when it comes to marketing.

      Our goal: To ensure that the marketing done TRULY reflects the experience and does not shine an inaccurate light on what TRiBot is lacking in.

      So I ask, what do you love about TRiBot and what do you hate about TRiBot? What does O S Bot, Rune M8, PowR Bot and Dre amBot do better? (yes I purposely didn't spell it right 😂).

      Love, 

      RileyZ
      • 23 replies
    • Over the last three weeks, I've been working on upgrading our server infrastructure. It's finally ready and is now live!

      Why?

      Increased reliability - less server errors


      Increased availability - less downtime


      Increased security - keeping us and you secure


      Increased capacity - ability to serve you better


      Increased speed - less waiting for things to load


      Faster development - server and service updates will come faster


      What are the changes?

      Move from a single AWS EC2 instance to AWS ECS (Elastic Container Service)


      Distributed computing


      Load balancing


      Git management of server files and filesystem


      Redis caching


      How?

      AWS ECS (with 10 EC2 instances)


      AWS ElastiCache (Redis)


      AWS Load Balancing


      AWS EFS (Elastic file system)


      Please bare with us as I continue to tune the server for maximum performance. Slow loading speeds may occur temporarily. I thank everyone for their patience.

      Please post on this thread if you experience any issues other than slow loading times.
      • 51 replies
    • This release will:

      Fix prayers and world hopper API (Thanks @JoeDezzy1 and @erickho123)


      Improve banking API (Thanks @Encoded)


      Adds methods for returning and using Java Lists, rather than arrays


      Slightly randomizes some hardcoded behaviour


      Removes sleeps from waitConditions; the efficiency saving potential is negligible in these use-cases, therefore cleaner code is preferable


      Other back-end improvements





      Note: If you are using LG, please restart both the RS client and TRiBot.
      • 90 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...