diff --git a/src/main/java/app/termora/SwingUtils.java b/src/main/java/app/termora/SwingUtils.java
new file mode 100644
index 0000000..eef1f14
--- /dev/null
+++ b/src/main/java/app/termora/SwingUtils.java
@@ -0,0 +1,433 @@
+package app.termora;/*
+ * @(#)SwingUtils.java 1.02 11/15/08
+ *
+ */
+//package darrylbu.util;
+
+import javax.swing.*;
+import java.awt.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.*;
+
+/**
+ * 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)
+ throws IllegalArgumentException {
+ 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)
+ throws IllegalArgumentException {
+ 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)
+ throws IllegalArgumentException {
+ 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)
+ throws IllegalArgumentException {
+ List list = getDescendantsOfClass(clazz, container, nested);
+ return getComponentFromList(clazz, list, property, value);
+ }
+
+ private static T getComponentFromList(Class clazz,
+ List list, String property, Object value)
+ throws IllegalArgumentException {
+ 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