Search code examples
javajavafxtreetableview

javafx TreeTableView string array columns


All existing answers were using a class object to display multiple columns. Do I have to use a class? Can I just use a string array like C#'s ListViewItem? If I can, how?

For example, display "hello" in the first column and "world" in the second column.

public class HelloController {
    @FXML
    private TreeTableView mytree;
    @FXML
    private TreeTableColumn colFirst;
    @FXML
    private TreeTableColumn colSecond;

    @FXML
    void initialize()
    {
        TreeItem<String[]> item = new TreeItem<String[]>(new String[]{"hello", "world"});
        colFirst.setCellValueFactory((CellDataFeatures<Object, String[]> p)
            -> new ReadOnlyStringWrapper(p.getValue().toString()));
        mytree.setRoot(item);
    }
}

fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.fx2.HelloController">
  <TreeTableView fx:id="mytree" prefHeight="200.0" prefWidth="200.0">
     <columns>
        <TreeTableColumn id="colFirst" prefWidth="75.0" text="First" />
        <TreeTableColumn id="colSecond" prefWidth="75.0" text="Second" />
     </columns>
  </TreeTableView>
</VBox>

Solution

  • Never use raw types: parameterize your types properly:

    public class HelloController {
        @FXML
        private TreeTableView<String[]> mytree;
        @FXML
        private TreeTableColumn<String[], String> colFirst;
        @FXML
        private TreeTableColumn<String[], String> colSecond;
    
        // ...
    }
    

    Then in the lambda expression, p is a TreeTableColumn.CellDataFeatures<String[], String>, so p.getValue() is a TreeItem<String[]> and p.getValue().getValue() is the String[] representing the row.

    So you can do

    @FXML
    void initialize() {
        TreeItem<String[]> item = new TreeItem<String[]>(new String[]{"hello", "world"});
        colFirst.setCellValueFactory(p
            -> new ReadOnlyStringWrapper(p.getValue().getValue()[0]));
        mytree.setRoot(item);
    }