2

I am trying to create a node-based graphical interface, à la blender or unreal engine. I've tried using JavaFx, however I run into difficulties with connecting the nodes -- I'm getting the feeling that I'm approaching the problem with the wrong technologies.

I've examined this similar question, however the answers seem to be based around OOP principles rather than the graphics itself.

What would be the easiest way to solve this problem? Any ideas? Thanks in advance.

Community
  • 1
  • 1
haz
  • 2,034
  • 4
  • 28
  • 52
  • You haven't really described what the problem is. Typically for "connections" (edges) like this I would just bind the start and end of a line (or curve) to the coordinates of the appropriate nodes. – James_D Sep 18 '16 at 13:56
  • Sorry if I was a bit vague. Conceptually I understand how to do this -- it's just the technical implementation. For example, in JavaFx I'd use Panes for individual nodes - but then how do I connect them? I can't just use a canvas node for drawing each line. I can't do the entire GUI on a canvas either, because that would be very unwieldy. In HTML5 I can draw the lines fine, but the panes and the GUI itself is a lot more difficult. I'd just like someone to point me in the right direction :) – haz Sep 18 '16 at 14:50
  • Use a group node, add a rectangle for the Box, smaller rectangles for connection endpoints and lines/curves for connections. – Jhonny007 Sep 18 '16 at 16:16

1 Answers1

1

If you are just looking to connect some nodes with lines, you probably just need to add them to a pane, with a line whose start and end points are bound to the coordinates of the nodes.

Here's a simple example of a couple of rectangles that can be dragged around the pane, with the line staying connected to them. Obviously you could improve this so the connecting line starts and ends from the appropriate side of the rectangle, etc, but it shows the basic idea.

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class ConnectedBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {
        Rectangle startBox = createDraggableBox(50, 50);
        startBox.setX(50);
        startBox.setY(50);

        Rectangle endBox = createDraggableBox(50, 50);
        endBox.setX(350);
        endBox.setY(200);

        Line connector = createConnector(startBox, endBox);

        Pane pane = new Pane(startBox, endBox, connector);
        Scene scene = new Scene(pane, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Line createConnector(Node start, Node end) {
        Line l = new Line();
        l.startXProperty().bind(Bindings.createDoubleBinding(
                () -> start.getBoundsInParent().getMaxX(),
                start.boundsInParentProperty()));
        l.startYProperty().bind(Bindings.createDoubleBinding(
                () -> start.getBoundsInParent().getMinY() + start.getBoundsInParent().getHeight() / 2,
                start.boundsInParentProperty()));
        l.endXProperty().bind(Bindings.createDoubleBinding(
                () -> end.getBoundsInParent().getMinX(),
                end.boundsInParentProperty()));
        l.endYProperty().bind(Bindings.createDoubleBinding(
                () -> end.getBoundsInParent().getMinY() + end.getBoundsInParent().getHeight() / 2,
                end.boundsInParentProperty()));
        return l ;

    }

    public Rectangle createDraggableBox(int width, int height) {
        Rectangle r = new Rectangle(width, height);
        r.setFill(Color.CORAL);

        DragDelta delta = new DragDelta();

        r.setOnMousePressed(e -> {
            delta.x = e.getX();
            delta.y = e.getY();
        });

        r.setOnMouseDragged(e -> {
            double deltaX = e.getX() - delta.x ;
            double deltaY = e.getY() - delta.y ;
            r.setX(r.getX() + deltaX);
            r.setY(r.getY() + deltaY);
            delta.x = e.getX();
            delta.y = e.getY();
        });

        return r ;
    }

    class DragDelta { double x,y ;}

    public static void main(String[] args) {
        launch(args);
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322