【问题标题】:JavaFx Canvas only resizes in height but not in widthJavaFx Canvas 仅调整高度而不调整宽度
【发布时间】:2017-07-05 14:19:19
【问题描述】:

我已经开始编写这个应用程序来绘制温度数据,当屏幕调整大小时,画布也应该调整大小。它正确初始化,但是当我想调整窗口大小时,draw() 方法只会根据它绑定的堆栈窗格高度值调整高度,但它会完全忽略宽度。 Listener 甚至不会开火。这我觉得很奇怪。此外,我必须为 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!");

    }

}

【问题讨论】:

    标签: java canvas javafx


    【解决方案1】:

    您的画布被放置在 BorderPane 的右侧,而您应该将其放置在中间。

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

    【讨论】:

    • @fabian 的回答提供了更多解释。另外,您是否考虑过使用图表而不是画布来绘制数据?
    • 我刚看过图表,会试一试。它似乎比画布更适合我的需求。但也许我还是应该自己编写代码来更好地理解 JavaFx?
    【解决方案2】:

    您使用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);
    }
    

    【讨论】:

    • 感谢您的精彩解释!我会试试你的替代方案。
    猜你喜欢
    • 2012-10-26
    • 2020-12-19
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    相关资源
    最近更新 更多