我想编写一个“简单的UML编辑器”
使用案例
单击UML画布,然后生成UML形状。 生成后,光标位于UML形状的左上角。作为this image。
以下是示例代码。
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("mainView.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane fx:id="canvas" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#onMouseClicked" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainViewController" />
package application;
import javafx.fxml.FXML;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
public class MainViewController {
@FXML Pane canvas;
@FXML private void onMouseClicked(MouseEvent event) {
myCircle c = new myCircle();
c.setLayoutX(event.getX());
c.setLayoutY(event.getY());
canvas.getChildren().add(c);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.Scene?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0" prefWidth="40.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Circle fx:id="circle" fill="DODGERBLUE" layoutX="20.0" layoutY="20.0" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
</children>
</Pane>
package application;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Parent;
import javafx.scene.shape.Circle;
public class myCircle extends Parent {
@FXML Circle circle;
public myCircle() {
// TODO Auto-generated constructor stub
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myCircle.fxml"));
//fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.getChildren().add(circle);
System.out.println("generate myCircle");
}
}
在文件中:myCircle.java。我无法添加代码fxmlLoader.setRoot(this);
,或者它将显示错误消息:“已指定根值”。
根节点是否动态加载? (我没有使用<fx:root>
或setRoot()
)如果是动态加载,哪一个是我当前的根节点?
在文件中:myCircle.java。我必须添加第this.getChildren().add(circle);
行,或者没有圈子生成。为什么?我认为有一些我不知道的重要细节......
centerXProperty()
来实现绑定行相对功能,但是存在一些问题。我的自定义UML形状应用并加载自定义fxml文件,我无法获得真正的centerXProperty。我打印centerXProperty messege:DoubleProperty [bean: Circle[id=circle, centerX=0.0, centerY=0.0, radius=20.0, fill=0x1e90ffff, stroke=0x000000ff, strokeWidth=1.0], name: centerX, value: 0.0]
。无论如何,该值始终为0.0。我该怎么办?
我不想输入意大利面条代码。
答案 0 :(得分:0)
FXML文件的根元素是<Pane>
元素,它基本上是FXMLLoader
创建Pane
实例的指令,该实例成为根。因此,当您尝试调用fxmlLoader.setRoot(...)
时,它会抱怨,因为FXML文件中已经指定了根。要解决此问题,您需要使用<fx:root...>
作为根元素:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.Scene?>
<fx:root type="Pane" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity"
prefHeight="40.0" prefWidth="40.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Circle fx:id="circle" fill="DODGERBLUE" layoutX="20.0" layoutY="20.0" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
</children>
</fx:root>
要使fxmlLoader.setRoot(this)
生效,this
必须是type
属性<fx:root>
指定的类的实例,即您必须myCircle
} Pane
的子类:
package application;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
public class myCircle extends Pane {
@FXML Circle circle;
public myCircle() {
// TODO Auto-generated constructor stub
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myCircle.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// circle is now added to this by the FXML.
// So next line is no longer needed:
// this.getChildren().add(circle);
System.out.println("generate myCircle");
}
}
通过修复fxmlLoader.setRoot(this)
来修复。圆圈是Pane
的子节点,它是FMXL文件的根。以前,除非您明确说明,否则它不会添加到myCircle
实例中。
您永远不会更改centerX
和centerY
属性,因此它们始终为0.您是不是要在FXML中使用centerX="20"
代替layoutX="20"
?如果您想公开它们以进行绑定/设置/等,您可以在myCircle
类中执行此操作:
package application;
import java.io.IOException;
import javafx.beans.property.DoubleProperty ;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
public class myCircle extends Pane {
@FXML Circle circle;
public myCircle() {
// TODO Auto-generated constructor stub
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myCircle.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// circle is now added to this by the FXML.
// So next line is no longer needed:
// this.getChildren().add(circle);
System.out.println("generate myCircle");
}
public DoubleProperty centerXProperty() {
return circle.centerXProperty();
}
public final double getCenterX() {
return centerXProperty().get();
}
public final void setCenterX(double centerX) {
centerXProperty().set(centerX);
}
// same for centerY...
}
您还可以考虑将MyCircle
作为Circle
的子类,以便您只继承centerX
和centerY
属性。即。
package application;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.shape.Circle;
public class myCircle extends Circle {
public myCircle() {
// TODO Auto-generated constructor stub
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myCircle.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("generate myCircle");
}
}
然后
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.Scene?>
<fx:root type="Circle" fill="DODGERBLUE" layoutX="20.0" layoutY="20.0"
radius="20.0" stroke="BLACK" strokeType="INSIDE"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
</fx:root>
虽然我不确定这是否仍能为您提供所需的全部功能。