1

我正在 JavaFx 中构建一个编辑器,用户可以在其中添加模块。每个模块都有许多输入,这些输入是 JavaFX 圆圈,可以通过拖放移动。圆圈之间可以有线条(从一个圆圈的中心到另一个圆圈的中心)。

我也看过这个问题,但问题是,我的圆圈不是画线节点的子节点。

所以我有以下代码(我使用 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方法的某个地方,Wire 因为从本地坐标到父坐标的转换,但是对于本地到场景的转换,由于其他节点,它不起作用。我也不明白为什么它不能与 gui 一起使用localToParent,因为在模块 gui 的坐标空间中它应该是正确的......

我不明白的另一点是为什么在我开始移动节点之前线总是在错误的位置。

如果我ScrollPane在它周围添加一个,则会出现更大的问题,所以线条会随着我滚动的方式移动。

那么如何适当地转换坐标以将线连接到端口的中心,并且可以将其放入ScrollPane?

4

0 回答 0