001/* 002 * MDIApplet.java 003 * Copyright (c) 2002 Tom B. Gutwin P.Eng. 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License 007 * as published by the Free Software Foundation; either version 2 008 * of the License, or any later version. 009 * 010 * This program 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 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 018 */ 019 020/* 021$Header: f:/cvsroot2/open/projects/WebARTS/ca/bc/webarts/MDIApplet.java,v 1.1 2002/07/11 06:17:23 tgutwin Exp $ 022 * 023$Log: MDIApplet.java,v $ 024Revision 1.1 2002/07/11 06:17:23 tgutwin 025Initial Revision 026 027Revision 1.4 2001/03/11 23:33:46 tgutwin 028Added the basics for creating the internal windows 029 030Revision 1.3 2001/03/03 07:30:44 tgutwin 031Added Button Processing logic & some general Cleanup 032 033Revision 1.2 2001/02/24 07:43:35 tgutwin 034Added CVS Header 035 036 */ 037/* Generic MDI app/let */ 038/* - Tom B. Gutwin - */ 039/* Copyright 2001 - WebARTS Design */ 040 041 042/* This program requires JVM 1.2 or at least JVM 1.1.5 with 043 * the Swing 1.1.1 components */ 044/* If building with the OS/2 JDK you must have at least 1.1.4 045 * with the 1.1.4 fixes */ 046 047package ca.bc.webarts; 048 049import ca.bc.webarts.widgets.Splash; 050import ca.bc.webarts.widgets.StatusBar; 051import ca.bc.webarts.widgets.AutoButtonBar; 052import ca.bc.webarts.widgets.JAboutBox; 053 054import java.awt.*; 055import java.awt.event.*; 056import java.awt.image.*; 057import java.net.*; 058import java.applet.*; 059import javax.swing.*; 060import java.lang.Class; 061import java.awt.event.ActionListener; 062import javax.swing.border.*; 063 064/** 065 * MDIApplet encapsulates a generic and extendable framework for a multiple 066 * desktop interface application. 067 * 068 * <P><B>This applet has a main() method so it can be directly called/started 069 * as an application.</B> 070 * 071 * <P>It contains all the basics of an <I>Multiple Document Interface (MDI)</I> 072 * windowing system with a Menubar at the top, a floatable toolbar, and a 073 * statusbar at the bottom. In the center of the applet is the main MDI Desktop. 074 * 075 * <P>New child windows all go into the main MDI Desktop panel and each contain 076 * a generic <code>Object</cose>. 077 * 078 * @author <A HREF="http://www.webarts.bc.ca">Tom Gutwin</A> 079 * 080 * @created December 13, 2000 081 */ 082public class MDIApplet extends JApplet implements ActionListener{ 083 084 /** 085 * Holds the line separator for the system this applet is running on. 086 */ 087 String lineSeperator = new String(System.getProperty("line.separator")); 088 089 /** 090 * Holds the file separator for the system this applet is running on. 091 */ 092 String fileSeperator = new String(System.getProperty("file.separator")); 093 094 /** 095 * The Toolkit object that is used to get some basic system information (ie screen size). 096 */ 097 Toolkit toolkit = Toolkit.getDefaultToolkit(); 098 099 /** 100 * String added to the iconNames used to auatomatically 101 * create the IconsBar 102 */ 103 String iconNamePrefix = "../images/20x20"; 104 105 /** 106 * String Tokens used to auatomatically create the IconsBar 107 */ 108 String iconNames[] = {"Exit.gif", "Open.gif", "Computer.gif", "Help.gif"}; 109 110 /** 111 * String Tokens used to auatomatically create the Icon bar tooltips 112 */ 113 String iconToolTips[] = {"Exit This App", "Open Something", "Computer??", "Help!"}; 114 115 /** 116 * String Tokens used to auatomatically create the menu bar 117 */ 118 String menuName[] = {"File", "View", "Properties", "Help"}; 119 120 /** 121 * String Tokens used to automatically create the menu items for each menu 122 * on the menubar. It is a 2D array of strings that will be used to create 123 * menuitems. If there are 4 menus... there will be 4 lists holding the 124 * words/Strings to use for the menu items. 125 */ 126 String menuItemName[][] = { 127 {"Open", "Save", "---", "Print...", "Print Preview", "---", "Close", "Exit"}, 128 {"Zoom In", "Zoom Out" }, 129 {"Set Debug Output Level...", "---", 130 "Java L&F", "Platform L&F", "Motif L&F" }, 131 {"Help", "---", "About MDIApplet..."}}; 132 133 /** 134 * The Tokens used to automatically assign the Mnemonic for each menu items. 135 * It is a 2D array of chars that will be used to assign the Mnemonic. 136 * If there are 4 menus... there will be 4 lists holding the chars to use 137 * as the Mnemonic for the menu items. 138 */ 139 char menuItemMnemonic[][] = { 140 {'o', 's', ' ', 'P', 'r', ' ', 'C', 'x'}, 141 {'I', 'O'}, 142 {'D', ' ', 'J', 'P', 'M'}, 143 {'H', ' ', 'A'}}; 144 145 /** 146 * The Tokens used when automatically assigning the accel key for each menu 147 * items. It is a 2D array of ints that will be used to assign the accel 148 * key constant. If there are 4 menus... there will be 4 lists holding the 149 * ints to use as the accel key constant value for the menu items. 150 */ 151 int menuItemAccel[][] = { 152 {KeyEvent.VK_O, KeyEvent.VK_S, 0, 153 KeyEvent.VK_A, KeyEvent.VK_B, 0, 154 KeyEvent.VK_W, KeyEvent.VK_Q}, 155 {0, 0 }, 156 {0, 0, 0, 0, 0}, 157 {KeyEvent.VK_F1, 0, KeyEvent.VK_F12}}; 158 159 /** 160 * The Tokens used when automatically assigning the 2nd level of accel key for 161 * each menu items. It is a 2D array of ints that will be used to assign the 162 * accel key constant. If there are 4 menus... there will be 4 lists holding 163 * the ints to use as the accel key constant value for the menu items. 164 */ 165 int menuItemAccel2[][] = { 166 {Event.CTRL_MASK, Event.CTRL_MASK, 0, Event.CTRL_MASK | Event.SHIFT_MASK, Event.CTRL_MASK | 167 Event.SHIFT_MASK, 0, Event.CTRL_MASK, Event.CTRL_MASK}, 168 {0, 0}, 169 {0, 0, 0, 0, 0}, 170 {0, 0, 0}}; 171 172 /** 173 * String Tokens used to automatically create the menu items tooltip for 174 * each menu on the menubar. It is a 2D array of strings that will be used 175 * to create menuitems tooltips. If there are 4 menus... there will be 4 176 * lists holding the words/Strings to use for the menu items tooltip. 177 */ 178 String menuToolTip[][] = {{"Open new window from File...", "Save Current Windows Output To File...", "---", "Print Current Authorization View", "Print Preview", "---", "Close Current Window", "Exit Application"}, 179 {"Zoom In", "Zoom Out"}, 180 {"Set Debug Output Level...", "---", "Set the User Interface to the Java-Metal L&F", "Set the User Interface to the Platform L&F", "Set the User Interface to the Motif L&F", "---", "Sets the 2nd Segment to be be designated as the START Segment", "Sets the 3rd Segment to be be designated as the START Segment"}, 181 {"Help On This Applet", "---", "About MDIApplet..."}}; 182 183 /** 184 * boolean Tokens used to enable automatic creation of the menu items for 185 * each menu on the menubar. It is a 2D array of booleans each one a flag 186 * directly refering to the menu item arrays already setup. If there are 4 187 * menus... there will be 4 lists holding the flags to use. If a value of 188 * false is specified the menu item will NOT get created. 189 */ 190 static boolean menuItemShown[][] = { 191 {true, true, true, true, true, true, true, true}, 192 {true, true}, 193 {true, true, true, true, true}, 194 {true, true, true}}; 195 196 /** 197 * boolean Tokens used to enable the menu items for each menu on the menubar. 198 * It is a 2D array of booleans each one a flag directly refering to the 199 * menu item arrays already setup. If there are 4 menus... there will be 4 200 * lists holding the flags to use. If a value of false is specified the menu 201 * item will be grayed. 202 */ 203 static boolean menuItemEnabled[][] = { 204 {true, true, true, true, true, true, true, true}, 205 {true, true}, 206 {true, true, true, true, true}, 207 {true, true, true}}; 208 209 /** 210 * The applets JToolbar. 211 */ 212 private AutoButtonBar myButtonBar; 213 214 /** 215 * The Applets MenuBar. It gets initialized by the method 216 * <code>initMenuBar</code>. 217 * @see initMenuBar 218 */ 219 private JMenuBar menuBar; 220 221 /** 222 * A status bar object that lives at the bottom of the Internal Window 223 * Desktop to provide useful information regarding the applet. 224 */ 225 private StatusBar statBar; 226 227 /** 228 * Status bar information variable used with the StatusBar object. 229 * It provides the sizes for the different sections of the status bar 230 * 231 * @see <code>StatusBar</code> 232 */ 233 private double[] statusSizes = {0.6, 0.2, 0.1, 0.1}; 234 235 /** 236 * Status bar information variable used with the StatusBar object. 237 * It provides the initial Strings for the different sections of the 238 * status bar 239 * 240 * @see <code>StatusBar</code> 241 */ 242 private String[] statusMsg = {"StatusArea0", "StatusArea1", 243 "StatusArea2", "Status Area 3"}; 244 245/** 246 * The Applets main internal window desktop panel. 247 * A JPanel that will hold desktop that is going into this 248 * applet EXCEPT the statusbar and menubar; this is so the status bar is at 249 * the bottom of the applet, the menubar stays at the top and everything 250 * else is in between. See the start method that sets it all up. 251 */ 252 private JPanel mdiPanel = new JPanel(); 253 254/** 255 * The Applets main desktop object manager. 256 */ 257 private DesktopController desktopController; 258 259/** 260 * myMDIDesktop is the Multiple Document Desktop that gets placed directly 261 * inside the MDIViewPanel JPanel. It will hold all the child windows for 262 * this app. 263 */ 264 private JLayeredPane myMDIDesktop; 265 266 267 268/** 269 * The initial X coordinate for this app/let. 270 */ 271 private short appX = 10; 272 273/** 274 * The initial Y coordinate for this app/let. 275 */ 276 private short appY = 10; 277 278 /** 279 * The Codes Base URL. 280 */ 281 private URL codeBase; 282 283 /** 284 * A flag that indicates if this applet is running as an application. 285 */ 286 public static boolean isRunningAsAnApplet = true; 287 288 /** 289 * Suffix applied to the key used in resource file 290 * lookups for an image. 291 */ 292 public final static String imageSuffix = "Image.gif"; 293 294 /** 295 * Suffix applied to the key used in resource file 296 * lookups for an action. 297 */ 298 public final static String actionSuffix = "Action"; 299 300 /** 301 * The filename for the graphic to splash up at start 302 */ 303 private static final String splashGraphic = "../images/DONT_PAN.GIF" ; 304 305 /** 306 * The Current Date and time. 307 */ 308 static java.util.Date currentDate; 309 310 /** 311 * Flag to spew debug output to the screen. 312 */ 313 static boolean debugOutput = false; 314 315 /** 316 * the Metal LookAndFeel CONSTANT. 317 */ 318 public static final short METAL_LOOKANDFEEL = 0; 319 320 /** 321 * the Windoze LookAndFeel CONSTANT. 322 */ 323 public static final short WINDOZE_LOOKANDFEEL = 1; 324 325 /** 326 * the Motif LookAndFeel CONSTANT. 327 */ 328 public static final short MOTIF_LOOKANDFEEL = 2; 329 330 /** 331 * the Mac LookAndFeel CONSTANT. 332 */ 333 public static final short MAC_LOOKANDFEEL = 3; 334 335 /** 336 * the Default LookAndFeel CONSTANT. DEFAULT_LOOKANDFEEL = METAL_LOOKANDFEEL 337 */ 338 public static final short DEFAULT_LOOKANDFEEL = METAL_LOOKANDFEEL; 339 340 /** 341 * The CONSTANT to represent LEFT screen justification. 342 * Used in the setScreenLocation method. 343 */ 344 public static final short LEFT_SCREENJUSTIFY = -1; 345 346 /** 347 * The CONSTANT to represent CENTER screen justification. 348 * Used in the setScreenLocation method. 349 */ 350 public static final short CENTER_SCREENJUSTIFY = -2; 351 352 /** 353 * The CONSTANT to represent RIGHT screen justification. 354 * Used in the setScreenLocation method. 355 */ 356 public static final short RIGHT_SCREENJUSTIFY = -3; 357 358 /** 359 * The CONSTANT to represent TOP screen justification. 360 * Used in the setScreenLocation method. 361 */ 362 public static final short TOP_SCREENJUSTIFY = -4; 363 364 /** 365 * The CONSTANT to represent BOTTOM screen justification. 366 * Used in the setScreenLocation method. 367 */ 368 public static final short BOTTOM_SCREENJUSTIFY = -5; 369 370 /** 371 * the Mac LookAndFeel class name 372 */ 373 private static String macClassName = 374 "com.sun.java.swing.plaf.mac.MacLookAndFeel"; 375 /** 376 * the Java LookAndFeel class name 377 */ 378 private static String metalClassName = 379 "javax.swing.plaf.metal.MetalLookAndFeel"; 380 /** 381 * the motif LookAndFeel class name 382 */ 383 private static String motifClassName = 384 "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; 385 /** 386 * the Windoze LookAndFeel class name 387 */ 388 private static String windowsClassName = 389 "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; 390 391 /** 392 * A holder for a string representation of the users starting directory. 393 */ 394 private static String userDir = ""; 395 396 /** 397 * General variables that are used as counters or temps. 398 */ 399 private static String tempPath; 400 401 /** 402 * Strings to hold the retrieved applet parameters. They are initialized 403 * to their default values. 404 */ 405 private static String mediaURL = "file:///c|/movie.mov"; 406 407 /** 408 * A variable to indicate the level of debug output produced. 409 * debug = 0 is OFF 410 * debug = 1 is Minimal Output 411 * debug = 2 is General Outline of Programs Position 412 * debug = 3 is Detailed Object creation and method location 413 * debug = 4 is verbose 414 */ 415 private static int debug = 3; 416 417 /** 418 * A temp variable that holds the APPLET parameter that might or might not 419 * have been specified at runtime. 420 * This value (if the user specified a value at Init) gets transfered 421 * into debug. 422 */ 423 private static int debugParam = 1; 424 425 426 /** 427 * the method that return the programmers customized information about 428 * this applet. 429 * 430 * @return The AppletInfo value 431 */ 432 public String getAppletInfo() { 433 return "Generic MDI Desktop. Copyright (c) WebARTS Design 2001 - Tom Gutwin P.Eng."; 434 } 435 436 437 /** 438 * The method that returns the information about the possible applet 439 * parameters. 440 * 441 * @return a table of Strings (String[][]) holding the input param 442 * name, type and description 443 */ 444 public String[][] getParameterInfo() { 445 String[][] retVal = { 446 {"DEBUG", "int", "specifies the level of debug output; 0=off; " + 447 "1=minor; 2=medium; 3=verbose; default = 1"}, 448 {"MEDIAURL", "String", "the string that indicates the filename to " + 449 "initially open up; DEFAULT = nothing"} 450 }; 451 return retVal; 452 } 453 454 455 /** 456 * Tells if this applet was started as an app via its main method 457 * 458 * @return The App value 459 */ 460 public boolean isApp() { 461 return (!isRunningAsAnApplet); 462 } 463 464 465 /** 466 * Tells if this applet was started as an applet directly without 467 * going through its main method. 468 * 469 * @return The Applet value 470 */ 471 public boolean isApplet() { 472 return (isRunningAsAnApplet); 473 } 474 475 /** 476 * Receives the button actions 477 */ 478public void actionPerformed(ActionEvent e) 479{ 480 int butInx = buttonIndexOf(iconToolTips, 481 ((JButton)e.getSource()).getToolTipText()); 482 debugOutput(3,"ActionEvent.... "+butInx); 483 switch (butInx ) 484 { 485 case 0: 486 debugOutput(3, " Exit Pressed " ); 487 /* now add the specific stuff for this button */ 488 stop(); 489 System.exit(0); 490 break; 491 case 1: 492 break; 493 case 2: 494 break; 495 case 3: 496 break; 497 default: 498 } 499} 500 501 502 /** 503 * Initializes the Applet. Gets all the initial data read in and set up. 504 */ 505 public void init() { 506 setVisible(false); 507 System.out.println("Into Init...."); 508 509 /* get the JApplets root pane & make a fix so this 510 applet does not crash NS or IE */ 511 JRootPane rp = getRootPane(); 512 rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); 513 514 try { 515 if (isRunningAsAnApplet) { 516 /* Get The Code Base */ 517 codeBase = new URL(getCodeBase().toString()); 518 519 /* Get the input parameters */ 520 debugParam = (new Integer(getParameter("DEBUG"))).intValue(); 521 522 mediaURL = getParameter("MEDIAURL"); 523 } 524 else { 525 getAppCodeBase(); 526 } 527 } 528 catch (java.net.MalformedURLException t) { 529 System.out.println("caught java.net.MalformedURLException: " + t + 530 "Cannot retrieve codebase"); 531 t.printStackTrace(); 532 } 533 534 /* Force SwingSet to come up in the Cross Platform L&F */ 535 setTheLookAndFeel(METAL_LOOKANDFEEL); 536 537 /* set the layout manager for correct spacing */ 538 getContentPane().setLayout(new BorderLayout()); 539 540 /* create the statusbar */ 541 debugOutput(1, "Creating StatusBar..."); 542 statBar = initStatusBar(); 543 544 /* create the scroll pane that is going to go into the frame */ 545 mdiPanel.setBorder(BorderFactory.createEtchedBorder()); 546 mdiPanel.setLayout(new BorderLayout()); 547 548 /* create the menu bar */ 549 menuBar = initMenuBar(); 550 551 /* create the button bar */ 552 debugOutput(2, "Creating ToolBar..."); 553// myButtonBar = new AutoButtonBar(mdiPanel, statBar, codeBase); 554 myButtonBar = new AutoButtonBar(codeBase); 555 myButtonBar.setIcons(iconNames, iconToolTips); 556 myButtonBar.setController( this); 557 myButtonBar.setRelImageLocator(iconNamePrefix); 558 myButtonBar.createButtons(); 559 myButtonBar.setFloatable(true); 560 561 } 562 563 564/** 565 * Starts the operation of the applet. 566 * It gets everything running by performing the following functions: 567 * <UL><LI><B>adds all the objects to the applet</B> 568 * <LI><B>opens up an initial desktopController that is the child window 569 * supervisor/B> 570 * <LI><B>sets location of the applet on the screen</B> 571 * <LI><B>then its SHOWTIME!</B> 572 * </UL> 573 * The way things are laid out in the applet are as follows: 574 * the media JPanel will hold everything that is going into this applet EXCEPT 575 * the statusbar and menubar; 576 * This is so the status bar stays at the bottom of the applet and the menubar 577 * stays at the top with the menubar able to float around the actual Internal 578 * Window desktop. 579 */ 580 public void start() { 581 System.out.println("Into Start...."); 582 583 /* add the button control button panel & deskTopController to the MdiPanel */ 584 mdiPanel.add(myButtonBar, "North"); 585 desktopController = new DesktopController(null); 586 JScrollPane scroller = new JScrollPane( 587 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 588 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 589 scroller.setBorder(new BevelBorder(BevelBorder.LOWERED)); 590 591 scroller.getViewport().add(desktopController); 592// setContentPane(desktopController); 593 mdiPanel.add(scroller, "Center"); 594 595 /* add the StatusBar to the bottom of the applet window */ 596 debugOutput(3, "Adding the StatusBar Panel...."); 597 getContentPane().add(statBar, "South"); 598 599 /* add the MenuBar to the Top of the applet window */ 600 debugOutput(3, "Adding the MenuBar Panel...."); 601 getContentPane().add(menuBar, "North"); 602 603 /* add the Desktop Area to the applet window */ 604 getContentPane().add(mdiPanel, "Center"); 605 606 if (isRunningAsAnApplet) { 607 /* set out the applets position on the screen */ 608 setScreenLocation(CENTER_SCREENJUSTIFY, CENTER_SCREENJUSTIFY, 0, 0); 609 } 610 validate(); 611 612 setVisible(true); 613 } 614 615 616 /** 617 * The stop method that gets called whne stoping the applet. 618 * It does clean up. 619 */ 620 public void stop() { 621 System.out.println("Stopping...."); 622 remove(statBar); 623 remove(menuBar); 624 remove(mdiPanel); 625 } 626 627 628 /** 629 * Initializes the statusbar with the pre- inititialized arrays of data. 630 */ 631 private StatusBar initStatusBar() { 632 StatusBar statBar; 633 634 statBar = new StatusBar(statusSizes.length, statusSizes, statusMsg); 635 statBar.updateBackgroundColour(0, new Color(210, 180, 210)); 636 for (int i=0; i< statusSizes.length; i++) { 637 statBar.updateFont(i, new Font("Arial", Font.PLAIN, 9)); 638 } 639 return statBar; 640 } 641 642 643 /** 644 * Forces a repaint to this apps menubar. 645 */ 646 public void repaintMenuBar() { 647 if (menuBar != null) { 648 menuBar.repaint(); 649 } 650 } 651 652 653 /** 654 * Calls the User Interface Manager and sets the look and feel setting based 655 * on the parameter it is passed. 656 * 657 * @param i The new TheLookAndFeel value 658 */ 659 private void setTheLookAndFeel(short i) { 660 /* Force SwingSet to come up in the Cross Platform L&F */ 661 try { 662 switch ((int)i){ 663 case METAL_LOOKANDFEEL: 664 // If you want the Java L&F 665 UIManager.setLookAndFeel(metalClassName); 666 debugOutput(3, "Setting the Java L&F"); 667 break; 668 case WINDOZE_LOOKANDFEEL: 669 // If you want the System L&F 670 UIManager.setLookAndFeel(windowsClassName);//UIManager.getSystemLookAndFeelClassName()); 671 debugOutput(3, "Setting the System L&F"); 672 break; 673 case MOTIF_LOOKANDFEEL: 674 // If you want the Motif L&F 675 UIManager.setLookAndFeel(motifClassName); 676 debugOutput(3, "Setting the Motif L&F"); 677 break; 678 case MAC_LOOKANDFEEL: 679 // If you want the Mac L&F 680 UIManager.setLookAndFeel(macClassName); 681 debugOutput(3, "Setting the Mac L&F"); 682 break; 683 default: 684 // defaults to Java L&F 685 UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 686 debugOutput(3, "Setting the Java L&F"); 687 } 688 SwingUtilities.updateComponentTreeUI(getAncestorFrame(this)); 689 } 690 catch (Exception exc) 691 { 692 System.err.println("Error loading L&F: " + exc); 693 } 694 } 695 696 697 698 /** 699 * This method sets the position of this app/applet on the users screen 700 * based on the supplied location parameters 701 * 702 * @param xPosition The new ScreenLocation value 703 * @param yPosition The new ScreenLocation value 704 * @param xOffset The new ScreenLocation value 705 * @param yOffset The new ScreenLocation value 706 */ 707 private void setScreenLocation(int xPosition, int yPosition, 708 int xOffset, int yOffset) { 709 /* the xPosition can be -1,-2, or -3 for left center and right justified */ 710 /* the yPosition can be -4,-2, or -5 for Top center and bottom justified */ 711 712 Dimension scrnSize = toolkit.getScreenSize(); 713 Frame topFrame = getAncestorFrame((Component) this); 714 int scrnWidth = scrnSize.width; 715 int 716 scrnHeight = scrnSize.height; 717 int frameWidth = topFrame.getSize().width; 718 int 719 frameHeight = topFrame.getSize().height; 720 Point startPoint = topFrame.getLocationOnScreen(); 721 Point newPoint = new Point(startPoint); 722 723 debugOutput(3, "Existing pos " + 724 " " + (new Integer(xPosition)).toString() + 725 " " + (new Integer(yPosition)).toString() + 726 " " + (new Integer(frameWidth)).toString() + 727 " " + (new Integer(frameHeight)).toString() + 728 " " + (new Integer(newPoint.x)).toString() + 729 " " + (new Integer(newPoint.y)).toString()); 730 731 switch (xPosition) 732 { 733 case LEFT_SCREENJUSTIFY: 734 newPoint.x = 0 + xOffset; 735 break; 736 case CENTER_SCREENJUSTIFY: 737 newPoint.x = scrnWidth / 2 - frameWidth / 2 + xOffset; 738 break; 739 case RIGHT_SCREENJUSTIFY: 740 newPoint.x = scrnWidth - frameWidth; 741 break; 742 default: 743 debugOutput(3, "Setting an Absolute X Screen Location"); 744 newPoint.x = xPosition + xOffset; 745 } 746 switch (yPosition) 747 { 748 case TOP_SCREENJUSTIFY: 749 newPoint.y = 0 + yOffset; 750 break; 751 case CENTER_SCREENJUSTIFY: 752 newPoint.y = scrnHeight / 2 - frameHeight / 2 + yOffset; 753 break; 754 case BOTTOM_SCREENJUSTIFY: 755 newPoint.y = scrnHeight - frameHeight; 756 break; 757 default: 758 debugOutput(3, "Setting an Absolute Y Screen Location"); 759 newPoint.y = yPosition + yOffset; 760 } 761 debugOutput(3, "NEW pos " + 762 " " + (new Integer(xPosition)).toString() + 763 " " + (new Integer(yPosition)).toString() + 764 " " + (new Integer(frameWidth)).toString() + 765 " " + (new Integer(frameHeight)).toString() + 766 " " + (new Integer(newPoint.x)).toString() + 767 " " + (new Integer(newPoint.y)).toString()); 768 topFrame.setLocation(newPoint); 769 } 770 771 772 /** 773 * Creates a URL for the location of the applications codebase. 774 */ 775 private void getAppCodeBase() { 776 /* because this is an application the codebase does not work */ 777 /* we have to create the codeBase URL from the userDir */ 778 int i = 0; 779 debugOutput(3, "userdir=" + userDir); 780 781 try { 782 /* 1st test if this is a DOS/OS/2 style path with a drive letter */ 783 if (userDir.charAt(1) == ':') 784 { 785 tempPath = userDir.substring(0, 1); 786 tempPath += ":"; 787 /* Replace the file separators with the forward slash */ 788 for (i = 2; i <= userDir.length() - 1; i++) { 789 if (userDir.charAt(i) != fileSeperator.charAt(0)) { 790 tempPath += userDir.substring(i, i + 1); 791 } 792 else { 793 tempPath += "/"; 794 } 795 } 796 codeBase = new URL("FILE:/" + tempPath + "/"); 797 } 798 else{ 799 /* 2nd test if this is a UN*x style path without a drive letter */ 800 if (userDir.charAt(0) == '/') { 801 debugOutput(3, "Appears to be a Unix filesystem"); 802 codeBase = new URL("FILE:" + userDir + "/"); 803 } 804 else { 805 codeBase = new URL("FILE:/./"); 806 } 807 } 808 debugOutput(3, "APP codeBase=" + codeBase.toString()); 809 } 810 catch (java.net.MalformedURLException t) { 811 System.out.println("caught java.net.MalformedURLException: " + t + 812 "Cannot retrieve User Directory"); 813 t.printStackTrace(); 814 } 815 catch (StringIndexOutOfBoundsException t) 816 { 817 System.out.println("caught StringIndexOutOfBoundsException: " + t + 818 "Cannot retrieve User Directory"); 819 t.printStackTrace(); 820 } 821 } 822 823 824 /** 825 * This method seeks out and returns the Parent Frame for a given component. 826 * 827 * @param c The Component to be used as the basis of the frame search 828 * @return Frame The Frame that eventually holds the giuven Component. 829 */ 830 private Frame getAncestorFrame(Component c) { 831 Frame retVal = null; 832 while ((c = c.getParent()) != null) 833 if (c instanceof Frame) { 834 retVal = (Frame) c; 835 } 836 return retVal; 837 } 838 839 840 /** 841 * Creates the JMenuBar and populates the menuitms into it. 842 * It uses a set of predefined String arrays that it loops through to create 843 * the menus. This way the menus can be easily changed by simply adding or 844 * removing entrys in the arrays. You can set the name, Accelerator, 845 * Mnemonic, Tooltip, enabled/disabled (clickable/gray), and even if the 846 * item gets created at all! 847 * <P>The fields it uses are: 848 * <UL> 849 * <LI>menuItemShown 850 * <LI>menuName 851 * <LI>menuItemName 852 * <LI>menuItemAccel 853 * <LI>menuItemAccel2 854 * </UL> 855 * 856 * @return JMenuBar 857 * @see MediaViewer#createMenuItem(int,int) 858 */ 859 private JMenuBar initMenuBar() { 860 int i; 861 int j; 862 JMenu tempMenu; 863 JMenuBar tempMenuBar; 864 865 tempMenuBar = new JMenuBar(); 866 867 for (i = 0; i < menuName.length; i++) { 868 tempMenu = new JMenu(menuName[i]); 869 for (j = 0; j < menuItemName[i].length; j++) 870 if (menuItemShown[i][j]) 871 if (menuItemName[i][j].equals("---")) 872 tempMenu.addSeparator(); 873 else 874 /* Use the HELPER function called *createMenuItem* to actually do 875 the menuItem Object creation */ 876 if (menuItemAccel[i][j] != 0) 877 tempMenu.add(createMenuItem(i, j)).setAccelerator( 878 KeyStroke.getKeyStroke(menuItemAccel[i][j], 879 menuItemAccel2[i][j])); 880 else 881 tempMenu.add(createMenuItem(i, j)); 882 tempMenuBar.add(tempMenu); 883 } 884 return tempMenuBar; 885 } 886 887 888 /** 889 * This is the hook through which all menu items are created. 890 * The fields it uses are: 891 * <UL> 892 * <LI>menuItemMnemonic 893 * <LI>menuToolTip 894 * <LI>menuItemEnabled 895 * </UL> 896 * 897 * @param menuRef Description of Parameter 898 * @param menuItemRef Description of Parameter 899 * @return Description of the Returned Value 900 * @see MediaViewer#createMenu() 901 */ 902 private JMenuItem createMenuItem(int menuRef, int menuItemRef) { 903 904 String cmd = menuItemName[menuRef][menuItemRef]; 905 JMenuItem mi = new JMenuItem(menuItemName[menuRef][menuItemRef]); 906 mi.setMnemonic(menuItemMnemonic[menuRef][menuItemRef]); 907 try { 908 URL url = new URL(codeBase, "images" + fileSeperator + 909 menuItemName[menuRef][menuItemRef] + imageSuffix); 910 mi.setHorizontalTextPosition(JButton.RIGHT); 911 mi.setIcon(new ImageIcon(url)); 912 } 913 catch (java.net.MalformedURLException t) { 914 debugOutput(3, "caught exception: " + t + 915 "Cannot retrieve Menu Item image"); 916 } 917 918 mi.setToolTipText(menuToolTip[menuRef][menuItemRef]); 919 mi.setEnabled(menuItemEnabled[menuRef][menuItemRef]); 920 /* call the one size fits all method to add the appropriate 921 listener to this menu item */ 922 addListener(mi); 923 return mi; 924 } 925 926 927 /** 928 * Aa simple indexOf helper function to look through the menu items and 929 * return an int to represent its HASH position 930 * 931 * @param s Description of Parameter 932 * @return int A value that is the HASH in the menuItem array for 933 * the menuItem passed in as a param 934 */ 935 private int indexOf(String s) { 936 int i; 937 int j; 938 int retVal = 0; 939 for (j = 0; j < menuName.length; j++){ 940 for (i = 0; i < menuToolTip[j].length; i++) { 941 try { 942 if (s.equals(menuToolTip[j][i])) { 943 i = menuToolTip[j].length - 1; 944 j = menuName.length - 1; 945 } 946 else { 947 retVal++; 948 } 949 } 950 catch (java.lang.ArrayIndexOutOfBoundsException t) { 951 debugOutput(3, "caught exception: " + t + "Index =" + 952 (new Integer(j)).toString() + "," + (new Integer(i)).toString()); 953 } 954 } 955 } 956 return retVal; 957 } 958 959 /** 960 * Aa simple indexOf helper function to look through the button items and 961 * return an int to represent its HASH position 962 * 963 * @param list List of strings to look through 964 * @param s Description of Parameter 965 * @return int A value that is the HASH in the menuItem array for 966 * the menuItem passed in as a param 967 */ 968 private int buttonIndexOf(String[] list, String s) { 969 int i; 970 int retVal = 0; 971 debugOutput(3, "buttonIndexOf: " + list[0] + s); 972 for (i = 0; i < list.length; i++) { 973 try { 974 if (s.equals(list[i])) { 975 i = list.length - 1; 976 } 977 else { 978 retVal++; 979 } 980 } 981 catch (java.lang.ArrayIndexOutOfBoundsException t) { 982 debugOutput(3, "caught exception: " + t + "Index =" + 983 (new Integer(i)).toString() + "," + (new Integer(i)).toString()); 984 } 985 } 986 return retVal; 987 } 988 989 990 /** 991 * Adds an ActionListener to the JMenuItem that is supplied in the 992 * passed param. This method SHOULD be overriden by the extending 993 * class to enable its specific fuctionality. 994 * @param menuItem The feature to be added to the Listener attribute 995 */ 996 private void addListener(JMenuItem menuItem) { 997 /* use a simple indexOf helper function to look through the menu 998 items and return an int to represent its HASH position */ 999 debugOutput(4, " Adding a listener for menu item " + 1000 menuItem.getToolTipText() + " " + 1001 indexOf(menuItem.getToolTipText()) 1002 ); 1003 switch (indexOf(menuItem.getToolTipText())) 1004 { 1005 case 0: 1006 /* Open Window Data To File */ 1007 menuItem.addActionListener( 1008 new ActionListener() 1009 { 1010 /** 1011 * Description of the Method 1012 * 1013 * @param event Description of Parameter 1014 */ 1015 public void actionPerformed(ActionEvent event) { 1016 repaintMenuBar(); 1017 /* now add the specific stuff for this Menu Item */ 1018 try 1019 { 1020 desktopController.makeNewChildWindow(); 1021 desktopController.addWindowContent( 1022 new JTextArea("EMPTY BOX")); 1023 } 1024 catch (Exception ex) 1025 { 1026 debugOutput(3, "caught exception: " + ex); 1027 // ex.printStackTrace(); 1028 } 1029 } 1030 /* action performed */ 1031 }); 1032 break; 1033 1034 case 1: 1035 /* Save Window Data To File */ 1036 menuItem.addActionListener( 1037 new ActionListener() 1038 { 1039 /** 1040 * Description of the Method 1041 * 1042 * @param event Description of Parameter 1043 */ 1044 public void actionPerformed(ActionEvent event) { 1045 repaintMenuBar(); 1046 /* now add the specific stuff for this Menu Item */ 1047 } 1048 /* action performed */ 1049 }); 1050 break; 1051 1052 case 3: 1053 /* print */ 1054 menuItem.addActionListener( 1055 new ActionListener() 1056 { 1057 /** 1058 * Description of the Method 1059 * 1060 * @param event Description of Parameter 1061 */ 1062 public void actionPerformed(ActionEvent event) { 1063 repaintMenuBar(); 1064 debugOutput(3, " PRINT MenuItem Selected (and Threaded)"); 1065 /* now add the specific stuff for this button */ 1066 } 1067 /* action performed */ 1068 }); 1069 break; 1070 1071 case 4: 1072 /* print preview */ 1073 menuItem.addActionListener( 1074 new ActionListener() 1075 { 1076 /** 1077 * Description of the Method 1078 * 1079 * @param event Description of Parameter 1080 */ 1081 public void actionPerformed(ActionEvent event) { 1082 repaintMenuBar(); 1083 debugOutput(3, " PRINT Preview MenuItem Selected"); 1084 /* now add the specific stuff for this button */ 1085 } 1086 /* action performed */ 1087 }); 1088 break; 1089 1090 case 6: 1091 /* close */ 1092 menuItem.addActionListener( 1093 new ActionListener() 1094 { 1095 /** 1096 * Description of the Method 1097 * 1098 * @param event Description of Parameter 1099 */ 1100 public void actionPerformed(ActionEvent event) { 1101 repaintMenuBar(); 1102 debugOutput(3, " Close MenuItem Selected"); 1103 /* now add the specific stuff for this button */ 1104 } 1105 /* action performed */ 1106 }); 1107 break; 1108 1109 case 7: 1110 /* exit */ 1111 menuItem.addActionListener( 1112 new ActionListener() 1113 { 1114 /** 1115 * Description of the Method 1116 * 1117 * @param event Description of Parameter 1118 */ 1119 public void actionPerformed(ActionEvent event) { 1120 repaintMenuBar(); 1121 debugOutput(3, " Exit MenuItem Pressed " ); 1122 /* now add the specific stuff for this button */ 1123 stop(); 1124 System.exit(0); 1125 } 1126 /* action performed */ 1127 }); 1128 break; 1129 1130 case 10: 1131 /* Set The Debug Level */ 1132 menuItem.addActionListener( 1133 new ActionListener() 1134 { 1135 /** 1136 * Description of the Method 1137 * 1138 * @param event Description of Parameter 1139 */ 1140 public void actionPerformed(ActionEvent event) { 1141 repaintMenuBar(); 1142 debugOutput(2, " Debug Level MenuItem Selected"); 1143 /* now add the specific stuff for this button */ 1144 } 1145 /* action performed */ 1146 }); 1147 break; 1148 1149 case 12: 1150 /* Set the L&F to Java */ 1151 menuItem.addActionListener( 1152 new ActionListener() 1153 { 1154 /** 1155 * Description of the Method 1156 * 1157 * @param event Description of Parameter 1158 */ 1159 public void actionPerformed(ActionEvent event) { 1160 debugOutput(2, " Java L&F MenuItem Selected"); 1161 repaintMenuBar(); 1162 1163 /* now add the specific stuff for this button */ 1164 setTheLookAndFeel(METAL_LOOKANDFEEL); 1165 } 1166 /* action performed */ 1167 }); 1168 break; 1169 1170 case 13: 1171 /* Set the L&F to Platform */ 1172 menuItem.addActionListener( 1173 new ActionListener() 1174 { 1175 /** 1176 * Description of the Method 1177 * 1178 * @param event Description of Parameter 1179 */ 1180 public void actionPerformed(ActionEvent event) { 1181 repaintMenuBar(); 1182 debugOutput(2, " Platform L&F MenuItem Selected"); 1183 /* now add the specific stuff for this button */ 1184 setTheLookAndFeel(WINDOZE_LOOKANDFEEL); 1185 } 1186 /* action performed */ 1187 }); 1188 break; 1189 1190 case 14: 1191 /* Set the L&F to Motif */ 1192 menuItem.addActionListener( 1193 new ActionListener() 1194 { 1195 /** 1196 * Description of the Method 1197 * 1198 * @param event Description of Parameter 1199 */ 1200 public void actionPerformed(ActionEvent event) { 1201 repaintMenuBar(); 1202 debugOutput(2, " Motif L&F MenuItem Selected"); 1203 /* now add the specific stuff for this button */ 1204 setTheLookAndFeel(MOTIF_LOOKANDFEEL); 1205 } 1206 /* action performed */ 1207 }); 1208 break; 1209 1210 case 18: 1211 /* Open the Help window */ 1212 menuItem.addActionListener( 1213 new ActionListener() 1214 { 1215 /** 1216 * Description of the Method 1217 * 1218 * @param event Description of Parameter 1219 */ 1220 public void actionPerformed(ActionEvent event) { 1221 repaintMenuBar(); 1222 debugOutput(2, " Help MenuItem Selected"); 1223 /* now add the specific stuff for this button */ 1224 } 1225 /* action performed */ 1226 }); 1227 break; 1228 1229 case 20: 1230 /* Open the About Box */ 1231 menuItem.addActionListener( 1232 new ActionListener() 1233 { 1234 /** 1235 * Description of the Method 1236 * 1237 * @param event Description of Parameter 1238 */ 1239 public void actionPerformed(ActionEvent event) { 1240 repaintMenuBar(); 1241 debugOutput(2, " About Box MenuItem Selected"); 1242 /* now add the specific stuff for this button */ 1243 JAboutBox box = new JAboutBox("Generic MDIApplet",getAppletInfo()); 1244 box.show(); 1245 box.toFront(); 1246 } 1247 /* action performed */ 1248 }); 1249 break; 1250 1251 default: 1252 debugOutput(3, "??? menu item number"+ 1253 indexOf(menuItem.getToolTipText())); 1254// repaintMenuBar(); 1255 } 1256 /* switch for menuitem */ 1257 } 1258 1259 1260 /** 1261 * The main entry for running the MDIApplet as an APP. 1262 * 1263 * @param args The command line arguments 1264 */ 1265 public static void main(String[] args) { 1266 isRunningAsAnApplet = false; 1267 1268 /* Put the opening splash screen up */ 1269 debugOutput(2," "); 1270 debugOutput(2,"Splash Logo"); 1271 Panel p = new Panel(); 1272 p.setBackground(new Color(210,210,210)); 1273 Label l = new Label(" Please wait while loading..."); 1274 p.add(l); 1275 Splash frame = new Splash(splashGraphic, 5000,p); 1276 1277 /* Get the current directory */ 1278 userDir = System.getProperty("user.dir"); 1279 debugOutput(3,"userdir=" + userDir); 1280 1281 /* Get Current Time */ 1282 currentDate = new java.util.Date(); 1283 1284 /* create an app frame that will start this applet inside it */ 1285 MyMDIApp app = new MyMDIApp("Generic MDI Desktop Template - WebARTS Design"); 1286 app.setSize(800, 600); 1287 1288 /* Put the opening app up */ 1289 app.show(); 1290 } 1291 1292 1293 /** 1294 * Handles debug messages by comparing the app debug level to the 1295 * message level. If the message level is less or == then the 1296 * message gets outout to System.out. 1297 * 1298 * @param l Description of Parameter 1299 * @param output Description of Parameter 1300 */ 1301 private static void debugOutput(int l, String output) { 1302 if (l <= debug) System.out.println(output); 1303 } 1304 1305 1306 1307/** 1308 * This is <B>the</B> object that will act as the main child window manager. 1309 * 1310 * @author gutwint 1311 * @created November 17, 2000 1312 */ 1313class DesktopController extends JDesktopPane 1314{ 1315 /** 1316 * generic counter 1317 */ 1318 private int i; 1319 1320 /** 1321 * The pop up menu for this area 1322 */ 1323 private JPopupMenu popupMenu; 1324 1325/** 1326 * MAX_CHILDREN is the constant representing the maximum number of children 1327 * that this class will allow in its desktop. It gets used to initialize 1328 * arrays and for general happiness. :) 1329 */ 1330 static final private short MAX_CHILDREN = 10; 1331 1332 /**an array of the files/internalwindows that can be used **/ 1333 private JInternalFrame[] childWindow = new JInternalFrame[MAX_CHILDREN]; 1334 1335/** 1336 * Reference number for the next child window to be created. 1337 */ 1338 private short nextWindowIndex = 0; 1339 1340/** 1341 * Reference number for the currently active child window. 1342 */ 1343 private short currentWindowIndex = nextWindowIndex; 1344 1345/** 1346 * The X coordinate for the next window. 1347 */ 1348 private short nextWindowXPos = 0; 1349 1350/** 1351 * The Y coordinate for the next window. 1352 */ 1353 private short nextWindowYPos = 110; 1354 1355// private JScrollPane scroller = new JScrollPane(); 1356 // set up a pop up menu when the mouse is over the pictures 1357 1358 /** 1359 * Constructor for the desktopController object 1360 * 1361 * @param codeBase Description of Parameter 1362 */ 1363 public DesktopController(URL codeBase) 1364 { 1365 super(); 1366 System.out.println("Creating the desktopController...."); 1367 1368 /* set up the popup menu */ 1369 popupMenu = new JPopupMenu(); 1370 popupMenu.add(new JMenuItem("New")); 1371 popupMenu.addSeparator(); 1372 popupMenu.add(new JMenuItem("Close")); 1373 popupMenu.add(new JMenuItem("Exit")); 1374 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 1375 1376 // scroller.getViewport().setMinimumSize(new java.awt.Dimension(20, 15)); 1377 1378 /* fill the arrays with the pictures and labels */ 1379 1380 System.out.println("Done Creating a desktopController...."); 1381 } 1382 1383 1384/** 1385 * Creates a new Internal Child Window that goes into this 1386 * Internal Desktop Pane/Panel. 1387 * 1388 * @return boolean Flags if the new window was created OKay. 1389 */ 1390 public boolean makeNewChildWindow() 1391 { 1392 boolean retVal = false; 1393 JInternalFrame child; 1394 System.out.println(" Creating The NEW Child window...."); 1395 1396 1397 /* create the new frame */ 1398 child = new JInternalFrame("Title",true,true,true,true); 1399 1400 if (child != null) 1401 { 1402 retVal = true; 1403 /* increase the index counters */ 1404 currentWindowIndex = nextWindowIndex++; 1405 System.out.println(" ......Done calling Create for The NEW Child window...." + 1406 currentWindowIndex); 1407 1408 childWindow[currentWindowIndex] = child; 1409 childWindow[currentWindowIndex].pack(); 1410 childWindow[currentWindowIndex].setVisible(true) ; 1411 1412 /* add it to my desktop */ 1413 add(childWindow[currentWindowIndex], JLayeredPane.PALETTE_LAYER); 1414 childWindow[currentWindowIndex].setLocation(nextWindowXPos,nextWindowYPos); 1415// setContentPane(desktop); 1416 nextWindowXPos += 20; 1417 nextWindowYPos += 29; 1418 1419 try 1420 { 1421 childWindow[currentWindowIndex].moveToFront() ; 1422 childWindow[currentWindowIndex].setSelected(true); 1423 } 1424 catch (java.beans.PropertyVetoException ex) 1425 { 1426 System.out.println("EXCEPTION CAUGHT for:"); 1427 System.out.println(" " + ex.getMessage()); 1428 System.out.println("Vetoed Property Change:"); 1429 System.out.println(" " + ex.getPropertyChangeEvent().getPropertyName()); 1430 } 1431 1432 revalidate(); 1433 } 1434 else 1435 System.out.println(" ......Done calling Create for The NEW Child window NO CONTENT"); 1436 1437 return retVal; 1438 } 1439 1440 public int getCurrentWindowIndex() 1441 { 1442 return currentWindowIndex; 1443 } 1444 1445 1446 public int getNextWindowIndex() 1447 { 1448 return nextWindowIndex; 1449 } 1450 1451 public void addWindowContent(Component content) 1452 { 1453 JComponent c = (JComponent) childWindow[currentWindowIndex].getContentPane(); 1454 c.setLayout(new BorderLayout()); 1455 c.add(content); 1456 childWindow[currentWindowIndex].pack(); 1457 } 1458 1459 public void addWindowContent(int windowIndex, Component content) 1460 { 1461 currentWindowIndex = (short) windowIndex; 1462 addWindowContent(content); 1463 } 1464 1465 /** 1466 * Description of the Method 1467 * 1468 * @param e Description of Parameter 1469 */ 1470 protected void processMouseEvent(MouseEvent e) { 1471 // System.out.println("mouse event...." e.getID()); 1472// System.out.println(); 1473// System.out.println(e); 1474 if (e.isPopupTrigger()) 1475 { 1476 // popupMenu.show(e.getComponent(), e.getX(), e.getY()); 1477 } 1478 super.processMouseEvent(e); 1479 } 1480 1481} 1482 1483} //end of the MDIApplet JApplet 1484 1485 1486/** 1487 * The App that holds the generic MDI applet. 1488 * It is simply a JFrame that encapsulates the applet as an application. 1489 * 1490 * @author gutwint 1491 * @created November 17, 2000 1492 */ 1493class MyMDIApp extends JFrame 1494{ 1495 1496 1497 /** 1498 * Description of the Field 1499 */ 1500 private MDIApplet myMDIApplet; 1501 1502 1503 /** 1504 * Constructor. 1505 * 1506 * @param frameTitle Description of Parameter 1507 */ 1508 public MyMDIApp(String frameTitle) { 1509 /* get the super class frame to build a frame with a title */ 1510 super(frameTitle); 1511 1512 /* Instantiate the MediaViewer APPLET */ 1513 myMDIApplet = new MDIApplet(); 1514 1515 /* place it into the app frame */ 1516 getContentPane().add(myMDIApplet, "Center"); 1517 1518 /* Init the applet */ 1519 myMDIApplet.init(); 1520 1521 /* Start the applet */ 1522 myMDIApplet.start(); 1523 1524 /* listen for closing */ 1525 addWindowListener( 1526 new WindowAdapter() 1527 { 1528 /** 1529 * Description of the Method 1530 * 1531 * @param event Description of Parameter 1532 */ 1533 public void windowClosing(WindowEvent event) { 1534 /* Start the applet */ 1535 myMDIApplet.stop(); 1536 dispose(); 1537 System.exit(0); 1538 } 1539 }); 1540 /* inner WindowAdapter class */ 1541 1542 } 1543}