javaswingawtjcomboboxjpopup

Find owner of combobox popup


I have a popup with settings displayed to the user. If you click outside it, its hidden but if you click inside it remains visible.

The event handler handling this behavior gets the Component (that was clicked) and by using component.getParent() recursively I can check if its a child of my settings panel. This has worked so far.

But I just added a JComboBox to that panel and it turns out that the "selectable items popup" (does it have a name?) the combobox shows when clicked isnt a child of the combobox. Attempting to select something in a combobox would hide my settings panel.

Using the NetBeans debugger I can see its of the type BasicComboPopup$1 (is that an anonymous class?), but it isn't an instance of neither ComboPopup, JPopupMenu nor BasicComboPopup.

I need a way to identify the owner/parent combobox of the "combobox popup" that was clicked.


Solution

  • not entirely sure, but you might be looking for

     popup.getInvoker();
    

    which would return the invoking comboBox.

    Below's utility method (copied from SwingXUtilities, which comes with the SwingX framework): given you found the source component (unfortunate naming in the method is focusOwner ;-) of an event, it checks whether that source is somehwhere below the parent, including popups.

    Just noticed that your parent is-a popup, so you have to adjust the logic a bit, switching the first and second if block (didn't try, though - it's unusual to have more than one visible popups. :-)

    /**
     * Returns whether the component is part of the parent's
     * container hierarchy. If a parent in the chain is of type 
     * JPopupMenu, the parent chain of its invoker is walked.
     * 
     * @param focusOwner
     * @param parent
     * @return true if the component is contained under the parent's 
     *    hierarchy, coping with JPopupMenus.
     */
    public static boolean isDescendingFrom(Component focusOwner, Component parent) {
        while (focusOwner !=  null) {
            if (focusOwner instanceof JPopupMenu) {
                focusOwner = ((JPopupMenu) focusOwner).getInvoker();
                if (focusOwner == null) {
                    return false;
                }
            }
            if (focusOwner == parent) {
                return true;
            }
            focusOwner = focusOwner.getParent();
        }
        return false;
    }