2010-04-25 2 views
2

Я собираю событие щелчка правой кнопкой мыши, чтобы отобразить контекстное меню. То, что я не смог выяснить, заключается в том, как сделать правый щелчок, фактически выбрав TreeItem, перед отображением контекстного меню.GWT: выберите TreeItem правой кнопкой мыши

Вся помощь приветствуется.

private Tree tree = new Tree() { 
    @Override 
    public void onBrowserEvent(Event event) { 
    if (event.getTypeInt() == Event.ONCONTEXTMENU) { 
    DOM.eventPreventDefault(event);   
    showContextMenu(event); 
    } 
    super.onBrowserEvent(event); 
    } 

    @Override 
    protected void setElement(Element elem) { 
    super.setElement(elem); 
    sinkEvents(Event.ONCONTEXTMENU); 
    } 

}; 

ответ

1

Событие ONMOUSEDOWN активируется до ONCONTEXTMENU. Вы пытались прослушивать события onMouseDown и задавать выбранный элемент? Что-то вдоль этих линий:

@Override 
public void onBrowserEvent(Event event) { 
switch (DOM.eventGetType(event)) { 
    case Event.ONMOUSEDOWN: 
     if (DOM.eventGetButton(event) == Event.BUTTON_RIGHT) { 
      TreeItem selectedItem = findSelectedItem(event); 
      if (selectedItem != null) { 
       selectedItem.setSelected(true); 
      } 
     } else { 
      super.onBrowserEvent(event); 
     } 
     break; 
    case Event.ONCONTEXTMENU: 
     showContextMenu(event); 
     break; 
    default: 
     super.onBrowserEvent(event); 
     break; 
    } 

и findSelectedItem обходит дерево в поисках выбранного элемента:

TreeItem findSelectedItem(Event e) { 
    return findSelectedItemRecursive(event.getClientX(), event.getClientY()); 
} 

TreeItem findSelectedTreeItemRecursive(TreeItem root, int x, int y) { 
    if (null == root) { 
     int count = getItemCount(); 
     for (int i = 0; i < count; i++) { 
      TreeItem selected = findSelectedTreeItemRecursive(getItem(i), x, y); 
      if (selected != null) { 
       return selected; 
      } 
     } 
     return null; 
    } 
    int count = item.getChildCount(); 
    for (int i = 0; i < count; i++) { 
     TreeItem selected = findSelectedTreeItem(item.getChild(i), x, y); 
     if (selected != null) { 
      return selected; 
     } 
    } 

    if (x >= item.getAbsoluteLeft() 
     && x <= item.getAbsoluteLeft() + item.getOffsetWidth() 
     && y >= item.getAbsoluteTop() 
     && y <= item.getAbsoluteTop() + item.getOffsetHeight()) { 
     return item; 
    } 
    return null; 
} 
1

Вы можете использовать посвященный перегруженный TreeItem:

public class MyTreeItem extends TreeItem implements ContextMenuHandler { 


    public SBTreeItem(SBItemTree tree, String name) { 
     super(); 
     Label w = new Label(name); 
     w.addDomHandler(this, ContextMenuEvent.getType()); 
     setWidget(w); 
    } 

      public void onContextMenu(ContextMenuEvent event) { 
     Window.alert(getSBItem().getName()); 
     event.getNativeEvent().stopPropagation(); 

    } 

    } 
0

Я знаю, что это старый вопрос, но, надеюсь, вот ответ, который позволит сэкономить время, чтобы массы попали на эту страницу из поиска Google. ИМО, лучший способ - использовать собственный код поиска дерева дерева Google - это решение, которое очень хорошо масштабируется с количеством элементов в дереве. I с использованием GWT 2.5.1.

private void initTree() { 
    tree = new Tree() { 

     @Override 
     public void onBrowserEvent(Event event) { 
      /* 
      * If the event is a context menu event, we want the tree item 
      * to also be selected. 
      * 
      * This logic must occur before the call to the superclass 
      * method so the selection is updated before the context menu 
      * logic executes. This is useful when we want to make items in 
      * the context menu invisible/disabled based on the selection. 
      */ 
      if (DOM.eventGetType(event) == Event.ONCONTEXTMENU) { 
       if (getItemCount() > 0) { 
        // In my use case there is only 1 top-level tree item 
        TreeItem root = getItem(0); 

        // Taken from com.google.gwt.user.client.ui.Tree.elementClicked(Element): 
        ArrayList<Element> chain = new ArrayList<Element>(); 
        collectElementChain(chain, getElement(), DOM.eventGetTarget(event)); 

        TreeItem selection = findItemByChain(chain, 0, root); 

        /* 
        * For some reason SelectionEvent will only fire if 
        * selection is non-null; I am firing the selection 
        * event manually because I want to know when there has 
        * been a deselection of an item in the tree. 
        */ 
        if (selection != null) { 
         this.setSelectedItem(selection); 
        } else { 
         SelectionEvent.fire(this, null); 
        } 
       } 
      } 

      super.onBrowserEvent(event); 
     } 

    }; 

    tree.setAnimationEnabled(true); 
} 


//// BEGIN code copied from com.google.gwt.user.client.ui.Tree: 

/** 
* Collects parents going up the element tree, terminated at the tree root. 
*/ 
private void collectElementChain(ArrayList<Element> chain, Element hRoot, 
     Element hElem) { 
    if ((hElem == null) || (hElem == hRoot)) { 
     return; 
    } 

    collectElementChain(chain, hRoot, DOM.getParent(hElem)); 
    chain.add(hElem); 
} 

private TreeItem findItemByChain(ArrayList<Element> chain, int idx, 
     TreeItem root) { 
    if (idx == chain.size()) { 
     return root; 
    } 

    Element hCurElem = chain.get(idx); 
    for (int i = 0, n = root.getChildCount(); i < n; ++i) { 
     TreeItem child = root.getChild(i); 
     if (child.getElement() == hCurElem) { 
      TreeItem retItem = findItemByChain(chain, idx + 1, 
        root.getChild(i)); 
      if (retItem == null) { 
       return child; 
      } 
      return retItem; 
     } 
    } 

    return findItemByChain(chain, idx + 1, root); 
} 

//// END 
Смежные вопросы