Перенос текста в ячейки JFXTreeTableView

Как я могу обернуть текст в ячейках JFXTreeTableView?

Моя фабрика ячеек столбца JFoenix TableTreeView создается, как показано ниже.

    // Set column cell factories and width preference
    for (JFXTreeTableColumn<LogEntry, String> column : columnList) {
        column.setCellFactory(param -> 
                new GenericEditableTreeTableCell<>(new TextFieldEditorBuilder()));
        column.setPrefWidth(100);
    }

После нескольких часов поиска я не могу понять, как заставить ячейки таблицы дерева переносить текст. Я даже пытался установить значение переноса текста для каждого GenericEditableTreeTableCell в true, но я думаю, что я также должен вызывать метод setWrappingWidth() для чего-то. Я попробовал следующий блок кода, но в итоге получил NullPointerException.

    // Set column cell factories and width preference
    for (JFXTreeTableColumn<LogEntry, String> column : columnList) {
        column.setCellFactory(param -> {
            GenericEditableTreeTableCell<LogEntry, String> cell =
                  new GenericEditableTreeTableCell<>(new TextFieldEditorBuilder());
            Text text = (Text) cell.getGraphic();
            text.setWrappingWidth(1); //null pointer exception
            cell.setWrapText(true);
            return cell;
        });
        column.setPrefWidth(100);
    }

Итак, у меня остался следующий блок кода, который отлично работает и отображает таблицу, но ячейки не переносят текст.

    // Set column cell factories and width preference
    for (JFXTreeTableColumn<LogEntry, String> column : columnList) {
        column.setCellFactory(param -> {
            GenericEditableTreeTableCell<LogEntry, String> cell =
                  new GenericEditableTreeTableCell<>(new TextFieldEditorBuilder());
            // I think I should call setWrappingWidth() on some object here
            // but I don't know what object
            cell.setWrapText(true);
            return cell;
        });
        column.setPrefWidth(100);
    }

Документацию по настройке JFXTreeTableView можно найти здесь. Кажется, ничего не говорится об переносе текста ячейки.

Изменить: я пытался сделать это с помощью CSS, но не получил никаких результатов. Фактически, cell.isWrapText() вернуло значение false после использования этого кода CSS, что означает, что событие не установило значение true. Я знаю, что блок CSS работает правильно, потому что с его помощью я могу изменить цвет заливки текста каждого элемента.

* {
    -fx-wrap-text: true;
}

Редактировать 2: некоторые люди говорили в других полусвязанных сообщениях, что панель прокрутки может заставить узел думать, что она имеет гораздо большую ширину, чем то, что показано пользователю. Поскольку JavaFX TreeTableView использует полосу прокрутки, когда таблица слишком велика, я решил попробовать их решения. Я попытался установить предпочтительную ширину ячейки - все равно безрезультатно.

cell.setWrapText(true);
cell.setPrefWidth(100);
//cell.setMaxWidth(100); doing this too made no difference
//cell.setMinWidth(100); doing this too made no difference

Изменить 3: кажется, я знаю, в чем проблема! Кажется, что высота строки не позволяет ячейке переносить текст. Если я установлю минимальную высоту строк на достаточно большое значение, ячейка перенесет свой текст! Теперь мне просто нужно знать, как настроить высоту строки динамически, чтобы разместить ячейку, когда она хочет обернуть текст.

Правка 4: кажется, что строка не допускает разрывов строк, что может быть причиной того, что ячейка не может переносить текст. Он не может обернуть текст, потому что новые строки, которые он создает, пережевываются.


person Region39    schedule 01.09.2017    source источник


Ответы (1)


Я использовал один из ваших подходов, но также создал собственный EditorBuilder с JFXTextArea вместо JFXTextField.

Пользовательский TextAreaEditorBuilder выглядит следующим образом:

public class TextAreaEditorBuilder  implements EditorNodeBuilder<String> {

private JFXTextArea textArea;

@Override
public void startEdit() {
    Platform.runLater(() -> {
        textArea.selectAll();
    });
}

@Override
public void cancelEdit() {

}

@Override
public void updateItem(String s, boolean isEmpty) {

    Platform.runLater(() -> {
        textArea.selectAll();
        textArea.requestFocus();
    });
}

@Override
public Region createNode(
        String value,
        DoubleBinding minWidthBinding,
        EventHandler<KeyEvent> keyEventsHandler,
        ChangeListener<Boolean> focusChangeListener) {

    StackPane pane = new StackPane();
    pane.setStyle("-fx-padding:-10 0 -10 0");
    textArea = new JFXTextArea(value);
    textArea.setPrefRowCount(4);
    textArea.setWrapText(true);
    textArea.minWidthProperty().bind(minWidthBinding.subtract(10));
    textArea.setOnKeyPressed(keyEventsHandler);
    textArea.focusedProperty().addListener(focusChangeListener);
    pane.getChildren().add(textArea);

    return ControlUtil.styleNodeWithPadding(pane);
}

@Override
public void setValue(String s) {
    textArea.setText(s);
}

@Override
public String getValue() {
    return textArea.getText();
}

@Override
public void validateValue() throws Exception {

}
}

а затем конфигурация для вашего столбца выглядит примерно так:

negativeCasingColumn.setCellFactory(param -> {
        TextAreaEditorBuilder textAreaEditorBuilder = new TextAreaEditorBuilder();
        GenericEditableTreeTableCell<DiagnosticMethodFX, String> cell
                = new GenericEditableTreeTableCell<>(textAreaEditorBuilder);
        cell.setWrapText(true);
        return cell;
    });

Итак, в основном я оборачиваю ячейку, но обязательно использую TextArea в качестве поля редактирования. Для меня это работает просто отлично, но если вам нужно более элегантное решение, возможно, вы можете проверить метод cancelEdit() в GenericEditableTreeTableCell, где он устанавливает отображение содержимого только в виде текста: setContentDisplay(ContentDisplay.TEXT_ONLY), который является настройкой свойства содержимого в абстрактном классе Labeled, где для переноса текста задано значение false. Я не копался слишком глубоко в этом, но наверняка можно найти какой-то обходной путь.

person smashbotica    schedule 16.09.2017
comment
Вместо этого я выбрал таблицу дерева Java, но в ближайшем будущем я планирую еще раз попробовать JFXTreeTable. Тогда я попробую ваш код, но пока это выглядит как надежный ответ, поэтому я тем временем проголосую за него! - person Region39; 16.09.2017
comment
Итак, я наконец-то добрался до реализации вашего решения сегодня, но я застрял на одной части процесса. Когда вы переопределяете метод createNode в TreeAreaEditorBuilder, вы возвращаете ControlUtil.styleNodeWithPadding(pane). Откуда ControlUtil? Я получаю сообщение об ошибке в IntelliJ, и он не предлагает никаких классов для импорта. Я также не смог найти никакой документации с поиском Google. - person Region39; 03.10.2017