JavaFX Canvas在StackPane中没有正确调整大小

时间:2017-01-16 22:48:58

标签: java canvas layout javafx

以下是Main.classController.class,我试图让它尽可能简单。

程序输出以下窗口: enter image description here

黑色是名为StackPane的{​​{1}},里面是名为visualizerStackPane的{​​{1}}。 我想要做的是Canvas内的visualizerCanvas根据Canvas尺寸减去4 进行相应调整。但是当你调整窗口大小时,一切都会失败。

你必须尝试......

1)最大化窗口然后将其标准化。

2)增加窗口的大小并慢慢减小它。

为什么会发生这种情况?我现在有3个月没遇到这个问题了,我找不到解决办法......

我也看了JavaFX - Resize Canvas when screen is resized,但这里的问题似乎有所不同......

Main.java:

StackPane

Controller.java:

我已经修改了Controller类来绘制Canvas并从StackPane方法中删除了绑定,它不起作用产生以下内容:

enter image description here

如果我没有手动设置画布的宽度和高度,它甚至不会画画......我不知道为什么。

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

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {

            //Scene
            Scene scene = new Scene(new Controller(), 400, 400);
            primaryStage.setScene(scene);

            //Show
            primaryStage.show();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

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

Controller.fxml:

Initialize

最后:

  

非常感谢能够解决这个问题的人:)。

2 个答案:

答案 0 :(得分:1)

initialize()方法中删除绑定。您试图自己控制布局操作,这会阻止StackPane执行它应该执行的操作。这将适当调整Canvas的大小。

您声明当您打印width的{​​{1}}和height时,它会返回-1。而不是这样做,打印容器Canvas的{​​{1}}和width。毕竟height完全包含在StackPane中,CanvasStackPane几乎相同,如果不相同的话。

答案 1 :(得分:1)

经过研究,我找到了解决方案。从Canvas创建自定义@Overriding类和Canvas方法:

对这个问题的最终答案非常高兴:How to make canvas Resizable in javaFX?

给我这个想法的链接:http://dlsc.com/2014/04/10/javafx-tip-1-resizable-canvas/

ResizableCavas.java:

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;

class ResizableCanvas extends Canvas {

    GraphicsContext gc                  = getGraphicsContext2D();
    int             canvasWidth         = 0;
    int             canvasHeight        = 0;
    int             halfCanvasHeight    = 0;

    /**
     * Constructor
     */
    public ResizableCanvas() {

        // if i didn't add the draw to the @Override resize(double width, double
        // height) then it must be into the below listeners

        // Redraw canvas when size changes.
        widthProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("Entered WIDTH property");
            canvasWidth = (int) widthProperty().get();
        });
        heightProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("Entered HEIGHT property");

            canvasHeight = (int) heightProperty().get();
            halfCanvasHeight = canvasHeight >> 1;
        });

    }

    /**
     * Redraw the Canvas
     */
    private void draw() {

        System.out.println(" Real Canvas Width is:" + getWidth() + " , Real Canvas Height is:" + getHeight() + "\n");

        gc.clearRect(0, 0, canvasWidth, canvasHeight);

        gc.setStroke(Color.RED);
        gc.strokeLine(0, 0, canvasWidth, canvasHeight);
        gc.strokeLine(0, canvasHeight, canvasWidth, 0);
    }

    @Override
    public double minHeight(double width) {
        return 1;
    }

    @Override
    public double maxHeight(double width) {
        return Double.MAX_VALUE;
    }

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

    @Override
    public double minWidth(double height) {
        return 1;
    }

    @Override
    public double maxWidth(double height) {
        return Double.MAX_VALUE;
    }

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

    @Override
    public void resize(double width, double height) {
        super.setWidth(width);
        super.setHeight(height);
        draw();
    }
}

<强> Controller.java:

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;

public class Controller extends StackPane {

    @FXML
    private GridPane container;

    @FXML
    private GridPane topGridPane;

    @FXML
    private StackPane visualizerStackPane;

    @FXML
    private VBox topRightVBox;

    @FXML
    private StackPane mediaFileStackPane;

    @FXML
    private GridPane bottomGridPane;

    // ------------------------------

    ResizableCanvas visualizerCanvas = new ResizableCanvas();

    /**
     * Constructor
     */
    public Controller() {

        // ------------------------FXMLLoader ---------------------------------
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Controller.fxml"));
        loader.setController(this);
        loader.setRoot(this);

        try {
            loader.load();
        } catch (IOException ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Controller FXML can't be loaded!", ex);
        }
    }

    /**
     * Called as soon as FXML FILE has been loaded
     */
    @FXML
    private void initialize() {

        visualizerStackPane.getChildren().add(visualizerCanvas);

    }
}