JavaFX Tree with self-joined table
Trees are always tricky, because it's not easy to fill a tree with data. The problem is not the tree itself, but the preparation of data for the three. It's easy if your data is structured or if you have only few records to prepare. If you have differnet datasources, it could be very tricky to build a tree.
The official tree documentation from Oracle has some examples.
It's boring to create trees because it needs a lot of boilerplate code - per tree. You need more boilerplate code if your trees should be editable.
We solved the "boilerplate code problem" with JVx and the active model implementation. I'll show you a simple example with a self-joined database table. The database table contains all filesystem folders of our Linux test VM.
The table was created with following statement:
(
ID INTEGER IDENTITY,
FOLDER VARCHAR(256) NOT NULL,
FOLD_ID INTEGER,
constraint FOLD_UK UNIQUE (FOLD_ID, FOLDER),
constraint FOLD_FOLD_ID_FK FOREIGN KEY (FOLD_ID) REFERENCES FOLDERS (ID) ON DELETE CASCADE
)
Not really tricky. The table contains an unique identifier, the folder name and the identifier of the parent folder. A simple self-joined table.
The UI code for the tree:
FXDataBooksTree tree = new FXDataBooksTree();
tree.getDataBooks().addAll(dataBook);
Short and no boilerplate code!
The missing piece is the createDataBook() method, because it defines the access to our database table:
rdbData.setDataSource(getDataSource());
rdbData.setName("folders");
rdbData.setMasterReference(new ReferenceDefinition(new String[] {"FOLD_ID"},
rdbData,
new String[] {"ID"}));
rdbData.open();
The code is similar to other examples likeJavaFX, JVx and data binding or Plain JDBC vs. DBStorage.
The tree will look like this one:
The whole source code is available in our dev branch.
Above test application reads records from a remote database via http, but it could also use a memory databook without database access, like this one:
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("ID",
new BigDecimalDataType()));
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("PARENT_ID",
new BigDecimalDataType()));
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("NAME",
new StringDataType()));
dataBook.setMasterReference(new ReferenceDefinition(new String[] { "PARENT_ID" },
dataBook,
new String[] { "ID" }));
dataBook.setName("MASTER");
dataBook.open();
An example with a MemDataBook is available in our kitchensink application.