Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Naton

Basic JavaFX with FXML + Uploading to the Repository Tutorial

Recommended Posts

While attempting to upload my own script to the repository with JavaFX, I realized there was not a lot of information on this topic. This tutorial will explain how to incorporate JavaFX into your Tribot scripts and how to make sure it will work correctly when uploaded to the repository.

 

Part 1 - JavaFX

 

Why use JavaFX?

JavaFX offers a high level of customization, including support of style sheets and FXML, and is the future of user interfaces in java. Prior to JavaFX, Swing was used to create user interfaces. JavaFX supports a variety of features that were previously not available in Swing. Furthermore, basic items in JavaFX have been updated to look much more modern then their Swing counterpart.

071VjvX.png kEB65IY.png

Swing GUI vs. JavaFX GUI

 

How do I learn JavaFX?

Because there is already a large number of resources that currently exist to teach JavaFX, I will not be discussing everything about how to learn the basics of JavaFX.

I highly recommend reading Oracle's guide to getting started with JavaFX located at https://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm 

(I used this myself to learn the basics)

 

FXML?

FXML is "an XML-based user interface markup language created by Oracle Corporation for defining the user interface of a JavaFX application." as stated by Wikipedia at https://en.wikipedia.org/wiki/FXML.

I highly recommend that you use FXML to design your GUI layouts. An easy to use drag and drop program that will create the FXML code for you is Scene Builder. Using this program, you don't need practically anything about FXML to get started. Scene Builder can be downloaded at http://gluonhq.com/products/scene-builder/. It is very similar to the Swing WindowBuilder plugin for Eclipse (or the Netbeans GUI builder, however, I don't recall its name).

zPgNwFC.png

Scene Builder

 

I'm ready to get started.

For the purpose of this tutorial, we will create a basic application that has a textfield and a button and will save the value of the textfield when the button is pressed and will print it to the Tribot Client Debug.

First, in order to use JavaFX in your IDE you must download the e(fx)clipse plugin for Eclipse located at https://www.eclipse.org/efxclipse/install.html. If you do not use Eclipse then you must find another plugin that will allow you to create JavaFX applications in your IDE. Do a quick google search and I'm sure you will be able to find it.

Now we want to set up our JavaFX program. I recommend using Laniax's GUI API located at https://github.com/Laniax/LanAPI/tree/master/core/gui (thanks @laniax) Download the GUI class and the AbstractGUIController class and put them into your scripts package. The GUI handles all front end parts of the user interface, and the controller handles the logic. For the sake of this basic program, we are not going to use anything else from Laniax so delete everything that contains LogProxy and log in it. Additionally you may have to delete a few extra lines from the GUI class that involve other classes from the Laniax's API.

Now create a main class that will extend script. We are going to create a new GUI object and display it, and wait until the GUI is complete.

Dnbf7Ba.png

The URL fxml will contain the path to where we will place the FXML file. The "null" will be replaced with the path as a string.

Now we want to build the GUI Controller. Remove the "getEnableNotifications" from the AbstractGUIController as we will not be using this. Create a new class called "Controller" that extends AbstractGUIController. The required initialize method is called when the FXML is loaded. Anything that must occur when the FXML is loaded can be placed within the method. In this case we will leave it blank.

qAPbAFI.png

We will come back to these later on.

 

Next we want to design the actual GUI with FXML. You must download Scene Builder (displayed above) at http://gluonhq.com/products/scene-builder/ to build your FXML file. An example of a complete FXML file created with Scene Builder is https://github.com/Naton1/nSand-Crabs/blob/master/fx/gui.fxml. Simply drag and drop the components you would like to use in Scene Builder.

 Open Scene Builder and click File, New to start a new application. Drag and drop the components as you wish to construct your GUI. I suggest messing around with this program for a bit to understand the basics of Scene Builder and JavaFX. Explore everything so that you can become familiar with all of the options you have (on both the left and right sidebars).

MxWhI3F.pngCode Created by Scene Builder

Spoiler

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="189.0" prefWidth="251.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.141">
  <columnConstraints>
    <ColumnConstraints hgrow="SOMETIMES" minWidth="250.0" prefWidth="200.0" />
  </columnConstraints>
  <rowConstraints>
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
  </rowConstraints>
   <children>
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
         <children>
            <TextField promptText="Enter Text" />
         </children>
      </HBox>
      <HBox alignment="CENTER" prefHeight="129.0" prefWidth="503.0" GridPane.rowIndex="1">
         <children>
            <Button mnemonicParsing="false" text="Start Script" />
         </children>
      </HBox>
   </children>
