当父节点有变换时拖动其子节点会导致节点消失。

6
非常奇怪的问题,我最终成功将其浓缩成一个小代码片段来演示这个问题。我有一个包含1个组的窗格,该组包含一个包含一些椭圆的组。顶部组应用了旋转变换。椭圆可以被拖动。
请尝试下面的示例,向下拖动一些椭圆(超出组的边界),您将看到它们消失了。如果您最大化窗口,它们会再次出现,但您无法再拖动它们,它们不再接收任何事件。
现在是真正奇怪的部分,有三种方法可以解决这个问题:
  1. 不要应用变换
  2. 删除一个椭圆(!?) (我进行了实验以得出这个数字,11)
  3. 同时启动ScenicView并选择包含椭圆的组,以便您可以看到组的边界
我完全不知所措,请问有人知道为什么会出现这个问题以及如何解决吗?
代码(JavaFX 2.2.3和java 1.7.0_09 64位Windows 7):
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.GroupBuilder;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.EllipseBuilder;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.RotateBuilder;
import javafx.stage.Stage;

public class DragProblem extends Application {
public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) {
    DrawingPane drawingPane = new DrawingPane();
    drawingPane.setStyle("-fx-background-color: darkgrey;");

    Scene scene = SceneBuilder.create().root(drawingPane).width(1280d).height(1024d).build();

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

public class DrawingPane extends Pane {
    private Group transformedGroup;
    private Group splinePoints;

    public DrawingPane() {
        transformedGroup = GroupBuilder.create().id("transformedGroup").build();

        getChildren().add(transformedGroup);

        addPoints();
        makePointsDraggable();
    }

    public void addPoints() {
        double[] coords = new double[] {
                // comment any one the below x,y coordinates and the problem doesn't occur..
                239.28353881835938, 488.2192687988281,
                245.04466247558594, 505.30169677734375,
                258.56671142578125, 539.49462890625,
                267.2294006347656, 563.618408203125,
                282.89141845703125, 587.84033203125,
                309.6925048828125, 602.2174072265625,
                327.4945068359375, 616.4683227539062,
                345.25445556640625, 633.718994140625,
                371.0416259765625, 649.0819702148438,
                393.78704833984375, 667.402587890625,
                442.67010498046875, 676.0886840820312 };

        splinePoints = GroupBuilder.create().build();
        for (int i = 0; i < coords.length; i += 2) {
            Ellipse ellipse = EllipseBuilder.create().radiusX(3).radiusY(3).centerX(coords[i]).centerY(coords[i + 1]).build();
            splinePoints.getChildren().add(ellipse);
        }

        transformedGroup.getChildren().add(splinePoints);

        Rotate rotateTransform = RotateBuilder.create().build();
        rotateTransform.setPivotX(224);
        rotateTransform.setPivotY(437);
        rotateTransform.setAngle(15);

        // ..or comment this line to prevent the problem occuring
        transformedGroup.getTransforms().add(rotateTransform);
    }

    public void makePointsDraggable() {
        for (final Node n : splinePoints.getChildren()) {
            Ellipse e = (Ellipse) n;
            final NodeDragHandler ellipseDragHandler = new NodeDragHandler(e, transformedGroup);

            e.setOnMousePressed(ellipseDragHandler);
            e.setOnMouseDragged(ellipseDragHandler);
        }
    }
}

public class NodeDragHandler implements EventHandler<MouseEvent> {
    protected final Ellipse node;
    private final Node transformedGroup;

    private double initialX;
    private double initialY;
    private Point2D initial;
    private boolean dragStarted = false;

    public NodeDragHandler(Ellipse node, Group transformedGroup) {
        this.node = node;
        this.transformedGroup = transformedGroup;
    }

    @Override
    public void handle(MouseEvent event) {
        if (!dragStarted) {
            initialX = event.getScreenX();
            initialY = event.getScreenY();

            initial = transformedGroup.localToParent(new Point2D(node.getCenterX(), node.getCenterY()));

            dragStarted = true;
        } else {
            double xDragged = event.getScreenX() - initialX;
            double yDragged = event.getScreenY() - initialY;

            Point2D newPos = new Point2D(initial.getX() + xDragged, initial.getY() + yDragged);

            Point2D p = transformedGroup.parentToLocal(newPos.getX(), newPos.getY());

            node.setCenterX(p.getX());
            node.setCenterY(p.getY());
        }
    }
}
}

如果已经确认为错误,您还在寻找解决方法吗?否则,您可以回答自己的问题并关闭它。 - JoshDM
我尝试关闭它,但在SO提供的原因中找不到一个好的匹配原因。而且,我也不确定未领取的赏金会发生什么,所以我正在等待它先过期。 - Nicolas Mommaerts
发布您自己的答案回答问题,并引用错误确认。然后将您的答案标记为已接受。您将获得报销。 - JoshDM
1个回答

1

JavaFX中已经确认存在一个错误,将在2.2.6版本中解决,详见此处。我已经使用早期访问版本进行了测试,并确认该问题已得到解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接