Могу ли я проверить, не будет ли содержимое TableCell переполнено при создании CellValueFactory? - PullRequest
0 голосов
/ 17 октября 2018

У меня есть столбец таблицы JavaFX, в котором я хотел бы отобразить список строк, разделенных запятыми, если только текст не помещается в текущие границы ячейки, и в этот момент он будет отображаться, например, "Foo and 3 others... "или" 3 Bars ", то есть, отражая количество элементов в списке .

Есть ли способ проверить при построении CellValueFactory для столбца таблицы, является литекст переполняет ячейку, поэтому я могу переключаться между этими двумя поведениями?

1 Ответ

0 голосов
/ 17 октября 2018

Вы можете указать стиль переполнения для Labeled элементов управления, таких как TableCell s.

Стиль переполнения 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;
        }
    }
}
...