2016-02-24 3 views
0

Я пытаюсь написать правильное правило о connecting nodes with edge. Я использовал решение от StackOverflow, которые используют данные из двух подключаемых nodes:Соедините два узла с краем JavaFX

 line.startXProperty().bind(source.layoutXProperty().add(source.getBoundsInParent().getWidth()/2.0)); 
     line.startYProperty().bind(source.layoutYProperty().add(source.getBoundsInParent().getHeight()/2.0)); 

     line.endXProperty().bind(target.layoutXProperty().add(target.getBoundsInParent().getWidth()/2.0)); 
     line.endYProperty().bind(target.layoutYProperty().add(target.getBoundsInParent().getHeight()/2.0)); 

Но это не сработало. Он рисует следующую строку: enter image description here

Так что я не могу понять, как написать правило, чтобы линия была помещена на его место? Спасибо.

+2

Что произойдет, если удалить «добавить (x.getBoundsInParent()» часть? Кажется, что свойства макета возвращают центр круга, так что может быть достаточно – Clayn

+0

спасибо, он работает. Но на движущихся узлах линии после них не перемещаются. Есть ли способ исправить это? – Alesto

+0

Я предполагаю, что вы что source.ayoutXProperty(). add (source.getBoundsInParent(). getWidth() является 'double', и это не' Observable'. Итак, если это круги, вы должны вычислить линейную точку линии linestartpoint из centerxpropery и r adiusprop (предполагая, что вам нужен край круга), иначе вы могли бы использовать какое-либо другое значение «Наблюдаемое» ваших узлов или, возможно, недействительный/изменяющий прослушиватель, чтобы получить желаемый эффект (в случае перемещения ваших узлов) –

ответ

1

Попробуйте

line.startXProperty().bind(Bindings.createDoubleBinding(() -> { 
    Bounds b = source.getBoundsInParent(); 
    return b.getMinX() + b.getWidth()/2 ; 
}, source.boundsInParentProperty()); 
line.startYProperty().bind(Bindings.createDoubleBinding(() -> { 
    Bounds b = source.getBoundsInParent() ; 
    return b.getMinY() + b.getHeight()/2 ; 
}, source.boundsInParentProperty()); 

и аналогично для цели и в конце линии. Комментарии ниже вопроса в основном объясняют, как это работает: вам нужно что-то видимое, которое зависит от границ в родительском и вычисляет центр.

SSCCE (нажмите, чтобы добавить круг, нажмите еще раз, чтобы добавить подключенный круг, бугельные круги, чтобы увидеть эффект):

import java.util.Random; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.event.Event; 
import javafx.geometry.Bounds; 
import javafx.geometry.Point2D; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Line; 
import javafx.stage.Stage; 

public class DraggingConnectedNodes extends Application { 

    private final Random rng = new Random(); 

    @Override 
    public void start(Stage primaryStage) { 
     Pane pane = new Pane(); 
     ObjectProperty<Node> lastUnconnectedNode = new SimpleObjectProperty<>(); 
     pane.setOnMouseClicked(e -> { 
      Circle c = createDraggingCircle(e.getX(), e.getY(), 25, pane, randomColor()); 
      pane.getChildren().add(c); 
      if (lastUnconnectedNode.get() == null) { 
       lastUnconnectedNode.set(c); 
      } else { 
       connect(lastUnconnectedNode.get(), c); 
       lastUnconnectedNode.set(null); 
      } 

     }); 

     Scene scene = new Scene(pane, 600, 600); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 

    } 

    private void connect(Node n1, Node n2) { 
     if (n1.getParent() != n2.getParent()) { 
      throw new IllegalArgumentException("Nodes are in different containers"); 
     } 
     Pane parent = (Pane) n1.getParent(); 
     Line line = new Line(); 
     line.startXProperty().bind(Bindings.createDoubleBinding(() -> { 
      Bounds b = n1.getBoundsInParent(); 
      return b.getMinX() + b.getWidth()/2 ; 
     }, n1.boundsInParentProperty())); 
     line.startYProperty().bind(Bindings.createDoubleBinding(() -> { 
      Bounds b = n1.getBoundsInParent(); 
      return b.getMinY() + b.getHeight()/2 ; 
     }, n1.boundsInParentProperty())); 
     line.endXProperty().bind(Bindings.createDoubleBinding(() -> { 
      Bounds b = n2.getBoundsInParent(); 
      return b.getMinX() + b.getWidth()/2 ; 
     }, n2.boundsInParentProperty())); 
     line.endYProperty().bind(Bindings.createDoubleBinding(() -> { 
      Bounds b = n2.getBoundsInParent(); 
      return b.getMinY() + b.getHeight()/2 ; 
     }, n2.boundsInParentProperty())); 
     parent.getChildren().add(line); 
    } 

    private Circle createDraggingCircle(double radius, double x, double y, Pane parent, Color fill) { 
     Circle c = new Circle(radius, x, y, fill); 
     ObjectProperty<Point2D> mouseLoc = new SimpleObjectProperty<>(); 
     c.setOnMousePressed(e -> mouseLoc.set(new Point2D(e.getX(), e.getY()))); 
     c.setOnMouseDragged(e -> { 
      double deltaX = e.getX() - mouseLoc.get().getX(); 
      double deltaY = e.getY() - mouseLoc.get().getY(); 
      c.setCenterX(c.getCenterX() + deltaX); 
      c.setCenterY(c.getCenterY() + deltaY); 
      mouseLoc.set(new Point2D(e.getX(), e.getY())); 
     }); 
     c.addEventFilter(MouseEvent.MOUSE_CLICKED, Event::consume); 
     return c ; 
    } 

    private Color randomColor() { 
     return new Color(rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), 1); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Спасибо, Джеймс, я попробую. Я все еще удивляюсь, почему вы все еще тратите свое время на мою глупость: D Я все еще не понимаю ничего. Разве не правильно, что Edge должен быть Observer и Node наблюдаемыми? Мы перемещаем узел, поэтому Edge - тот, кому нужно наблюдать за действиями узла, не так ли? – Alesto

+1

Кромка наблюдает за узлом, или, по крайней мере, свойства края являются наблюдаемыми свойствами узла. 'startX' является свойством ребра, и он наблюдает свойство' boundsInParent' узла. (И что-нибудь в JavaFX, которое представлено свойством JavaFX - почти все - наблюдаемо.) –

+0

Ваш совет действительно помог. Но ребра все еще перекрывают узлы, и по некоторым причинам методы 'toFront' и' toBack' не работают. – Alesto

Смежные вопросы