Java 如何知道JComponent是何时添加到它的&x27;谁的父母?

Java 如何知道JComponent是何时添加到它的&x27;谁的父母?,java,swing,jcomponent,Java,Swing,Jcomponent,首先,创建JComponent实例JComponent。然后将其添加到其父级,如parent.add(jComponent)。现在我想知道在jComponent类中,它被添加到它的父级。有可能吗 目标是在已将jComponentparent添加到其父级时设置它,如: Container window = getParent(); while (!(window instanceof JWindow)) { window = window.getParent

首先,创建
JComponent
实例
JComponent
。然后将其添加到其父级,如
parent.add(jComponent)。现在我想知道在
jComponent
类中,它被添加到它的父级。有可能吗

目标是在已将
jComponent
parent添加到其父级时设置它,如:

Container window = getParent();
        while (!(window instanceof JWindow)) {
            window = window.getParent();
        }
JWindow parent = (JWindow) window;
所以答案是:

public class MyComponent extends JComponent {

   private JWindow parent;

   //(...)

   @Override
   public void addNotify() {
     parent = (JWindow) SwingUtilities.getAncestorOfClass(JWindow.class, getParent());
     super.addNotify();
   }

}
或者我们可以:

   @Override
   public void addNotify() {
     parent = (JWindow) SwingUtilities.getWindowAncestor(this);
     super.addNotify();
   }
不知道哪种更好,看起来第二种方法更简单。

使用

javax.swing.SwingUtilities.getWindowAncestor(yourComponent)
它返回组件添加到的窗口,如果未添加到窗口,则返回null

当然,如果您将组件添加到JPanel,而JPanel尚未添加到窗口中,则上述方法将返回null


在这种情况下,其中一条注释更好:component.getParent()将为您提供包含组件的容器(如果存在)。

您可能正在查找
AncestorListener
,如图所示。
setVisible(true)
调用源或其祖先之一时,或将其添加到组件层次结构中时,将“调用源或其祖先之一”。

根据您的需要,有多种选择

如果您想知道任何现有组件何时添加到父级,可以向其添加HierarchyListener,并侦听在组件添加到父级后发送的事件类型

例如:

component.addHierarchyListener(new HierarchyListener() {

  @Override
  public void hierarchyChanged(HierarchyEvent e) {
    if ( (e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {
      if (getParent() == e.getChangedParent()) {
         System.out.println("*** Added to parent " + e.getChangedParent());
      }
    }
  }
});
如果已经在创建自定义组件,则可以重写“addNotify()”方法:


如果只想在组件可见后才了解父级,可以使用。每次组件可见时都将调用。例如,每当用户选择要显示的选项卡时,JTabbedPane中JPanel上的AncestorListener就会收到这样的事件。

那么
jComponent.getParent()呢null
?但它可能是某个侦听器?您可以重写addNotify方法。但是你一定要打电话给super.addNotify,我真的不知道。我认为你必须自己写一篇听众文章,但要等待其他的答案/评论,看看这是否是你所想的唯一方法want@Petr哇,太棒了,这是100%的答案:)谢谢!已测试。重写addNotify会起作用,但您必须像上面那样创建一个子类。如果要使用现有组件而不创建子类,则只需使用HierarchyListener接口。是的,它也可以工作,经过测试:),但与重写
addNotify()
相比,代码更大。这取决于是否创建子类。无论如何,可以简化用于确定所属JWindow的代码。您不需要“while”循环:parent=(JWindow)SwingUtilities.getAncestorOfClass(JWindow.class,getParent())@谢谢你,这种方法确实是一流的,经过测试的。我已经更改了上面的答案。也按照@GerritCap建议进行了测试:
SwingUtilities.getWindowSencenter(此)的工作原理相同。看起来更好吗?AncestorListener让您知道每次组件由于层次结构中发生的事情而变得可见时。例如,如果它是JTabbedPane的子级,则每次该选项卡可见时都会调用ancestorAdded()。如果您只想知道组件何时添加到其父级,而不考虑当前的可见性,那么可以使用HierarchyListener。对,但我不确定问题中是否有足够的信息可供选择。你为什么不展开你的答案&我将删除我的答案。我也尝试了
AncestorListener
,效果很好,但是
AncestorEvent
只有在父项设置为可见时才会发生。重写
addNotify()
时,即使父项不可见,也会在将子项添加到父项后立即调用它。所以我更喜欢
addNotify()
,因为我可以在对话框可见之前创建它——当用户单击某个按钮时,它会打开得更快一点。
@Override public void addNotify() {
  super.addNotify();
  // do something here with getParent();
}