Canvas JavaFX:在窗格或画布上显示自己的对象
我有一个具有x坐标和y坐标的物体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
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);
}
}