2015-07-22 20 views
8

Voglio stessa cosa che ha chiesto in questo post track changes of nodes bound in JavaFXcambiamento traccia dei nodi legati in JavaFX

ho qualcosa di simile a questo: (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); 
} 

} 

ma il problema è cambiato il metodo non viene chiamato correttamente ... Si chiama solo una volta .... se aggiungo questo codice nel metodo modificato invece del vecchio Si chiama correttamente ... Ma è molto molto lento

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

Qualcuno può aiutarmi? di Grazie ...

risposta

4

Dal momento che la Button e la Circle in questo esempio si trovano nella stessa riquadro genitore, si potrebbe ovviamente fare questo molto più semplice (ed efficiente) proprio legando la posizione del cerchio per il pulsante di boundsInParentProperty(). Presumo che lo stai facendo in questo modo perché hai una vera applicazione in cui i due nodi sono in genitori diversi.

Sembra che lo localToSceneTransformProperty() riceva i dati obsoleti prematuramente (vedere anche this). È possibile risolvere questo problema utilizzando un listener anziché un binding:

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

Grazie ma purtroppo non funziona! Avete qualche altra idea? – faraa

+0

Ho modificato e inserito un codice SSCCE – faraa

+0

Aggiornamento risposta di conseguenza. –