Skip to content

Instantly share code, notes, and snippets.

@danielpeintner
Last active March 7, 2024 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielpeintner/9b561eb57261e8c5bc608f1346df74cf to your computer and use it in GitHub Desktop.
Save danielpeintner/9b561eb57261e8c5bc608f1346df74cf to your computer and use it in GitHub Desktop.
JavaFX Label truncated, see https://github.com/openjdk/jfx/pull/1389/
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.converter.DefaultStringConverter;
public class TableViewExampleTruncated extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("jacob.smith@example.com"),
new Person("isabella.johnson@example.com"),
new Person("ethan.williams@example.com"),
new Person("emma.jones@example.com"),
new Person("michael.brown@example.com"));
public static void main(String[] args) {
launch(args);
}
static void changeTooltip(Labeled labeled, boolean b) {
System.out.println("Tooltip for '" + labeled.getText() + "' --> " + b);
if (b) {
labeled.setTooltip(new Tooltip(labeled.getText()));
} else {
labeled.setTooltip(null);
}
}
@Override
public void start(Stage stage) {
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
// TableView
table.setEditable(true);
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setCellValueFactory(param -> param.getValue().emailProperty());
// emailCol.setCellFactory(TextFieldTableCell.forTableColumn());
emailCol.setCellFactory((tableColumn) -> new TextFieldTableCell<>(new DefaultStringConverter()) {
// ReadOnlyBooleanWrapper tableCellTextTruncated;
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
System.out.println("Recalculating for TableCell: " + this.getText());
if (isWrapText()) {
boolean b1 = (getHeight() < prefHeight(getWidth()));
System.out.println("\tTable-Email-Cell isWrapText: " + getHeight() + " < " + prefHeight(getWidth()) + " --> " + b1);
changeTooltip(this, b1);
return;
}
boolean b2 = (getWidth() < prefWidth(-1));
System.out.println("\tTable-Email-Cell !isWrapText: " + getWidth() + " < " + prefWidth(-1) + " --> " + b2);
changeTooltip(this, b2);
// // Note: can not re-use a ReadOnlyBooleanWrapper since TableCells are re-used in JavaFX heavily
// if (tableCellTextTruncated == null) {
// tableCellTextTruncated = new ReadOnlyBooleanWrapper(this, "textTruncated");
// tableCellTextTruncated.bind(Bindings.createBooleanBinding(() -> {
// System.out.println("Recalculating for TableCell: " + this.getText());
// if (isWrapText()) {
// boolean b1 = (getHeight() < prefHeight(getWidth()));
// System.out.println("\tTable-Email-Cell isWrapText: " + getHeight() + " < " + prefHeight(getWidth()) + " --> " + b1);
// return b1;
// }
// boolean b2 = (getWidth() < prefWidth(-1));
// System.out.println("\tTable-Email-Cell !isWrapText: " + getWidth() + " < " + prefWidth(-1) + " --> " + b2);
// return b2;
// },
// ellipsisStringProperty(),
// fontProperty(),
// heightProperty(),
// textProperty(),
// widthProperty(),
// wrapTextProperty()
// ));
// }
}
});
emailCol.setOnEditCommit(t -> t.getTableView().getItems().get(t.getTablePosition().getRow()).emailProperty().set(t.getNewValue()));
table.setItems(data);
table.getColumns().addAll(emailCol);
// Label Test
final MyLabel label = new MyLabel("A text which can be extended");
label.textTruncatedProperty().addListener((observableValue, aBoolean, t1) -> changeTooltip(label, t1));
final Button bAdd = new Button("Add text to label above");
bAdd.setOnAction(event -> label.setText(label.getText() + " " + System.currentTimeMillis()));
final Button bReset = new Button("Reset text");
bReset.setOnAction(event -> label.setText("A text which can be extended"));
// Layout
BorderPane pb = new BorderPane();
pb.setCenter(table);
pb.setBottom(new VBox(new Label(" - - - - - - - - "), label, bAdd, bReset));
Scene scene = new Scene(pb);
stage.setScene(scene);
stage.show();
}
static class MyLabel extends Label {
private ReadOnlyBooleanWrapper textTruncated;
public MyLabel(String text) {
super(text);
}
public final ReadOnlyBooleanProperty textTruncatedProperty() {
if (textTruncated == null) {
textTruncated = new ReadOnlyBooleanWrapper(this, "textTruncated");
textTruncated.bind(Bindings.createBooleanBinding(() -> {
if (isWrapText()) {
return (getHeight() < prefHeight(getWidth()));
}
return (getWidth() < prefWidth(-1));
},
ellipsisStringProperty(),
fontProperty(),
heightProperty(),
textProperty(),
widthProperty(),
wrapTextProperty()
));
}
return textTruncated.getReadOnlyProperty();
}
public final boolean isTextTruncated() {
return textTruncatedProperty().get();
}
}
public static class Person {
private final StringProperty email;
private Person(String email) {
this.email = new SimpleStringProperty(email);
}
public StringProperty emailProperty() {
return email;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment