Coverage Report - net.wotonomy.ui.swing.util.WindowUtilities
 
Classes in this File Line Coverage Branch Coverage Complexity
WindowUtilities
0% 
0% 
2.95
 
 1  
 /*
 2  
 Wotonomy: OpenStep design patterns for pure Java applications.
 3  
 Copyright (C) 2000 Michael Powers
 4  
 
 5  
 This library is free software; you can redistribute it and/or
 6  
 modify it under the terms of the GNU Lesser General Public
 7  
 License as published by the Free Software Foundation; either
 8  
 version 2.1 of the License, or (at your option) any later version.
 9  
 
 10  
 This library is distributed in the hope that it will be useful,
 11  
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 Lesser General Public License for more details.
 14  
 
 15  
 You should have received a copy of the GNU Lesser General Public
 16  
 License along with this library; if not, see http://www.gnu.org
 17  
 */
 18  
 
 19  
 package net.wotonomy.ui.swing.util;
 20  
 
 21  
 import java.awt.Component;
 22  
 import java.awt.Container;
 23  
 import java.awt.Dialog;
 24  
 import java.awt.Dimension;
 25  
 import java.awt.Point;
 26  
 import java.awt.Toolkit;
 27  
 import java.awt.Window;
 28  
 import java.util.ArrayList;
 29  
 import java.util.Collection;
 30  
 import java.util.Collections;
 31  
 import java.util.HashMap;
 32  
 import java.util.Iterator;
 33  
 import java.util.List;
 34  
 import java.util.Map;
 35  
 
 36  
 /**
 37  
 * A collection of window-related utilities.
 38  
 *
 39  
 * @author michael@mpowers.net
 40  
 * @author $Author: cgruber $
 41  
 * @version $Revision: 904 $
 42  
 * $Date: 2006-02-18 23:19:05 +0000 (Sat, 18 Feb 2006) $
 43  
 *
 44  
 */
 45  0
 public class WindowUtilities
 46  
 {
 47  
 
 48  
 /**
 49  
 * Place frame at center (vertically and horizontally) of screen.
 50  
 */
 51  
     public static final int CENTER = 0;
 52  
 
 53  
 /**
 54  
 * Center dialog on frame area of parent, if any.
 55  
 */
 56  
     public static final int CENTER_PARENT = 1;
 57  
 
 58  
 /**
 59  
 * Place lower and to the right of the last window
 60  
 * placed in this manner.  Will wrap to top and left
 61  
 * of screen as necessary.
 62  
 */
 63  
     public static final int CASCADE = 10;
 64  
 
 65  
     // cascade state
 66  0
     private static int lastX = 0;
 67  0
     private static int lastY = 0;
 68  0
     private static int incrementX = 20;
 69  0
     private static int incrementY = 20;
 70  
 
 71  
 /**
 72  
 * Place the window in the center of the screen.
 73  
 * Note: don't forget to first set the size of your window.
 74  
 * This is a convenience method and simply calls place() with
 75  
 * the CENTER parameter.
 76  
 * @param aWindow The window to be centered.
 77  
 * @see #place
 78  
 */
 79  
     public static void center( Window aWindow )
 80  
     {
 81  0
         place( aWindow, CENTER );
 82  0
     }
 83  
 
 84  
 /**
 85  
 * Place lower and to the right of the last window
 86  
 * placed in this manner.  Will wrap to top and left
 87  
 * of screen as necessary.
 88  
 * This is a convenience method and simply calls place() with
 89  
 * the CASCADE parameter.
 90  
 * @param aWindow The window to be cascaded.
 91  
 * @see #place
 92  
 */
 93  
     public static void cascade( Window aWindow )
 94  
     {
 95  0
         place( aWindow, CASCADE );
 96  0
     }
 97  
 
 98  
 /**
 99  
 * Place the window in the specified location.
 100  
 * Note: don't forget to first set the size of your window.
 101  
 * @param aWindow The window to be placed.
 102  
 * @param location Where on screen to place the frame.
 103  
 */
 104  
     public static void place( Window aWindow, int location)
 105  
     {
 106  0
         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
 107  0
         Dimension mySize = aWindow.getSize();
 108  0
         int x = (aWindow.getLocation()).x;
 109  0
         int y = (aWindow.getLocation()).y;
 110  0
         float aspectRatio = (float)screenSize.height/(float)screenSize.width;
 111  
 
 112  
         // hack to make windows appear on left monitor if dual monitor
 113  
         // if aspect ratio is less than 0.6, assume dual monitor
 114  0
         if (aspectRatio < 0.6)
 115  
         {
 116  0
             screenSize.width = screenSize.width/2;
 117  
         }
 118  
 
 119  0
         switch (location)
 120  
         {
 121  
           case CENTER_PARENT:
 122  0
                   if ( ( ! ( aWindow instanceof Dialog ) )
 123  0
                   ||  ( ((Dialog)aWindow).getParent() == null ) )
 124  
 //1.2                  ||  ( ((Dialog)aWindow).getOwner() == null ) )
 125  
                   {
 126  0
                     place( aWindow, CENTER );
 127  0
                     return;
 128  
                   }
 129  0
                   Point parentLocation = (((Dialog)aWindow).getParent()).getLocation();
 130  
 //1.2 (((Dialog)aWindow).getOwner()).getLocation();
 131  0
                   Dimension parentSize = (((Dialog)aWindow).getParent()).getSize();
 132  
 
 133  
 //1.2                  Dimension parentSize = (((Dialog)aWindow).getOwner()).getSize();
 134  
 
 135  0
                   if (parentSize.width > mySize.width)
 136  
                   {
 137  0
                     x = ((parentSize.width - mySize.width)/2) + parentLocation.x;
 138  
                   }
 139  0
                   if (parentSize.height > mySize.height)
 140  
                   {
 141  0
                     y = ((parentSize.height - mySize.height)/2) + parentLocation.y;
 142  0
                   }
 143  0
                   break;
 144  
           case CENTER:
 145  0
                   if (screenSize.width > mySize.width)
 146  
                   {
 147  0
                     x = (screenSize.width - mySize.width)/2;
 148  
                   }
 149  0
                   if (screenSize.height > mySize.height)
 150  
                   {
 151  0
                     y = (screenSize.height - mySize.height)/2;
 152  0
                   }
 153  0
                   break;
 154  
           case CASCADE:
 155  0
                   x = lastX + incrementX;
 156  0
                   if ( x + mySize.width > screenSize.width )
 157  
                   {
 158  0
                     x = incrementX;
 159  
                   }
 160  0
                   y = lastY + incrementY;
 161  0
                   if ( y + mySize.height > screenSize.height )
 162  
                   {
 163  0
                     y = incrementY;
 164  
                   }
 165  0
                   lastX = x;
 166  0
                   lastY = y;
 167  0
                   break;
 168  
           default:
 169  
                   // don't move the frame
 170  0
                   Point p = aWindow.getLocation();
 171  0
                   x = p.x;
 172  0
                   y = p.y;
 173  
                   break;
 174  
         }
 175  0
         aWindow.setLocation(x,y);
 176  0
     }
 177  
 
 178  
 /**
 179  
  * Returns the first parent Window of the specified component.
 180  
  *
 181  
  * @param c the Component whose parent will be found.
 182  
  * @return the Window that contains the component,
 183  
  * or null if the component does not have a valid Frame parent.
 184  
  */
 185  
     public static Window getWindowForComponent(Component c)
 186  
     {
 187  0
         for(Component p = c; p != null; p = p.getParent()) {
 188  0
             if (p instanceof Window) {
 189  0
                 return (Window) p;
 190  
             }
 191  
         }
 192  0
         return null;
 193  
     }
 194  
 
 195  
 
 196  
 
 197  
 /**
 198  
 * Prints out a list of all components to System.out.
 199  
 * @param aContainer the Container whose components will be listed.
 200  
 */
 201  
     public static void dumpComponents( Container aContainer )
 202  
     {
 203  0
         dumpComponents( aContainer, "" );
 204  0
     }
 205  
 
 206  
     protected static void dumpComponents( Container aContainer, String padding )
 207  
     {
 208  0
         Component c = null;
 209  0
         int count = aContainer.getComponentCount();
 210  0
         for ( int i = 0; i < count; i++ )
 211  
         {
 212  0
             c = aContainer.getComponent( i );
 213  0
             if ( c instanceof javax.swing.JComponent )
 214  
             {
 215  0
                 System.out.println( padding + c.getClass() + ": "
 216  0
                     + ((javax.swing.JComponent)c).getAccessibleContext().getAccessibleName() );
 217  0
             }
 218  
             else
 219  
             {
 220  0
                 System.out.println( padding + c.getClass() + ": " + c.getName() );
 221  
             }
 222  0
             if ( c instanceof Container )
 223  
             {
 224  0
                 dumpComponents( (Container) c, padding + "     " );
 225  
             }
 226  
         }
 227  0
     }
 228  
 
 229  
 /**
 230  
 * Gets a list of all children of a specified container, sorted by position.
 231  
 * Components are sorted from top to bottom and then left to right.
 232  
 * @param aContainer The container whose children are to be returned.
 233  
 * @result A List containing the sorted components.
 234  
 */
 235  
     public static List getSortedChildComponents( Container aContainer )
 236  
     {
 237  0
         List result = new ArrayList( getAllChildComponents( aContainer ) );
 238  0
         Collections.sort( result, new PositionComparator( aContainer ) );
 239  0
         return result;
 240  
     }
 241  
 
 242  
     public static void dumpSortedChildComponents( Container aContainer )
 243  
     {
 244  0
         Component c = null;
 245  0
         Iterator it = getSortedChildComponents( aContainer ).iterator();
 246  0
         while ( it.hasNext() )
 247  
         {
 248  0
             c = (Component) it.next();
 249  0
             System.out.println( c.getLocation() + " : " + c.getClass()  );
 250  0
         }
 251  0
     }
 252  
 
 253  
     public static void dumpNamedChildComponents( Container aContainer )
 254  
     {
 255  0
         Iterator it = getUniqueNameMap( getSortedChildComponents( aContainer ) ).values().iterator();
 256  0
         while ( it.hasNext() )
 257  
         {
 258  0
             System.out.println( it.next() );
 259  0
         }
 260  0
     }
 261  
 
 262  
 /**
 263  
 * Generates a unique name for each object in a list and returns
 264  
 * a map that maps the objects to the names.  The name is based
 265  
 * on the class of the object in the object list.
 266  
 * @param anObjectList A List of objects.
 267  
 * @return A Map that maps the objects in the list to the generated names.
 268  
 */
 269  
     public static Map getUniqueNameMap( List anObjectList )
 270  
     {
 271  0
         Map namesToObjects = new HashMap(anObjectList.size(), 1F);
 272  0
         Map objectsToNames = new HashMap(anObjectList.size(), 1F);
 273  
 
 274  0
         Object o = null;
 275  0
         String name = null;
 276  0
         int lastIndex = 0;
 277  0
         Iterator it = anObjectList.iterator();
 278  0
         while ( it.hasNext() )
 279  
         {
 280  0
             o = it.next();
 281  0
             name = o.getClass().getName();
 282  0
             lastIndex = name.lastIndexOf( "." );
 283  0
             if ( lastIndex != -1 )
 284  
             {
 285  0
                 name = name.substring( lastIndex+1 );
 286  
             }
 287  0
             name = incrementString( name );
 288  0
             while ( namesToObjects.get( name ) != null )
 289  
             {
 290  0
                 name = incrementString( name );
 291  0
             }
 292  0
             namesToObjects.put( name, o );
 293  0
             objectsToNames.put( o, name );
 294  0
         }
 295  
 
 296  0
         return objectsToNames;
 297  
     }
 298  
 
 299  
 /**
 300  
 * Numerically increments a string.  For example, "hello" becomes "hello1"
 301  
 * and "hello1" becomes "hello2" while "hello999" becomes "hello1000".
 302  
 * @param aString a String to be incremented.
 303  
 * @return The incremented String.
 304  
 */
 305  
     public static String incrementString( String aString )
 306  
     {
 307  0
         int i = aString.length()-1;
 308  0
         while ( ( i >= 0 ) && ( Character.isDigit( aString.charAt( i ) ) ) )
 309  
         {
 310  0
             i--;
 311  0
         }
 312  
 
 313  0
         if ( i == aString.length()-1 )
 314  
         { // no numerics at end of string, increment manually
 315  0
             return aString + "1";
 316  
         }
 317  
 
 318  0
         String alpha = aString.substring( 0, i+1 );
 319  0
         String numeric = aString.substring( i+1 );
 320  0
         numeric = Integer.toString( Integer.parseInt( numeric ) + 1 );
 321  
 
 322  0
         return alpha + numeric;
 323  
 
 324  
     }
 325  
 
 326  
 /**
 327  
 * Gets all children of the specified container.
 328  
 * @param aContainer the Container to be searched.
 329  
 * @return A Collection containing all of the child components of the container.
 330  
 */
 331  
     public static Collection getAllChildComponents( Container aContainer )
 332  
     {
 333  0
         Collection result = new ArrayList();
 334  0
         addAllChildComponents( aContainer, result );
 335  0
         return result;
 336  
     }
 337  
 
 338  
 /**
 339  
 * Adds all children of the specified container to the specified collection.
 340  
 * @param aContainer the Container to be searched.
 341  
 * @param aCollection the Collection to which the child components will be added.
 342  
 */
 343  
     protected static void addAllChildComponents( Container aContainer, Collection aCollection )
 344  
     {
 345  0
         Component c = null;
 346  0
         int count = aContainer.getComponentCount();
 347  0
         for ( int i = 0; i < count; i++ )
 348  
         {
 349  0
             c = aContainer.getComponent( i );
 350  0
             aCollection.add( c );
 351  0
             if ( c instanceof Container )
 352  
             {
 353  0
                 addAllChildComponents( (Container) c, aCollection );
 354  
             }
 355  
         }
 356  0
     }
 357  
 
 358  
 /**
 359  
 * Sets each child component's tooltip to show the name generated from
 360  
 * getComponentNameMap(). 
 361  
 * (We're doing this so the tooltip authors can know how to reference
 362  
 * the components.)
 363  
 * @param aContainer the Container whose components will be labeled.
 364  
 */
 365  
     public static void labelComponents( Container aContainer )
 366  
     {
 367  0
         Map nameToComponent = getNameToComponentMap( aContainer );
 368  0
         Map nameToName = new HashMap(nameToComponent.size(), 1F);
 369  0
         Iterator it = nameToComponent.keySet().iterator();
 370  
         String key;
 371  0
         while ( it.hasNext() )
 372  
         {
 373  0
             key = it.next().toString();
 374  0
             nameToName.put( key, key );
 375  0
         }
 376  0
         labelComponents( aContainer, nameToName );
 377  0
     }
 378  
 
 379  
 /**
 380  
 * Sets each child component's tooltip to show a given string retrieved
 381  
 * from a map using the component's generated name as a key.
 382  
 * @param aContainer the Container whose components will be labeled.
 383  
 * @param aNameMap a Map of generated names to string values.
 384  
 */
 385  
     public static void labelComponents( Container aContainer, Map aNameMap )
 386  
     {
 387  0
         if ( aNameMap == null ) return;
 388  
 
 389  
         String key;
 390  
         Object o ;
 391  0
         Iterator it = aNameMap.keySet().iterator();
 392  0
         Map nameToComponent = getNameToComponentMap( aContainer );
 393  0
         while ( it.hasNext() )
 394  
         {
 395  0
             key = it.next().toString();
 396  0
             o = nameToComponent.get( key );
 397  0
             if ( o instanceof javax.swing.JComponent )
 398  
             {
 399  0
                 ((javax.swing.JComponent)o).setToolTipText( aNameMap.get( key ).toString() );
 400  0
             }
 401  
         }
 402  0
     }
 403  
 
 404  
 /**
 405  
 * Generates a deterministically unique name for each component in a
 406  
 * container.  The name is based on the name of the class of the component
 407  
 * followed by a number.  Each class of component is numbered based on it's
 408  
 * position in the container, sorted from top to bottom and left to right.
 409  
 * @param aContainer the Container whose components will named.
 410  
 * @return a Map that maps each component to its name.
 411  
 */
 412  
     public static Map getComponentToNameMap( Container aContainer )
 413  
     {
 414  0
         return getUniqueNameMap( getSortedChildComponents( aContainer ) );
 415  
     }
 416  
 
 417  
 /**
 418  
 * Maps a deterministically unique name to a component in a
 419  
 * container.  The name is based on the name of the class of the component
 420  
 * followed by a number.  Each class of component is numbered based on it's
 421  
 * position in the container, sorted from top to bottom and left to right.
 422  
 * @param aContainer the Container whose components will named.
 423  
 * @return a Map that maps each component to its name.
 424  
 */
 425  
     public static Map getNameToComponentMap( Container aContainer )
 426  
     {
 427  0
         Map componentToName = getComponentToNameMap( aContainer );
 428  0
         Map result = new HashMap(componentToName.size(), 1F);
 429  0
         Iterator it = componentToName.keySet().iterator();
 430  
         Object key;
 431  0
         while ( it.hasNext() )
 432  
         {
 433  0
             key = it.next();
 434  0
             result.put( componentToName.get( key ), key );
 435  0
         }
 436  0
         return result;
 437  
     }
 438  
 
 439  
 /**
 440  
 * Sets the tooltips of all components in a container to the
 441  
 * respective names of those components.  (We're using this
 442  
 * so the tooltip authors can know how to reference the components.)
 443  
 * @param aContainer the Container whose components will be labeled.
 444  
 */
 445  
     public static void nameComponents( Container aContainer )
 446  
     {
 447  0
         nameComponents( aContainer, "" );
 448  0
     }
 449  
 
 450  
     protected static void nameComponents( Container aContainer, String path )
 451  
     {
 452  0
         Component c = null;
 453  0
         String className = null;
 454  0
         int index = 0;
 455  0
         int count = aContainer.getComponentCount();
 456  0
         for ( int i = 0; i < count; i++ )
 457  
         {
 458  0
             c = aContainer.getComponent( i );
 459  0
             className = c.getClass().getName();
 460  0
             className = className.substring( className.lastIndexOf( '.' ) + 1 );
 461  0
             System.out.println( path + className );
 462  0
             if ( c instanceof javax.swing.JComponent )
 463  
             {
 464  
                 // ((javax.swing.JComponent)c).setToolTipText( path + className + " (" + c.getName() + ")" );
 465  0
                 ((javax.swing.JComponent)c).setToolTipText( c.getName() );
 466  
             }
 467  0
             if ( c instanceof Container )
 468  
             {
 469  0
                 nameComponents( (Container) c, path + className + "." );
 470  
             }
 471  
         }
 472  0
     }
 473  
 
 474  
 /**
 475  
 * Sets the enabled state of a container and all of its components.
 476  
 * @param aContainer the Container whose components will be enabled.
 477  
 * @param isEnabled True if enabled, false id disabled.
 478  
 */
 479  
     public static void enableComponents( Container aContainer, boolean isEnabled )
 480  
     {
 481  0
         Component c = null;
 482  0
         String className = null;
 483  0
         int index = 0;
 484  0
         int count = aContainer.getComponentCount();
 485  0
         for ( int i = 0; i < count; i++ )
 486  
         {
 487  0
             c = aContainer.getComponent( i );
 488  0
             if ( c instanceof Container )
 489  
             {
 490  0
                 enableComponents( (Container) c, isEnabled );
 491  0
             }
 492  
             else
 493  
             {
 494  0
                 c.setEnabled( isEnabled );
 495  
             }
 496  
         }
 497  0
         aContainer.setEnabled( isEnabled );
 498  0
     }
 499  
 
 500  
 }
 501  
 
 502  
 /*
 503  
  * $Log$
 504  
  * Revision 1.2  2006/02/18 23:19:05  cgruber
 505  
  * Update imports and maven dependencies.
 506  
  *
 507  
  * Revision 1.1  2006/02/16 13:22:22  cgruber
 508  
  * Check in all sources in eclipse-friendly maven-enabled packages.
 509  
  *
 510  
  * Revision 1.2  2001/02/17 16:52:05  mpowers
 511  
  * Changes in imports to support building with jdk1.1 collections.
 512  
  *
 513  
  * Revision 1.1.1.1  2000/12/21 15:51:55  mpowers
 514  
  * Contributing wotonomy.
 515  
  *
 516  
  * Revision 1.2  2000/12/20 16:25:46  michael
 517  
  * Added log to all files.
 518  
  *
 519  
  *
 520  
  */
 521