2014-10-20 2 views
0

У меня есть перетаскиваемый контейнер в JavaFX. Этот контейнер реализован в PopUp. Я могу перетащить Контейнер, но если я его перетащил, событие mouse не имеет постоянной координаты. Там очень быстро устанавливается положение мыши между двумя фиксированными позициями.JavaFX Container Draggable

Thats мой код:

container.setOnMouseDragged(new EventHandler<MouseEvent>() { 

      @Override 
      public void handle(MouseEvent me) { 
       // TODO Auto-generated method stub 

       if(dragAct==true){ 
        //Set the Position of the PopUp to the Position of the Mouse 
        setX(me.getX()); 
        setY(me.getY()); 
       } 
      } 
     }); 

containe является VBox. Основной класс - это расширенная версия PopUp-класса.

ответ

1
JavaFX Container Draggable 

Методы setX и setY, которые вы вызываете, задают положение всплывающего окна в координатах экрана. Вызовы me.getX() и me.getY() дают вам координаты мыши относительно контейнера. Когда вы перемещаете всплывающее окно, контейнер также перемещается, поэтому положение мыши изменилось относительно контейнера. Таким образом, ваши вычисления не будут согласованы с одним событием перетаскивания на другое.

Исправление состоит в том, чтобы вычислять позиции относительно неподвижного. Поскольку вы перемещаете всплывающее окно, которое является окном, фиксированная система координат является системой координат экрана. MouseEvent имеет методы getScreenX и getScreenY, которые вы можете использовать, чтобы их легко получить.

Мне нравится выполнять перетаскивание, сохраняя последнее местоположение мыши, а затем вычисляя расстояние, перемещаемое при перетаскивании. Существуют и другие (возможно, менее подробные) способы сделать это, но для меня это яснее:

import javafx.application.Application; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.geometry.Point2D; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Popup; 
import javafx.stage.Stage; 

public class DraggingPopup extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     Button button = new Button("Show popup"); 
     button.setOnAction(event -> showDraggablePopup(primaryStage)); 
     StackPane root = new StackPane(button); 
     Scene scene = new Scene(root, 250, 75); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private void showDraggablePopup(Stage owner) { 
     Popup popup = new Popup(); 
     Button closeButton = new Button("Close"); 
     closeButton.setOnAction(event -> popup.hide()); 
     StackPane container = new StackPane(closeButton); 
     container.setStyle("-fx-background-color: steelblue;"); 
     container.setMinWidth(300); 
     container.setMinHeight(125); 

     // Dragging implementation: 

     ObjectProperty<Point2D> mouseLocation = new SimpleObjectProperty<>(); 

     container.setOnMousePressed(event -> 
      mouseLocation.set(new Point2D(event.getScreenX(), event.getScreenY()))); 

     container.setOnMouseDragged(event -> { 
      if (mouseLocation.get() != null) { 
       double x = event.getScreenX(); 
       double deltaX = x - mouseLocation.get().getX() ; 
       double y = event.getScreenY(); 
       double deltaY = y - mouseLocation.get().getY() ; 
       //in case of 2 or more computer screens this help me to avoid get stuck on 1 screen 
       if(Math.abs(popup.getX()-x)>popup.getWidth()){ 
        popup.setX(x); 
        popup.setY(y); 
       }else { 
       popup.setX(popup.getX() + deltaX); 
       popup.setY(popup.getY() + deltaY); 
       } 
       mouseLocation.set(new Point2D(x, y)); 
      } 
     }); 

     container.setOnMouseReleased(event -> mouseLocation.set(null)); 

     popup.getScene().setRoot(container); 
     popup.show(owner); 
    } 

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

Это работает очень хорошо, у меня есть еще один вопрос о всплывающем окне. На данный момент возможно, что PopUp может выйти из основной сцены ... Возможно ли связать PopUp на главной сцене. Нельзя оставлять окно основного этапа ... Есть ли решение для него, я много пробовал, но я не знаю, как я могу решить эту проблему. –

+0

Просто проверьте положение основного этапа, его ширины и высоты, а также ширины и высоты всплывающего окна перед перемещением. –

+0

Спасибо за ваш ответ, нет встроенной автоматической функции? Я должен решить проблему с математикой? –