2014-02-05 156 views
1

我有这个简单的方法,使拖动节点:鼠标拖动没有被按下?

private void setNodeDraggable(final Node node) { 
    EventHandler<MouseEvent> dragHandler = new EventHandler<MouseEvent>() { 
     private Point2D dragAnchor; 
     @Override public void handle(MouseEvent event) { 
      EventType<? extends MouseEvent> type = event.getEventType(); 

      if (type == MOUSE_PRESSED) { 
       dragAnchor = new Point2D(event.getSceneX(), event.getSceneY()); 
      } else if (type == MOUSE_DRAGGED) { 
       try { 
        stage.setX(event.getScreenX() - dragAnchor.getX()); 
        stage.setY(event.getScreenY() - dragAnchor.getY()); 
       } catch (Exception e) { ///catch all to track the occasional exception 
        LOG.error("in setNodeDraggable: {},{},{}", stage, event, dragAnchor); 
       } 
      } 
     } 
    }; 
    node.setOnMouseDragged(dragHandler); 
    node.setOnMousePressed(dragHandler); 
} 

但是异常是从时间抛出时间在try块和日志显示dragAnchor为空。

据我所见,唯一的解释是MOUSE_DRAGGED已被检测到,没有相应的事先MOUSE_PRESSED事件。

这怎么可能?我应该改变什么吗?

+0

用JavaFX 2.2.45在win8上测试你的代码。没有例外。您还应该指定您的JavaFX环境和版本。 –

+0

@UlukBiy感谢您的尝试。我只是偶尔得到异常,而不是每次 - 我在Win7 x64上使用Java 8 b119运行它。 – assylias

+0

我在JavaFX 2.2.45和Java 8 b123上都试过,并且无法生成异常。我尝试着对另一个组件进行全面拖拽,看看是否有所作为。也许看看你是否可以创建一个完整的(但很短)的例子来说明问题。也许也尝试创建一个ObjectProperty 作为你的dragAnchor;那么您可以为mousePressed和mouseDragged创建不同的处理程序,但也可以通过dragAnchor注册一个侦听器来查看它何时更改。 –

回答

0

您可以尝试其他方法。我建议,当你编写JavaFX程序时,你更多地关注JavaFX库。忘记旧标准。我知道这看起来很激进,但JavaFX库提供了开发丰富应用程序所需的一切。

正如我告诉过你,关于你的问题,我可以为你提供另一种方法。我不知道这是否会符合你的喜好,但它是一种非常实用的方法。我的方法是创建两个类。一个将作为一个实用工具类,并使节点的逻辑运动,另一个将成为你的主要类。我们先来看看主要的课程。在主类中,我们可以找到一个使任何节点都可移动的方法。我们利用在想要变为可移动的节点上添加两个事件。请看:

protected void makeMovable(final Node node) 
{ 
    node.addEventHandler(MouseEvent.MOUSE_PRESSED , new EventHandler<MouseEvent>() 
    { 
     @Override public void handle(MouseEvent e) 
     { 
      // Just move node if the mouse button is the left button. 
      if(e.getButton() == MouseButton.PRIMARY) 
      { 
       NodeUtil.pressNode(node , e); 
      }    
     } 
    }); 

    node.addEventHandler(MouseEvent.MOUSE_DRAGGED , new EventHandler<MouseEvent>() 
    { 
     @Override public void handle(MouseEvent e) 
     { 
      // Just move node if the mouse button is the left button. 
      if(e.getButton() == MouseButton.PRIMARY) 
      { 
       NodeUtil.moveNode(node , e); 
      } 
     } 
    }); 
} 

在这段代码中,你可以看到,它只是添加处理程序的某些类型上makeMovable方法节点参数事件。节点对象的真实运动的逻辑可以在NodeUtil类中找到:

public final class NodeUtil 
{ 
    private static double dist_x = 0; 
    private static double dist_y = 0; 

    private NodeUtil(){} 

    public static void pressNode(final Node node , final MouseEvent e) 
    { 
     dist_x = e.getSceneX() - node.getLayoutX(); 
     dist_y = e.getSceneY() - node.getLayoutY(); 
    } 

    public static void moveNode(final Node node , final MouseEvent e) 
    { 
     node.setLayoutX(e.getSceneX() - dist_x); 
     node.setLayoutY(e.getSceneY() - dist_y); 
    } 
} 

基本上就是这样。你现在必须做的就是在你的应用程序中使用这些代码。如果您仍然有关于代码逻辑的问题,或者遇到问题,请添加评论,我会帮助您。

我希望这对你有用。祝你的项目好运。 ;)

+0

谢谢你的回答 - 但说实话我没有看到它与我的方法有什么不同:你已经在一个单独的类中重构了pressNode/moveNode方法,但逻辑似乎与我很相似。 – assylias

+0

当我们和其他用户无法访问您的源代码时,很难指出问题。许多用户甚至评论说,他们在运行应用程序时没有得到异常。如果引入的代码最终会向您显示一些异常,我只能断定您应该更新您正在使用的JDK。 – Loa