我可以检查TableCell的内容在构建CellValueFactory时是否会溢出

时间:2018-10-17 15:06:07

标签: java javafx tableview

我有一个JavaFX table列,我想显示一个用逗号分隔的字符串列表,除非文本不适合该单元格的当前边界,此时它将显示,例如,“ {{ 1}}”或“ Foo and 3 others...”,即反映列表中元素的数量

在为表列构建CellValueFactory时,有没有一种方法可以检查文本是否会超出单元格,以便可以在这两种行为之间切换?

1 个答案:

答案 0 :(得分:1)

您可以为Labeled之类的TableCell控件指定溢出样式。

溢出样式ELLIPSIS将根据需要自动添加这些省略号,以指示内容是否会超出标签范围。

我建议在单元工厂中这样做,就像这样:

column.setCellFactory(() -> {
    TableCell<?, ?> cell = new TableCell<>();
    cell.setTextOverrun(OverrunStyle.ELLIPSIS);
    return cell;
});

因此,您需要使用单元格工厂而不是。 我建议使用单元工厂的原因是因为表可以根据需要自行创建和销毁单元,因此如果您无法像您那样控制这些单元的创建,您将很难获取所有这些实例并设置其溢出行为与电池工厂有关。


新尝试

尝试按以下方式进行操作,您可能需要调整该方法以获取字符串的长度,并且您可能希望在每次更新时尝试找出表单元格的当前长度,但这应该可以帮助您开始。认为这是一个体面的方法?

public class TestApplication extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }


    public void start(final Stage stage) {
        stage.setResizable(true);

        TestTableView table = new TestTableView();
        ObservableList<String> items = table.getItems();
        items.add("this,is,short,list");
        items.add("this,is,long,list,it,just,keeps,going,on,and,on,and,on");

        Scene scene = new Scene(table, 400, 200);
        stage.setScene(scene);

        stage.show();
    }


    /**
     * Note: this does not take into account font or any styles.
     * <p>
     * You might want to modify this to put the text in a label, apply fonts and css, layout the label,
     * then get the width.
     */
    private static double calculatePixelWidthOfString(String str) {
        return new Text(str).getBoundsInLocal().getWidth();
    }

    public class TestTableView extends TableView<String> {

        public TestTableView() {
            final TableColumn<String, CsvString> column = new TableColumn<>("COL1");
            column.setCellValueFactory(cdf -> {
                return new ReadOnlyObjectWrapper<>(new CsvString(cdf.getValue()));
            });
            column.setCellFactory(col -> {
                return new TableCell<String, CsvString>() {

                    @Override
                    protected void updateItem(CsvString item, boolean empty) { 
                        super.updateItem(item, empty);

                        if (item == null || empty) {
                            setText(null);
                        } else {

                            String text = item.getText();
                            // get the width, might need to tweak this.
                            double textWidth = calculatePixelWidthOfString(text);
                            // might want to compare against current cell width
                            if (textWidth > 100) {
                                // modify the text here
                                text = item.getNumElements() + " elements";
                            }

                            setText(text);
                        }
                    }
                };
            });
            this.getColumns().add(column);
        }
    }

    private static class CsvString {

        private final String text;
        private final String[] elements;


        public CsvString(String string) {
            Objects.requireNonNull(string);
            this.text = string;
            this.elements = string.split(" *, *");
        }


        public int getNumElements() {
            return elements.length;
        }


        public String getText() {
            return text;
        }
    }
}