org.bidib.wizard.darrylbu.util.SwingUtils Maven / Gradle / Ivy
Show all versions of bidibwizard-client Show documentation
/*
* @(#)SwingUtils.java 1.02 11/15/08
*
*/
package org.bidib.wizard.darrylbu.util;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
/**
* A collection of utility methods for Swing.
*
* @author Darryl Burke
*/
public final class SwingUtils {
private SwingUtils() {
throw new Error("SwingUtils is just a container for static methods");
}
/**
* Convenience method for searching below container
in the component hierarchy and return nested
* components that are instances of class clazz
it finds. Returns an empty list if no such components
* exist in the container.
*
* Invoking this method with a class parameter of JComponent.class will return all nested components.
*
* This method invokes getDescendantsOfType(clazz, container, true)
*
* @param clazz
* the class of components whose instances are to be found.
* @param container
* the container at which to begin the search
* @return the List of components
*/
public static List getDescendantsOfType(Class clazz, Container container) {
return getDescendantsOfType(clazz, container, true);
}
/**
* Convenience method for searching below container
in the component hierarchy and return nested
* components that are instances of class clazz
it finds. Returns an empty list if no such components
* exist in the container.
*
* Invoking this method with a class parameter of JComponent.class will return all nested components.
*
* @param clazz
* the class of components whose instances are to be found.
* @param container
* the container at which to begin the search
* @param nested
* true to list components nested within another listed component, false otherwise
* @return the List of components
*/
public static List getDescendantsOfType(
Class clazz, Container container, boolean nested) {
List tList = new ArrayList();
for (Component component : container.getComponents()) {
if (clazz.isAssignableFrom(component.getClass())) {
tList.add(clazz.cast(component));
}
if (nested || !clazz.isAssignableFrom(component.getClass())) {
tList.addAll(SwingUtils. getDescendantsOfType(clazz, (Container) component, nested));
}
}
return tList;
}
/**
* Convenience method that searches below container
in the component hierarchy and returns the first
* found component that is an instance of class clazz
having the bound property value. Returns
* {@code null} if such component cannot be found.
*
* This method invokes getDescendantOfType(clazz, container, property, value, true)
*
* @param clazz
* the class of component whose instance is to be found.
* @param container
* the container at which to begin the search
* @param property
* the className of the bound property, exactly as expressed in the accessor e.g. "Text" for getText(),
* "Value" for getValue().
* @param value
* the value of the bound property
* @return the component, or null if no such component exists in the container
* @throws java.lang.IllegalArgumentException
* if the bound property does not exist for the class or cannot be accessed
*/
public static T getDescendantOfType(
Class clazz, Container container, String property, Object value) {
return getDescendantOfType(clazz, container, property, value, true);
}
/**
* Convenience method that searches below container
in the component hierarchy and returns the first
* found component that is an instance of class clazz
and has the bound property value. Returns
* {@code null} if such component cannot be found.
*
* @param clazz
* the class of component whose instance to be found.
* @param container
* the container at which to begin the search
* @param property
* the className of the bound property, exactly as expressed in the accessor e.g. "Text" for getText(),
* "Value" for getValue().
* @param value
* the value of the bound property
* @param nested
* true to list components nested within another component which is also an instance of
* clazz
, false otherwise
* @return the component, or null if no such component exists in the container
* @throws java.lang.IllegalArgumentException
* if the bound property does not exist for the class or cannot be accessed
*/
public static T getDescendantOfType(
Class clazz, Container container, String property, Object value, boolean nested) {
List list = getDescendantsOfType(clazz, container, nested);
return getComponentFromList(clazz, list, property, value);
}
/**
* Convenience method for searching below container
in the component hierarchy and return nested
* components of class clazz
it finds. Returns an empty list if no such components exist in the
* container.
*
* This method invokes getDescendantsOfClass(clazz, container, true)
*
* @param clazz
* the class of components to be found.
* @param container
* the container at which to begin the search
* @return the List of components
*/
public static List getDescendantsOfClass(Class clazz, Container container) {
return getDescendantsOfClass(clazz, container, true);
}
/**
* Convenience method for searching below container
in the component hierarchy and return nested
* components of class clazz
it finds. Returns an empty list if no such components exist in the
* container.
*
* @param clazz
* the class of components to be found.
* @param container
* the container at which to begin the search
* @param nested
* true to list components nested within another listed component, false otherwise
* @return the List of components
*/
public static List getDescendantsOfClass(
Class clazz, Container container, boolean nested) {
List tList = new ArrayList();
for (Component component : container.getComponents()) {
if (clazz.equals(component.getClass())) {
tList.add(clazz.cast(component));
}
if (nested || !clazz.equals(component.getClass())) {
tList.addAll(SwingUtils. getDescendantsOfClass(clazz, (Container) component, nested));
}
}
return tList;
}
/**
* Convenience method that searches below container
in the component hierarchy in a depth first manner
* and returns the first found component of class clazz
having the bound property value.
*
* Returns {@code null} if such component cannot be found.
*
* This method invokes getDescendantOfClass(clazz, container, property, value, true)
*
* @param clazz
* the class of component to be found.
* @param container
* the container at which to begin the search
* @param property
* the className of the bound property, exactly as expressed in the accessor e.g. "Text" for getText(),
* "Value" for getValue(). This parameter is case sensitive.
* @param value
* the value of the bound property
* @return the component, or null if no such component exists in the container's hierarchy.
* @throws java.lang.IllegalArgumentException
* if the bound property does not exist for the class or cannot be accessed
*/
public static T getDescendantOfClass(
Class clazz, Container container, String property, Object value) {
return getDescendantOfClass(clazz, container, property, value, true);
}
/**
* Convenience method that searches below container
in the component hierarchy in a depth first manner
* and returns the first found component of class clazz
having the bound property value.
*
* Returns {@code null} if such component cannot be found.
*
* @param clazz
* the class of component to be found.
* @param container
* the container at which to begin the search
* @param property
* the className of the bound property, exactly as expressed in the accessor e.g. "Text" for getText(),
* "Value" for getValue(). This parameter is case sensitive.
* @param value
* the value of the bound property
* @param nested
* true to include components nested within another listed component, false otherwise
* @return the component, or null if no such component exists in the container's hierarchy
* @throws java.lang.IllegalArgumentException
* if the bound property does not exist for the class or cannot be accessed
*/
public static T getDescendantOfClass(
Class clazz, Container container, String property, Object value, boolean nested) {
List list = getDescendantsOfClass(clazz, container, nested);
return getComponentFromList(clazz, list, property, value);
}
private static T getComponentFromList(
Class clazz, List list, String property, Object value) {
T retVal = null;
Method method = null;
try {
method = clazz.getMethod("get" + property);
}
catch (NoSuchMethodException ex) {
try {
method = clazz.getMethod("is" + property);
}
catch (NoSuchMethodException ex1) {
throw new IllegalArgumentException("Property " + property + " not found in class " + clazz.getName());
}
}
try {
for (T t : list) {
Object testVal = method.invoke(t);
if (equals(value, testVal)) {
return t;
}
}
}
catch (InvocationTargetException ex) {
throw new IllegalArgumentException("Error accessing property " + property + " in class " + clazz.getName());
}
catch (IllegalAccessException ex) {
throw new IllegalArgumentException("Property " + property + " cannot be accessed in class "
+ clazz.getName());
}
catch (SecurityException ex) {
throw new IllegalArgumentException("Property " + property + " cannot be accessed in class "
+ clazz.getName());
}
return retVal;
}
/**
* Convenience method for determining whether two objects are either equal or both null.
*
* @param obj1
* the first reference object to compare.
* @param obj2
* the second reference object to compare.
* @return true if obj1 and obj2 are equal or if both are null, false otherwise
*/
public static boolean equals(Object obj1, Object obj2) {
return obj1 == null ? obj2 == null : obj1.equals(obj2);
}
/**
* Convenience method for mapping a container in the hierarchy to its contained components. The keys are the
* containers, and the values are lists of contained components.
*
* Implementation note: The returned value is a HashMap and the values are of type ArrayList. This is subject to
* change, so callers should code against the interfaces Map and List.
*
* @param container
* The JComponent to be mapped
* @param nested
* true to drill down to nested containers, false otherwise
* @return the Map of the UI
*/
public static Map> getComponentMap(JComponent container, boolean nested) {
HashMap> retVal = new HashMap>();
for (JComponent component : getDescendantsOfType(JComponent.class, container, false)) {
if (!retVal.containsKey(container)) {
retVal.put(container, new ArrayList());
}
retVal.get(container).add(component);
if (nested) {
retVal.putAll(getComponentMap(component, nested));
}
}
return retVal;
}
/**
* Convenience method for retrieving a subset of the UIDefaults pertaining to a particular class.
*
* @param clazz
* the class of interest
* @return the UIDefaults of the class
*/
public static UIDefaults getUIDefaultsOfClass(Class> clazz) {
String name = clazz.getName();
name = name.substring(name.lastIndexOf(".") + 2);
return getUIDefaultsOfClass(name);
}
/**
* Convenience method for retrieving a subset of the UIDefaults pertaining to a particular class.
*
* @param className
* fully qualified name of the class of interest
* @return the UIDefaults of the class named
*/
public static UIDefaults getUIDefaultsOfClass(String className) {
UIDefaults retVal = new UIDefaults();
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
List> listKeys = Collections.list(defaults.keys());
for (Object key : listKeys) {
if (key instanceof String && ((String) key).startsWith(className)) {
String stringKey = (String) key;
String property = stringKey;
if (stringKey.contains(".")) {
property = stringKey.substring(stringKey.indexOf(".") + 1);
}
retVal.put(property, defaults.get(key));
}
}
return retVal;
}
/**
* Convenience method for retrieving the UIDefault for a single property of a particular class.
*
* @param clazz
* the class of interest
* @param property
* the property to query
* @return the UIDefault property, or null if not found
*/
public static Object getUIDefaultOfClass(Class> clazz, String property) {
Object retVal = null;
UIDefaults defaults = getUIDefaultsOfClass(clazz);
List