Welcome!

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

Sign up now!

Resolved Resources cannot be loaded from the bot constructor

Author of MaxiBots
Joined
Dec 3, 2013
Messages
7,032
So special thanks to @Savior for working out why my resource loading wasn't working.

@Cloud @Arbiter The reason it wasn't working was because i was creating my gui in the bot constructor, as you said to do @Arbiter (you moved the line in there when you tv'd me). As soon as i moved it to onStart it loaded the fxml perfectly fine.
 
Java Warlord
Joined
Nov 17, 2014
Messages
4,906
The reason for this is the getScript() method returns null if the code/thread is still in the constructor of the bot.
 
Mod Automation
Joined
Jul 26, 2013
Messages
3,053
@Arbiter - thoughts on whether to consider this an actual bug?
It's definitely a problem, because now we have conflicting requirements: we are requiring developers to set the EmbeddableUI in the no-args constructor, but we aren't letting them initialize the UI there. :/
 
Joined
Dec 10, 2014
Messages
3,332
It's definitely a problem, because now we have conflicting requirements: we are requiring developers to set the EmbeddableUI in the no-args constructor, but we aren't letting them initialize the UI there. :/
Is there a reason why there can't be a default EmbeddableUI, where we just pass the node and shit gets done? Like, bot.setUi(coolUiParent);?
 
Mod Automation
Joined
Jul 26, 2013
Messages
3,053
Solution: Stop trying to load resources in the constructor. Lazily instantiate (and thus load resources for) UI upon invocation of the botInterfaceProperty() method in EmbeddableUI. How many times do I need to mention this?

Example:
Java:
public class DevelopmentToolkit extends LoopingScript implements EmbeddableUI {

    public DevelopmentToolkit() {
        setEmbeddableUI(this);
    }

    ...

    @Override
    public ObjectProperty<DevelopmentToolkitPage> botInterfaceProperty() {
        if (botInterfaceProperty == null) {
            try {
                developmentToolkitPage = new DevelopmentToolkitPage();
            } catch (IOException ioe) {
                System.err.println("Failed to load Development Toolkit UI.");
                ioe.printStackTrace();
            }
            botInterfaceProperty = new SimpleObjectProperty<>(developmentToolkitPage);
        }
        return botInterfaceProperty;
    }

    private ObjectProperty<DevelopmentToolkitPage> botInterfaceProperty;

}
 
@Aidden
 
Is there a reason why there can't be a default EmbeddableUI, where we just pass the node and shit gets done? Like, bot.setUi(coolUiParent);?
I support this idea, but it would have to be Callable<Node> and would still need to be in the no-args constructor. Would be relatively easy to implement on our end. Please create a feature request.
 
Joined
Dec 10, 2014
Messages
3,332
Solution: Stop trying to load resources in the constructor. Lazily instantiate (and thus load resources for) UI upon invocation of the botInterfaceProperty() method in EmbeddableUI. How many times do I need to mention this?

Example:
Java:
public class DevelopmentToolkit extends LoopingScript implements EmbeddableUI {

    public DevelopmentToolkit() {
        setEmbeddableUI(this);
    }

    ...

    @Override
    public ObjectProperty<DevelopmentToolkitPage> botInterfaceProperty() {
        if (botInterfaceProperty == null) {
            try {
                developmentToolkitPage = new DevelopmentToolkitPage();
            } catch (IOException ioe) {
                System.err.println("Failed to load Development Toolkit UI.");
                ioe.printStackTrace();
            }
            botInterfaceProperty = new SimpleObjectProperty<>(developmentToolkitPage);
        }
        return botInterfaceProperty;
    }

    private ObjectProperty<DevelopmentToolkitPage> botInterfaceProperty;

}
 
@Aidden
 

I support this idea, but it would have to be Callable<Node> and would still need to be in the no-args constructor. Would be relatively easy to implement on our end. Please create a feature request.
The issue is when things rely on stuff like metadata, which can't be called until onStart, which includes getSettings(), which I use for saving profiles, because that calls getMetaData().isLocal(), and it seems like the UI is being set before onStart(), but after initialisation.
This can be remedied by lazyloading the UI, and adding things that rely on metadata in onStart, but that's only if you're guaranteed that it'll be called before onStart. Another thing that could be done, is making the metadata available before setting the UI.

Is the flash you're talking about due to the image disappearing/being pushed down when the UI is loaded during onStart? At the moment I add panes dynamically, which pushes down the image anyway. I was thinking about making the UI fit the space, having static top bar, and putting the panes in a ScrollPane so when they're expanded you can still scroll though them, which would make sure that the image is always absent when there is a UI, and that the runtime and status are always viewable, which @Savior has already suggested https://www.runemate.com/community/threads/bot-interface-scaling.5664/

Or if the flash is the where the "This bot has no UI" message disappears, then if you set the property to something empty like a new VBox or Text then that message doesn't appear xD

Either way, I've separated the parts of my UI that require metadata and adding them in onStart, and loading the rest of the UI w/ lazyloading.

TLDR: Make metadata available before loading the UI pls, and mayyybe allow the bot interface to take the dimensions of the bot ui area.
 
Last edited:
Mod Automation
Joined
Jul 26, 2013
Messages
3,053
The issue is when things rely on stuff like metadata, which can't be called until onStart, which includes getSettings(), which I use for saving profiles, because that calls getMetaData().isLocal(), and it seems like the UI is being set before onStart(), but after initialisation.
This can be remedied by lazyloading the UI, and adding things that rely on metadata in onStart, but that's only if you're guaranteed that it'll be called before onStart. Another thing that could be done, is making the metadata available before setting the UI.

Is the flash you're talking about due to the image disappearing/being pushed down when the UI is loaded during onStart? At the moment I add panes dynamically, which pushes down the image anyway. I was thinking about making the UI fit the space, having static top bar, and putting the panes in a ScrollPane so when they're expanded you can still scroll though them, which would make sure that the image is always absent when there is a UI, and that the runtime and status are always viewable, which @Savior has already suggested https://www.runemate.com/community/threads/bot-interface-scaling.5664/

Or if the flash is the where the "This bot has no UI" message disappears, then if you set the property to something empty like a new VBox or Text then that message doesn't appear xD

Either way, I've separated the parts of my UI that require metadata and adding them in onStart, and loading the rest of the UI w/ lazyloading.

TLDR: Make metadata available before loading the UI pls, and mayyybe allow the bot interface to take the dimensions of the bot ui area.
Again, you should have full access to the metadata if you're lazy loading the UI. I'm going to leave it at that unless you confirm otherwise.
 
Joined
Dec 10, 2014
Messages
3,332
Again, you should have full access to the metadata if you're lazy loading the UI. I'm going to leave it at that unless you confirm otherwise.
Yeah you're right xD The issue was I was using a metadata variable that I set in onStart haha.
Still, it's a pain when you want to have things loaded into the UI that aren't specifically part of the UI, a BreakHandler with profiles kept in the ManagedProperties. I've decided to create those things and their respective panes in onStart, which doesn't seem to be an issue.
 
Top