2015-07-22 8 views
8

möchte ich gleiche Sache, die in diesem Beitrag fragte track changes of nodes bound in JavaFXSpurwechsel von Knoten in javafx gebunden

Ich habe so etwas wie dies: (Edited) SSCCE:

public class FloatCircle { 

Node node; 


Circle rectangle; 
Bounds localToScreen; 
static ArrayList<ObjectBinding> list = new ArrayList<>(); 
private ObjectBinding<Bounds> boundsInScene ; 
Pane root ; 

public FloatCircle(Node node,Pane root) { 
    this.node = node; 
    this.root =root; 
    this.rectangle = new Circle(); 
    this.rectangle.setManaged(false); 

    initSetting(); 

} 



public Circle getFloatCircle() { 
    return rectangle; 
} 

public void initSetting() { 

    boundsInScene = Bindings.createObjectBinding(
      () -> node.localToScene(node.getBoundsInLocal()), 
      node.localToSceneTransformProperty(), 
      node.boundsInLocalProperty()); 
    boundsInScene.addListener(new ChangeListener<Bounds>() { 

     @Override 
     public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) { 
      setLocation(newValue); 
      System.err.println("CHANGED!!!!!!"); 
     } 

    }); 
    localToScreen = node.localToScene(node.getBoundsInLocal()); 
    setLocation(localToScreen); 
    addCircle(); 
} 

public void setLocation(Bounds localToScreen) { 
    int r = 10; 
      rectangle.setCenterX(localToScreen.getMinX() - r); 
      rectangle.setCenterY(localToScreen.getMinY() - 5); 
      rectangle.setRadius(r); 

    // return rect; 

} 

public void addCircle(){ 
      root.getChildren().add(rectangle); 

} 

} 




public class SelfContained extends Application { 

ArrayList<Node> nodes = new ArrayList<>(); 

@Override 
public void start(Stage primaryStage) { 
    Button btn = new Button(); 

    StackPane root = new StackPane(); 
    root.getChildren().add(btn); 
    nodes.add(btn); 

    Scene scene = new Scene(root, 300, 250); 

    primaryStage.setTitle("Hello World!"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    for (int i = 0; i < nodes.size(); i++) { 
     Node n = nodes.get(i); 
     FloatCircle floatCircle = new FloatCircle(n, root); 

    } 
} 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    launch(args); 
} 

} 

aber das Problem geändert wird Methode wird nicht korrekt aufgerufen ... Es wird nur einmal aufgerufen .... wenn ich diesen Code in geänderter Methode an Stelle des alten hinzufüge Es wird korrekt aufgerufen ... Aber es ist sehr sehr langsam

  FloatCircle fc = new FloatCircle(node); 
      fc.rectangle = rectangle ; 
      fc.setLocation(newValue, directionID, alignment); 

Kann mir jemand helfen? Dankt ...

Antwort

4

Seit Button und die Circle in diesem Beispiel sind in der gleichen Mutterscheibe, könnte man so viel mehr offensichtlich tut einfach (und effizient) nur durch den Kreis Lage auf den Knopf der Bindung boundsInParentProperty(). Ich nehme an, dass Sie es so machen, weil Sie eine echte Anwendung haben, in der die zwei Knoten in verschiedenen Elternteilen sind.

Es sieht aus wie die localToSceneTransformProperty() wird Müll vorzeitig gesammelt (siehe auch this). Sie können dies mit einem Listener anstelle einer Bindung beheben:

public static class FloatCircle { 

    Node node; 

    Circle rectangle; 
    Pane root; 

    public FloatCircle(Node node, Pane root) { 
     this.node = node; 
     this.root = root; 
     this.rectangle = new Circle(); 
     this.rectangle.setManaged(false); 

     initSetting(); 

    } 

    public Circle getFloatCircle() { 
     return rectangle; 
    } 

    public void initSetting() { 

     ChangeListener<Object> updater = (obs, oldValue, newValue) -> 
      setLocation(node.localToScene(node.getBoundsInLocal())); 
     node.boundsInLocalProperty().addListener(updater); 
     node.localToSceneTransformProperty().addListener(updater); 

     setLocation(node.localToScene(node.getBoundsInLocal())); 
     addCircle(); 
    } 

    public void setLocation(Bounds localToScreen) { 
     int r = 10; 
     rectangle.setCenterX(localToScreen.getMinX() - r); 
     rectangle.setCenterY(localToScreen.getMinY() - 5); 
     rectangle.setRadius(r); 
    } 

    public void addCircle() { 
     root.getChildren().add(rectangle); 

    } 

} 
+0

Vielen Dank, aber leider funktioniert es nicht! Haben Sie eine andere Idee? – faraa

+0

Ich bearbeitet und einen SSCCE-Code – faraa

+0

Aktualisierte Antwort entsprechend. –

Verwandte Themen