2015-07-23 1 views
0

Это javafx8, я должен написать это здесь, так как у меня недостаточно rep, чтобы использовать тег.Как сделать Vbox использовать все пространство

Простой пример:

public class Test extends Application 
{ 
    public static void main(String args[]) throws Exception { launch(args); } 

    private Canvas canvas; 

    @Override 
    public void start(Stage primaryStage) 
    { 
    VBox box = new VBox(); 

    Button dummyButton = new Button("some text"); 
    canvas = new Canvas(); 
    canvas.heightProperty().addListener(observable -> draw()); 
    canvas.widthProperty().addListener(observable -> draw()); 

    VBox.setVgrow(canvas, Priority.ALWAYS); 

    box.getChildren().addAll(dummyButton, canvas); 

    Scene scene = new Scene(box, 1300, 800); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
    } 

    private void draw() 
    { 
    final double width = canvas.getWidth(); 
    final double height = canvas.getHeight(); 
    System.out.println("w, h: " + width + "; " + height); 
    final GraphicsContext gc = canvas.getGraphicsContext2D(); 
    gc.setFill(Color.GREENYELLOW); 
    gc.fillRect(0, 0, width, height); 
    } 
} 

Я, наверное, неправильно поняли documentation of vbox, в нижней части он говорит, что

Например, если VBox нуждается в ListView, чтобы выделить все дополнительное пространство

, а затем делает эту вещь VBox.grow, как и в моем примере. Но полотно никогда не меняет его размер. Он всегда имеет ширину и высоту 0, в то время как я ожидал, что холст будет расти и уменьшаться при изменении размера окна.

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

Пожалуйста, не предлагайте использовать основную ступень, в моем реальном приложении. Я так много слоев, что есть много других элементов между ними. Первичный этап только здесь, чтобы иметь запущенную программу.

ответ

1

Ваш метод рисования немного испорчен.

private void draw() { 
    final double width = canvas.getWidth(); 
    final double height = canvas.getHeight(); 
    System.out.println("w, h: " + width + "; " + height); 
    final GraphicsContext gc = canvas.getGraphicsContext2D(); 
    gc.setFill(Color.GREENYELLOW); 
    gc.fillRect(0, 0, width, height); 
} 

Если мы посмотрим на ваш метод, вы делаете несколько вещей, которые могут вызвать проблемы.

Но первый, как вы заметили, заявление:

VBox.setVgrow(canvas, Priority.ALWAYS); 

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

Если мы просто изменить слушателей из холста в коробке:

canvas.heightProperty().addListener(observable -> draw()); 
canvas.widthProperty().addListener(observable -> draw()); 

в

box.heightProperty().addListener(observable -> draw()); 
box.widthProperty().addListener(observable -> draw()); 

Мы теперь динамически обновлять вещи, как ваши изменения размера VBOX. Это означает, что ваш метод рисования не будет вызываться, когда мы изменим размер, он не делал этого раньше, так что это хорошо!

Итак, теперь вернемся к методу рисования. Прежде всего, вы просите ширину холста каждый раз, когда мы действительно заботимся о том, чтобы получить холст в соответствии с полем, поэтому давайте изменим это с холста на поле (теперь вы объявите свой Vbox как поле).

private void draw() { 
    final double width = box.getWidth(); 
    final double height = box.getHeight(); 
    System.out.println("w, h: " + width + "; " + height); 
    final GraphicsContext gc = canvas.getGraphicsContext2D(); 
    gc.setFill(Color.GREENYELLOW); 
    gc.fillRect(0, 0, width, height); 
} 

Но это все еще не очень хорошо работает. Это потому, что мы никогда не обновляем размер холста! Так давайте добавим setWidth и setHeight в

private void draw() { 
    final double width = box.getWidth(); 
    final double height = box.getHeight(); 
    canvas.setWidth(width); 
    canvas.setHeight(height); 
    System.out.println("w, h: " + width + "; " + height); 
    final GraphicsContext gc = canvas.getGraphicsContext2D(); 
    gc.setFill(Color.GREENYELLOW); 
    gc.fillRect(0, 0, width, height); 
} 

с этим, мы заметим, что все, кажется, выглядит довольно хорошо, но с одним исключением. Теперь кнопка блокирует верхнюю часть экрана и сделает так, что вы не сможете заполнить эту верхнюю часть. Это потому, что кнопка была нарисована сначала на экране и получает приоритет (если мы включим ее, чтобы ее добавить в индекс 1 с помощью другого вызова метода добавления, мы видим, что кнопка исчезает). Я не могу придумать способ исправить это прямо сейчас, но, надеюсь, это решает часть вашей проблемы!

+0

спасибо. Собираюсь попробовать это завтра. – Nozdrum