I have a JavaFX application, starting with main window as a TabPane
object.
In that TabPane
I have a specific Tab
, which contains a Button
object, that can add new tabs to the main TabPane
. But I need to entangle each Tab
in the main TabPane
with a single object instance (each tab should work with one instance of a class Merchant
)
The class Merchant
has some method createSortiment()
that generates ArrayList
of randomly picked items based on the parameters of the Merchant
object.
The main controller GUIController
controls the main window and another controller GUIMerchantTabController
controls the tabs.
I need to be able to add a new tab (this I can do) and somehow bind it to a Merchant JohnSmith = new Merchant();
Then I need the controller GUIMerchantTabController
to be able to respond to an action event of the button with fx:id="createSortiment"
with calling the JohnSmith.createSortiment()
(which I have no clue how to do it) and the add each generated item to some Accordion
in the Tab
as a TitledPane
(which I also can do).
MY MAIN QUESTION:
How can I save an instance of JohnSmith to that particular Tab
that the GUIMerchantTabController will be able to use John's methods and access his data?
Is possible some kind of object instance refference? Can I somehow add the object to that pane as a node? Does some "data" attribute exists in Java (as in HTML <element data-storeSomething="Some text here, or json object">
)?
I think that looking to my files is not necessary, but just for some better idea, these are my fmxls...
FXML of the merchant tab:
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.text.Font?>
<Tab fx:controller="damn.fuck.shit.GUIMerchantTabController" closable="false" text="Merchant name" xmlns:fx="http://javafx.com/fxml/1">
<content>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<SplitPane dividerPositions="0.7508361204013378" prefHeight="371.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<ScrollPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<Accordion fx:id="sortimentViewSpace" prefHeight="369.0" prefWidth="438.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<panes>
<TitledPane animated="false" text="Item00">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<Label text="This is testing item label lol" />
</AnchorPane>
</content>
</TitledPane>
</panes>
</Accordion>
</ScrollPane>
<ScrollPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<Button fx:id="createSortimentButton" layoutX="51.0" layoutY="-338.0" mnemonicParsing="false" onAction="#generateSortiment" prefHeight="31.0" prefWidth="142.0" text="Vytvoř sortiment" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Button>
</ScrollPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</content>
</Tab>
FXML of the main window:
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.cell.ChoiceBoxListCell?>
<TabPane fx:id="mainWindow" maxHeight="400.0" maxWidth="600.0" minHeight="400.0" minWidth="600.0" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="damn.fuck.shit.GUIController">
<tabs>
<Tab closable="false" text="Volby">
<content>
<Pane prefHeight="200.0" prefWidth="200.0">
<children>
<FlowPane hgap="5.0" layoutX="0.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="371.0" prefWidth="300.0" vgap="5.0">
<children>
<Label alignment="CENTER" prefHeight="25.0" prefWidth="307.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
<text>
Vytvoř nového kupce
</text>
</Label>
<Label prefHeight="25.0" prefWidth="40.0" text="Jméno:" />
<TextField prefHeight="25.0" prefWidth="235.0" promptText="Vepiš jméno nového kupce" />
<CheckBox mnemonicParsing="false" prefHeight="25.0" prefWidth="115.0" text="Prodává magicé předměty" />
<Button fx:id="createMerchantButton" prefHeight="25.0" prefWidth="150.0" text="Vytvoř nového kupce" onAction="#addMerchantTab">
</Button>
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</FlowPane>
</children>
</Pane>
</content></Tab>
</tabs>
</TabPane>
Node has a userData API:
public void setUserData(Object value)
Convenience method for setting a single Object property that can be retrieved at a later date. This is functionally equivalent to calling the
getProperties().put(Object key, Object value)
method. This can later be retrieved by callinggetUserData()
.
It also has a properties API for associating a map of key->value pairs:
public final ObservableMap<Object,Object> getProperties()
Returns an observable map of properties on this node for use primarily by application developers.
Both of these APIs allow you to associate user object instances with JavaFX nodes.
Alternately, you can extend whatever node type you are using (as long as it is not final, lots of things are final and not user extensible in JavaFX), and store a reference in your extension. For example:
class MyTab extends Tab {
private MyClass myObject;
public MyTab(MyClass myObject) {
super();
this.myObject = myObject;
}
}
Using a class extension has the advantage of preserving type information in case your app would benefit from that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With