Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

Sign up now!

Question How to update GUI using TreeBot

Joined
Dec 20, 2016
Messages
37
Hello all and happy holidays.

Running into a wall at the moment trying to get a UI functioning properly.

I have just added a bunch of stuff to my main java class, where the bot initially is constructed from.

There is a method named "updateInfo", which successfully updates information on the UI. The problem is, I am unable to call this method after my RootTask is created and then running.

Here is the code to my main java class:
Code:
package com.CodeNinja.bots.NDivination;

import com.CodeNinja.bots.NDivination.Branches.RootBranch;
import com.CodeNinja.bots.NDivination.UI.GuiFX;
import com.CodeNinja.bots.NDivination.UI.Info;
import com.CodeNinja.bots.NDivination.UI.InfoUI;
import com.runemate.game.api.client.embeddable.EmbeddableUI;
import com.runemate.game.api.hybrid.input.Mouse;
import com.runemate.game.api.hybrid.util.StopWatch;
import com.runemate.game.api.hybrid.util.io.ManagedProperties;
import com.runemate.game.api.script.Execution;
import com.runemate.game.api.script.framework.listeners.InventoryListener;
import com.runemate.game.api.script.framework.tree.TreeBot;
import com.runemate.game.api.script.framework.tree.TreeTask;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Node;

public class NDivination extends TreeBot implements InventoryListener, EmbeddableUI {

    public Info info;
    public static int EnergyLevel = 0;
    public static int EnergyTicks = 0;

    private ObjectProperty<Node> botInterfaceProperty;
    private String currentTaskString;
    private GuiFX configUI;
    private InfoUI infoUI;

    public boolean guiWait = true;

    private StopWatch stopWatch = new StopWatch();

    public String GatherType, Wisp;

    public NDivination() {
        guiWait = true;
        setEmbeddableUI(this);
    }

    @Override
    public ObjectProperty<Node> botInterfaceProperty() {
        if (botInterfaceProperty == null) {
            botInterfaceProperty = new SimpleObjectProperty<>(configUI = new GuiFX(this));
            infoUI = new InfoUI(this);
        }

        return botInterfaceProperty;
    }

    @Override
    public void onStart(String... args){
        currentTaskString = "Starting bot";
        stopWatch.start();
        setLoopDelay(200,400);
        Mouse.setSpeedMultiplier(1);
        Mouse.setForceMenuInteraction(true);
        getEventDispatcher().addListener(this);
    }

    @Override
    public void onStop(){
        System.out.println("Bot ended, ran for " + stopWatch.getRuntime());
    }

    @Override
    public TreeTask createRootTask() {
        // While we are waiting for guiWait to be false, stay in this loop
        // This will prevent the bot from starting before the GUI is complete
        // Note: It will wait for 60 seconds (60,000 milliseconds)
        if (!Execution.delayUntil(() -> !guiWait, 60000)) {
            System.out.println("Still waiting for GUI after a minute, stopping.");
            stop();
        }
        return new RootBranch();
    }

    // When called, switch the botInterfaceProperty to reflect the InfoUI
    public void setToInfoProperty(){
        botInterfaceProperty.set(infoUI);
    }

    // This method is used to update the GUI thread from the bot thread
    public void updateInfo() {
        try {
            // Assign all values to a new instance of the Info class
            info = new Info(stopWatch.getRuntimeAsString(), currentTaskString);

        }catch(Exception e){
            e.printStackTrace();
        }

        // Be sure to run infoUI.update() through runLater.
        // This will run infoUI.update() on the dedicated JavaFX thread which is the only thread allowed to update anything related to JavaFX rendering
        Platform.runLater(() -> infoUI.update());

        /*
        *  "The way to think about it
            is that the "some stuff" is a package
            and you're at your house (the bot thread)
            Platform.runLater is the mailman
            you give the mailman your package and then go about your life however you want
            i.e. keep going in the code
            and then the mailman does what he needs with the package to get it delivered
            and it's no longer your or your house's problem"
            - The Wise. The One. The Arbiter.
         */
    }
}

Usually the "updateInfo" method would run in a "onLoop()" method, however I am using TreeBot and not LoopingScript.

How can I call this method using TreeBots "createRootTask()"

Thanks a ton! :D
 
Last edited:
I've been called a god before.
Joined
Aug 5, 2014
Messages
3,212
Hello all and happy holidays.

Running into a wall at the moment trying to get a UI functioning properly.

I have just added a bunch of stuff to my main java class, where the bot initially is constructed from.

There is a method named "updateInfo", which successfully updates information on the UI. The problem is, I am unable to call this method after my RootTask is created and then running.

Here is the code to my main java class:
Code:
package com.CodeNinja.bots.NDivination;

