绑定Circle与Line坐标失效:拖动Circle时Line无法联动
Hey there! Let's fix that broken coordinate binding issue so your Line stays connected to those draggable Circles as you move them around. Here's what's going wrong and how to fix it:
You're most likely not properly binding the Line's endpoint coordinates to the Circles' centerX/centerY properties—instead, you probably set static initial coordinates. JavaFX's property binding is the key to dynamic linkage; you need to use the bind() method on properties, not just assign static values with setX()/setY().
I've filled out and corrected your code snippet with the critical fixes:
import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.layout.Pane; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.scene.paint.Color; import javafx.scene.input.MouseEvent; import java.net.URL; import java.util.ArrayList; import java.util.ResourceBundle; public class GraphController implements Initializable { @FXML private Pane draw_zone; private ArrayList<Circle> vertex_list; private ArrayList<Line> edge_list; // Assuming Edge wraps a Line; adjust if you have a custom Edge class @Override public void initialize(URL url, ResourceBundle rb) { vertex_list = new ArrayList<>(); edge_list = new ArrayList<>(); // Create draggable red circles Circle c1 = new Circle(20, 50, 5, Color.RED); Circle c2 = new Circle(100, 120, 5, Color.RED); // Add drag functionality to circles (if you hadn't implemented this yet) makeDraggable(c1); makeDraggable(c2); // Create line to connect the two circles Line connectingLine = new Line(); // 🔑 Critical binding: Link line endpoints to circle center properties connectingLine.startXProperty().bind(c1.centerXProperty()); connectingLine.startYProperty().bind(c1.centerYProperty()); connectingLine.endXProperty().bind(c2.centerXProperty()); connectingLine.endYProperty().bind(c2.centerYProperty()); // Add elements to the pane and tracking lists draw_zone.getChildren().addAll(c1, c2, connectingLine); vertex_list.addAll(c1, c2); edge_list.add(connectingLine); // Keep your existing vertex-adding handler draw_zone.addEventHandler(MouseEvent.MOUSE_PRESSED, add_vertex_handler); } // Reusable method to make any circle draggable private void makeDraggable(Circle circle) { final double[] dragDelta = new double[2]; circle.setOnMousePressed(e -> { dragDelta[0] = circle.getCenterX() - e.getSceneX(); dragDelta[1] = circle.getCenterY() - e.getSceneY(); }); circle.setOnMouseDragged(e -> { circle.setCenterX(e.getSceneX() + dragDelta[0]); circle.setCenterY(e.getSceneY() + dragDelta[1]); }); } // Your existing vertex-adding handler (fill in your logic here) private final MouseEvent.EventHandler add_vertex_handler = e -> { // Add your code to create new circles on mouse press }; }
- Property Binding Magic: The
bind()method ensures the Line's endpoints update automatically whenever the Circles' center coordinates change—no manual coordinate updates needed. - Drag Logic Correctness: Make sure your drag code modifies the Circle's
centerX/centerYproperties (notlayoutX/layoutY), since that's what we're binding the Line to. - Element Order: Add the Line to the Pane after the Circles so it sits underneath them, preventing it from blocking drag interactions.
If you're using a custom Edge class instead of a raw Line, just add a Line instance to your Edge class and apply the same binding logic to that Line's properties.
内容的提问来源于stack exchange,提问作者StuYYY

