Положение делителя JavaFX SplitPane непоследовательное
У меня есть две StackPanes (pane1 & pane2), отображаемые в SplitPane (splitPane). Положение делителя SplitPane в компоновщике установлено на.3. Второе StackPane (pane2) содержит кнопку, которая также устанавливает позицию делителя SplitPane на.3.
При прочих равных условиях ожидаемое поведение будет состоять в том, что оба действия (установка позиции делителя в конструкторе и установка позиции делителя посредством действия) либо работают, либо нет.
Тем не менее, только последний на самом деле работает.
Что меняется между построением SplitPane и активацией кнопки. Что мешает размещению делителя в застройщике?
StackPane pane1 = new StackPane();
StackPane pane2 = new StackPane();
final SplitPane splitPane = SplitPaneBuilder.create()
.items(pane1, pane2)
// Environment A
.dividerPositions(new double[] {.3}) // splitPane.setDividerPosition(s)(...), etc. yield same result
.orientation(Orientation.HORIZONTAL)
.build();
// The following line influences environment A outcome, though it does not fix the issue
SplitPane.setResizableWithParent(pane1, false);
pane2.getChildren().add(ButtonBuilder.create()
.text("Divider Position")
.onAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Environment B
splitPane.setDividerPositions(.3);
}
})
.build());
Scene primaryScene = SceneBuilder.create()
.root(splitPane)
.build();
primaryStage.setScene(primaryScene);
primaryStage.setTitle("Name");
primaryStage.setWidth(500);
primaryStage.setHeight(500);
primaryStage.show();
2 ответа
Итак, благодаря Джеймсу Д. на форумах поддержки Oracle, вот полный ответ:
"Похоже, проблема заключается в том, что размер сцены меньше размера ее окна. Это вызывает дополнительный проход макета при первом отображении окна; второй проход макета считается как" изменение размера окна "и, следовательно, позиция делителя разделения панель не соблюдается на этом проходе. " ( https://forums.oracle.com/forums/thread.jspa?threadID=2503701)
Обходной путь 1
Установить Scene
размер вместо Stage
размер:
Scene primaryScene = SceneBuilder.create()
.root(splitPane)
.width(500)
.height(500)
.build();
primaryStage.setScene(primaryScene);
primaryStage.setTitle("Name");
primaryStage.show();
Обходной путь 2
Как правильно заметил Рамазан, другим решением было бы установить положение делителя в Platform.runLater(...)
,
Followups
Я подал ошибку в jira ( http://javafx-jira.kenai.com/browse/RT-28607), ссылаясь на оригинальный отчет об ошибке ( http://javafx-jira.kenai.com/browse/RT-17229) который был отмечен как "неразрешимый". Я думаю, что окончательное решение было бы обеспечить методы для абсолютного позиционирования делителя.
У меня была проблема, связанная с положением разделенной панели, и похоже, что у вас. Вот оно: у меня есть вкладка, и всякий раз, когда я добавляю новую вкладку, я загружаю содержимое вкладки из fxml, в котором существует разделенная панель, с положением делителя, установленным на 0,8.
Когда первая вкладка загружена, все в порядке, делитель располагается на 0,8. Когда я добавляю вторую вкладку, точно так же, как и первая вкладка через fxml, положение разделенной панели на второй вкладке составляет 0,5, то есть значение по умолчанию.
Я попытался программно установить положение делителя с помощью setDividerPositions
Метод после загрузки содержимого вкладки, но это не сработало. Тогда, как в вашем случае, если я помещу setDividerPositions
вызов метода onAction, он успешно устанавливает позицию делителя.
Как я уже говорил, моя проблема не совсем такая, как у вас, но кажется похожей. Поэтому я не уверен, но надеюсь, что моя работа поможет вам: в моей ситуации setDividerPositions
вызывать Platform.runLater
сделал трюк.