JavaFX TableView列宽度\内容自动截断

时间:2013-05-24 05:21:38

标签: java string javafx-2 javafx tableview

我正在尝试“巧妙地”缩写/截断嵌套在TableView中的列的String内容。我尝试过使用UNCONSTRAINED_RESIZE_POLICY,但我更喜欢CONSTRAINED_RESIZE_POLICY,因为它会根据窗口大小自动调整列的大小。

我正在努力实现的目标:

String one = "SomeVeryLongString";

// Displayed in the column where user has shrunk it too narrow

+-------------+
| Some...ring |
+-------------+

// and if the user shrunk it a bit more

+-----------+
| Som...ing |
+-----------+

// and if they stretch it a bit

+---------------+
| SomeV...tring |
+---------------+

// etc...

我已经探索了读取String长度并进行自己的截断的可能性,但是当用户收缩/拉伸gui时,不可能动态更新。我的直觉说这必须使用JavaFX Classes来完成,因为它与TableView密切相关,但我找不到办法。

如何使用JavaFX完成此操作?

1 个答案:

答案 0 :(得分:7)

<强>解决方案

标准TableCell的默认溢出行为是截断它的字符串并在字符串末尾显示...以指示该字符串已被截断。 JavaFX中的所有Labeled控件都以这种方式工作。

您问题中的示例在字符串中间有...个省略号。为了达到这个目的,set the overrun style在适当的细胞工厂生成的细胞上:

setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);

为省略号显示的文本字符串也可以由适当的单元工厂生成的单元格上的setting a new ellipsis string修改:

setEllipsisString(ellipsisString);

一个简单的表格单元格用于演示:

class CenteredOverrunTableCell extends TableCell<Person, String> {
    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);
    }
}

示例应用

CenteredOverrunTableCell用于以下示例应用程序。

  1. “名字”列忽略中心的文字,并使用自定义省略号字符串<--->
  2. “姓氏”列省略了中心的文字,但未提供自定义省略号字符串。
  3. “电子邮件”列只使用默认的超限策略和省略号字符串,该字符串将...省略号放在超限字符串的末尾。
  4. 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<Person> table = new TableView<>();
        private final ObservableList<Person> 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<Person, String>("firstName"));
            firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
                @Override public TableCell<Person, String> call(TableColumn<Person, String> p) {
                    return new CenteredOverrunTableCell("<--->");
                }
            });
    
            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("lastName"));
            lastNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
                @Override public TableCell<Person, String> call(TableColumn<Person, String> p) {
                    return new CenteredOverrunTableCell();
                }
            });
    
            TableColumn emailCol = new TableColumn("Email");
            emailCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("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<Person, String> {
            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);
            }
        }
    }