Home > Software design >  Elements are not displayed on the pane inside a pane
Elements are not displayed on the pane inside a pane

Time:07-09

I am writing a vector canvas in JavaFX (vector graphics, just shapes are displayed on the canvas): well, so that you can move around and zoom in on it.

Since the position of the upper-left corner of the node changes when translating, and it no longer responds to clicks, I decided to make a panel inside the canvas itself, on which everything will be displayed.

Inside the VectorCanvas there is a VectorCanvasContent.
Lines are added to VectorCanvasContent, but for some reason they are not visible (although they are there, I added a listener that outputs "!!!" when you click on them, and checked).
If I draw lines on the canvas itself, then they are visible.

What is the problem?

import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;

import java.util.function.Consumer;

public class VectorCanvas extends Pane {

    public class VectorCanvasContent extends Pane {
        public static final Consumer<VectorCanvas> DEFAULT_DRAWER = canvas -> {
            Line[] lines = {
                    new Line(0, 0, canvas.getWidth(), 0),
                    new Line(canvas.getWidth(), 0, canvas.getWidth(), canvas.getHeight()),
                    new Line(canvas.getWidth(), canvas.getHeight(), 0, canvas.getHeight()),
                    new Line(0, canvas.getHeight(), 0, 0),
                    new Line(0, 0, canvas.getWidth(), canvas.getHeight()),
                    new Line(0, canvas.getHeight(), canvas.getWidth(), 0)
            };
            for (Line line : lines) {
                line.setStrokeWidth(30);
                line.setStroke(Color.RED);
                line.setFill(Color.RED);
                line.setOnMouseClicked(mouseEvent -> System.out.println("!!!"));
            }
            canvas.drawAll(lines);
        };
    }

    private final Consumer<VectorCanvas> drawer;

    public final VectorCanvasContent content = new VectorCanvasContent();

    public VectorCanvas() {
        this(VectorCanvasContent.DEFAULT_DRAWER);
    }

    public VectorCanvas(Consumer<VectorCanvas> drawer) {
        this.drawer = drawer;
        getRealChildren().add(content);
        draw();
    }

    public void clear() {
        getChildren().clear();
    }

    public void draw() {
        if (drawer != null)
            drawer.accept(this);
    }

    public void redraw() {
        clear();
        draw();
    }

    @Override
    public ObservableList<Node> getChildren() {
        return content.getChildren();
    }

    @Override
    public ObservableList<Node> getChildrenUnmodifiable() {
        return content.getChildrenUnmodifiable();
    }

    private ObservableList<Node> getRealChildren() {
        return super.getChildren();
    }

    private ObservableList<Node> getRealChildrenUnmodifiable() {
        return super.getChildrenUnmodifiable();
    }

    public void draw(Shape shape) {
        getChildren().add(shape);
    }

    public void drawAll(Shape... shapes) {
        getChildren().addAll(shapes);
    }
}

CodePudding user response:

You should not override getChildren() and getChildrenUnmodifiable() to return the children of a different node (especially a contained node).

That may confuse and break the JavaFX layout system because it would be something quite unexpected for it.

  • Related