JavaFx Canvas仅在高度上调整大小,但在宽度上不调整大小

时间:2017-07-05 14:19:19

标签: java canvas javafx

我已开始编写此应用程序以绘制温度数据,当屏幕调整大小时,画布也应调整大小。它正确初始化但是当我想调整窗口大小时,draw()方法只会调整高度,根据绑定的stackpanes高度值,但它将完全忽略宽度。听众甚至不会开火。我发现这很奇怪。此外,我必须为StackPane设置minSize,否则根本不会绘制任何内容。我没有使用FXML。

有人有什么想法吗?

编辑我将第58行从setRight()更改为setCenter,如InternetUnexplorer解决方案中所述。但我仍然很好奇为什么会这样,所以我做了一些研究。我在互联网上找到了这个:

  • 顶部/底部区域:可以水平收缩/扩展并保持高度 不变。
  • 左/右区域:可以垂直收缩/扩展并保持长度 不变。
  • 中心区域:可以向两个方向收缩/扩展。

http://o7planning.org/en/10629/javafx-borderpane-layout-tutorial

这是我的主要课程:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class main extends Application {

    @Override
    public void start(Stage mainStage) throws Exception {
        TempViewerWindow view = new TempViewerWindow();
        ReadData controller = new ReadData(view);
        controller.selectAll();

        mainStage.setScene(new Scene(view));
        //mainStage.setMinWidth(500);
        //mainStage.setMinHeight(400);
        mainStage.setTitle("Temperature Viewer");
        mainStage.show();
    }

    public static void main(String[] args) {

        launch(args);

    }

}

在这里我的观点类:

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;

public class TempViewerWindow extends BorderPane {

    public TableView<TempData> tableView;
    public Canvas canvas;
    public GraphicsContext gc;
    public StackPane holder;

    public TempViewerWindow() {
        tableView = new TableView<>();
        TableColumn<TempData, String> col_date = new TableColumn<>("Date");
        TableColumn<TempData, Float> col_temperature = new TableColumn<>("Temperature");

        col_date.setCellValueFactory(e -> e.getValue()
                                           .dateProperty());
        col_temperature.setCellValueFactory(e -> e.getValue()
                                                  .temperatureProperty()
                                                  .asObject());

        tableView.getColumns()
                 .addAll(col_date, col_temperature);

        setLeft(tableView);

        holder = new StackPane();
        holder.setMinSize(400, 400); // must be here for some reason

        canvas = new Canvas();

        gc = canvas.getGraphicsContext2D();

        canvas.widthProperty()
              .bind(holder.widthProperty()
                          .subtract(10));
        canvas.heightProperty()
              .bind(holder.heightProperty()
                          .subtract(10));

        canvas.widthProperty()
              .addListener(observable -> redraw(gc));
        canvas.heightProperty()
              .addListener(observable -> redraw(gc));

        holder.getChildren()
              .add(canvas);

        setCenter(holder); //here was the bug

    }

    private void redraw(GraphicsContext gc) {
        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        gc.setFill(Color.WHITE);
        gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
        System.out.println("redraw!");

    }

}

2 个答案:

答案 0 :(得分:0)

当你将它放在中心时,你的画布放在你的BorderPane的右边。

如果您将TempViewerWindow的第54行从setRight(holder)更改为setCenter(holder),则缩放功能正常。

答案 1 :(得分:0)

您使用BorderPane作为holder的父级。 holder用作BorderPane的右子。但是,右/左子项的大小调整为其首选宽度,并调整大小以填充顶部和底部节点之间的高度。 (见javadoc

  

leftright子项的大小将调整为首选宽度,并延长topbottom个节点之间的长度。

如果您使用holder作为center,则会根据您的预期调整宽度。

或者,您可以使用HBox作为TempViewerWindow的基类来实现此类行为。

public TempViewerWindow() {
    ...
    this.getChildren().addAll(tableView, holder);
    HBox.setHgrow(holder, Priority.ALWAYS);
    HBox.setHgrow(tableView, Priority.NEVER);
    this.setFillHeight(true);
}