5

JavaFX 2.2プロジェクトに取り組んでおり、TreeItemでマウス(ダブル)クリックイベントのカスタム処理を設定したいと思います。treeview.setOnMouseClickedを使用すると、エラーなしでコードが起動されますが、問題は、TreeItemがマウスをダブルクリックするたびに、展開と折りたたみが切り替わるということです。これがデフォルトの動作だと思いますが、どうすれば無効にできますか?

4

2 に答える 2

4

私は同じ問題を抱えていて、を使用して時間内にそれを解決しました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));
        }
      }
    };
  }
}
于 2014-01-12T11:23:57.643 に答える
2

ボルグの答えは機能しますが、それは厳密には「正しい」方法ではなく、予期しない動作を引き起こす可能性があることがわかりました。

この問題の原因は、このバグで説明されています。要約すると、ツリーセルのデフォルトのダブルクリック動作は、実際にはマウスプレスイベントによって引き起こされるため、イベントを消費してマウスクリックリスナー内でブロックするには遅すぎます。

受け入れられた回答が機能する理由は、マウスイベントタイプをフィルタリングしないためです。つまり、プライマリボタンと2回のクリックカウントに関連するすべてのマウスイベントを消費します。これは、ユーザーアクションが3回処理されることも意味しますが、これはおそらく意図された動作ではありません。

修正はBolgの答えに対する1行の変更にすぎませんが、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();
    }
});
于 2016-09-01T15:09:58.990 に答える