Автопрокрутка JavaFX TextFlow

У меня есть JavaFX TextFlow завернутый в ScrollPane, и я пытаюсь заставить его автоматически прокручивать вниз, когда новый Text добавляется в TextFlow,

Я пытался прикрепить слушателей макси ScrollPane"s vvalue чтобы:

  • ScrollPane"s vvalue собственность
    • Это блокирует ScrollPane на дно, что не желательно.
  • ScrollPane"s viewportBounds имущество.
    • Это просто не работает.
  • TextFlowСписок детей.
    • Это прокручивает к месту, которое было дно до последней Text был добавлен, как ни странно. Я пытался явно запросить макет перед прокруткой, но это не имело никакого эффекта

За еще одно большое спасибо, я хотел бы прокрутить так, чтобы, если новое дополнение было слишком большим для отображения сразу, ScrollPane прокручивается так, что новое дополнение находится вверху, и пользователь должен прокручивать вручную, чтобы увидеть "переполнение". Как я уже сказал, это было бы дополнительным бонусом, просто прокрутка до дна была бы просто замечательной, так как я не ожидаю таких больших дополнений (регулярно).

И нет, я не переключаюсь на TextArea, в котором это было бы относительно просто. Я хочу, чтобы можно было легко добавлять обычный, жирный и курсивный текст к TextFlow, а также TextArea не поддерживает это Я также попробовал RichTextFX Томаса Микулы, но

  1. Это продолжало бросать StackruErrorна внутренний код без объяснения причин.
  2. Я действительно не хочу использовать сторонние библиотеки для этого проекта.

Так что любое решение, которое будет работать с TextFlow будет принята с благодарностью.

РЕДАКТИРОВАТЬ: Решение, в соответствии с просьбой:

private ScrollPane textContainer;
private TextFlow text;

public BaseGui() {
    //....
    text.getChildren().addListener(
                (ListChangeListener<Node>) ((change) -> {
                    text.layout();
                    textContainer.layout();
                    textContainer.setVvalue(1.0f);
                }));
    textContainer.setContent(text);
    //....
}

public void appendBold(String msg) { //similar for italic and regular
    append(msg, "-fx-font-weight: bold");
}

private synchronized void append(String msg, String style) {
    Platform.runLater(() -> {
        Text t = new Text(msg);
        t.setFont(segoe(13));
        if (!style.equals("")) {
            t.setStyle(style);
        }
        text.getChildren().add(t);
    });
}

Он не получит никаких наград за стиль кода, но так как это личный проект, мне все равно.

1 ответ

Решение

Измените свой третий подход к использованию layout() вместо requestLayout(),

requestLayout() помечает макет как грязный и вызывает изменение макета на следующем импульсе. В коде

requestLayout();
doSomethingThatDependsOnLayout();

doSomethingThatDependsOnLayout() увидим старый макет.

layout() выполняет макет немедленно (синхронно), но только если макет грязный. (В вашем случае изменение текста TextFlow помечает его макет как грязный.) В коде

layout();
doSomethingThatDependsOnLayout();

doSomethingThatDependsOnLayout() увидим новый макет.

Другие вопросы по тегам