Last active
March 7, 2024 15:04
-
-
Save danielpeintner/9b561eb57261e8c5bc608f1346df74cf to your computer and use it in GitHub Desktop.
JavaFX Label truncated, see https://github.com/openjdk/jfx/pull/1389/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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("[email protected]"), | |
new Person("[email protected]"), | |
new Person("[email protected]"), | |
new Person("[email protected]"), | |
new Person("[email protected]")); | |
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