JavaFX TreeItem Displaying Non-String Object – Troubleshooting

javajavafx

Hello StackExchange community! This is my first post and appreciate any help anyone can offer. I'm new to Java, and I'm sure this issue is simply due to my misunderstanding of the fundamentals.

I have a JavaFX (Java 8) window with a TreeView filled with TreeItems containing a Product object. This object has many fields, one of which is model of type String. When I add a TreeItem, I want it to not only store the Product object but also display the model String field in the TreeView list; however, I get this instead: com.[company name].Products.Product@[number]. This is the package path to the Product class. The [number] is a random string of what appears to be 8 hexidecimal characters that is unique to each instance.

TreeItems are added via a class method, and I suspect that's where my problem lies. Here's a list of the proper flow:

  1. Click the "Add Product" button.
  2. Open pop up window.
  3. Select the appropriate model.
  4. Click OK.
  5. Product object is added to the TreeView via the makeTreeItem method (see below).
  6. New TreeItem should show the model which is a String.

Minimum Working Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TreeItemTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override public void start(Stage primaryStage) {
        TreeItem<Product> rootTree = new TreeItem<>(new Product("root"));
        TreeView<Product> treeView = new TreeView<>(rootTree);
        treeView.setShowRoot(false);

        BorderPane rootPane = new BorderPane();
        rootPane.setCenter(treeView);

        makeTreeItem("New Item 1", rootTree);
        makeTreeItem("New Item 2", rootTree);

        Scene scene = new Scene(rootPane);

        primaryStage.setScene(scene);
        primaryStage.setTitle("Tree Item Test");
        primaryStage.show();
    }

    private TreeItem<Product> makeTreeItem(String title, TreeItem<Product> parent) {
        TreeItem<Product> newItem = new TreeItem<>(new Product(title));
        newItem.setExpanded(true);
        parent.getChildren().add(newItem);
        return newItem;
    }
}

Both "New Items" simply show up as Product@######## (recall the hash symbols are hex characters). The Product class:

public class Product {
    String model;
    public Product(String model) {
        this.model = model;
    }
}

I suspect that what I'm looking for is a CellFactory of some sort, similar to the TableView's CellFactory. No matter how hard I look though I can't for the life of me find anything very promising. Help! What am I missing?!

Best Answer

"New Items" simply show up as Product@########

It's normal. The default toString() method is being invoked.

Invoking the toString() method on an object returns a string that describes this object. By default, it returns a string consisting of the classname of which the object is an instance of, an at sign (@), and the object's memory address in hexadecimal notation.

Therefore, you need to override the toString() method in your Product class.

In your case you could add :

@Override
public String toString() {
    return this.model;
}

Therefore, your Product class should look like this :

public class Product {
    String model;
    public Product(String model) {
        this.model = model;
    }

    @Override
    public String toString() {
        return this.model;
    }
}

Now, your "New Items" won't show up as Product@######## but it will be displayed according to how you implement the toString() method (which you override) in the Product class.

Related Topic