【问题标题】:Why do my JavaFX application's drag routines break in JavaFX 8?为什么我的 JavaFX 应用程序的拖动例程在 JavaFX 8 中会中断?
【发布时间】:2014-11-21 03:38:02
【问题描述】:

我有一些代码可以让我拖动 StackPane 的一个实例。该代码在 JavaFX v2.2 中运行良好,但 StackPane 保持在默认位置并且在 JavaFX v8 中不会移动。

代码如下:

private void initDragRoutine(final Node source,
                             final boolean replaceSource,
                             final Node replaceWith,
                             final Pane replaceFrom)
{
    /*
     * add the draggable pane and create its text
     */
    source.setOnDragDetected(new EventHandler<MouseEvent>()
    {
        @Override
        public void handle(MouseEvent mouseEvent)
        {
            System.out.println("drag initialized");

            //update the content of the draggable instance with that of the fixed position source
            if (mouseEvent.getSource() instanceof StringPane)
                draggablePane.setOverlay(((StringPane) mouseEvent.getSource()).getOverlay());

            //update position
            Point2D localPoint = questionInfoNode.sceneToLocal(
                    new Point2D(mouseEvent.getSceneX(), mouseEvent.getSceneY()));
            draggablePane.relocate(
                    (int) (localPoint.getX() - draggablePane.getBoundsInLocal().getWidth() / 2),
                    (int) (localPoint.getY() - draggablePane.getBoundsInLocal().getHeight() / 2)
            );
            //add to scene
            styledRootNode.getChildren().add(draggablePane);

            draggablePane.startFullDrag();

            //replace source
            if (replaceSource && replaceFrom != null)
                for (int index = 0; index < replaceFrom.getChildren().size(); index++)
                    if (replaceFrom.getChildren().get(index) == source)
                        replaceFrom.getChildren().set(index, replaceWith);

            mouseEvent.consume();
        }
    });

    /*
     * update the position
     */
    source.setOnMouseDragged(new EventHandler<MouseEvent>()
    {
        @Override
        public void handle(MouseEvent mouseEvent)
        {
            System.out.println("dragged");

            //update position
            Point2D localPoint = questionInfoNode.sceneToLocal(
                    new Point2D(mouseEvent.getSceneX(), mouseEvent.getSceneY()));
            System.out.println("x" + mouseEvent.getSceneX() + "y" + mouseEvent.getSceneY());
            draggablePane.relocate(
                    (int) (localPoint.getX() - draggablePane.getBoundsInLocal().getWidth() / 2),
                    (int) (localPoint.getY() - draggablePane.getBoundsInLocal().getHeight() / 2)
            );
            //draggablePane.relocate(450, 1000);

            //source.setCursor(Cursor.NONE);
            mouseEvent.consume();
        }
    });

    /*
     * adjust cursor on entry
     */
    source.setOnMouseEntered(new EventHandler<MouseEvent>()
    {
        public void handle(MouseEvent e)
        {
            source.setCursor(Cursor.HAND);
            e.consume();
        }
    });

    /*
     * adjust cursor on pressed
     */
    source.setOnMousePressed(new EventHandler<MouseEvent>()
    {
        public void handle(MouseEvent e)
        {
            System.out.println("mouse pressed");

            source.setMouseTransparent(true);
            draggablePane.setMouseTransparent(true);
            source.setCursor(Cursor.CLOSED_HAND);

            e.consume();

            System.out.println("mouse pressed done");
        }
    });

    /*
     * adjust cursor on released
     */
    source.setOnMouseReleased(new EventHandler<MouseEvent>()
    {
        public void handle(MouseEvent e)
        {
            System.out.println("mouse released");

            source.setMouseTransparent(false);
            draggablePane.setMouseTransparent(false);
            source.setCursor(Cursor.DEFAULT);
            styledRootNode.getChildren().remove(draggablePane);

            e.consume();

            System.out.println("mouse released done");
        }
    });
}

我尝试将位置更新硬编码为测试,但也无法重新定位窗格。如果有人有任何想法,即使是最轻微的,我也很乐意尝试一下。我已经坚持了几天了。谢谢。

【问题讨论】:

    标签: java drag-and-drop javafx javafx-2 javafx-8


    【解决方案1】:

    我没有时间为您的代码错误创建一个完整的示例。所以这是我自己的一个例子,用 StackPane 扩展,向你展示它是如何工作的:

    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Cursor;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Ellipse;
    import javafx.stage.Stage;
    
    public class DragExample extends Application {
    
        Circle circle_R, circle_G, circle_B;
        WrappedInStackPane wrapped;
        double orgSceneX, orgSceneY;
        double orgTranslateX, orgTranslateY;
    
        @Override
        public void start(Stage primaryStage) {
    
            // Create Circles
            circle_R = createCircle( 50, Color.RED, 100, 100);
            circle_G = createCircle( 50, Color.GREEN, 400, 100);
            circle_B = createCircle( 50, Color.BLUE, 700, 100);
    
            wrapped = new WrappedInStackPane();
    
            Group root = new Group();
            root.getChildren().addAll(circle_R, circle_G, circle_B, wrapped);
    
            primaryStage.setResizable(true);
            primaryStage.setScene(new Scene(root, 1600, 900));
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        public Circle createCircle( double radius, Color color, double x, double y) {
    
            Circle circle;
    
            circle = new Circle(50.0f, color);
            circle.setCursor(Cursor.MOVE);
            circle.setTranslateX(x);
            circle.setTranslateY(y);
            circle.setOnMousePressed(onMousePressedEventHandler);
            circle.setOnMouseDragged(onMouseDraggedEventHandler);
    
            return circle;
        }
        EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
    
            @Override
            public void handle(MouseEvent t) {
                orgSceneX = t.getSceneX();
                orgSceneY = t.getSceneY();
                orgTranslateX = ((Node) (t.getSource())).getTranslateX();
                orgTranslateY = ((Node) (t.getSource())).getTranslateY();
            }
        };
    
        EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
    
            @Override
            public void handle(MouseEvent t) {
                double offsetX = t.getSceneX() - orgSceneX;
                double offsetY = t.getSceneY() - orgSceneY;
                double newTranslateX = orgTranslateX + offsetX;
                double newTranslateY = orgTranslateY + offsetY;
    
                ((Node) (t.getSource())).setTranslateX(newTranslateX);
                ((Node) (t.getSource())).setTranslateY(newTranslateY);
            }
        };
    
        public class WrappedInStackPane extends StackPane {
    
            public WrappedInStackPane() {
    
                setStyle("-fx-background-color: orange;");
    
                Ellipse ellipse = new Ellipse(100, 50);
                ellipse.setFill(Color.YELLOW);
    
                Label label = new Label( "Inside StackPane");
    
                getChildren().addAll(ellipse, label);
    
                setOnMousePressed(onMousePressedEventHandler);
                setOnMouseDragged(onMouseDraggedEventHandler);
    
                relocate(200, 200);
    
            }
        }
    }
    

    我建议您在 StackPane 上设置背景样式,以查看是否有问题。

    【讨论】:

      【解决方案2】:

      长话短说,FX2.2 和 FX8.0 之间对听众的处理方式发生了变化。在我从场景中删除对象并添加另一个对象之前。在 FX2.2 中,该对象不会被垃圾回收,但在 FX8.0 中它会出现(当它出现时,拖动例程会冻结)。通过在拖动开始时执行交换而不是删除原始对象,引用保留,然后可以在拖动完成处理程序中销毁原始对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        • 1970-01-01
        • 1970-01-01
        • 2019-05-22
        相关资源
        最近更新 更多