JavaFX TableView Column Width\Contents auto-truncating

前端 未结 1 734
情深已故
情深已故 2021-02-09 14:14

I\'m trying to \"smartly\" abbreviate/truncate the String contents of a column nested in a TableView. I have tried using UNCONSTRAINED_RESIZE_POLICY bu

1条回答
  •  花落未央
    2021-02-09 14:51

    Solution

    The default overrun behavior of a standard TableCell is to truncate it's string and display ... at the end of the string to indicate that the string has been truncated. All Labeled controls in JavaFX work this way.

    The examples in your question have ... ellipsises in the middle of the strings. To achieve that, set the overrun style on the cell generated by the appropriate cell factory:

    setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);
    

    The text string displayed for ellipsises can also be modifed by setting a new ellipsis string on the cell generated by the appropriate cell factory:

    setEllipsisString(ellipsisString);
    

    A simple table cell which demonstrates this is:

    class CenteredOverrunTableCell extends TableCell {
        public CenteredOverrunTableCell() {
            this(null);
        }
    
        public CenteredOverrunTableCell(String ellipsisString) {
            super();
            setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);
            if (ellipsisString != null) {
                setEllipsisString(ellipsisString);
            }  
        }
    
        @Override protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            setText(item == null ? "" : item);
        }
    }
    

    Sample Application

    The CenteredOverrunTableCell is used in the following sample application.

    1. The First Name column elides the text in the center and uses a custom ellipsis string of <--->
    2. The Last Name column elides the text in the center but provides no custom ellipsis string.
    3. The Email column just uses the default overrun policy and ellipsis string which places the ... ellipsis at the end of the overrun string.

    elidedtableview

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.*;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.VBox;
    import javafx.scene.text.Font;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class ElidedTableViewSample extends Application {
        private TableView table = new TableView<>();
        private final ObservableList data =
            FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethangorovichswavlowskikaliantayaprodoralisk", "Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch", "ethan@llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com")
            );
    
        public static void main(String[] args) { launch(args); }
    
        @Override public void start(Stage stage) {
            stage.setTitle("Table View Sample");
            stage.setWidth(470);
            stage.setHeight(500);
    
            final Label label = new Label("Address Book");
            label.setFont(new Font("Arial", 20));
    
            TableColumn firstNameCol = new TableColumn("First Name");
            firstNameCol.setCellValueFactory(
                    new PropertyValueFactory("firstName"));
            firstNameCol.setCellFactory(new Callback, TableCell>() {
                @Override public TableCell call(TableColumn p) {
                    return new CenteredOverrunTableCell("<--->");
                }
            });
    
            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setCellValueFactory(
                    new PropertyValueFactory("lastName"));
            lastNameCol.setCellFactory(new Callback, TableCell>() {
                @Override public TableCell call(TableColumn p) {
                    return new CenteredOverrunTableCell();
                }
            });
    
            TableColumn emailCol = new TableColumn("Email");
            emailCol.setCellValueFactory(
                    new PropertyValueFactory("email"));
    
            table.setItems(data);
            table.getColumns().addAll(
                firstNameCol, 
                lastNameCol, 
                emailCol
            );
    
            final VBox vbox = new VBox();
            vbox.setSpacing(5);
            vbox.setPadding(new Insets(10));
            vbox.getChildren().addAll(label, table);
    
            table.setColumnResizePolicy(
                TableView.CONSTRAINED_RESIZE_POLICY
            );
    
            Scene scene = new Scene(vbox);
            stage.setScene(scene);
            stage.show();
        }
    
        class CenteredOverrunTableCell extends TableCell {
            public CenteredOverrunTableCell() {
                this(null);
            }
    
            public CenteredOverrunTableCell(String ellipsisString) {
                super();
                setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);
                if (ellipsisString != null) {
                    setEllipsisString(ellipsisString);
                }  
            }
    
            @Override protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                setText(item == null ? "" : item);
            }
        }
    
        public static class Person {
            private final SimpleStringProperty firstName;
            private final SimpleStringProperty lastName;
            private final SimpleStringProperty email;
    
            private Person(String fName, String lName, String email) {
                this.firstName = new SimpleStringProperty(fName);
                this.lastName = new SimpleStringProperty(lName);
                this.email = new SimpleStringProperty(email);
            }
    
            public String getFirstName() {
                return firstName.get();
            }
    
            public void setFirstName(String fName) {
                firstName.set(fName);
            }
    
            public String getLastName() {
                return lastName.get();
            }
    
            public void setLastName(String fName) {
                lastName.set(fName);
            }
    
            public String getEmail() {
                return email.get();
            }
    
            public void setEmail(String fName) {
                email.set(fName);
            }
        }
    }
    

    0 讨论(0)
提交回复
热议问题