SwingRecursionUtil

import javax.swing.*;

import java.awt.*;

public class SwingRecursionUtil {

public static void recurseComponents(JComponent root, Recursor recursor) {

if (root == null) {

return;

}

int numChildren = root.getComponents().length;

recursor.in(numChildren);

int current;

for (int i = 0; i < numChildren; i++) {

current = i+1;

Component component = root.getComponents()[i];

recursor.workOn(current, numChildren, component);

if (component instanceof JComponent) {

recurseComponents((JComponent) component, recursor);

recursor.out(current, numChildren);

}

}

}

public static interface Recursor {

void workOn(int itemNumber, int numItems, Component c);

/**

* Called when recursion takes a step "in" to a set of children

* @param numChildren # of children

*/

void in(int numChildren);

/**

* Called when recursion takes a step back "out" of a set of children

* @param itemNumber What you just finished work on

* @param numItems Number of items in the set to which you are returning

*/

void out(int itemNumber, int numItems);

}

public static class RecursorAdapter implements Recursor {

public void workOn(int itemNumber, int numItems, Component c) {}

public void in(int numChildren) {}

public void out(int itemNumber, int numItems) {}

}

// ==========================================================================================

// Usage example

// ==========================================================================================

public static void printComponentTree(JComponent root) {

recurseComponents(root, new Recursor() {

int depth = 0;

int numSpaces = 0;

int backToItemNumber = 0;

int backToNumItems = 0;

int numChildren = 0;

public void workOn(int itemNumber, int numItems, Component c) {

System.out.println(t() + "+-[" + itemNumber + "]" + getShortClassName(c.getClass().getName()));

System.out.println(d() + "Bounds : " + c.getBounds());

if (!c.isVisible()) {

System.out.println(d() + "Visible: " + c.isVisible());

}

System.out.println(d() + "Bckgrnd: " + (c.isOpaque() ? c.getBackground() : "Not opaque"));

if (c.getName() != null && c.getName().length() > 0) {

System.out.println(d() + "Name : " + c.getName());

}

if (c instanceof JPanel) {

System.out.println(d() + "Layout : " + ((JPanel) c).getLayout());

}

if (c instanceof JComponent) {

if (((JComponent) c).getBorder() != null) {

System.out.println(d() + "Border : " + ((JComponent) c).getBorder());

}

if (((JComponent) c).getComponentCount() > 0) {

System.out.println(d() + "#Kids : " + ((JComponent) c).getComponentCount());

}

}

if (c instanceof JLabel) {

System.out.println(d() + "Text : " + ((JLabel) c).getText());

}

}

public void in(int numChildren) {

depth++;

this.numChildren = numChildren;

}

public void out(int itemNumber, int numItems) {

depth--;

backToItemNumber = itemNumber;

backToNumItems = numItems;

}

private String t() {

return strings(" ", depth - 1);

}

private String d() {

return strings(" ", depth - 1) + "| ";

}

});

}

/**

* <p>Gets the class name minus the package name from a String.</p>

* <p/>

* <p>The string passed in is assumed to be a class name - it is not checked.</p>

*

* @param className the className to get the short name for

* @return the class name of the class without the package name or an empty string

*/

public static String getShortClassName(String className) {

if (className == null) {

return "";

}

if (className.length() == 0) {

return "";

}

char[] chars = className.toCharArray();

int lastDot = 0;

for (int i = 0; i < chars.length; i++) {

if (chars[i] == '.') {

lastDot = i + 1;

}

else if (chars[i] == '$') {// handle inner classes

chars[i] = '.';

}

}

return new String(chars, lastDot, chars.length - lastDot);

}

/**

* @return a String of param string, repeated repetitions times

*/

public static String strings(String string, int repetitions) {

StringBuilder buf = new StringBuilder();

for (int i = 0; i < repetitions; i++) {

buf.append(string);

}

return buf.toString();

}

}