jake
jake

Reputation: 679

javafx scene builder custom component

I would like to use the custom component in the scene builder.
I want to embed a canvas to custom component. so i try to change the canvas of attributes .
canvas code like this:

    package test;

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

    public class DrawCanvas extends Canvas{
        public DrawCanvas() {
            draw();
        }

        private void draw() {
            // TODO Auto-generated method stub
            double width = getWidth();
            double height = getHeight();
            GraphicsContext gc = getGraphicsContext2D();
            gc.strokeLine(0,0,50,50);
        }
    }


Custom Component code like this:

    package test;

    import java.io.IOException;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.layout.BorderPane;

    public class Test extends BorderPane{

        public Test() {
            super();
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Test.fxml"));
            fxmlLoader.setRoot(this);
            fxmlLoader.setController(this);
            try {
                fxmlLoader.load();
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }
        }
    }


fxml file:

    <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.canvas.Canvas?>


    <fx:root xmlns:fx="http://javafx.com/fxml" type="javafx.scene.layout.BorderPane">
        <center>
        </center>
    </fx:root>


I've tried in this way , but it failed.

    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.canvas.Canvas?>
    <?import org.korecky.myjavafx.fxml10.DrawCanvas?>
    <fx:root xmlns:fx="http://javafx.com/fxml" type="javafx.scene.layout.BorderPane">
        <center>
            <DrawCanvas ></DrawCanvas>
        </center>
    </fx:root>

Please give me advice and tips .

Upvotes: 3

Views: 3038

Answers (1)

Jos&#233; Pereda
Jos&#233; Pereda

Reputation: 45456

Your approach is working for me, but you need to create a valid canvas, providing some dimensions, otherwise those will be 0x0. For instance:

private void draw() {
    setWidth(50);
    setHeight(50);
    GraphicsContext gc = getGraphicsContext2D();
    gc.strokeLine(0,0,50,50);
}

Now you can import your DrawCanvas component into SceneBuilder, as @jewelsea suggests, and you'll be able to drag it to your scene:

canvas

You could add some properties to the class, like canvasWidth and canvasHeight.

public class DrawCanvas extends Canvas {

    private final GraphicsContext gc;

    public DrawCanvas() {
        gc = getGraphicsContext2D();
        draw();
    }

    private void draw() {
        setWidth(canvasWidth.get());
        setHeight(canvasHeight.get());
        gc.clearRect(0,0,canvasWidth.get(),canvasHeight.get());
        gc.strokeLine(0,0,canvasWidth.get(),canvasHeight.get());
    }

    private final DoubleProperty canvasWidth = new SimpleDoubleProperty(50){
        @Override
        protected void invalidated() {
            draw();
        }
    };

    public double getCanvasWidth() {
        return canvasWidth.get();
    }

    public void setCanvasWidth(double value) {
        canvasWidth.set(value);
    }

    public DoubleProperty canvasWidthProperty() {
        return canvasWidth;
    }
    private final DoubleProperty canvasHeight = new SimpleDoubleProperty(50){
        @Override
        protected void invalidated() {
            draw();
        }
    };

    public double getCanvasHeight() {
        return canvasHeight.get();
    }

    public void setCanvasHeight(double value) {
        canvasHeight.set(value);
    }

    public DoubleProperty canvasHeightProperty() {
        return canvasHeight;
    }

}

This will allow you to set them on the Inspector panel:

enter image description here

or in your fxml files:

<fx:root type="javafx.scene.layout.BorderPane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
   <center>
      <DrawCanvas canvasWidth="150" canvasHeight="250" />
   </center>
</fx:root>

Upvotes: 4

Related Questions