001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: KiwiUtils.java,v $ 023 Revision 1.23 2004/05/12 18:03:42 markl 024 javadoc updates 025 026 Revision 1.22 2004/05/05 21:22:45 markl 027 Comment header updates. 028 029 Revision 1.21 2004/05/05 18:33:49 markl 030 added randomInt() 031 032 Revision 1.20 2004/03/16 06:37:29 markl 033 Removed deprecated methods. 034 035 Revision 1.19 2004/03/10 00:51:27 markl 036 added getWindowForCompnent() method 037 038 Revision 1.18 2003/11/07 19:17:59 markl 039 Added setFonts() and set*LookAndFeel() methods. 040 041 Revision 1.17 2003/01/19 09:42:39 markl 042 Javadoc & comment header updates. 043 044 Revision 1.16 2002/03/08 21:36:39 markl 045 Fixed NullPointerException in paintImmediately() 046 047 Revision 1.15 2001/08/28 21:37:33 markl 048 Split out stream methods into their own class. 049 050 Revision 1.14 2001/03/12 05:43:34 markl 051 Javadoc cleanup. 052 053 Revision 1.13 2001/03/12 02:57:40 markl 054 Source code cleanup. 055 056 Revision 1.12 2000/10/15 09:33:08 markl 057 Minor fixes to window positioning code. 058 059 Revision 1.11 1999/11/15 03:43:39 markl 060 Replaced some public members with accessors. 061 062 Revision 1.10 1999/08/05 14:37:45 markl 063 Added printWindow() method. 064 065 Revision 1.9 1999/07/19 03:58:56 markl 066 Added bounds checking in centerWindow(). 067 068 Revision 1.8 1999/06/28 08:19:08 markl 069 Added Font constants. 070 071 Revision 1.7 1999/06/14 00:51:41 markl 072 Removed second form of paintImmediately() method; it didn't work reliably. 073 074 Revision 1.6 1999/04/25 03:33:14 markl 075 Added new form of paintImmediately() for JComponents. 076 077 Revision 1.5 1999/04/19 05:31:42 markl 078 Added some useful Insets constants. 079 080 Revision 1.4 1999/03/11 07:51:31 markl 081 Added another form of cascadeWindow(). 082 083 Revision 1.3 1999/02/28 00:37:23 markl 084 Added yet another form of centerWindow(). 085 086 Revision 1.2 1999/01/10 03:47:05 markl 087 added GPL header & RCS tag 088 ---------------------------------------------------------------------------- 089*/ 090 091package kiwi.util; 092 093import java.awt.*; 094import java.awt.datatransfer.*; 095import java.io.*; 096import java.util.Random; 097import javax.swing.*; 098import javax.swing.border.EmptyBorder; 099 100import kiwi.ui.AboutFrame; 101 102/** This class consists of several convenience routines and constants, 103 * all of which are static. 104 * 105 * @author Mark Lindner 106 */ 107 108public final class KiwiUtils 109 { 110 private static Random _rand = new Random(System.currentTimeMillis()); 111 112 /** The data transfer block size. */ 113 public static final int blockSize = 4096; 114 115 /** A phantom Frame. */ 116 private static Frame phantomFrame = null; 117 118 /** Empty insets (zero pixels on all sides). */ 119 public static final Insets emptyInsets = new Insets(0, 0, 0, 0); 120 121 /** A default Kiwi border (empty, 5 pixels on all sides). */ 122 public static final EmptyBorder defaultBorder = new EmptyBorder(5, 5, 5, 5); 123 124 /** A default Kiwi border (empty, 0 pixels on all sides). */ 125 public static final EmptyBorder emptyBorder = new EmptyBorder(0, 0, 0, 0); 126 127 /** Predefined insets for first component on first or subsequent lines. 128 * Defines 5 pixels of space to the right and below. 129 */ 130 public static final Insets firstInsets = new Insets(0, 0, 5, 5); 131 132 /** Predefined insets for last component on first or subsequent lines. 133 * Defines 5 pixels of space below. 134 */ 135 public static final Insets lastInsets = new Insets(0, 0, 5, 0); 136 137 /** Predefined insets for first component on last line. 138 * Defines 5 pixels of space to the right. 139 */ 140 public static final Insets firstBottomInsets = new Insets(0, 0, 0, 5); 141 142 /** Predefined insets for last component on last line. 143 * Defines no pixels of space. 144 */ 145 public static final Insets lastBottomInsets = emptyInsets; 146 147 /** The root of the filesystem. */ 148 public static final File filesystemRoot 149 = new File(System.getProperty("file.separator")); 150 151 /** A default bold font. */ 152 public static final Font boldFont = new Font("Dialog", Font.BOLD, 12); 153 154 /** A default plain font. */ 155 public static final Font plainFont = new Font("Dialog", Font.PLAIN, 12); 156 157 /** A default italic font. */ 158 public static final Font italicFont = new Font("Dialog", Font.ITALIC, 12); 159 160 /** An origin point: (0,0) */ 161 public static final Point origin = new Point(0, 0); 162 163 private static Cursor lastCursor 164 = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 165 private static Clipboard clipboard = null; 166 private static ResourceManager resmgr = null; 167 private static AboutFrame aboutFrame = null; 168 169 private KiwiUtils() { } 170 171 /** Paint a component immediately. Paints a component immediately (as opposed 172 * to queueing a repaint request in the event queue.) 173 * 174 * @param c The component to repaint. 175 */ 176 177 public static final void paintImmediately(Component c) 178 { 179 Graphics gc = c.getGraphics(); 180 if(gc != null) 181 { 182 c.paint(gc); 183 gc.dispose(); 184 } 185 } 186 187 /** Cascade a window off of a parent window. Moves a window a specified 188 * number of pixels below and to the right of another window. 189 * 190 * @param parent The parent window. 191 * @param w The window to cascade. 192 * @param offset The number of pixels to offset the window by 193 * vertically and horizontally. 194 */ 195 196 public static final void cascadeWindow(Window parent, Window w, int offset) 197 { 198 _cascadeWindow(parent, w, offset, offset); 199 } 200 201 /** Cascade a window off of a parent window. Moves a window a specified 202 * number of pixels below and to the right of another window. 203 * 204 * @param parent The parent window. 205 * @param w The window to cascade. 206 * @param offsetx The number of pixels to offset the window by horizontally. 207 * @param offsety The number of pixels to offset the window by vertically. 208 */ 209 210 public static final void cascadeWindow(Window parent, Window w, int offsetx, 211 int offsety) 212 { 213 _cascadeWindow(parent, w, offsetx, offsety); 214 } 215 216 /** Cascade a window off of a parent window. Moves a window 40 pixels below 217 * and to the right of another window. 218 * 219 * @param parent The parent window. 220 * @param w The window to cascade. 221 */ 222 223 public static final void cascadeWindow(Window parent, Window w) 224 { 225 _cascadeWindow(parent, w, 40, 40); 226 } 227 228 /** Cascade a window off of a component's parent window. 229 * 230 * @param w The window to cascade. 231 * @param c The component off whose parent window this window should be 232 * cascaded. If a window cannot be found in the component hierarchy above 233 * <code>c</code>, the window is centered on the screen. 234 */ 235 236 public static final void cascadeWindow(Component c, Window w) 237 { 238 Window pw = SwingUtilities.windowForComponent(c); 239 240 if(pw == null) 241 KiwiUtils.centerWindow(w); 242 else 243 KiwiUtils.cascadeWindow(pw, w); 244 } 245 246 /* common window cascading code */ 247 248 private static void _cascadeWindow(Window parent, Window w, int offsetx, 249 int offsety) 250 { 251 Dimension s_size, w_size; 252 Point loc = parent.getLocation(); 253 loc.translate(offsetx, offsety); 254 255 _positionWindow(w, loc.x, loc.y); 256 } 257 258 /** Center a window on the screen. 259 * 260 * @param w The window to center. 261 */ 262 263 public static final void centerWindow(Window w) 264 { 265 Dimension s_size, w_size; 266 int x, y; 267 268 s_size = w.getToolkit().getScreenSize(); 269 w_size = w.getSize(); 270 271 x = (s_size.width - w_size.width) / 2; 272 y = (s_size.height - w_size.height) / 2; 273 274 _positionWindow(w, x, y); 275 } 276 277 /* 278 * Make sure no part of the window is off-screen. 279 */ 280 281 private static final void _positionWindow(Window w, int x, int y) 282 { 283 Dimension s_size, w_size; 284 285 s_size = w.getToolkit().getScreenSize(); 286 w_size = w.getSize(); 287 288 int xe = (x + w_size.width) - s_size.width; 289 int ye = (y + w_size.height) - s_size.height; 290 291 if(xe > 0) 292 x -= xe; 293 if(ye > 0) 294 y -= ye; 295 296 w.setLocation(x, y); 297 } 298 299 /** Center a window within the bounds of another window. 300 * 301 * @param w The window to center. 302 * @param parent The window to center within. 303 */ 304 305 public static final void centerWindow(Window parent, Window w) 306 { 307 Dimension p_size, w_size, s_size; 308 int x, y; 309 310 p_size = parent.getSize(); 311 w_size = w.getSize(); 312 s_size = w.getToolkit().getScreenSize(); 313 Point p_loc = parent.getLocationOnScreen(); 314 315 x = ((p_size.width - w_size.width) / 2) + p_loc.x; 316 y = ((p_size.height - w_size.height) / 2) + p_loc.y; 317 318 // If placing the window at (x,y) would make part if it off-screen, 319 // then center it in the middle of the screen instead. 320 321 if(((x + w_size.width) > s_size.width) || (x < 0) 322 || ((y + w_size.height) > s_size.height) || (y < 0)) 323 centerWindow(w); 324 else 325 w.setLocation(x, y); 326 } 327 328 /** Center a window within the bounds of a component's parent window. 329 * 330 * @param w The window to center. 331 * @param c The component within whose parent window this window should be 332 * centered. If a window cannot be found in the component hierarchy above 333 * <code>c</code>, the window is centered on the screen. 334 */ 335 336 public static final void centerWindow(Component c, Window w) 337 { 338 Window pw = SwingUtilities.windowForComponent(c); 339 340 if(pw == null) 341 KiwiUtils.centerWindow(w); 342 else 343 KiwiUtils.centerWindow(pw, w); 344 } 345 346 /** Turn on a busy cursor. 347 * 348 * @param c The component whose cursor will be changed. 349 */ 350 351 public static final void busyOn(Component c) 352 { 353 lastCursor = c.getCursor(); 354 c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 355 } 356 357 /** Turn off the busy cursor. The last cursor saved will be restored. 358 * 359 * @param c The component whose cursor will be changed. 360 */ 361 362 public static final void busyOff(Component c) 363 { 364 c.setCursor(lastCursor); 365 } 366 367 /** Get the Frame parent of a component. This method searches upward in the 368 * component hierarchy, searching for an ancestor that is a Frame. 369 */ 370 371 public static final Frame getFrameForComponent(Component c) 372 { 373 while((c = c.getParent()) != null) 374 if(c instanceof Frame) 375 return((Frame)c); 376 377 return(null); 378 } 379 380 /** Get the Window parent of a component. This method searches upward in the 381 * component hierarchy, searching for an ancestor that is a Frame. 382 * 383 * @since Kiwi 2.0 384 */ 385 386 public static final Window getWindowForComponent(Component c) 387 { 388 while((c = c.getParent()) != null) 389 if(c instanceof Window) 390 return((Window)c); 391 392 return(null); 393 } 394 395 /** Print a hardcopy of the contents of a window. 396 * 397 * @param window The window to print. 398 * @param title A title for the print job. 399 * 400 * @return <code>true</code> if the print job was started, or 401 * <code>false</code> if the user cancelled the print dialog. 402 */ 403 404 public static final boolean printWindow(Window window, String title) 405 { 406 PrintJob pj = Toolkit.getDefaultToolkit() 407 .getPrintJob(getPhantomFrame(), title, null); 408 409 if(pj == null) 410 return(false); 411 412 int res = Toolkit.getDefaultToolkit().getScreenResolution(); 413 Dimension d = pj.getPageDimension(); // buggy in JDK 1.1.x 414 //Dimension d = new Dimension((int)(2 * res * 8.5), (int)(res * 11 * 2)); 415 416 d.width -= (int)(res * 0.75 /*in*/); 417 d.height -= (int)(res * 0.75 /*in*/); 418 419 Graphics gc = pj.getGraphics(); 420 window.paint(gc); 421 422 gc.dispose(); 423 pj.end(); 424 return(true); 425 } 426 427 /** Get a reference to the system clipboard. 428 * 429 * @return The clipboard. 430 */ 431 432 public static final Clipboard getClipboard() 433 { 434 if(clipboard == null) 435 clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 436 437 return(clipboard); 438 } 439 440 /** Copy text to the system clipboard. 441 * 442 * @param text The text to copy to the clipboard. 443 */ 444 445 public static synchronized final void setClipboardText(String text) 446 { 447 StringSelection sel = new StringSelection(text); 448 getClipboard().setContents(sel, sel); 449 } 450 451 /** Copy text from the system clipboard. 452 * 453 * @return The text that is in the clipboard, or <code>null</code> if the 454 * clipboard is empty or does not contain plain text. 455 */ 456 457 public static synchronized final String getClipboardText() 458 { 459 try 460 { 461 return((String)(getClipboard().getContents(Void.class) 462 .getTransferData(DataFlavor.stringFlavor))); 463 } 464 catch(Exception ex) 465 { 466 return(null); 467 } 468 } 469 470 /** Get a reference to the internal resource manager singleton. The Kiwi 471 * Toolkit has a small built-in collection of textures, icons, audio clips, 472 * and HTML files. 473 */ 474 475 public static final ResourceManager getResourceManager() 476 { 477 if(resmgr == null) 478 resmgr = new ResourceManager(kiwi.ResourceAnchor.class); 479 480 return(resmgr); 481 } 482 483 /** Suspend the calling thread. Suspends the calling thread, returning 484 * immediately if an exception occurs. 485 * 486 * @param sec The number of seconds to sleep. 487 */ 488 489 public static final void sleep(int sec) 490 { 491 try 492 { 493 Thread.currentThread().sleep(sec * 1000); 494 } 495 catch(InterruptedException ex) 496 { 497 } 498 } 499 500 /** Get a reference to a phantom frame. 501 * 502 * @return The phantom frame. 503 */ 504 505 public static final Frame getPhantomFrame() 506 { 507 if(phantomFrame == null) 508 phantomFrame = new Frame(); 509 510 return(phantomFrame); 511 } 512 513 /** Get an instance to a prebuilt about window that describes the Kiwi 514 * Toolkit itself. 515 */ 516 517 public static final AboutFrame getKiwiAboutFrame() 518 { 519 if(aboutFrame == null) 520 aboutFrame = new AboutFrame("About Kiwi", 521 getResourceManager().getURL("kiwi.html")); 522 523 return(aboutFrame); 524 } 525 526 /** Recursively delete files in a directory. Deletes all files and 527 * subdirectories in the given directory. 528 * 529 * @param parent The parent (presumed to be a directory) of the files to 530 * be deleted. The parent is not deleted. 531 * 532 * @return The number of files and directories deleted. 533 */ 534 535 public static final int deleteTree(File parent) 536 { 537 int ct = 0; 538 539 if(!parent.isDirectory()) return(0); 540 541 String files[] = parent.list(); 542 for(int i = 0; i < files.length; i++) 543 { 544 File f = new File(parent.getAbsolutePath(), files[i]); 545 546 if(f.isDirectory()) 547 ct += deleteTree(f); 548 549 f.delete(); 550 ct++; 551 } 552 553 return(ct); 554 } 555 556 /** 557 * Recursively set the font on a container and all of its descendant 558 * components. 559 * 560 * @param container The container. 561 * @param font The new font. 562 * 563 * @since Kiwi 1.4.3 564 */ 565 566 public static void setFonts(Container container, Font font) 567 { 568 container.setFont(font); 569 570 Component[] components = container.getComponents(); 571 572 for(int i = 0; i < components.length; i++) 573 { 574 if(Container.class.isInstance(components[i])) 575 setFonts((Container)components[i], font); 576 else 577 components[i].setFont(font); 578 } 579 } 580 581 /** 582 * Set the default cross-platform Look and Feel 583 * 584 * @since Kiwi 1.4.3 585 */ 586 587 public static void setDefaultLookAndFeel() 588 { 589 try 590 { 591 UIManager.setLookAndFeel( 592 UIManager.getCrossPlatformLookAndFeelClassName()); 593 } 594 catch(Exception ex) { } 595 } 596 597 /** 598 * Set the native (system) Look and Feel 599 * 600 * @since Kiwi 1.4.3 601 */ 602 603 public static void setNativeLookAndFeel() 604 { 605 try 606 { 607 UIManager.setLookAndFeel( 608 UIManager.getSystemLookAndFeelClassName()); 609 } 610 catch(Exception ex) { } 611 } 612 613 /** 614 * @since Kiwi 2.0 615 */ 616 617 public static int randomInt(int range) 618 { 619 return(_rand.nextInt(range)); 620 } 621 622 } 623 624/* end of source file */