import com.CodeNinja.bots.NDivination.Branches.RootBranch;
import com.CodeNinja.bots.NDivination.UI.GuiFX;
import com.CodeNinja.bots.NDivination.UI.Info;
import com.CodeNinja.bots.NDivination.UI.InfoUI;
import com.runemate.game.api.client.embeddable.EmbeddableUI;
import com.runemate.game.api.hybrid.input.Mouse;
import com.runemate.game.api.hybrid.util.StopWatch;
import com.runemate.game.api.hybrid.util.io.ManagedProperties;
import com.runemate.game.api.script.Execution;
import com.runemate.game.api.script.framework.listeners.InventoryListener;
import com.runemate.game.api.script.framework.tree.TreeBot;
import com.runemate.game.api.script.framework.tree.TreeTask;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Node;

public class NDivination extends TreeBot implements InventoryListener, EmbeddableUI {

    public Info info;
    public static int EnergyLevel = 0;
    public static int EnergyTicks = 0;

    private ObjectProperty<Node> botInterfaceProperty;
    private String currentTaskString;
    private GuiFX configUI;
    private InfoUI infoUI;

    public boolean guiWait = true;

    private StopWatch stopWatch = new StopWatch();

    public String GatherType, Wisp;

    public NDivination() {
        guiWait = true;
        setEmbeddableUI(this);
    }

    @Override
    public ObjectProperty<Node> botInterfaceProperty() {
        if (botInterfaceProperty == null) {
            botInterfaceProperty = new SimpleObjectProperty<>(configUI = new GuiFX(this));
            infoUI = new InfoUI(this);
        }

        return botInterfaceProperty;
    }

    @Override
    public void onStart(String... args){
        currentTaskString = "Starting bot";
        stopWatch.start();
        setLoopDelay(200,400);
        Mouse.setSpeedMultiplier(1);
        Mouse.setForceMenuInteraction(true);
        getEventDispatcher().addListener(this);
    }

    @Override
    public void onStop(){
        System.out.println("Bot ended, ran for " + stopWatch.getRuntime());
    }

    @Override
    public TreeTask createRootTask() {
        // While we are waiting for guiWait to be false, stay in this loop
        // This will prevent the bot from starting before the GUI is complete
        // Note: It will wait for 60 seconds (60,000 milliseconds)
        if (!Execution.delayUntil(() -> !guiWait, 60000)) {
            System.out.println("Still waiting for GUI after a minute, stopping.");
            stop();
        }
        return new RootBranch();
    }

    // When called, switch the botInterfaceProperty to reflect the InfoUI
    public void setToInfoProperty(){
        botInterfaceProperty.set(infoUI);
    }

    // This method is used to update the GUI thread from the bot thread
    public void updateInfo() {
        try {
            // Assign all values to a new instance of the Info class
            info = new Info(stopWatch.getRuntimeAsString(), currentTaskString);

        }catch(Exception e){
            e.printStackTrace();
        }

        // Be sure to run infoUI.update() through runLater.
        // This will run infoUI.update() on the dedicated JavaFX thread which is the only thread allowed to update anything related to JavaFX rendering
        Platform.runLater(() -> infoUI.update());

        /*
        *  "The way to think about it
            is that the "some stuff" is a package
            and you're at your house (the bot thread)
            Platform.runLater is the mailman
            you give the mailman your package and then go about your life however you want
            i.e. keep going in the code
            and then the mailman does what he needs with the package to get it delivered
            and it's no longer your or your house's problem"
            - The Wise. The One. The Arbiter.
         */
    }
}

View entire project: RuneMate-Bots/CodeNinja/bots/NDivination at master · Acinate/RuneMate-Bots · GitHub

Usually the "updateInfo" method would run in a "onLoop()" method, however I am using TreeBot and not LoopingScript.

How can I call this method using TreeBots "createRootTask()"

Thanks a ton! :D

Add on start:
Code:
        new LoopingThread(() -> Platform.runLater(() -> infoUi.update()), 500).start();
 
I've been called a god before.
Joined
Aug 5, 2014
Messages
3,212
Code:
LoopingThread loop;
onStart(){
LoopingThread loop = new LoopingThread(() -> Platform.runLater(() -> infoUI.update()), 500);
loop.start();
}
Am I doing this wrong?
Yes. Why are you initializing loop twice?
You can just do what i wrote before. You will not use this thread anywhere else anyway.
 
Joined
Dec 20, 2016
Messages
37
Yes. Why are you initializing loop twice?
You can just do what i wrote before. You will not use this thread anywhere else anyway.
Fixed, thank you very much!

Code:
onStart()
new LoopingThread(() -> Platform.runLater(() -> updateInfo()), 500).start();
 
Top