我正在JavaFx中构建一个编辑器,用户可以在其中添加模块。每个模块都有许多输入,这些输入是JavaFX-circles,可以通过拖放移动。在圆圈之间可以有线条(从一个圆圈的中心到另一个圆圈的中心)。
我也查看了this个问题,但问题是,我的圈子不是绘制线条的节点的子节点。
所以我有以下代码(我使用ControlsFX绘制边框):
public class EditorTest extends Application
{
private Pane editorPane;
@Override
public void start(Stage primaryStage) throws Exception
{
VBox root = new VBox();
MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(new Menu("Test"));
editorPane = new Pane();
root.getChildren().add(menuBar);
root.getChildren().add(editorPane);
editorPane.setPrefSize(1000, 700);
initBindings();
Scene scene = new Scene(root);
editorPane.requestFocus();
primaryStage.setScene(scene);
primaryStage.show();
}
private void initBindings()
{
editorPane.setOnMouseClicked((event) ->
{
if (event.getButton() == MouseButton.SECONDARY)
{
Module moduleInput = new Module();
Node inputGui = moduleInput.getGui();
inputGui.setLayoutX(event.getX());
inputGui.setLayoutY(event.getY());
Module moduleOutput = new Module();
Node outputGui = moduleOutput.getGui();
outputGui.setLayoutX(event.getX() + 200);
outputGui.setLayoutY(event.getY());
Wire line = new Wire();
line.setInput(moduleInput.getPort());
line.setOutput(moduleOutput.getPort());
editorPane.getChildren().add(inputGui);
editorPane.getChildren().add(outputGui);
editorPane.getChildren().add(line);
}
});
}
public static void main(String[] args)
{
launch(args);
}
}
这是行的类:
public class Wire extends Line
{
private Port input;
private Port output;
public Wire()
{
super();
setStroke(Color.GREEN);
setStrokeWidth(3);
}
public void setInput(Port input)
{
this.input = input;
input.connectWire(this);
update();
}
public void setOutput(Port output)
{
this.output = output;
output.connectWire(this);
update();
}
public void update()
{
if (input != null)
{
Point2D centerInput = input.localToScene(input.getCenterX(), input.getCenterY());
System.out.println(centerInput);
setStartX(centerInput.getX());
setStartY(centerInput.getY());
}
if (output != null)
{
Point2D centerOutput = output.localToScene(output.getCenterX(), output.getCenterY());
setEndX(centerOutput.getX());
setEndY(centerOutput.getY());
}
}
}
这是输入:
public class Port extends Circle
{
private Wire connLine;
public Port()
{
super(10, Color.ALICEBLUE);
setStroke(Color.BLACK);
}
public void connectWire(Wire connLine)
{
this.connLine = connLine;
}
public void update()
{
if (connLine != null)
connLine.update();
}
}
这是模块:
public class Module extends Pane
{
private double oldX;
private double oldY;
private Port circle;
public Module()
{
HBox root = new HBox(5);
root.setAlignment(Pos.CENTER);
circle = new Port();
root.getChildren().add(circle);
getChildren().add(root);
}
public Node getGui()
{
Node returnPane = Borders.wrap(this).lineBorder().title("Test").buildAll();
returnPane.setOnMousePressed((event) ->
{
if (event.getButton() == MouseButton.PRIMARY)
{
oldX = returnPane.getLayoutX() - event.getSceneX();
oldY = returnPane.getLayoutY() - event.getSceneY();
}
});
returnPane.setOnMouseDragged((event) ->
{
if (event.getButton() == MouseButton.PRIMARY)
{
double newX = event.getSceneX() + oldX;
if (newX > 0 && newX < returnPane.getScene().getWidth())
{
returnPane.setLayoutX(newX);
}
double newY = event.getSceneY() + oldY;
if (newY > 0 && newY < returnPane.getScene().getHeight())
{
returnPane.setLayoutY(newY);
}
}
});
returnPane.layoutXProperty().addListener((obs, newValue, oldValue) ->
{
circle.update();
});
returnPane.layoutYProperty().addListener((obs, newValue, oldValue) ->
{
circle.update();
});
return returnPane;
}
public Port getPort()
{
return circle;
}
}
所以我认为问题出现在update
的{{1}}方法中
因为从本地坐标到父坐标的转换,但是由于其他节点,它在本地到场景转换时不起作用。我也不明白为什么它不能与Wire
一起使用,因为在模块gui的坐标空间中它应该是正确的...
另一点我不明白为什么在我开始移动节点之前,线总是处于错误的位置。
如果我在它周围添加localToParent
,则会出现更大的问题,因此按照我滚动的方式移动线条。
那么如何恰当地转换坐标以将线连接到端口的中心,并且可以将其放入ScrollPane
?