Jump to content
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 update will:

      Fix GE inventory item positioning bug


      Fix broken object hooks
      • 21 replies
    • This release will:

      Fix some ClosedChannelException bug


      Fix bug in RSObject#getAllTiles


      Add game tab support for "Kourend Favour"
      • 15 replies
    • This release will:

      Fix Settings UI placement bug


      Fix game object location bug


      Fix small layout bug making the client shift up and down


      Fix client crashing bug where loading the client with a small display area will cause the client to crash


      Fix annoying Linux bug relating to painting events and peers


      Fix settings saving bug where settings are saved to disk more often than they should


      Fix RSInterface#isBeingDrawn bug affecting a limited amount of people


      Drop Java 1.7 bytecode version for 1.8


      Important: Since the downloadable RS client uses Java 7, it will no longer be compatible with Looking Glass. To make up for this, we will add support for using other clients such as RuneLite (at a later date).


      This change was necessary to allow us to use Java 8 syntax. It also paves the way for Java 9/10/11 support.
      • 40 replies
    • This update will:

      Fix the RSMenuNode bug which also fixes the bug with bank opening


      Fix the incorrect object positions bug


      Fix and re-enable the LG Objects API Accelerator


      Fix the RSObject#getAllTiles bug
      • 22 replies
    • Try our development release by checking "Development Release" on the TRiBot Loader. Note that these new features are currently in beta.

      This release features:

      Re-sizable mode support for both LG and the regular client


      Slightly improved login bot


      Removed final access modifiers from API classes


      Added RSServer hook wrapper to get the client's cached list of server/world info


      [NEW] Bug fix for intelligent banking


      [NEW] Improvement to the stability of LG over time


      [NEW] Vastly improved the reliability and speed of Screen#getColorAt on both LG and the regular client


      [NEW] Fix LG login problems


      [NEW] Fixed re-sizable mode container bug


      [NEW] Fixed re-sizable mode mouse bug


      [NEW] Use of public constants in the Banking API


      [NEW] Use of other various constants such as Projection#NULL_PT and Screen#EMPTY_COLOR



      More features to come very soon!

      Please test it and let us know here if there are any new bugs introduced in this release.
      • 12 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×