View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: SwingContext.java,v 1.17 2002/09/12 18:23:24 ludovicc Exp $ 37 */ 38 package org.scopemvc.controller.swing; 39 40 41 import java.awt.BorderLayout; 42 import java.awt.Container; 43 import java.awt.Cursor; 44 import java.awt.Dialog; 45 import java.awt.Frame; 46 import java.awt.Image; 47 import java.awt.Rectangle; 48 import java.awt.Window; 49 import java.awt.event.WindowAdapter; 50 import java.awt.event.WindowEvent; 51 import java.util.Iterator; 52 import java.util.LinkedList; 53 import java.util.Timer; 54 import java.util.TimerTask; 55 import javax.swing.JComponent; 56 import javax.swing.JDialog; 57 import javax.swing.JFrame; 58 import javax.swing.JMenu; 59 import javax.swing.JMenuBar; 60 import javax.swing.JMenuItem; 61 import javax.swing.JOptionPane; 62 import javax.swing.JRootPane; 63 import javax.swing.WindowConstants; 64 import org.apache.commons.logging.Log; 65 import org.apache.commons.logging.LogFactory; 66 import org.scopemvc.core.View; 67 import org.scopemvc.util.Debug; 68 import org.scopemvc.util.ResourceLoader; 69 import org.scopemvc.util.ScopeConfig; 70 import org.scopemvc.view.awt.AWTUtilities; 71 import org.scopemvc.view.swing.SMenuItem; 72 import org.scopemvc.view.swing.SwingUtil; 73 import org.scopemvc.view.swing.SwingView; 74 import org.scopemvc.controller.basic.ViewContext; 75 76 /*** 77 * <P> 78 * 79 * Swing implementation of {@link org.scopemvc.controller.basic.ViewContext} to 80 * show views inside JFrames or JDialogs and show errors using JOptionPanes. 81 * <br> 82 * Also allows Views to take ownership of SMenuItems from their containing 83 * Window. </P> 84 * 85 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 86 * @created 05 August 2002 87 * @version $Revision: 1.17 $ $Date: 2002/09/12 18:23:24 $ 88 * @see org.scopemvc.controller.basic.ViewContext 89 */ 90 public class SwingContext extends ViewContext { 91 92 /*** 93 * The property in ScopeConfig for the delay before showing the wait cursor 94 * when startProgress once startProgress() has been called, value in 95 * milliseconds 96 */ 97 public static final String PROGRESS_START_DELAY_PROPERTY = 98 "org.scopemvc.controller.swing.SwingContext.progress_start_delay"; 99 100 private static final Log LOG = LogFactory.getLog(SwingContext.class); 101 102 private static final long PROGRESS_START_DELAY = 103 ScopeConfig.getInteger(PROGRESS_START_DELAY_PROPERTY).longValue(); 104 105 // ----------------- Shared null frame ---------------- 106 107 /*** 108 * The parent of views that get shown when no parent can be found. Ensures 109 * everything has the application icon. 110 */ 111 private Frame sharedNullFrame; 112 113 // ----------------- Visible View management ---------------- 114 115 /*** 116 * Keep track of all open Frames and Dialogs by keeping references to their 117 * JRootPane. Don't bother tracking Message Boxes because they're modal and 118 * don't interact with Controllers directly. This is an ordered list: the 119 * last opened rootpane is at the end. 120 */ 121 private LinkedList rootpanes = new LinkedList(); 122 123 /*** 124 * The timer used to delay the display of the wait cursor when {@link 125 * #startProgress} is called 126 */ 127 private Timer progressStartTimer = new Timer(true); 128 private TimerTask task; 129 130 131 /*** 132 * Constructor for the SwingContext object 133 */ 134 public SwingContext() { } 135 136 137 /*** 138 * Find the SMenuItem in the menu. 139 * 140 * @param inMenu A menu 141 * @param inControlID The control ID of the menu item to find 142 * @return The SMenuItem matching the control ID, or null if not found 143 */ 144 protected static SMenuItem findMenuItemInMenu(JMenu inMenu, String inControlID) { 145 if (inControlID == null) { 146 throw new IllegalArgumentException("ControlID is null"); 147 } 148 149 for (int i = 0; i < inMenu.getItemCount(); i++) { 150 JMenuItem item = inMenu.getItem(i); 151 if (item instanceof JMenu) { 152 SMenuItem result = findMenuItemInMenu((JMenu) item, inControlID); 153 if (result != null) { 154 return result; 155 } 156 continue; 157 } else if (item instanceof SMenuItem 158 && inControlID.equals(((SMenuItem) item).getControlID())) { 159 return (SMenuItem) item; 160 } 161 } 162 return null; 163 } 164 165 166 /*** 167 * Show the view. <br> 168 * Depending on the display mode of the view, the view is displayed in a 169 * frame or a dialog. 170 * 171 * @param inView The view to show. Must be a subclass of SwingView 172 */ 173 public void showView(View inView) { 174 if (LOG.isDebugEnabled()) { 175 LOG.debug("showView: " + inView); 176 } 177 178 if (!(inView instanceof SwingView)) { 179 throw new IllegalArgumentException("Can only show SwingViews: " + inView); 180 } 181 182 // Get topmost SwingView container 183 Container parentContainer = getTopmostContainer((SwingView) inView); 184 if (!(parentContainer instanceof SwingView)) { 185 throw new IllegalArgumentException("Can only show SwingViews: " + parentContainer); 186 } 187 SwingView view = (SwingView) parentContainer; 188 189 // Try to find the Dialog or Frame that holds View 190 // If one exists, bring it to the front and return. 191 JRootPane rootpane = findRootPaneFor(view); 192 if (rootpane != null) { 193 Container window = rootpane.getParent(); 194 if (Debug.ON) { 195 Debug.assertTrue(window instanceof Window, "window not window: " + window.getClass()); 196 } 197 ((Window) window).toFront(); 198 return; 199 } 200 201 // OK, doesn't exist so create a new Dialog or Frame and show it 202 if (view.getDisplayMode() == SwingView.PRIMARY_WINDOW) { 203 showViewInPrimaryWindow(view); 204 } else { 205 showViewInDialog(view); 206 } 207 if (Debug.ON) { 208 Debug.assertTrue(findRootPaneFor(view) != null, "null findRootPaneFor"); 209 } 210 } 211 212 213 /*** 214 * Find the Window that is showing this View and then close it on Swing's 215 * event-handling thread. Does nothing if the passed View isn't showing. 216 * <br> 217 * This method disposes the Window from memory. 218 * 219 * @param inView The view to hide. Must be a subclass of SwingView 220 */ 221 public void hideView(View inView) { 222 if (!(inView instanceof SwingView)) { 223 throw new IllegalArgumentException("Can only hide SwingViews: " + inView); 224 } 225 226 // Get topmost SwingView container 227 Container parentContainer = getTopmostContainer((SwingView) inView); 228 if (!(parentContainer instanceof SwingView)) { 229 throw new IllegalArgumentException("Can only hide SwingViews: " + parentContainer); 230 } 231 SwingView view = (SwingView) parentContainer; 232 233 JRootPane rootpane = findRootPaneFor(view); 234 if (rootpane == null) { 235 LOG.warn("Found no root pane for view " + view + ". View has not been shown"); 236 return; 237 } 238 239 // Save bounds of window for when reshown 240 if (Debug.ON) { 241 Debug.assertTrue(rootpane.getParent() != null, "parent: " + rootpane.getParent()); 242 } 243 view.setViewBounds(rootpane.getParent().getBounds()); 244 245 hideRootPane(rootpane); 246 } 247 248 249 /*** 250 * Hide all open Views. 251 */ 252 public void hideAllViews() { 253 while (!rootpanes.isEmpty()) { 254 JRootPane rootpane = (JRootPane) rootpanes.getLast(); 255 hideRootPane(rootpane); 256 } 257 } 258 259 260 /*** 261 * Are there any Views left open? 262 * 263 * @return true if all views are closed 264 */ 265 public boolean areAllViewsClosed() { 266 return (rootpanes.size() < 1); 267 } 268 269 270 // ----------------- Message boxes ---------------- 271 272 /*** 273 * Show an error message in a JOptionPane 274 * 275 * @param inErrorTitle The title for the error message 276 * @param inErrorMessage The error message 277 */ 278 public void showError(final String inErrorTitle, final String inErrorMessage) { 279 if (LOG.isDebugEnabled()) { 280 LOG.debug("showError: " + inErrorTitle + ", " + inErrorMessage); 281 } 282 283 SwingUtil.runFromSwingEventThread( 284 new Runnable() { 285 public void run() { 286 if (LOG.isDebugEnabled()) { 287 LOG.debug("showError: " + inErrorTitle); 288 } 289 JOptionPane.showMessageDialog(getFocussedRootPane(), inErrorMessage, inErrorTitle, 290 JOptionPane.ERROR_MESSAGE); 291 } 292 }); 293 } 294 295 296 /*** 297 * Show a message in a JOptionPane 298 * 299 * @param inTitle The title for the message 300 * @param inMessage The message 301 */ 302 public void showMessage(final String inTitle, final String inMessage) { 303 SwingUtil.runFromSwingEventThread( 304 new Runnable() { 305 public void run() { 306 JOptionPane.showMessageDialog(getFocussedRootPane(), inMessage, inTitle, 307 JOptionPane.INFORMATION_MESSAGE); 308 } 309 }); 310 } 311 312 313 // protected Object showOKCancelWarning(final String inTitle, final String inMessage) { 314 // OKCancelOptionDialogShower s = new OKCancelOptionDialogShower(parentComponent, inTitle, inMessage, 315 // JOptionPane.WARNING_MESSAGE); 316 // Display.runFromSwingEventThread(s); 317 // return s.result; 318 // } 319 // 320 // 321 // protected Object showYesNoWarning(final String inTitle, final String inMessage) { 322 // YesNoOptionDialogShower s = new YesNoOptionDialogShower(parentComponent, inTitle, inMessage, 323 // JOptionPane.WARNING_MESSAGE); 324 // Display.runFromSwingEventThread(s); 325 // return s.result; 326 // } 327 328 329 /*** 330 * Exit the application 331 */ 332 public void exit() { 333 hideAllViews(); 334 // default Swing operation 335 System.exit(0); 336 } 337 338 339 /*** 340 * Start a progress indicator to notify the user that a long operation is 341 * running. <br> 342 * In the SwingContext, the progress indicator is a wait cursor, and it is 343 * displayed after a delay of n milliseconds defined in the Scope property 344 * 'org.scopemvc.controller.swing.SwingContext.progress_start_delay' 345 */ 346 public void startProgress() { 347 if (task != null) { 348 task.cancel(); 349 } 350 task = 351 new TimerTask() { 352 public void run() { 353 getDefaultParentWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 354 } 355 }; 356 progressStartTimer.schedule(task, PROGRESS_START_DELAY); 357 } 358 359 360 /*** 361 * Stop the progress indicator 362 */ 363 public void stopProgress() { 364 if (task != null) { 365 task.cancel(); 366 } 367 getDefaultParentWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 368 } 369 370 371 // ------------------------------------ Menu handling ------------------------------ 372 373 /*** 374 * Hook a menu item to a view. <br> 375 * The view and its bound controller will receive the Controls issued by the 376 * menu item. 377 * 378 * @param inView the view to hook the menu item to. 379 * @param inControlID The control ID used to identity the menu item 380 * @param inEnabled Set to true to enable the menu item 381 */ 382 public void hookMenuItem(SwingView inView, String inControlID, boolean inEnabled) { 383 SMenuItem item = findMenuItem(inView, inControlID); 384 if (item == null) { 385 LOG.error("Can't find menuitem for: " + inControlID, new Throwable()); 386 return; 387 } 388 389 item.setOwner(inView); 390 item.setEnabled(inEnabled); 391 } 392 393 394 /*** 395 * Get the frame used as default parent for the views. <br> 396 * This frame uses the default application icon. 397 * 398 * @return The sharedNullFrame value 399 */ 400 protected Frame getSharedNullFrame() { 401 if (sharedNullFrame == null) { 402 try { 403 sharedNullFrame = new NullFrame(); 404 sharedNullFrame.setIconImage(getDefaultWindowIcon()); 405 AWTUtilities.centreOnScreen(sharedNullFrame); 406 } catch (UnsupportedOperationException ignore) { 407 // thrown by JDK 1.4 408 } 409 } 410 return sharedNullFrame; 411 } 412 413 414 /*** 415 * Get the default icon. <br> 416 * The icon is initialised from the property 417 * 'org.scopemvc.controller.swing.SwingContext.window_icon' defined in the 418 * Scope configuration. This property should contain the location of the 419 * icon resource. The icon is loaded with the ResourceLoader. 420 * 421 * @return The defaultWindowIcon value 422 * @see org.scopemvc.util.ResourceLoader 423 */ 424 protected Image getDefaultWindowIcon() { 425 String iconPath = ScopeConfig.getString("org.scopemvc.controller.swing.SwingContext.window_icon"); 426 if (iconPath == null || iconPath.length() < 1) { 427 return null; 428 } 429 try { 430 return ResourceLoader.getImage(iconPath); 431 } catch (RuntimeException e) { 432 LOG.warn("getDefaultWindowIconPath: (" + iconPath + ")", e); 433 return null; 434 } 435 } 436 437 438 /*** 439 * Find the rootpane that currently contains the focussed component, or null 440 * if none. 441 * 442 * @return The focussedRootPane value 443 */ 444 protected JRootPane getFocussedRootPane() { 445 for (Iterator i = rootpanes.iterator(); i.hasNext(); ) { 446 Object o = i.next(); 447 if (Debug.ON) { 448 Debug.assertTrue(o instanceof JRootPane, "not JRootPane: " + o.getClass()); 449 } 450 JRootPane r = (JRootPane) o; 451 Container w = r.getParent(); 452 if (Debug.ON) { 453 Debug.assertTrue(w instanceof Window, "not Window: " + w.getClass()); 454 } 455 if (isFocusOwner((Window) w)) { 456 return r; 457 } 458 } 459 return null; 460 } 461 462 463 /*** 464 * <p> 465 * 466 * Returns true if the window owns the focus. </p> <p> 467 * 468 * Swing loses focus from the current component when a menu is pulled down 469 * so for a Window to have focus we say it needs to either contain the focus 470 * owner OR parent a Window (not a Dialog/Frame) that owns the focus.</p> 471 * 472 * @param inWindow The Window to test for focus 473 * @return True if the window or one of its child owns the focus 474 */ 475 protected boolean isFocusOwner(Window inWindow) { 476 if (inWindow.getFocusOwner() != null) { 477 return true; 478 } 479 Window[] children = inWindow.getOwnedWindows(); 480 if (children == null) { 481 return false; 482 } 483 for (int i = 0; i < children.length; i++) { 484 Window child = children[i]; 485 if (child instanceof Dialog || child instanceof Frame) { 486 continue; 487 } 488 if (isFocusOwner(child)) { 489 return true; 490 } 491 } 492 return false; 493 } 494 495 496 /*** 497 * For dialogs to be opened, find the currently focussed window, or if none, 498 * the last opened window or if none, the shared null Frame. 499 * 500 * @return The defaultParentWindow value 501 */ 502 protected Window getDefaultParentWindow() { 503 504 // The currently focussed window 505 JRootPane r = getFocussedRootPane(); 506 if (r != null) { 507 Container c = r.getParent(); 508 if (Debug.ON) { 509 Debug.assertTrue(c instanceof Window, "not Window: " + c.getClass()); 510 } 511 return (Window) c; 512 } 513 514 // if no open windows, the shared null frame 515 if (rootpanes.size() == 0) { 516 if (LOG.isDebugEnabled()) { 517 LOG.debug("null frame"); 518 } 519 return getSharedNullFrame(); 520 } 521 522 // the last opened window 523 if (Debug.ON) { 524 Debug.assertTrue(rootpanes.getLast() instanceof JRootPane); 525 } 526 if (LOG.isDebugEnabled()) { 527 LOG.debug("last shown frame: " + (Window) ((JRootPane) rootpanes.getLast()).getParent()); 528 } 529 return (Window) ((JRootPane) rootpanes.getLast()).getParent(); 530 } 531 532 533 /*** 534 * Finds the topmost Container, stopping before any Window structure. 535 * 536 * @param inView The View to get the topmost Container from 537 * @return The topmost Container 538 */ 539 protected Container getTopmostContainer(SwingView inView) { 540 541 // Already in a JRootPane? Then find the content pane so we know when to stop below 542 Container contentPane = null; 543 JRootPane parentRootpane = inView.getRootPane(); 544 if (parentRootpane != null) { 545 contentPane = parentRootpane.getContentPane(); 546 } 547 548 Container result = inView; 549 while (result.getParent() != null && result.getParent() != contentPane) { 550 result = result.getParent(); 551 } 552 return result; 553 } 554 555 556 /*** 557 * Setup the window: insert the view in the window, setup the title and the 558 * menubar in the window and position the window on the screen. 559 * 560 * @param inRootPane The RootPane where to add the View 561 * @param inView The View to setup 562 * @param inCentreWindow If true, centre the window on the screen or on its 563 * parent window 564 */ 565 protected void setupWindow(JRootPane inRootPane, SwingView inView, boolean inCentreWindow) { 566 567 Container c = inRootPane.getParent(); 568 if (Debug.ON) { 569 Debug.assertTrue(c instanceof Window, "not Window: " + c.getClass()); 570 } 571 final Window window = (Window) c; 572 573 // Keep track of the new RootPane 574 rootpanes.add(inRootPane); 575 576 // Put the View in the content pane 577 inRootPane.getContentPane().setLayout(new BorderLayout()); 578 inRootPane.getContentPane().add(BorderLayout.CENTER, inView); 579 580 // Attach the View's menubar to the dialog 581 inRootPane.setJMenuBar(inView.getMenuBar()); 582 583 // Restore last bounds of this View 584 Rectangle lastShownBounds = inView.getViewBounds(); 585 if (lastShownBounds == null) { 586 window.pack(); 587 if (inCentreWindow) { 588 if (Debug.ON) { 589 Debug.assertTrue(window.getParent() instanceof Window, "no window parent"); 590 } 591 AWTUtilities.centreOnWindow((Window) window.getParent(), window); 592 } 593 } else if (lastShownBounds == SwingView.CENTRED) { 594 window.pack(); 595 AWTUtilities.centreOnScreen(window); 596 } else { 597 window.setBounds(lastShownBounds); 598 } 599 // If too big for screen, adjust 600 AWTUtilities.fitOnScreen(window); 601 602 // WindowCloser to issue close Control 603 window.addWindowListener(new WindowCloser(inView)); 604 // Don't let Swing handle the window close. Nasty... Swing needs an interface here 605 if (window instanceof JFrame) { 606 ((JFrame) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 607 } else if (window instanceof JDialog) { 608 ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 609 } 610 611 // Display safely from event queue 612 SwingUtil.runFromSwingEventThread( 613 new Runnable() { 614 public void run() { 615 window.setVisible(true); 616 } 617 }); 618 } 619 620 621 /*** 622 * Find the Rootpane that contains the SwingView or null if none can be 623 * found. 624 * 625 * @param inView The View to get the RootPane from 626 * @return The parent RootPane, or null 627 */ 628 protected JRootPane findRootPaneFor(View inView) { 629 if (LOG.isDebugEnabled()) { 630 LOG.debug("findRootPaneFor: " + inView); 631 } 632 if (Debug.ON) { 633 Debug.assertTrue(inView instanceof JComponent, "not JComponent: " + inView.getClass().getName()); 634 } 635 for (Iterator i = rootpanes.iterator(); i.hasNext(); ) { 636 Object o = i.next(); 637 if (LOG.isDebugEnabled()) { 638 LOG.debug("findRootPaneFor: looking at: " + o); 639 } 640 if (Debug.ON) { 641 Debug.assertTrue(o instanceof JRootPane, "not JRootPane: " + o.getClass()); 642 } 643 JRootPane r = (JRootPane) o; 644 if (r.isAncestorOf((JComponent) inView)) { 645 if (LOG.isDebugEnabled()) { 646 LOG.debug("findRootPaneFor: got it"); 647 } 648 return r; 649 } 650 } 651 if (LOG.isDebugEnabled()) { 652 LOG.debug("findRootPaneFor: not found"); 653 } 654 return null; 655 } 656 657 658 /*** 659 * Hide the root pane and dispose of the parent window. 660 * 661 * @param inRootPane The RootPane to hide 662 */ 663 protected void hideRootPane(JRootPane inRootPane) { 664 rootpanes.remove(inRootPane); 665 Container window = inRootPane.getParent(); 666 if (window == sharedNullFrame) { 667 sharedNullFrame = null; 668 } 669 670 if (Debug.ON) { 671 Debug.assertTrue(window instanceof Window, "not Window: " + window); 672 } 673 hideWindow((Window) window); 674 if (areAllViewsClosed() && sharedNullFrame != null) { 675 hideWindow(sharedNullFrame); 676 sharedNullFrame = null; 677 } 678 } 679 680 /*** 681 * Hide the window safely from the Swing event thread. 682 * 683 * @param window The window to close 684 */ 685 protected void hideWindow(final Window window) { 686 SwingUtil.runFromSwingEventThread( 687 new Runnable() { 688 public void run() { 689 window.dispose(); 690 } 691 }); 692 } 693 694 /*** 695 * Make a dialog (modal or modeless determined by {@link 696 * org.scopemvc.view.swing.SwingView#getDisplayMode the display mode}) 697 * parented to either currently focussed window, or last shown, or null 698 * shared frame. 699 * 700 * @param inView The View to show 701 */ 702 protected void showViewInDialog(SwingView inView) { 703 704 // Make a JDialog to contain the view. 705 Window parentWindow = getDefaultParentWindow(); 706 if (Debug.ON) { 707 Debug.assertTrue(parentWindow != null, "null parentWindow"); 708 } 709 710 final JDialog dialog; 711 if (parentWindow instanceof Dialog) { 712 dialog = new JDialog((Dialog) parentWindow); 713 } else { 714 if (Debug.ON) { 715 Debug.assertTrue(parentWindow instanceof Frame); 716 } 717 dialog = new JDialog((Frame) parentWindow); 718 } 719 720 // Set title, modality, resizability 721 if (inView.getTitle() != null) { 722 dialog.setTitle(inView.getTitle()); 723 } 724 if (inView.getDisplayMode() == SwingView.MODAL_DIALOG) { 725 dialog.setModal(true); 726 } else { 727 dialog.setModal(false); 728 } 729 dialog.setResizable(inView.isResizable()); 730 731 setupWindow(dialog.getRootPane(), inView, true); 732 } 733 734 735 /*** 736 * Show the view in a new frame 737 * 738 * @param inView The View to show 739 */ 740 protected void showViewInPrimaryWindow(SwingView inView) { 741 742 // Make a JFrame to contain the view 743 final JFrame frame = new JFrame(); 744 745 // Set its title, icon, resizability 746 if (inView.getTitle() != null) { 747 frame.setTitle(inView.getTitle()); 748 } 749 // All JFrames take the same icon 750 Image icon = getDefaultWindowIcon(); 751 if (icon != null) { 752 frame.setIconImage(icon); 753 } 754 frame.setResizable(inView.isResizable()); 755 756 setupWindow(frame.getRootPane(), inView, false); 757 } 758 759 760 /*** 761 * Unhook a menu item from a view. 762 * 763 * @param inView the view where the menu item was hooked to. 764 * @param inControlID The control ID used to identity the menu item 765 */ 766 protected void unhookMenuItemImpl(String inControlID, SwingView inView) { 767 SMenuItem item = findMenuItem(inView, inControlID); 768 if (item == null) { 769 LOG.error("Can't find menuitem for: " + inControlID, new Throwable()); 770 return; 771 } 772 773 item.unsetOwner(inView); 774 } 775 776 777 /*** 778 * Find the SMenuItem in the menu bar associated with the frame of the view. 779 * 780 * @param inView A view contained in a frame containing a menubar 781 * @param inControlID The control ID of the menu item to find 782 * @return The SMenuItem matching the control ID, or null 783 */ 784 protected SMenuItem findMenuItem(SwingView inView, String inControlID) { 785 JRootPane rootPane = findRootPaneFor(inView); 786 if (rootPane == null) { 787 return null; 788 } 789 790 JMenuBar menuBar = rootPane.getJMenuBar(); 791 if (menuBar == null) { 792 return null; 793 } 794 795 for (int i = 0; i < menuBar.getMenuCount(); i++) { 796 JMenu menu = menuBar.getMenu(i); 797 SMenuItem result = findMenuItemInMenu(menu, inControlID); 798 if (result != null) { 799 return result; 800 } 801 } 802 return null; 803 } 804 805 806 static class NullFrame extends Frame { 807 /*** 808 * Sets the visible attribute 809 * 810 * @param inVisible The new visible value 811 */ 812 public void setVisible(boolean inVisible) { 813 // Don't ever show! 814 } 815 } 816 817 818 // ----------------- Show/hide Views ---------------- 819 820 /*** 821 * Attached to windows opened by this manager so that they issue a Control 822 * on closing. 823 * 824 * @author smefroy 825 * @created 05 August 2002 826 */ 827 static class WindowCloser extends WindowAdapter { 828 private SwingView view; 829 830 /*** 831 * Constructor for the WindowCloser object 832 * 833 * @param inView The View to watch for close events. 834 */ 835 WindowCloser(SwingView inView) { 836 view = inView; 837 } 838 839 /*** 840 * Notifies that the Window is closing 841 * 842 * @param e the Window event 843 */ 844 public void windowClosing(WindowEvent e) { 845 view.issueControl(view.getCloseControl()); 846 } 847 } 848 }

This page was automatically generated by Maven