</GridPane>
 

Now, in order to reference any of these objects from our java program, we need to give them each an fx id. This can be done by clicking on the item in Scene Builder that you want to reference, and then clicking "code" on the right sidebar. Type in whatever you want to call the component in your java program. Additionally, to add event handlers, enter the name of a method you want to call when an action is performed on the specified component in the onAction textfield. For this example, we will name the textfield as "textField" and the button as "startScriptButton". We will name the method that is called when the button is pressed "startScriptPressed".

2NvzLNr.png

Furthermore, we need to set the "controller" of this FXML file. This can be done by clicking on the Controller tab and selecting your Controller class in the bottom left hand corner.

YjbmC2q.png

Now, we want to incorporate this into our JavaFX application.

Open up the GUIController and add two new fields, one for the new textfield and one for the button. They must be named exactly as named in the FXML. Additionally, all fxml objects must be referenced with the @FXML annotation. While you are doing this be sure that you are importing the correct javafx packages (hopefully your IDE will do this for you). We also need to add in the method that we added, #startScriptPressed

xgNuAMn.png

Now when the button is pressed in the GUI, the startScriptPressed method will be called. Place all logic inside this method. We are simply going to have to print to the client debug. Don't forget to close the GUI so that the loop in the main script will end.

BMMqtcF.png

Now all we have to do is go back in and edit the path to our FXML file, and we are all set to run the program.

fjKs3Rw.png

Now run the program and the text in the textfield will print to the client debug in Tribot.

Wwpo7DN.png

Congratulations! You made your first (very basic) Tribot script with JavaFX & FXML! This only shows the basics of what JavaFX can do but as you explore it more you will discover all of the incredible things that can now be done with this useful platform. 

 

 

Part 2 - JavaFX & FXML on the Tribot repository

Obfuscation

When uploading any files to the repository, they are all obfuscated, meaning the names of the objects in the code are all changed. When the FXML tries to reference a java object, it needs the exact name of the object. Therefore, we need something that can make sure the obfuscator does not change the names of important objects. This can be done by downloading an external .jar known as Allatori Annotations, also located on Laniax's API. https://github.com/Laniax/LanAPI/blob/master/allatori-annotations.jar

This must be added to your build path in your IDE by right clicking on your project, going to build path, add external jar, and locating the jar that was just downloaded.

Now to make sure certain names do not change, we just add the @DoNotRename annotation to the class, and all fields + methods that are related to the FXML.

IDwkHdw.png

Example of adding in the @DoNotRename annotations

Cannot reference local .fxml files

When uploading your script to the repository, you cannot access your .fxml file. The only way to load a .fxml file into your GUI through Tribot is by uploading the .fxml file to a website or another method discovered by Laniax. 

You can either upload it to your own website and use the path of that as the argument to your URL object 

CDBOE5t.png

Example of URL of .fxml file uploaded to personal website

Or you can do what  @IceKontroI came up with - "I did have this problem a while back and my solution was to use Pastebin. Upload the .fxml file to https://pastebin.com/ then load up the raw FXML. That link can be used instead of a local file path, only problem is that it needs to be manually updated."

The method that Laniax discovered to get around uploading your .fxml file is as follows:

If you change 

 FXMLLoader loader = new FXMLLoader(fxml);

into 

 FXMLLoader loader = new FXMLLoader();

And 

Parent box = loader.load();

into

Parent box = loader.load(new ByteArrayInputStream(fxml.getBytes()));

 

Now instead of passing an URL into the GUI constructor, you can pass the entire contents of your .fxml, as string as the argument.

(ie. instead of

new Gui("http://...")

you can do 

new GUI("<?xml version=\"1.0\" encoding=\"UTF-8\"?>...")

 

Quoted from Laniax

The End

 

Thanks for reading my guide, if you have any questions or if you have any other useful information that I could add, than please let me know. Hope this helps some of you from some of the problems that I had :)

 

Edited by Naton
  • Like 5
  • Thanks 2

Share this post


Link to post
Share on other sites

