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

Canvas JavaFX:在窗格或画布上显示自己的对象,canvas,javafx,shape,pane,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; guiRepre

我有一个具有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);
    }
}
有没有办法将此对象作为子对象添加到窗格中,并将矩形视为此对象的表示形式?稍后,对象应该是更复杂的形状

更新

完整代码,但“子项:添加的重复子项:父项=TrackplanPane@[…]存在问题”

Main.java

TrackplanElement.java

公共类TrackPlaneElement{
int x;
int-y;
形状表示;
字符串名;
公共轨道平面元素(整数x,整数y){
这个.x=x;
这个。y=y;
图形表示法=新矩形(60,60,
Color.Color(Math.random()*1+0,Math.random()*1+0,Math.random()*1+0));
}
@凌驾
公共内部比较(轨道平面){
如果(此.xo.x){
返回1;
}否则{
如果(本年<本年){
返回-1;
}否则如果(this.y>o.y){
返回1;
}否则{
返回0;
}
}
}
@凌驾
公共布尔等于(对象obj){
if(轨道平面元素的obj实例){
如果(this.x==((trackplanement)obj.x&&this.y==((trackplanement)obj.y){
返回true;
}
返回false;
}
返回super.equals(obj);
}
公共形状getShape(){
返回表示;
}
公共空间设置形状(形状表示){
this.guiRepresentation=guiRepresentation;
}
公共int getX(){
返回x;
}
公共无效集合x(整数x){
这个.x=x;
}
公共int getY(){
返回y;
}
公共空间设置(整数y){
这个。y=y;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
TrackplanPane.java

公共类TrackplanPane扩展窗格{
私有ObservableList元素=FXCollections.observableArrayList();
私人双箱尺寸=60;
SimpleDoubleProperty scaleProperty=新的SimpleDoubleProperty(1.0);
SimpleDoubleProperty元素SizeProperty=新的SimpleDoubleProperty(boxSize);
私有静态双尺度因子=0.1;
私人轨道计划;
双orgSceneX,orgSceneY;
双orgTranslateX,orgTranslateY;
EventHandler elementOnMousePressedEventHandler=新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent t){
orgSceneX=t.getSceneX();
orgSceneY=t.getSceneY();
orgTranslateX=((矩形)(t.getSource()).getTranslateX();
orgTranslateY=((矩形)(t.getSource()).getTranslateY();
((矩形)(t.getSource()).setCursor(Cursor.NONE);
((矩形)(t.getSource()).toFront();
}
};
EventHandler elementOnMouseDraggedEventHandler=新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent t){
双偏移量x=t.getSceneX()-orgSceneX;
double offsetY=t.getSceneY()-orgseney;
双newTranslateX=坐标位置((int)数学圆((orgTranslateX+offsetX)/boxSize));
double newTranslateY=坐标位置((int)数学圆((orgTranslateY+offsetY)/boxSize));
((矩形)(t.getSource()).setTranslateX(newTranslateX);
((矩形)(t.getSource()).setTranslateY(newTranslateY);
}
};
公共轨道平面窗格(轨道平面图t){
这个.trackplan=t;
此.setStyle(“-fx边框颜色:红色;”);
this.elements.addListener(新的ListChangeListener(){

public void onChanged(javafx.collections.ListChangeListener.Change由于
GuiElement
不是
节点,因此不能将此类的实例添加到
窗格中。但是,您可以创建一个包装类,将此类的内部
形状
实例绘制到
窗格中

我为您创建了一个示例,它由两个类组成。第一个类是对现有类的更新,第二个是可以存储第一个类的实例的“manager”类

示例

GuiElement.java

DrawManager.java

输出如下所示:


GuiElement
不可分配给
节点
。做一个有根据的猜测……我这样做了。这就是为什么有guiRepresentation变量的原因。我想有一个更好的方法,比如exends Shape(试试看)。在这种情况下,单击时,我必须使用x和y来访问我的对象的名称。谢谢。但问题是我得到了“添加的子对象:重复的子对象”。只需不添加相同的
GuiElement
实例两次。请参阅我一直制作的初始帖子上的更新“track.add(new trackplanement(1,1));”我最好的猜测是
drawTrackplan();
被多次调用,它将多次添加相同的元素,这些元素将向侦听器中的
窗格添加相同的节点。
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);
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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);
    }
}