Положение делителя 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 сделал трюк.

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