Great tutorial, thanks for giving credits! 
There is in fact a way around uploading your .fxml file somewhere online, and thus preventing the TRiBot firewall prompt and any possible downtime of the webhost. 

If you change 

 FXMLLoader loader = new FXMLLoader(fxml);

into 

 FXMLLoader loader = new FXMLLoader();

And 

Parent box = loader.load();

into

Parent box = loader.load(new ByteArrayInputStream(fxml.getBytes()));

 

Now instead of passing an URL into the GUI constructor, you can pass the entire contents of your .fxml, as string as the argument.

(ie. instead of

new Gui("http://...")

you can do 

new GUI("<?xml version=\"1.0\" encoding=\"UTF-8\"?>...")

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, IceKontroI said:

A tutorial like this was absolutely needed for TRiBot. Having a guide like this available would have saved me so many hours when I was first getting started with JavaFX. You covered all the major points to get up and running with JavaFX, excellent job.

Thank you I appreciate it man

9 hours ago, laniax said:

Great tutorial, thanks for giving credits! 
There is in fact a way around uploading your .fxml file somewhere online, and thus preventing the TRiBot firewall prompt and any possible downtime of the webhost. 

If you change 

 FXMLLoader loader = new FXMLLoader(fxml);

into 

 FXMLLoader loader = new FXMLLoader();

And 

Parent box = loader.load();

into

Parent box = loader.load(new ByteArrayInputStream(fxml.getBytes()));

 

Now instead of passing an URL into the GUI constructor, you can pass the entire contents of your .fxml, as string as the argument.

(ie. instead of

new Gui("http://...")

you can do 

new GUI("<?xml version=\"1.0\" encoding=\"UTF-8\"?>...")

 

Thank you! Thats awesome I didn't even think about that. I'm going to use that for my scripts and add it into the tutorial.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Our picks

    • This release will:

      Fix LG for both OSBuddy and RuneLite


      Fix issue where the resizable client isn't able to be made smaller (Thanks @JoeDezzy1)


      Fix detection of the logout game tab when resizable mode and side panels are enabled (Thanks @JoeDezzy1)


      Add initial support for Sentry to allow us to identify and easily debug exceptions happening with all TRiBot users


      Add methods to determine if the bank is actually loaded, and not just the overarching interface (Thanks @wastedbro)



      Upcoming updates:

      Improved CLI support


      Full Sentry support


      Much more
      • 46 replies
    • This release will:

      Fix NPE in Camera API (Thanks @wastedbro)


      Update deposit box interface ids (Thanks @Encoded)


      Add various bank methods (Thanks @wastedbro)


      Banking#getWithdrawXQuantity


      Banking#getDefaultWithdrawQuantity


      Banking#arePlaceholdersOn




      Fix resizeable minimap bug (Thanks @wastedbro)


      Remove Java 8 requirement


      Please note: TRiBot is not yet fully compatible with Java 10+




      Fix the break handler issues by ensuring the break handler thread never gets paused


      Fix broken settings hooks



      Upcoming updates:

      Improved CLI support


      Much more



      Note: If you are using LG, please restart both the RS client and TRiBot
      • 68 replies
    • This release will:

      Add support for using custom F key bindings to switch between game tabs (Thanks @erickho123)


      Fix tab opening for "Skills" and "Kourend Tasks" (Thanks @erickho123)



      Note: If you are using LG, please restart both the RS client and TRiBot
      • 34 replies
    • This release will:

      Fix an issue where breaks would stop firing


      Fix Combat#getWildernessLevel, use dynamic search for text and cache ID for later calls


      Fix an NPE in the Combat API


      Fix Mouse#leaveGame bug where the mouse wouldn't actually leave the game screen
      • 21 replies
    • This release will:

      Add LG support for Runelite


      Fix NPCChat issues


      Fix a bug where the camera angle setter would just hold down a key for 5 seconds (the timeout)


      Slightly adjust the rotation via keys to be more accurate


      Add the ability for asynchronous camera movement via keys


      Make Camera rotation via mouse more fluid, with more antiban, and work much better in resizable mode


      Add a "Camera#setCamera" method, allowing the rotation and angle to be set in parallel


      Increase the likelihood of using the mouse for camera movements


      Add support for adjusting the camera to positionable entities (Positionable#adjustCameraTo)



      Upcoming updates:

      Improved CLI support


      Much more



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

    No registered users viewing this page.

×