非常に奇妙な問題でしたが、私はついにそれを問題を示す小さなコードに抽出することができました。1つのグループを含むペインがあり、そのグループにはいくつかの省略記号を含むグループが含まれています。一番上のグループには、回転変換が適用されています。楕円はドラッグ可能になります。
以下の例を試して、いくつかの省略記号を下に(グループの境界の外側に)ドラッグすると、それらが消えるのがわかります。ウィンドウを最大化すると、それらは再び表示されますが、ドラッグすることはできなくなり、イベントを受信しなくなります。
さて、本当に奇妙な部分については、問題を解決するための3つの方法があります。
- 変換を適用しないでください
- 1つの楕円を削除します(!?)(私はこの数、11に到達するために実験しました)
- 一緒にScenicViewを起動し、省略記号を含むグループを選択して、グループの境界を確認できるようにします
私はここで完全に途方に暮れ、完全に呆然としている。どうか、この問題が発生している理由とその解決方法を誰かが知っていますか?
コード(JavaFX2.2.3およびjava1.7.0_0964ビットWindows7):
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());
}
}
}
}