JavaFX Получить предпочтительный размер панели

Мне нужен реальный предпочтительный размер (результат от детей) панели, но я получаю только -1. Есть ли возможность это узнать?

Хорошо, вот пример кода: вывод -1.0, 0.0, -1.0, -1.0, но очевидно, что панель с кнопкой имеет «предпочтительный» размер!? Только новый поток имеет в качестве вывода «реальный» размер панели, но не предпочтительный, потому что, если я изменю размер окна за 3 секунды, он покажет «реальный» размер, а не предпочтительный размер начала...

public class ButtonTest extends Application
{
    public static void main(String [] a)
    {
        Application.launch(a);
    }

    @Override
    public void start(Stage stage) throws Exception
    {
        BorderPane root = new BorderPane();

        StackPane pane = new StackPane();


        Button b = new Button("Testbutton");


        pane.getChildren().add(b);
        pane.setStyle("-fx-background-color: red;");

        System.out.println(pane.getPrefWidth());
        System.out.println(pane.getWidth());
        System.out.println(pane.getMinWidth());
        System.out.println(pane.getMaxWidth());

        root.setCenter(pane);
        Scene scene  = new Scene(root);

        Thread t = new Thread(new Runnable()
        {           
            @Override
            public void run()
            {
                try
                {
                    Thread.sleep(3000);
                } catch (InterruptedException e)
                {
                    // TODO: Handle Exception
                    e.printStackTrace();
                }
                System.out.println(pane.getPrefWidth());
                System.out.println(pane.getWidth());
                System.out.println(pane.getMinWidth());
                System.out.println(pane.getMaxWidth());
            }
        });
        t.setDaemon(true);
        t.start();
    }
}

person Jerry0022    schedule 30.08.2014    source источник
comment
Опубликуйте свой код, пожалуйста. Кстати, вы можете получить такой результат, если ваша панель пуста или не видна, или если вы не вызвали метод setPreferredSize   -  person R2B2    schedule 31.08.2014
comment
Что именно вы имеете в виду под предпочтительным размером? Если это -1, это означает любое из ограничений класса. Если вам нужен фактический реальный размер компонента, попробуйте такие методы, как getBoundsInParent().getWidth().   -  person Rodrigo Leitão    schedule 31.08.2014


Ответы (2)


По умолчанию StackPane имеет PrefWidth и PrefHeight, установленные унаследованным ограничением «USE_COMPUTED_SIZE» (значения ведьмы равны -1), определенным в родительском классе «Регион».

Это определение означает, что предпочтительный размер будет вычисляться в процессе компоновки.

Возможно, ваша концепция неуместна. Значения Pref используются для того, чтобы процесс компоновки знал, как он должен расположить объект на холсте. Чтобы узнать реальный размер компонентов, вы можете использовать такие методы, как я упоминал ранее, «getBoundsInParent()» или «getBoundsInLocal()» (разница между ними объясняется в javadoc).

НО важно понимать, что размер компонента просто вычисляется в процессе компоновки. Обычно процесс компоновки происходит в отдельном потоке, чем ваши события или поток main(). Вот почему после сна 3 секунды позволяют вам добиться цели. Вы можете попробовать что-то вроде использования следующего кода, чтобы ваш код выполнялся в потоке графического интерфейса JavaFX (начиная с последней строки кода):

Platform.runLater(new Runnable() {
    @Override public void run() {
        <Your code in GUI Thread>
    }
});

Надеюсь, это может немного помочь. Извините, что не предлагаю вам пример кода, но я не на машине с установленной средой. Постараюсь улучшить мой ответ последним.

Удачи. (Пожалуйста, не стесняйтесь исправлять мой английский, я знаю, что это ужасно)

person Rodrigo Leitão    schedule 31.08.2014

Хорошо, большое спасибо за это объяснение. Но другие методы тоже не возвращают правильный результат...

Может быть, этот случай помогает понять, какова моя цель: одна связанная проблема заключается в том, что у меня есть SplitPane, две части, теперь я скрываю вторую часть (позиция делителя = 1.0) и показываю только первую, иногда мне нравится показывать также вторая часть. Я делаю это по перестановке разделителей. Но в любой момент может случиться так, что вторая часть может быть дополнена новыми элементами (=> обновление нужного размера). Теперь, чтобы изменить положение разделителя (с анимацией), мне нужен предпочтительный размер (скрытой) второй части?! Без реального кода для этого у вас есть идеи, как решить проблему?

Обновление: я решил проблему с «реальным размером», добавив общедоступное двойное свойство на панель и привязав его к свойству ширины панели. Теперь я могу добавить прослушиватель изменений к этому двойному свойству в разделенной панели. После того, как я впервые стал видимым, я получил правильный размер пикселя.

public DoubleProperty realWidth;

    pane.setPrefWidth(USE_PREF_SIZE);
    pane.setMaxWidth(USE_PREF_SIZE);

    realWidth = new SimpleDoubleProperty(0.0);
    realWidth.bind(this.widthProperty());

=> Добавить прослушиватель изменений из другого места

Но знайте, что у меня проблема в том, что если я добавлю кнопку (через 3 секунды) на панель, разделенная панель (прослушиватель изменений в этом свойстве realWidth) не уведомляется...

Обновление: он уведомлен: D Но не добавление кнопки, а добавление e. грамм. панель стека работает так, как ожидалось. Большое спасибо за вашу помощь, чтобы понять, как это работает!

person Jerry0022    schedule 01.09.2014