Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I store instance of an object in a javaFX node?

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>
like image 856
Adam Bajger Avatar asked Jan 03 '23 11:01

Adam Bajger


1 Answers

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 calling getUserData().

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.

like image 125
jewelsea Avatar answered Jan 06 '23 03:01

jewelsea