Обтекание текста в ячейках 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
правда, но я думаю, что я также должен назвать 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: Похоже, что строка не допускает разрывы строк, что может быть причиной того, что ячейка не может переносить текст. Он не может переносить текст, потому что новые строки, которые он создает, разбиты.
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), который является установкой свойства содержимого в Абстрактный класс Помечен, где обтекание текста установлено в false. Я не слишком углубился в это, но некоторые обходные пути можно сделать наверняка.