Desktop Java
JavaFX Tip 1: Resizable Canvas
While working on FlexGanttFX I had to deal a lot with the JavaFX Canvas node. I am using it to render activities on a timeline. Each row in the Gantt chart is a Canvas node. The user has the option to resize each row individually. So I had to figure out the best way to resize a canvas, which out-of-the-box is not resizable. The listing below shows how this can be accomplished.
The main steps needed are:
- Create a subclass of Canvas.
- Override the isResizable() method and return true.
- Override the prefWidth() and prefHeight() methods. Return the values of Canvas.getWidth() and Canvas.getHeight().
- Add listeners to the width and height properties of Canvas in order to trigger a redraw when the size of the canvas changes.
- Bind the width and height properties of Canvas to the width and height properties of the parent pane.
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.StackPane; 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 { ResizableCanvas canvas = new ResizableCanvas(); StackPane stackPane = new StackPane(); stackPane.getChildren().add(canvas); // Bind canvas size to stack pane size. canvas.widthProperty().bind( stackPane.widthProperty()); canvas.heightProperty().bind( stackPane.heightProperty()); stage.setScene(new Scene(stackPane)); stage.setTitle("Tip 1: Resizable Canvas"); stage.show(); } public static void main(String[] args) { launch(args); } }
When run you should see the following:
Reference: | JavaFX Tip 1: Resizable Canvas from our JCG partner Dirk Lemmermann at the Pixel Perfect blog. |