JavaFX TableView列宽度\内容自动截断 [英] JavaFX TableView Column Width\Contents auto-truncating

查看:1605
本文介绍了JavaFX TableView列宽度\内容自动截断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to "smartly" abbreviate/truncate the String contents of a column nested in a TableView. I have tried using UNCONSTRAINED_RESIZE_POLICY but really prefer CONSTRAINED_RESIZE_POLICY since it auto-resizes the columns based on the window size.

我想要完成的任务:

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 密切相关,但我还没有找到了办法。

I have explored the possibility of reading the String length and doing my own truncating, but then it's not possible to have this dynamically update as the user shrinks/stretches the gui. My gut says this must be done with the JavaFX Classes since it would be closely tied with TableView, however I have not found a way.

如何使用 JavaFX 完成此操作?

推荐答案

解决方案

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

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<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 用于以下示例应用程序。

The CenteredOverrunTableCell is used in the following sample application.


  1. First Name列忽略了中心的文本,并使用的自定义省略号字符串< --- >

  2. 姓氏列省略了中心的文字,但未提供自定义省略号字符串。

  3. 电子邮件column只使用默认的溢出策略和省略号字符串,它将 ... 省略号放在溢出字符串的末尾。

  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.

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);
        }
    }
}

这篇关于JavaFX TableView列宽度\内容自动截断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