2014-11-21 36 views
0

我有一些代碼可以讓我拖動一個StackPane的實例。該代碼在JavaFX v2.2中正常工作,但StackPane保持默認位置,並且不會在JavaFX v8中移動。爲什麼我的JavaFX應用程序的拖動例程在JavaFX 8中中斷?

下面是代碼:

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"); 
     } 
    }); 
} 

我試過只是硬編碼作爲測試,也不能重新定位窗格的位置更新。如果有人有任何想法,即使有絲毫的想法,我也想嘗試一下。我一直堅持這幾天。謝謝。

回答

2

我沒有時間用代碼的錯誤創建一個完整的示例。因此,這裏是我自己的例子之一,擴展了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背景風格,以看看是否有處於關閉狀態。

0

長話短說,聽衆的處理方式在FX2.2和FX8.0之間變化。在我刪除並反對現場並添加另一個之前。在FX2.2中,對象不會被垃圾收集,但在FX8.0中出現它(當它是時,拖動例程凍結)。通過在拖動開始時執行交換而不是刪除原始對象,引用保持不變,然後可以在拖動完成處理程序中銷燬原始對象。