簡體   English   中英

JavaFX:在TabsPane中時,畫布的尺寸不正確

[英]JavaFX: canvas improperly resized while in the TabsPane

我正在嘗試創建一個使用JavaFX for GUI的應用程序。 主窗口具有一組選項卡,其中一個選項卡具有用於可視化的畫布。 我已經注意到,調整畫布的大小不是一件容易的事,並且有很多技巧和問題與此相關。

我以這段代碼為例。 它工作正常,直到我嘗試將其放入TabsPane中為止。 當我放大窗口時,圖像也會放大,但是當我推開窗口時,畫布不會閃爍! 此外,選項卡頂部的面板也不會收縮。

這是演示此問題的窗口的屏幕截圖:

畫布調整大小無效

這是代碼:

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * Tip 1: A canvas resizing itself to the size of
 *        the parent pane.
 */
public class Tip1ResizableCanvas extends Application {

    class ResizableCanvas extends Canvas {

        public ResizableCanvas() {
            // Redraw canvas when size changes.
            widthProperty().addListener(evt -> draw());
            heightProperty().addListener(evt -> draw());
        }

        private void draw() {
            double width = getWidth();
            double height = getHeight();

            GraphicsContext gc = getGraphicsContext2D();
            gc.clearRect(0, 0, width, height);

            gc.setStroke(Color.RED);
            gc.strokeLine(0, 0, width, height);
            gc.strokeLine(0, height, width, 0);
        }

        @Override
        public boolean isResizable() {
            return true;
        }

        @Override
        public double prefWidth(double height) {
            return getWidth();
        }

        @Override
        public double prefHeight(double width) {
            return getHeight();
        }
    }

    @Override
    public void start(Stage stage) throws Exception {


        TabPane tabs = new TabPane();


        Tab tab = new Tab("tab", createNewTaskArea());
        tabs.getTabs().add(tab);

        stage.setScene(new Scene(tabs, 500, 500));
        stage.setTitle("Tip 1: Resizable Canvas");
        stage.show();
    }

    private Pane createNewTaskArea() {
        Label newTaskNameQuery = new Label("Task name:");
        TextField newTaskName = new TextField("Untitled task");
        newTaskNameQuery.setLabelFor(newTaskName);


        GridPane topPane = new GridPane();
        topPane.setPadding(new Insets(5));
        topPane.setHgap(5);
        topPane.setVgap(10);

        topPane.add(newTaskNameQuery, 0, 0);
        topPane.add(newTaskName, 1, 0);

        GridPane.setHalignment(newTaskNameQuery, HPos.RIGHT);

        GridPane.setHgrow(newTaskName, Priority.ALWAYS);


        ResizableCanvas canvas = new ResizableCanvas();

        VBox panel = new VBox();

        // Bind canvas size to stack pane size.
        panel.widthProperty().addListener(observable -> canvas.setWidth(panel.getWidth()));
        panel.heightProperty().addListener(
                observable -> canvas.setHeight(panel.getHeight() - topPane.getHeight())
        );

        panel.getChildren().addAll(topPane, canvas);

        return panel;
    }

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

是否可以使其正常工作?

似乎TabPane會引起問題,因為如果我將其刪除並使該選項卡的內容成為整個窗口的內容,則所有功能都將按我的預期工作。

這是行不通的,因為VBox減小其大小,就需要減小Canvas的大小,這不會發生,因為只有在減小VBox大小時才減小Canvas大小...

只需將Canvas放在可調整大小的父級中,為其設置適當的布局參數,然后根據此父級的大小調整Canvas的大小,就容易得多:

class ResizableCanvas extends Canvas {

    public ResizableCanvas() {
        // Redraw canvas when size changes.
        widthProperty().addListener(evt -> draw());
        heightProperty().addListener(evt -> draw());
    }

    private void draw() {
        double width = getWidth();
        double height = getHeight();

        GraphicsContext gc = getGraphicsContext2D();
        gc.clearRect(0, 0, width, height);

        gc.setStroke(Color.RED);
        gc.strokeLine(0, 0, width, height);
        gc.strokeLine(0, height, width, 0);
    }

}
VBox panel = new VBox();

// parent to be resized
Pane pane = new Pane(canvas);

// grow/shrink pane when VBox height is increased/decreased    
VBox.setVgrow(pane, Priority.ALWAYS);

// bind canvas size to parent size
canvas.widthProperty().bind(pane.widthProperty());
canvas.heightProperty().bind(pane.heightProperty());

panel.getChildren().addAll(topPane, pane);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM