2013-03-19 70 views
3

我正在开发一个JavaFX 2.2项目,并且我想在TreeItem上设置自定义处理鼠标(双击)事件。使用treeview.setOnMouseClicked我激发我的代码没有错误,但问题是,TreeItem,每一次鼠标双击,它在展开和折叠之间切换。我想这是默认行为,但我如何禁用它?在双击时禁用TreeItem的默认展开/折叠JavaFX 2.2

+0

尝试看看论坛之前... [http://stackoverflow.com/a/10950824/2170935][1] [1]:http://stackoverflow.com/a/10950824/2170935 – Perco 2013-03-20 13:52:55

+0

我的问题是TreeItem的默认双击行为,而不是检测到鼠标单击事件。随着treeview.setOnMouseClicked我检测事件没有问题,但这不是我正在寻找。 TreeItem,双击时,默认情况下是扩展和折叠自己,这是我的问题。我想禁用它。 – 2013-03-20 16:49:39

回答

5

我有同样的问题,并及时解决它使用EventDispatcher

class TreeMouseEventDispatcher implements EventDispatcher { 
    private final EventDispatcher originalDispatcher; 

    public TreeMouseEventDispatcher(EventDispatcher originalDispatcher) { 
     this.originalDispatcher = originalDispatcher; 
    } 

    @Override 
    public Event dispatchEvent(Event event, EventDispatchChain tail) { 
     if (event instanceof MouseEvent) { 
      if (((MouseEvent) event).getButton() == MouseButton.PRIMARY 
       && ((MouseEvent) event).getClickCount() >= 2) { 

      if (!event.isConsumed()) { 
       // Implement your double-click behavior here, even your 
       // MouseEvent handlers will be ignored, i.e., the event consumed! 
      } 

      event.consume(); 
      } 
     } 
     return originalDispatcher.dispatchEvent(event, tail); 
    } 
} 

,然后用这个TreeMouseEventDispatcherTreeCell

treeView.setCellFactory(new Callback<TreeView<T>, TreeCell<T>>() { 
    @Override 
    public TreeCell<T> call(TreeView<T> param) { 
    return new TreeCell<T>() { 
     @Override 
     protected void updateItem(T item, boolean empty) { 
     if (item != null && !empty) { 
      EventDispatcher originalDispatcher = getEventDispatcher(); 
      setEventDispatcher(new TreeMouseEventDispatcher(originalDispatcher)); 
     } 
     } 
    }; 
    } 
} 
+0

谢谢 - 我也必须使用它! – CMerrill 2015-08-12 01:29:47

+0

这个答案只是偶然发生的!因为它以另一种方式被打破。我正在添加另一个解释该问题的答案。 – 2016-09-01 14:49:17

0

原来,虽然Bolg的答案的作品,它不是严格的“正确”的方式做到这一点,并可能导致一些意想不到的行为。

此问题的原因在this bug中描述。总结一下:树形单元的默认双击行为实际上是由鼠标按下事件引起的,因此消耗事件并在鼠标内阻止该事件已为时过晚单击侦听器。

接受答案的工作原理是它不会过滤鼠标事件类型,这意味着它消耗与主按钮有关的所有鼠标事件并且点击数为2。这也意味着用户操作被处理了三次,这可能不是预期的行为。

该修复仅对Bolg的答案进行了单行更改,但我认为最好不要涉及EventDispatcher。像下面这样的东西应该只是正常工作:

node.addEventHandler(MouseEvent.ANY, event -> { 
    if (event.getClickCount() == 2 && event.getButton().equals(MouseButton.PRIMARY)) { 
     if (event.getEventType().equals(MouseEvent.MOUSE_CLICKED)) { 
      System.out.println("hello"); // perform some action 
     } 

     event.consume(); 
    } 
});