-1

I have an Object with x- and y-coordinates.

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);
    }
}

Is there a way to add this object as a child to a Pane and see the rectangle as representation of this Object? Later on the object should be a more complex shape.

UPDATE

Full Code, but problem with "Children: duplicate children added: 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;
    }
}
kayf
  • 87
  • 1
  • 11

1 Answers1

2

You cannot add instances of this class to a Pane as GuiElement is not a Node. You can however create a wrapper class, that draws the inner Shape instances of this class to a Pane.

I have created an example for you, which consist of two classes. The first class is an update on your existing class, the second one is a "manager" class that can store instances of the first class.

Example

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 (usage)

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);
    }
}

Output is like:

enter image description here

DVarga
  • 21,311
  • 6
  • 55
  • 60
  • In this way i have done it. That's the reason why there is guiRepresentation variable. I was thinking there is a better way like exends Shape (have try it). In this case on click i have to use x and y for access to the name of my object. Thank you. – kayf Aug 24 '16 at 09:04
  • But the Problem is I get "Children: duplicate children added". – kayf Aug 24 '16 at 09:22
  • Just do not add the same `GuiElement` instance twice. – DVarga Aug 24 '16 at 09:25
  • See Update on inital post I always make "track.add(new TrackplanElement(1, 1) );" – kayf Aug 24 '16 at 09:57
  • My best guess is that `drawTrackplan();` is getting called multiple times and it will add the same elements several times that will add the same Nodes to the `Pane` in the listener. – DVarga Aug 24 '16 at 10:08
  • Thanks DVarga! I have fixed in inside the update content. – kayf Aug 24 '16 at 10:59