1

When I am adding a nested column dynamically after table is created,nested column headers are NOT rendering. Here is the code reproducing the problem. I am using JDK 1.8.0_121

However If I add the nested columns inline then everything appears as expected.

package hellofx;

import javafx.application.*;
import javafx.application.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.*;
import javafx.stage.*;

public class TableViewSample extends Application {

private TreeTableView table = new TreeTableView();

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

@Override
public void start(Stage stage) {
    Scene scene = new Scene(new Group());
    stage.setTitle("Table View Sample");
    stage.setWidth(600);
    stage.setHeight(500);

    final Label label = new Label("Address Book");
    label.setFont(new Font("Arial", 20));

    table.setEditable(true);

    TreeTableColumn firstNameCol = new TreeTableColumn("First Name");
    TreeTableColumn lastNameCol = new TreeTableColumn("Last Name");
    TreeTableColumn emailCol = new TreeTableColumn("Email");

    //Simulate adding nested columns after stage is set.
    Platform.runLater(() -> {
        TreeTableColumn firstEmailCol = new TreeTableColumn("Primary");
        TreeTableColumn secondEmailCol = new TreeTableColumn("Secondary");

        emailCol.getColumns().addAll(firstEmailCol, secondEmailCol);
    });
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

    final VBox vbox = new VBox();
    vbox.setSpacing(5);
    vbox.setPadding(new Insets(10, 0, 0, 10));
    vbox.getChildren().addAll(label, table);

    ((Group) scene.getRoot()).getChildren().addAll(vbox);

    stage.setScene(scene);
    stage.show();
}
}
  • That `sleep(100)` does not do what you think it does. It doesn’t wait for any events to occur; rather, it temporarily prevents any events from being processed. If your goal is to make something happen after the stage is shown, use `stage.setOnShown`. – VGR Aug 24 '17 at 01:09
  • @VGR You're correct, of course; however I tested the OP's code using a `PauseTransition` to create the delay instead, and it doesn't work that way either. Looks like the table header might fail to recompute the height, or fail to layout somehow. – James_D Aug 24 '17 at 01:11
  • Number of nested columns is not known at table rendering time, depending on the incoming feed the columns will change. That delay is just a demonstration purpose only. It will be a real world event causing that piece of code to execute. –  Aug 24 '17 at 01:17
  • @BiswaDas The point being made was that the delay doesn't actually do anything at all, because it blocks the UI thread (so for all purposes it's equivalent to it not being there at all, as you can easily verify). The `Platform.runLater()` on its own causes the columns to be added after the stage is shown. Your example would be better and more believable if you got rid of this error, as it's distracting to anyone who might want to help. You're workaround won't work in all cases. – James_D Aug 24 '17 at 01:27
  • True removed the distraction... –  Aug 24 '17 at 01:33

2 Answers2

0

Here is a workaround working for me.

Add a dummy column inline when building the table.

    emailCol.getColumns().add( new TreeTableColumn("DummyColumn"));

Remove it later while adding real columns.

    emailCol.getColumns().remove(0)
0

@VGR's comment is on the right track. As you said in your comment @user2635530

Number of nested columns is not known at table rendering time, depending on the incoming feed the columns will change.

Platform.runLater() should be invoked in listener code, not in the start() method. Add a listener for the event that occurs due to the incoming feed and in that listener, change the columns in your TreeTableView.

Abra
  • 19,142
  • 7
  • 29
  • 41