JavaFX:在窗格或画布上显示自己的对象

时间:2016-08-24 08:01:41

标签: canvas javafx shape pane

我有一个带有x坐标和y坐标的物体。

public class GuiElement
{
    int x;
    int y;
    Shape guiRepresentation;
    String name;

    public GuiElement(String name, int x , int y)
    {
        this.name = name;
        this.x = x;
        this.y = y;
        guiRepresentation = new Rectangle(60, 60, Color.AZURE);
    }
}

有没有办法将此对象作为子项添加到窗格中,并将矩形视为此对象的表示形式?稍后对象应该是一个更复杂的形状。

更新

完整代码,但问题是"儿童:重复的儿童添加:parent = TrackplanPane @ [...]"

Main.java

public class Main extends Application {

    Rectangle circle_Red;
    Rectangle circle_Blue;
    Rectangle circle_Green;
    double orgSceneX, orgSceneY;
    double orgTranslateX, orgTranslateY;

    @Override
    public void start(Stage primaryStage) {

        Trackplan track = new Trackplan();
        track.add(new TrackplanElement(1, 1) );
        track.add(new TrackplanElement(1, 2) );
        track.add(new TrackplanElement(2, 1) );
        track.add(new TrackplanElement(2, 2) );

        TrackplanPane dg = new TrackplanPane(track);
        primaryStage.setResizable(true);
        primaryStage.setScene(new Scene(dg, Color.WHITE));
        primaryStage.setWidth(500);
        primaryStage.setHeight(500);

        primaryStage.setResizable(true);
        primaryStage.show();
    }

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

TrackplanElement.java

public class TrackplanElement implements Comparable<TrackplanElement> {
    int x;
    int y;
    Shape guiRepresentation;
    String name;

    public TrackplanElement(int x, int y) {
    this.x = x;
    this.y = y;
    guiRepresentation = new Rectangle(60, 60,
        Color.color(Math.random() * 1 + 0, Math.random() * 1 + 0, Math.random() * 1 + 0));
    }

    @Override
    public int compareTo(TrackplanElement o) {
    if (this.x < o.x) {
        return -1;
    } else if (this.x > o.x) {
        return 1;
    } else {
        if (this.y < o.y) {
        return -1;
        } else if (this.y > o.y) {
        return 1;
        } else {
        return 0;
        }
    }
    }

    @Override
    public boolean equals(Object obj) {
    if (obj instanceof TrackplanElement) {
        if (this.x == ((TrackplanElement) obj).x && this.y == ((TrackplanElement) obj).y) {
        return true;
        }
        return false;
    }
    return super.equals(obj);
    }


    public Shape getShape() {
    return guiRepresentation;
    }


    public void setShape(Shape guiRepresentation) {
    this.guiRepresentation = guiRepresentation;
    }

    public int getX() {
    return x;
    }

    public void setX(int x) {
    this.x = x;
    }

    public int getY() {
    return y;
    }

    public void setY(int y) {
    this.y = y;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }
}

TrackplanPane.java

public class TrackplanPane extends Pane {
    private ObservableList<TrackplanElement> elements = FXCollections.observableArrayList();
    private double boxSize = 60;
    SimpleDoubleProperty scaleProperty = new SimpleDoubleProperty(1.0);
    SimpleDoubleProperty elementSizeProperty = new SimpleDoubleProperty(boxSize);
    private static double scaleFactor = 0.1;
    private Trackplan trackplan;
    double orgSceneX, orgSceneY;
    double orgTranslateX, orgTranslateY;

