2015-05-11 3 views
5

Моя первая попытка играть с JavaFX, и я пытаюсь понять немного о макетировании. Как получить доступ к предпочтительному размеру элемента управления?Каков предпочтительный размер элемента управления?

В приведенном ниже примере я пытаюсь установить максимальную ширину на 200 пикселей больше, чем предпочтительная ширина. То есть, я хочу, чтобы кнопка увеличивалась (до максимума) по мере увеличения ширины кадра.

Однако, когда я бегу код предпочтительным ширина равен -1, так что добавление 200 к предпочтительной ширине дает максимальную ширину 199.

import javafx.application.Application; 
import javafx.event.*; 
import javafx.stage.Stage; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.geometry.Insets; 

public class BorderPaneSSCCE extends Application 
{ 
    @Override 
    public void start(Stage primaryStage) 
    { 
     Button button = new Button("Button at PreferredSize"); 
     button.setMaxWidth(button.getPrefWidth() + 200); 
     System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); 

     button.setOnAction(new EventHandler<ActionEvent>() 
     { 
      @Override 
      public void handle(ActionEvent event) 
      { 
       System.out.println("Width: " + button.getWidth()); 
      } 
     }); 

     HBox root = new HBox(); 
     HBox.setHgrow(button, Priority.ALWAYS); 
     root.getChildren().add(button); 

     Scene scene = new Scene(root); 
     primaryStage.setTitle("Java FX"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
     System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); 
    } 

    public static void main(String[] args) 
    { 
     launch(args); 
    } 
} 

При запуске код и нажать на кнопку я вижу : Width: 139.0

После того как я изменить ширину кадра, так что кнопка как можно больше, и я нажмите на кнопку Я вижу: Width: 199.0

Я надеялся увидеть Width: 339.0 (т.е. 139 + 200.)

Итак, как мы получаем доступ к предпочитаемому размеру/ширине элемента управления?

ответ

4

getPrefWidth() возвращает USE_COMPUTED_SIZE флаг (который -1) по умолчанию.

Вы можете использовать prefWidth(-1), чтобы получить внутренне рассчитанную предпочтительную ширину. Однако предпочтительная ширина не будет рассчитываться до тех пор, пока узел не будет выложен панелью макета (HBox в вашем примере). Это происходит в первый раз, когда отображается сцена.

У вас есть несколько вариантов, если вы хотите, чтобы максимальная ширина зависела от предпочтительной ширины. Один из них - установить предпочтительную ширину на фиксированное значение с setPrefWidth() до установки максимальной ширины.

Другой - реализовать собственный алгоритм компоновки - либо на узле, либо на панели макета. Вот пример использования пользовательской кнопки.

// button whose maxWidth is always prefWidth + 200 
Button button = new Button() { 
    @Override 
    protected double computeMaxWidth(double height) 
    { 
     return this.prefWidth(height) + 200.0; 
    } 
}; 
+0

Вы говорите, что 'prefWidth (-1)' будет возвращать '-1' (или некоторую другую недопустимую ширину) до тех пор, пока экран не будет отображаться? –

+0

PrefWidth (-1) был методом, который я искал. Слишком плохо, что оно не имеет значения до тех пор, пока не будет показана этап: (переопределение метода 'computeMaxWidth (...)' похоже на лучшее решение для данного примера, но я не знал, как реализовать этот метод без метода prefWidth (...) (+1). – camickr

+0

@JAtkin, Да, я только что изменил свой SSCCE, чтобы отобразить prefWidth (-1) после создания кнопки, и отображает 0. Когда я показываю ширину после show() отображает 138.238 .... – camickr

1

getPrefWidth() только работ послеNode был показан/оказан.

Вы можете либо показать Button, либо попытаться использовать Node.prefWidth(-1).

+0

Да, prefWidth (-1) работает после показа Stage (+1). GetPrefWidth() не работает даже после показа стадии. – camickr

+0

@camickr 'Stage 'и' Button' должны быть показаны до 'getPrefWidth()' работает. – eckig

+0

Я изменил свой SSCCE, чтобы отобразить 'prefWidth (-1)' и 'getPrefWidth()', когда кнопка создана и после показа Stage. Значение для 'prefWidth (-1)' изменяется, но 'getPrefWidth()' не изменяется.Это имеет смысл для меня знать, что я знаю о методе 'prefWidth (...)'. 'GetPrefWidth()' будет изменяться только в том случае, если вы используете метод 'setPrefWidth (...)'. – camickr

2

-1 - значение Region.USE_COMPUTED_SIZE, которое сообщает компоненту, чтобы выяснить его собственный лучший размер. Это работает, потому что каждый Node имеет метод, называемый prefWidth(double height), и он равен prefHeight(double width) (тот же для минимального/максимального размера), который менеджеры макета используют для расчета макета своих детей. Чтобы получить прив размер вам нужно использовать

button.prefWidth([-1 or Region.USE_COMPUTED_SIZE]) 

(docs)

+0

Спасибо, за вход (+1), я пропустил метод 'prefWidth()'. Я посмотрел на все методы «getter». Все еще есть Свинг в затылке. В следующий раз я буду осторожнее. – camickr