Die Iteration / Rekursion durch Container und Komponenten zum Auffinden von Objekten einer bestimmten Klasse?
Ich habe eine schriftliche MnemonicsBuilder Klasse für JLabels und AbstractButtons. Ich möchte schreiben, eine bequeme Methode setMnemonics( JFrame f )
wird Durchlaufen und jedes Kind von den JFrame und wählen Sie aus den JLabels und AbstractButtons. Wie erhalte ich Zugriff auf alles, was enthalten ist in dem JFrame? Ich habe versucht:
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;
}
In manchen Situationen, das funktioniert gut. In anderen, es läuft out of memory. Was soll ich nicht denken? Gibt es einen besseren Weg, um die Suche für untergeordnete Bauteile? Ist mein Rekursion fehlerhaft? Ist das nicht ein Bild, wie die Dinge "Sind" andere Sachen in Swing - z.B., Swing ist nicht ein Verwurzelter Baum?
JFrame
|
|\__JMenuBar
| |
| \__JMenu
| |
| \__JMenuItem
|
|\__JPanel
| |
| |\__JButton
| |
| |\__JLabel
| |
| |\__ ... JCheckBoxes, other AbstractButtons, etc.
- +1 für die schöne ASCII-Baum
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einverstanden mit Tom hier... Ihr problem ist, dass Sie bereits bei übergabe der
List
zum hinzufügen vonJLabel
s bis zu Ihrem rekursiven Methode UND Sie sind auch wieder - so addieren sich die gleichen Elemente, um Ihre Liste mehr als einmal. In mehr politisch korrekte Begriffe - dieList
ist Ihr Akku.Ihre Methode sollte stattdessen wie folgt Aussehen:
Dann kannst du eine helper-Methode zum initiieren dieser Ernte:
Hier ist dein problem:
Haben Sie nur eine einzige Liste. Sie werden Anhängen einer Liste an eine andere Liste. Deshalb sind Sie hinzufügen einer Liste auf sich selbst. Das kann funktionieren, in gewissem Sinne, aber Sie gehen zu müssen, eine Verdoppelung der Länge (exponentielles Wachstum).
Entweder eine einzelne
List
(in der Regel gibt es keine Notwendigkeit, einen Algorithmus angeben, der in Deklarationen) oder erstellen Sie eine neue list-Instanz jedes mal, wenn die Methode aufgerufen wird. Vermeiden Rückgabe einer Referenz, die Sie nicht brauchen, um - es ist nur irreführend.Auch
ArrayList
wäre passender alsLinkedList
.LinkedList
ist fast immer die falsche Wahl.Was, wenn Sie hatte zwei Komponenten, jede von Ihnen hatte eine der anderen Komponenten der Sammlung? Es würde infinetly recurse durch Sie hinzufügen zu Ihrer Sammlung.
Haben, könnten Sie einen Zirkelbezug irgendwo, dass ist vielleicht nicht so offensichtlich oder einfach als das, was ich beschrieben habe. Ich bin nicht vertraut mit JFrame, also ich bin mir nicht sicher, ob dies möglich ist.
Wenn Sie diese Art von Sache, die Sie brauchen könnten, "besucht" - Eigenschaft der einige Sortieren, so dass Sie markieren können Objekte besucht, und, wenn dies nicht der rekursive Aufruf auf Sie.
Können Sie versuchen, Sie zu entfernen Rekursion zur Freigabe des arrays von Komponenten:
Einem anderen utility-Methode stehen auf den Schultern von anderen, wie @Moritz und @Cem:
und rufen Sie es mit etwas wie:
oder
Obwohl ich auch wie die Swing-Fest-Ansatz durch die Verwendung org.fest.swing.core.GenericTypeMatcher