    EventHandler<MouseEvent> elementOnMousePressedEventHandler = new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        orgSceneX = t.getSceneX();
        orgSceneY = t.getSceneY();
        orgTranslateX = ((Rectangle) (t.getSource())).getTranslateX();
        orgTranslateY = ((Rectangle) (t.getSource())).getTranslateY();
        ((Rectangle) (t.getSource())).setCursor(Cursor.NONE);
        ((Rectangle) (t.getSource())).toFront();
    }
    };

    EventHandler<MouseEvent> elementOnMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        double offsetX = t.getSceneX() - orgSceneX;
        double offsetY = t.getSceneY() - orgSceneY;
        double newTranslateX = coordinateToPosition((int) Math.round(((orgTranslateX + offsetX) / boxSize)));
        double newTranslateY = coordinateToPosition((int) Math.round(((orgTranslateY + offsetY) / boxSize)));

        ((Rectangle) (t.getSource())).setTranslateX(newTranslateX);
        ((Rectangle) (t.getSource())).setTranslateY(newTranslateY);
    }
    };

    public TrackplanPane(Trackplan t) {
    this.trackplan = t;
    this.setStyle("-fx-border-color: red;");

    this.elements.addListener(new ListChangeListener<TrackplanElement>() {
        public void onChanged(javafx.collections.ListChangeListener.Change<? extends TrackplanElement> c) {
        while (c.next()) {
            for (TrackplanElement remitem : c.getRemoved()) {
            getChildren().remove(remitem.getShape());
            }
            for (TrackplanElement additem : c.getAddedSubList()) {
            Shape shape = additem.getShape();
            shape.setOnMousePressed(elementOnMousePressedEventHandler);
            shape.setOnMouseDragged(elementOnMouseDraggedEventHandler);
            shape.setCursor(Cursor.MOVE);
            getChildren().add(shape);
            shape.relocate(coordinateToPosition(additem.getX()), coordinateToPosition(additem.getY()));
            }
        }
        }
    });
    drawTrackplan();
}

    private void drawTrackplan() {
    for (TrackplanElement e : trackplan.getElements()) {
        this.elements.add(e);
    }
    }

    private double coordinateToPosition(int c) {
    return c * boxSize;
    }

    @Override
    protected void layoutChildren() {
    final int top = (int) snappedTopInset();
    final int right = (int) snappedRightInset();
    final int bottom = (int) snappedBottomInset();
    final int left = (int) snappedLeftInset();
    final int w = (int) getWidth() - left - right;
    final int h = (int) getHeight() - top - bottom;
    }

    public ObservableList<TrackplanElement> getElements() {
    return elements;
    }

    public void setElements(ObservableList<TrackplanElement> elements) {
    this.elements = elements;
    }
}

1 个答案:

答案 0 :(得分:2)

您无法将此类的实例添加到Pane,因为GuiElement不是Node。但是,您可以创建一个包装类,将此类的内部Shape实例绘制为Pane

我为你创建了一个例子,它由两个类组成。第一个类是现有类的更新,第二个类是&#34;经理&#34;可以存储第一个类的实例的类。

示例

GuiElement.java

public class GuiElement {
    private int x;
    private int y;
    private Shape guiRepresentation;
    private String name;

    public GuiElement(String name, int x, int y, Color color) {
        this.name = name;
        this.x = x;
        this.y = y;
        guiRepresentation = new Rectangle(60, 60, color);
    }

    public Shape getShape() {
        return guiRepresentation;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

DrawManager.java

public class DrawManager {

    private Pane  group = new Pane ();
    private ObservableList<GuiElement> elements = FXCollections.observableArrayList();

    public DrawManager() {
        elements.addListener(new ListChangeListener<GuiElement>() {

            @Override
            public void onChanged(javafx.collections.ListChangeListener.Change<? extends GuiElement> c) {
                while (c.next()) {
                    for (GuiElement remitem : c.getRemoved()) {
                        group.getChildren().remove(remitem.getShape());
                    }
                    for (GuiElement additem : c.getAddedSubList()) {
                        Shape shape = additem.getShape();

                        group.getChildren().add(shape);

                        shape.relocate(additem.getX(), additem.getY());
                    }
                }
            }
        });
    }

    public ObservableList<GuiElement> getElements() {
        return elements;
    }

    public Pane getPane() {
        return group;
    }
}

Main.java (用法)

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,600,600);

            DrawManager dm = new DrawManager();

            dm.getElements().add(new GuiElement("elem1", 0, 0, Color.AZURE));
            dm.getElements().add(new GuiElement("elem2", 100, 100, Color.RED));
            dm.getElements().add(new GuiElement("elem3", 500, 500, Color.BLACK));

            dm.getPane().setStyle("-fx-background-color: gray");

            root.setCenter(dm.getPane());

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

输出就像:

enter image description here