1

我有一个向用户显示设置的弹出窗口。如果您在外部单击,它会隐藏,但如果您在内部单击,它仍然可见。

处理此行为的事件处理程序获取Component(被单击),并且通过component.getParent()递归使用,我可以检查它是否是我的设置面板的子项。到目前为止,这已经奏效。

但是我只是JComboBox在该面板中添加了一个,结果发现“可选项目弹出窗口”(它有名称吗?)单击时显示的组合框不是组合框的子项。尝试在组合框中选择某些内容会隐藏我的设置面板。

使用 NetBeans 调试器,我可以看到它的类型BasicComboPopup$1(那是一个匿名类吗?),但它不是既不是ComboPopupJPopupMenu也不是BasicComboPopup

我需要一种方法来识别单击的“组合框弹出窗口”的所有者/父组合框。

4

2 回答 2

5

不完全确定,但您可能正在寻找

 popup.getInvoker();

这将返回调用组合框。

下面的实用方法(从 SwingXUtilities 中复制,它是 SwingX 框架附带的):如果您找到了事件的源组件(不幸的是,方法中的命名是 focusOwner ;-),它会检查该源是否在父级下方的某个位置,包括弹出窗口.

只是注意到你的父母是一个弹出窗口,所以你必须稍微调整逻辑,切换第一个和第二个 if 块(虽然没有尝试 - 有多个可见弹出窗口是不寻常的。:-)

/**
 * 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;
}
于 2012-08-24T12:18:23.327 回答
1
  1. 不确定你是否在谈论

    • mouse事件

    • keyboard事件

    • mousekeyboard事件

  2. 看看SwingUtilities有用于childvs的方法,parent反之亦然

  3. 发布SSCCE,详细描述所需事件,因为有几种方法可以提取和修改PopupfromJComboBox

编辑

如果您使用AWT PopupSwing lightweightAWT heavyweight组件混合,那么您必须查看Darryl 的 Swing Utils

于 2012-08-24T11:51:56.210 回答