Search code examples
javafxcanvasjavafx-8javafx-2fxml

How to make canvas Resizable in javaFX?


In javaFX to resize a canvas there is no such method to do that, the only solution is to extends from 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);

    }

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

is extends from Canvas is the only solution to make canvas Resizable ? because this solution work only if we don't want to use FXML, if we declare in fxml a canvas how can we make it resizable?

this is my code :

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

    Controller controller;

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        AnchorPane root = loader.load(); // controller initialized
        controller = loader.getController();
        GraphicsContext gc = controller.canvas.getGraphicsContext2D();
        gc.setFill(Color.AQUA);
        gc.fillRect(0, 0, root.getPrefWidth(), root.getPrefHeight());
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(controller.Pane, controller.Pane.getPrefWidth(), controller.Pane.getPrefHeight()));
        primaryStage.show();
    }

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

Solution

  • There's a guide that I think that you may find useful for setting up a resizable canvas:

    JavaFx tip - resizable canvas

    Piece of code from the guide:

    /**
     * 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();
            }
        }