问题
I wont to place formated text inside a JavaFX table. First I was trying to embedd a Webview but I had problems with cell heigh. This seems to be a mission feature in JavafX (see: Java FX: TableView - display simple HTML).
Based on the recommendation here I tried to embed a TextFlow. However again the sizing of the TabelCell is not correct. I want the height of the row just as big, that the content of the cell fits inside. Changeing the column width should result in changeing the row heigth.
Here is my minimal running example.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private final ObservableList<MyData> data = FXCollections.observableArrayList(new MyData(1L), new MyData(3L), new MyData(2L), new MyData(4L), new MyData(1L));
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage stage) {
final Scene scene = new Scene(new Group());
TableView<MyData> table = new TableView<>();
final TableColumn<MyData, Long> nameCol = new TableColumn("So So");
nameCol.setMinWidth(200);
nameCol.setCellValueFactory(new PropertyValueFactory<>("i"));
// Allow to display Textflow in Column
nameCol.setCellFactory(column -> {
return new TableCell<MyData, Long>() {
@Override
protected void updateItem(Long item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setStyle("");
} else {
// Generate Textflow with variable length
TextFlow textFlow = new TextFlow();
textFlow.setPrefHeight(Region.USE_COMPUTED_SIZE);
for (Long ii = 1L; ii <= item; ii++) {
Text text1 = new Text("la la la ");
text1.setFill(Color.RED);
Text text2 = new Text("blue blue blue ");
text2.setFill(Color.BLUE);
textFlow.getChildren().add(text1);
textFlow.getChildren().add(text2);
}
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setGraphic(textFlow);
// setPrefHeight(20); // <- Shows the expected effect.
// However I want to have variable height of row.
setPrefHeight(Region.USE_COMPUTED_SIZE); // <- Why is that not working
}
}
};
});
table.setItems(data);
table.getColumns().addAll(nameCol);
((Group) scene.getRoot()).getChildren().addAll(table);
stage.setScene(scene);
stage.show();
}
public static class MyData {
private Long i;
public MyData(Long i) { this.i = i; }
public Long getI() { return i; }
}
}
As you can see the row height is way to big. Any Suggestions?
回答1:
I had the same issue within an application and thought it is a bug in the FX code. After debugging the JDK code I finally understood where the problem is coming from.
During rendering the TextFlow
will be asked for its preferred height given a width of -1. The TextFlowLayout
will then return the height as if it would have to display everything in an extremely narrow column, thus resulting in a preferred height direct proportional to the number of characters in your TextFlow
object. Because the height of a row is not bounded in a TableView
or TreeTableView
the table will allocate the preferred height of the TextFlow
object resulting in the strange appearance as above.
The problem can be solved by setting the preferred height of the cell to the height of the textFlow
and additionally adding a ChangeListner
to the width to adapt the height if the the width of the cell changes.
setPrefHeight(textFlow.prefHeight(nameCol.getWidth()) + 4);
nameCol.widthProperty().addListener((v, o, n) ->
setPrefHeight(textFlow.prefHeight(n.doubleValue()) + 4));
回答2:
TableView increase cell height for each text node in cell. If you use a TextFlow component, row increases the own height as if each letter were in a separate row.
image
I dont khow how to prevent this bug.
I can advise you to use only one Text node in cell, or instead of a TableView use a ListView. This component is free of this shortcoming.
来源:https://stackoverflow.com/questions/42855724/textflow-inside-tablecell-not-correct-cell-height