Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8119983

Mac: DragEvent.getScreenY() returns incorrect value on drag drop

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 8
    • 7u10, 8
    • javafx
    • Mac OSX 10.7.5; tested with JavaFX 2.2.4 under JDK 1.7.0_13 and JavaFX 8 under JDK 1.8.0-ea-b77.

      The coordinate returned by DragEvent.getScreenY() is incorrect. In the following sample, the dialog should open at the location of the mouse when the drag event is dropped. When the main window is moved down, the dialog appears at a higher location, and vice-versa. DragEvent.getScreenX() returns the correct value.

      To reproduce:

      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.geometry.Bounds;
      import javafx.geometry.Point2D;
      import javafx.scene.Node;
      import javafx.scene.Scene;
      import javafx.scene.control.RadioButton;
      import javafx.scene.control.ToggleGroup;
      import javafx.scene.input.ClipboardContent;
      import javafx.scene.input.DragEvent;
      import javafx.scene.input.Dragboard;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.input.TransferMode;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.Pane;
      import javafx.scene.layout.VBox;
      import javafx.scene.paint.Color;
      import javafx.scene.shape.Rectangle;
      import javafx.scene.text.Text;
      import javafx.stage.Modality;
      import javafx.stage.Stage;
      import javafx.stage.Window;

      public class DragEventScreenLocationTest extends Application {

        @Override
        public void start(Stage primaryStage) {
          final Pane pane = new Pane();
          final Text text = new Text(20, 20, "Drag text to Rectangle");
          final Rectangle rectangle = new Rectangle(20, 50, 100, 100);
          rectangle.setFill(Color.ALICEBLUE);

          pane.getChildren().addAll(text, rectangle);
          final VBox controls = new VBox(5);
          final RadioButton useGetScreen = new RadioButton("Use getScreenX() and getScreenY()");
          useGetScreen.setSelected(true);
          final RadioButton useComputation = new RadioButton("Compute manually");
          new ToggleGroup().getToggles().addAll(useGetScreen, useComputation);
          controls.getChildren().addAll(useGetScreen, useComputation);

          text.setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
              Dragboard db = text.startDragAndDrop(TransferMode.COPY);
              ClipboardContent content = new ClipboardContent();
              content.putString("Thanks!");
              db.setContent(content);
            }
          });
          rectangle.setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
              event.acceptTransferModes(TransferMode.COPY);
            }
          });
          rectangle.setOnDragDropped(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
              Point2D location = getDropLocation(event, rectangle,
                  useGetScreen.isSelected());
              HBox dialogRoot = new HBox();
              dialogRoot.getChildren()
                  .add(new Text(event.getDragboard().getString()));
              Scene dialogScene = new Scene(dialogRoot, 100, 30);
              Stage dialog = new Stage();
              dialog.setScene(dialogScene);
              dialog.initModality(Modality.APPLICATION_MODAL);
              dialog.setX(location.getX());
              dialog.setY(location.getY());
              dialog.show();
            }
          });

          final BorderPane root = new BorderPane();
          root.setCenter(pane);
          root.setBottom(controls);
          Scene scene = new Scene(root, 200, 300);
          primaryStage.setScene(scene);
          primaryStage.show();
        }

        private Point2D getDropLocation(DragEvent event, Node node,
            boolean useGetScreen) {
          if (useGetScreen) {
            return new Point2D(event.getScreenX(), event.getScreenY());
          } else {
            Scene scene = node.getScene();
            Window window = scene.getWindow();
            double x = event.getSceneX() + scene.getX() + window.getX();
            double y = event.getSceneY() + scene.getY() + window.getY();
            return new Point2D(x, y);
          }
        }

        public static void main(String[] args) {
          launch(args);
        }
      }

            pchelko Petr Pchelko (Inactive)
            jdenvirjfx James Denvir (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: