通过容器和组件迭代/递归以查找给定类的对象?

P. *_*ore 3 java recursion swing

我为JLabels和AbstractButtons编写了一个MnemonicsBuilder类.我想编写一个方便的方法setMnemonics( JFrame f ),它将迭代JFrame的每个子节点并选择JLabel和AbstractButtons.如何获取对JFrame中包含的所有内容的访问权限?我试过了:

LinkedList<JLabel> harvestJLabels( Container c, LinkedList<JLabel> l ) {
    Component[] components = c.getComponents();
    for( Component com : components )
    {
        if( com instanceof JLabel )
        {
            l.add( (JLabel) com );
        } else if( com instanceof Container )
        {
            l.addAll( harvestJLabels( (Container) com, l ) );
        }
    }
    return l;
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,这很好用.在其他情况下,它耗尽内存.我没想到什么?有没有更好的方法来搜索子组件?我的递归有缺陷吗?这不是Swing中"包含"其他东西的图​​片 - 例如,Swing不是Root Tree吗?

JFrame
|
|\__JMenuBar
|   |
|    \__JMenu
|       |
|        \__JMenuItem
|
|\__JPanel
|   |
|   |\__JButton 
|   |
|   |\__JLabel
|   |
|   |\__ ... JCheckBoxes, other AbstractButtons, etc.
Run Code Online (Sandbox Code Playgroud)

Cem*_*kas 5

在这里同意Tom ...你的问题是你已经传递了ListJLabels 添加到你的递归方法而你也将它返回 - 因此不止一次将相同的项添加到你的列表中.在政治上更正确的术语 - List是你的累积者.

你的方法应该是这样的:

public void harvestJLabels(Container c, List<JLabel> l) {
    Component[] components = c.getComponents();
    for(Component com : components) {
        if(com instanceof JLabel) {
            l.add((JLabel) com);
        } else if(com instanceof Container) {
            harvestJLabels((Container) com, l));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以有一个辅助方法来启动这个收获:

public List<JLabel> harvestJLabels(Container c) {
    List<JLabel> jLabels = new ArrayList<JLabel>();
    harvestJLabels(c, jLabels);
    return jLabels;
}
Run Code Online (Sandbox Code Playgroud)