如何使Vbox使用整个空间

时间:2015-07-23 14:48:58

标签: java javafx

这是javafx8,我必须在这里写,因为我没有足够的代表来使用标签。

简单示例:

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 个答案:

答案 0 :(得分: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大小更改时动态更新内容。这意味着我们调整大小时不会调用方法绘制,之前没有这样做,所以这很好!

现在回到draw方法。首先,你每次都要求画布宽度,当我们真正关心画布与盒子匹配时,让我们将它从画布改为框(你现在将你的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处添加,我们看到按钮消失)。我现在想不出办法解决这个问题,但希望能解决部分问题!