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();
}
}