JavaFX TableColumn text wrapping
Asked Answered
H

2

12

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.

Hydrated answered 29/3, 2014 at 13:57 Comment(4)
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.Fann
That's interesting, works the same for me too. Do you have any idea about how to fix the height issue?Hydrated
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.Fann
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.Leban
F
21

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.

Fann answered 29/3, 2014 at 15:4 Comment(2)
It works like a charm if you bind the width of the Text to the columns widthProperty instead of the cell.widthProperty. Just replace "text.wrappingWidthProperty().bind(cell.widthProperty());" with "text.wrappingWidthProperty().bind(textCol.widthProperty());"Electrotechnology
@MayurPatel That seems like a completely different question; nothing in the OP here asks about text fills.Fann
P
0

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);
                }
            }
        };
    });
Piles answered 6/6, 2019 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.