通过容器和组件迭代/递归以查找给定类的对象? [英] Iterate / recurse through Containers and Components to find objects of a given class?
问题描述
我为JLabels和AbstractButtons编写了一个MnemonicsBuilder类。我想编写一个方便的方法 setMnemonics(JFrame f)
,它将遍历JFrame的每个子节点并选择JLabel和AbstractButtons。如何获取对JFrame中包含的所有内容的访问权限?我试过了:
I've written a MnemonicsBuilder class for JLabels and AbstractButtons. I would like to write a convenience method setMnemonics( JFrame f )
that will iterate through every child of the JFrame and select out the JLabels and AbstractButtons. How can I obtain access to everything contained in the JFrame? I've tried:
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;
}
在某些情况下,这很好用。在其他情况下,它耗尽内存。我没想到什么?有没有更好的方法来搜索子组件?我的递归有缺陷吗?这不是Swing中包含其他东西的图片 - 例如,Swing不是Root Tree吗?
In some situations, this works just fine. In others, it runs out of memory. What am I not thinking of? Is there a better way to search for child components? Is my recursion flawed? Is this not a picture of how things "Contain" other things in Swing - e.g., is Swing not a Rooted Tree?
JFrame
|
|\__JMenuBar
| |
| \__JMenu
| |
| \__JMenuItem
|
|\__JPanel
| |
| |\__JButton
| |
| |\__JLabel
| |
| |\__ ... JCheckBoxes, other AbstractButtons, etc.
推荐答案
在这里同意Tom ...你的问题是你已经通过了 List
来添加 JLabel
s到你的递归方法,你也返回它 - 因此不止一次将相同的项添加到你的列表中。在政治上更正确的术语 - 列表
是你的累加器。
Agree with Tom here... Your problem is that you're already passing the List
to add the JLabel
s down to your recursive method AND you're also returning it - thus adding the same items to your list more than once. In more politically correct terms - the List
is your accumulator.
您的方法应该如下所示:
Your method should instead look like this:
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));
}
}
}
然后你可以有一个帮手启动此收获的方法:
Then you can have a helper method to initiate this harvesting:
public List<JLabel> harvestJLabels(Container c) {
List<JLabel> jLabels = new ArrayList<JLabel>();
harvestJLabels(c, jLabels);
return jLabels;
}
这篇关于通过容器和组件迭代/递归以查找给定类的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!