12
votes

I am experiencing an issue when resizing a TableView which contains text items that wrap around TableCell items. Upon resizing, hidden values are resized but the visible items do not re-calculate the text wrapping.

The issue.

The tweets in the red box were hidden during the resize and had their text wrapping adjusted as expected. Tweets above the box were visible during the resize phase and still have the old wrapping.

Below is my code for the resize phase.

fxSearchResultsTableTweet.setCellFactory(new Callback<TableColumn<Status, String>, TableCell<Status, String>>() {
        @Override
        public TableCell<Status, String> call(TableColumn<Status, String> arg0) {
            return new TableCell<Status, String>() {
                private Text text;

                @Override
                public void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (!isEmpty()) {
                        text = new Text(item.toString());
                        text.setWrappingWidth(fxSearchResultsTableTweet.getWidth());
                        this.setWrapText(true);

                        setGraphic(text);
                    }
                }
            };
        }
    });
}

Any help would be greatly appreciated.

2
Try text.wrappingWidthProperty().bind(widthProperty());. The widthProperty is the width of the cell. I mocked this up quickly, and the width behaves properly, though the height doesn't. - James_D
That's interesting, works the same for me too. Do you have any idea about how to fix the height issue? - Steve
No. It actually behaves really badly with respect to selection. If you use a default TableCell and bind the text to the cell's item property (I'll post code) it seems better, but still not perfect. - James_D
Note that if you're using a Text instead of a Label like here, you can use -fx-font-smoothing-type: LCD; to avoid aliasing problems if your text is small. - Chavjoh

2 Answers

18
votes

This is closer, but not great:

    textCol.setCellFactory(new Callback<TableColumn<Status, String>, TableCell<String, String>>() {

        @Override
        public TableCell<Status, String> call(
                TableColumn<Status, String> param) {
            TableCell<Status, String> cell = new TableCell<>();
            Text text = new Text();
            cell.setGraphic(text);
            cell.setPrefHeight(Control.USE_COMPUTED_SIZE);
            text.wrappingWidthProperty().bind(cell.widthProperty());
            text.textProperty().bind(cell.itemProperty());
            return cell ;
        }

    });

In 2.2 this displays the wrong height when you add new items to the table, then on resize the cells are sized correctly. In 8 it's almost perfect, just seems to fail after the first item is added (at least in my mock-up).

As noted in the comments,

textCol.setCellFactory(tc -> {
    TableCell<Status, String> cell = new TableCell<>();
    Text text = new Text();
    cell.setGraphic(text);
    cell.setPrefHeight(Control.USE_COMPUTED_SIZE);
    text.wrappingWidthProperty().bind(textCol.widthProperty());
    text.textProperty().bind(cell.itemProperty());
    return cell ;
});

appears to work better.

0
votes

Just add cell factory on each table of column. It should add before adding your data to table view. It is worked fine for me.

    yourTableColumn.setCellFactory(param -> {
        return new TableCell<YourDataClass, String>() {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setText(null);
                    setStyle("");
                } else {
                    Text text = new Text(item);
                    text.setStyle("-fx-text-alignment:justify;");                      
                    text.wrappingWidthProperty().bind(getTableColumn().widthProperty().subtract(35));
                    setGraphic(text);
                }
            }
        };
    });