1

Need help to fix the display issue on table view JavaFX.

I can't paste full code. but, will try to include maximum.

TextField headerTextField = new TextField();
Label label = new Label((String) allColumns[i]);
VBox headerGraphic = new VBox();
headerGraphic.setAlignment(Pos.CENTER);
headerGraphic.getChildren().addAll(label, headerTextField);
TableColumn tableColumn = new TableColumn<>();
tableColumn.setGraphic(headerGraphic);

Output is: enter image description here

if I don't set graphics and directly create a table column with a column name, it looks good.

TableColumn tableColumn = new TableColumn<>((String) allColumns[i]);

Output is: enter image description here

Updates: I resolved it by using Text instead of Label. Seems that Label's width is calculated only after Scene is loaded. Hence, the table column pref width was not set.

With the code below, it worked.

TextField headerTextField = new TextField();
Text label = new Text((String) allColumns[i]);
VBox headerGraphic = new VBox();
headerGraphic.setAlignment(Pos.CENTER);
headerGraphic.getChildren().addAll(label, headerTextField);
TableColumn tableColumn = new TableColumn<>();
tableColumn.setGraphic(headerGraphic);

Output is: enter image description here

  • looks like a bug - which fx version is it? – kleopatra Jun 21 '20 at 12:58
  • @kleopatra, it is javafx 14.0.1 – Kevin Bhuva Jun 21 '20 at 13:02
  • yeah, definitely a bug, can reproduce (and faintly remember having seen it some time ago): the initial sizing is incorrect, later double-clicking into to resize region is fine. You can hack around and manually invoke resizeColumnToFitContent for each header after the table is added to a scene. Either by going dirty and reflectively access that method for each header of implement a custom columnHeader that exposes the method (and the whole stack TableViewSkin, TableHeaderRow, NestedTableColumnHeader for the sole purpose of using that custom header ;) – kleopatra Jun 21 '20 at 13:53
  • @klepatra, Thanks. I fixed it by replacing label with text. Seems Label's width is calcuated only after it is layouted. didn't have to hack resize method. edited above post with result. :) – Kevin Bhuva Jun 21 '20 at 13:55
  • good :) You might consider self-answering (and accepting the answer) your question to make it findable by future readers. – kleopatra Jun 21 '20 at 13:57

1 Answers1

0

I resolved it by using Text instead of Label. Seems that Label's width is calculated only after Scene is loaded. Hence, the table column pref width was not set. Edited the above post.

Updates: I had to use resize custom method as above approach didn't work when the table doesn't have records. So, I called the below function and it worked for both when table with records and table without records.

public static void autoResizeColumns( TableView<?> table )
    {
        //Set the right policy
        table.getColumns().stream().forEach( (column) ->
        {
            Text t = new Text( column.getText() );
            double max = 0.0f;
            if("".equals(t.getText()))
            {
                VBox vBox = (VBox) column.getGraphic();
                ObservableList<Node> vBoxChild = vBox.getChildren();
                max = vBoxChild.get(0).getLayoutBounds().getWidth();
            }
            else
            {
                max = t.getLayoutBounds().getWidth();
            }
            
            for ( int i = 0; i < table.getItems().size(); i++ )
            {
                //cell must not be empty
                if ( column.getCellData( i ) != null )
                {
                    t = new Text( column.getCellData( i ).toString() );
                    double calcwidth = t.getLayoutBounds().getWidth();
                    //remember new max-width
                    if ( calcwidth > max )
                    {
                        max = calcwidth;
                    }
                }
            }
            //set the new max-widht with some extra space
            column.setPrefWidth( max + 15.0d );
        } );
    }