001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.core.windows.view.ui;
043:
044: import java.awt.AWTEvent;
045: import java.awt.BorderLayout;
046: import java.awt.Component;
047: import java.awt.Dimension;
048: import java.awt.EventQueue;
049: import java.awt.FlowLayout;
050: import java.awt.Frame;
051: import java.awt.Graphics;
052: import java.awt.Graphics2D;
053: import java.awt.GraphicsDevice;
054: import java.awt.GraphicsEnvironment;
055: import java.awt.Image;
056: import java.awt.Rectangle;
057: import java.awt.event.*;
058: import java.awt.image.BufferedImage;
059: import java.lang.reflect.InvocationTargetException;
060: import java.lang.reflect.Method;
061: import java.text.*;
062: import java.util.*;
063: import java.util.logging.Level;
064: import java.util.logging.Logger;
065: import javax.swing.*;
066: import javax.swing.border.*;
067: import javax.swing.event.*;
068: import org.netbeans.core.windows.*;
069: import org.netbeans.core.windows.view.ui.toolbars.ToolbarConfiguration;
070: import org.openide.LifecycleManager;
071: import org.openide.awt.*;
072: import org.openide.cookies.InstanceCookie;
073: import org.openide.filesystems.*;
074: import org.openide.loaders.DataObject;
075: import org.openide.util.*;
076:
077: /** The MainWindow of IDE. Holds toolbars, main menu and also entire desktop
078: * if in MDI user interface. Singleton.
079: * This class is final only for performance reasons, can be unfinaled
080: * if desired.
081: *
082: * @author Ian Formanek, Petr Hamernik
083: */
084: public final class MainWindow extends JFrame {
085: /** generated Serialized Version UID */
086: static final long serialVersionUID = -1160791973145645501L;
087:
088: /** Desktop. */
089: private Component desktop;
090:
091: /** Inner panel which contains desktop component */
092: private JPanel desktopPanel;
093:
094: private static JPanel innerIconsPanel;
095:
096: /** Flag indicating main window is initialized. */
097: private boolean inited;
098:
099: /** Constructs main window. */
100: public MainWindow() {
101: }
102:
103: /** Overrides superclass method, adds help context to the new root pane. */
104: protected void setRootPane(JRootPane root) {
105: super .setRootPane(root);
106: if (root != null) {
107: HelpCtx.setHelpIDString(root, new HelpCtx(MainWindow.class)
108: .getHelpID());
109: }
110: //Optimization related to jdk bug 4939857 - on pre 1.5 jdk's an
111: //extra repaint is caused by the search for an opaque component up
112: //to the component root. Post 1.5, root pane will automatically be
113: //opaque.
114: root.setOpaque(true);
115: if (Utilities.isWindows()) {
116: // use glass pane that will not cause repaint/revalidate of parent when set visible
117: // is called (when setting wait cursor in ModuleActions) #40689
118: JComponent c = new JPanel() {
119: public void setVisible(boolean flag) {
120: if (flag != isVisible()) {
121: super .setVisible(flag);
122: }
123: }
124: };
125: c.setName(root.getName() + ".nbGlassPane"); // NOI18N
126: c.setVisible(false);
127: ((JPanel) c).setOpaque(false);
128: root.setGlassPane(c);
129: }
130: }
131:
132: /** Initializes main window. */
133: public void initializeComponents() {
134: if (inited) {
135: return;
136: }
137: inited = true;
138:
139: // initialize frame
140: initFrameIcons(this );
141:
142: initListeners();
143:
144: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
145:
146: getAccessibleContext().setAccessibleDescription(
147: NbBundle.getBundle(MainWindow.class).getString(
148: "ACSD_MainWindow"));
149:
150: setJMenuBar(createMenuBar());
151:
152: if (!Constants.NO_TOOLBARS) {
153: JComponent tb = getToolbarComponent();
154: getContentPane().add(tb, BorderLayout.NORTH);
155: }
156:
157: if (!Constants.SWITCH_STATUSLINE_IN_MENUBAR) {
158: if (Constants.CUSTOM_STATUS_LINE_PATH == null) {
159: JLabel status = new StatusLine();
160: // XXX #19910 Not to squeeze status line.
161: status.setText(" "); // NOI18N
162: status.setPreferredSize(new Dimension(0, status
163: .getPreferredSize().height));
164: // text in line should be shifted for 4pix.
165: status.setBorder(BorderFactory.createEmptyBorder(0, 4,
166: 0, 0));
167:
168: JPanel statusLinePanel = new JPanel(new BorderLayout());
169: int magicConstant = 0;
170: if (Utilities.isMac()) {
171: // on mac there is window resize component in the right most bottom area.
172: // it paints over our icons..
173: magicConstant = 12;
174: }
175:
176: // status line should add some pixels on the left side
177: statusLinePanel.setBorder(BorderFactory
178: .createCompoundBorder(BorderFactory
179: .createEmptyBorder(0, 0, 0,
180: magicConstant), statusLinePanel
181: .getBorder()));
182:
183: statusLinePanel.add(new JSeparator(),
184: BorderLayout.NORTH);
185: statusLinePanel.add(status, BorderLayout.CENTER);
186:
187: decoratePanel(statusLinePanel);
188: statusLinePanel.setName("statusLine"); //NOI18N
189: getContentPane().add(statusLinePanel,
190: BorderLayout.SOUTH);
191: } else { // custom status line provided
192: JComponent status = getCustomStatusLine();
193: if (status != null) {
194: getContentPane().add(status, BorderLayout.SOUTH);
195: }
196: }
197: }
198:
199: getContentPane().add(getDesktopPanel(), BorderLayout.CENTER);
200:
201: //#38810 start - focusing the main window in case it's not active and the menu is
202: // selected..
203: MenuSelectionManager.defaultManager().addChangeListener(
204: new ChangeListener() {
205: public void stateChanged(ChangeEvent e) {
206: MenuElement[] elems = MenuSelectionManager
207: .defaultManager().getSelectedPath();
208: if (elems != null && elems.length > 0) {
209: if (elems[0] == getJMenuBar()) {
210: if (!isActive()) {
211: toFront();
212: }
213: }
214: }
215: }
216: });
217: //#38810 end
218: setTitle(NbBundle.getMessage(MainWindow.class,
219: "CTL_MainWindow_Title_No_Project", System
220: .getProperty("netbeans.buildnumber")));
221: }
222:
223: private static void decoratePanel(JPanel panel) {
224: assert SwingUtilities.isEventDispatchThread() : "Must run in AWT queue.";
225: if (innerIconsPanel != null) {
226: panel.remove(innerIconsPanel);
227: }
228: innerIconsPanel = getStatusLineElements(panel);
229: if (innerIconsPanel != null) {
230: panel.add(innerIconsPanel, BorderLayout.EAST);
231: }
232: }
233:
234: private static Lookup.Result<StatusLineElementProvider> result;
235:
236: // package-private because StatusLineElementProviderTest
237: static JPanel getStatusLineElements(JPanel panel) {
238: // bugfix #56375, don't duplicate the listeners
239: if (result == null) {
240: result = Lookup.getDefault().lookup(
241: new Lookup.Template<StatusLineElementProvider>(
242: StatusLineElementProvider.class));
243: result.addLookupListener(new StatusLineElementsListener(
244: panel));
245: }
246: Collection<? extends StatusLineElementProvider> c = result
247: .allInstances();
248: if (c == null || c.isEmpty()) {
249: return null;
250: }
251: Iterator<? extends StatusLineElementProvider> it = c.iterator();
252: JPanel icons = new JPanel(
253: new FlowLayout(FlowLayout.RIGHT, 0, 0));
254: icons.setBorder(BorderFactory.createEmptyBorder(1, 0, 0, 2));
255: boolean some = false;
256: while (it.hasNext()) {
257: StatusLineElementProvider o = it.next();
258: Component comp = o.getStatusLineElement();
259: if (comp != null) {
260: some = true;
261: icons.add(comp);
262: }
263: }
264: return some ? icons : null;
265: }
266:
267: static private class StatusLineElementsListener implements
268: LookupListener {
269: private JPanel decoratingPanel;
270:
271: StatusLineElementsListener(JPanel decoratingPanel) {
272: this .decoratingPanel = decoratingPanel;
273: }
274:
275: public void resultChanged(LookupEvent ev) {
276: SwingUtilities.invokeLater(new Runnable() {
277: public void run() {
278: decoratePanel(decoratingPanel);
279: }
280: });
281: }
282: }
283:
284: /** Creates and returns border for desktop which is visually aligned
285: * with currently active LF */
286: private static Border getDesktopBorder() {
287: Border b = (Border) UIManager
288: .get("nb.desktop.splitpane.border");
289: if (b != null) {
290: return b;
291: } else {
292: return new EmptyBorder(1, 1, 1, 1);
293: }
294: }
295:
296: private static final String ICON_16 = "org/netbeans/core/startup/frame.gif"; // NOI18N
297: private static final String ICON_32 = "org/netbeans/core/startup/frame32.gif"; // NOI18N
298: private static final String ICON_48 = "org/netbeans/core/startup/frame48.gif"; // NOI18N
299:
300: private static Image createIDEImage() {
301: return Utilities.loadImage(ICON_16, true);
302: }
303:
304: private static List<Image> createIDEImages() {
305: List<Image> l = new ArrayList<Image>();
306: l.add(Utilities.loadImage(ICON_16, true));
307: l.add(Utilities.loadImage(ICON_32, true));
308: l.add(Utilities.loadImage(ICON_48, true));
309: return l;
310: }
311:
312: static void initFrameIcons(Frame f) {
313: Class clazz = null;
314: try {
315: clazz = Class.forName("java.awt.Window");
316: } catch (ClassNotFoundException ex) {
317: //This cannot happen because without AWT classes we would not get here.
318: }
319: Method m = null;
320: try {
321: m = clazz.getMethod("setIconImages",
322: new Class[] { List.class });
323: } catch (NoSuchMethodException ex) {
324: //Method not available so we are on JDK 5. Use setIconImage.
325: }
326: if (m != null) {
327: List<Image> l;
328: l = createIDEImages();
329: try {
330: m.invoke(f, new Object[] { l });
331: } catch (IllegalAccessException ex) {
332: Logger.getLogger(MainWindow.class.getName()).log(
333: Level.INFO, "Cannot invoke setIconImages", ex); //NOI18N
334: f.setIconImage(createIDEImage());
335: } catch (InvocationTargetException ex) {
336: Logger.getLogger(MainWindow.class.getName()).log(
337: Level.INFO, "Cannot invoke setIconImages", ex); //NOI18N
338: f.setIconImage(createIDEImage());
339: }
340: } else {
341: f.setIconImage(createIDEImage());
342: }
343: }
344:
345: private void initListeners() {
346: addWindowListener(new WindowAdapter() {
347: public void windowClosing(WindowEvent evt) {
348: LifecycleManager.getDefault().exit();
349: }
350:
351: public void windowActivated(WindowEvent evt) {
352: // #19685. Cancel foreigner popup when
353: // activated main window.
354: org.netbeans.core.windows.RegistryImpl
355: .cancelMenu(MainWindow.this );
356: }
357: });
358: }
359:
360: /** Creates menu bar. */
361: private static JMenuBar createMenuBar() {
362: JMenuBar menu = getCustomMenuBar();
363: if (menu == null) {
364: menu = new MenuBar(null);
365: }
366: menu.setBorderPainted(false);
367: if (menu instanceof MenuBar) {
368: ((MenuBar) menu).waitFinished();
369: }
370:
371: if (Constants.SWITCH_STATUSLINE_IN_MENUBAR) {
372: if (Constants.CUSTOM_STATUS_LINE_PATH == null) {
373: JLabel status = new StatusLine();
374: JSeparator sep = new JSeparator(JSeparator.VERTICAL);
375: Dimension d = sep.getPreferredSize();
376: d.width += 6; // need a bit more padding...
377: sep.setPreferredSize(d);
378: JPanel statusLinePanel = new JPanel(new BorderLayout());
379: statusLinePanel.add(sep, BorderLayout.WEST);
380: statusLinePanel.add(status, BorderLayout.CENTER);
381:
382: decoratePanel(statusLinePanel);
383: statusLinePanel.setName("statusLine"); //NOI18N
384: menu.add(statusLinePanel);
385: } else {
386: JComponent status = getCustomStatusLine();
387: if (status != null) {
388: menu.add(status);
389: }
390: }
391: }
392:
393: return menu;
394: }
395:
396: /**
397: * Tries to find custom menu bar component on system file system.
398: * @return menu bar component or <code>null</code> if no menu bar
399: * component is found on system file system.
400: */
401: private static JMenuBar getCustomMenuBar() {
402: try {
403: String fileName = Constants.CUSTOM_MENU_BAR_PATH;
404: if (fileName == null) {
405: return null;
406: }
407: FileObject fo = Repository.getDefault()
408: .getDefaultFileSystem().findResource(fileName);
409: if (fo != null) {
410: DataObject dobj = DataObject.find(fo);
411: InstanceCookie ic = (InstanceCookie) dobj
412: .getCookie(InstanceCookie.class);
413: if (ic != null) {
414: return (JMenuBar) ic.instanceCreate();
415: }
416: }
417: } catch (Exception e) {
418: Exceptions.printStackTrace(e);
419: }
420: return null;
421: }
422:
423: /**
424: * Tries to find custom status line component on system file system.
425: * @return status line component or <code>null</code> if no status line
426: * component is found on system file system.
427: */
428: private static JComponent getCustomStatusLine() {
429: try {
430: String fileName = Constants.CUSTOM_STATUS_LINE_PATH;
431: if (fileName == null) {
432: return null;
433: }
434: FileObject fo = Repository.getDefault()
435: .getDefaultFileSystem().findResource(fileName);
436: if (fo != null) {
437: DataObject dobj = DataObject.find(fo);
438: InstanceCookie ic = (InstanceCookie) dobj
439: .getCookie(InstanceCookie.class);
440: if (ic != null) {
441: return (JComponent) ic.instanceCreate();
442: }
443: }
444: } catch (Exception e) {
445: Exceptions.printStackTrace(e);
446: }
447: return null;
448: }
449:
450: /** Creates toolbar component. */
451: private static JComponent getToolbarComponent() {
452: ToolbarPool tp = ToolbarPool.getDefault();
453: tp.waitFinished();
454: // ErrorManager.getDefault().getInstance(MainWindow.class.getName()).log("toolbar config name=" + WindowManagerImpl.getInstance().getToolbarConfigName());
455: // tp.setConfiguration(WindowManagerImpl.getInstance().getToolbarConfigName()); // NOI18N
456:
457: return tp;
458: }
459:
460: private Rectangle forcedBounds = null;
461:
462: /** Packs main window, to set its border */
463: private void initializeBounds() {
464: Rectangle bounds;
465: if (WindowManagerImpl.getInstance().getEditorAreaState() == Constants.EDITOR_AREA_JOINED) {
466: bounds = WindowManagerImpl.getInstance()
467: .getMainWindowBoundsJoined();
468: } else {
469: bounds = WindowManagerImpl.getInstance()
470: .getMainWindowBoundsSeparated();
471: }
472: if (null != forcedBounds) {
473: bounds = new Rectangle(forcedBounds);
474: setPreferredSize(bounds.getSize());
475: forcedBounds = null;
476: }
477:
478: if (!bounds.isEmpty()) {
479: setBounds(bounds);
480: }
481: }
482:
483: /**
484: * don't allow smaller bounds than the one constructed from preffered sizes, making sure everything is visible when
485: * in SDI. #40063
486: */
487: public void setBounds(Rectangle rect) {
488: Rectangle bounds = rect;
489: if (bounds != null) {
490: if (bounds.height < getPreferredSize().height) {
491: bounds = new Rectangle(bounds.x, bounds.y,
492: bounds.width, getPreferredSize().height);
493: }
494: }
495: super .setBounds(bounds);
496: }
497:
498: /** Prepares main window, has to be called after {@link initializeComponents()}. */
499: public void prepareWindow() {
500: initializeBounds();
501: }
502:
503: /** Sets desktop component. */
504: public void setDesktop(Component comp) {
505: if (desktop == comp) {
506: // XXX PENDING revise how to better manipulate with components
507: // so there don't happen unneeded removals.
508: if (desktop != null
509: && !Arrays
510: .asList(getDesktopPanel().getComponents())
511: .contains(desktop)) {
512: getDesktopPanel().add(desktop, BorderLayout.CENTER);
513: }
514: return;
515: }
516:
517: if (desktop != null) {
518: getDesktopPanel().remove(desktop);
519: }
520:
521: desktop = comp;
522:
523: if (desktop != null) {
524: getDesktopPanel().add(desktop, BorderLayout.CENTER);
525: }
526: invalidate();
527: validate();
528: // use #24291 hack only on Win OS
529: if (isOlderJDK
530: && !System.getProperty("os.name").startsWith("Windows")) {
531: releaseWaitingForPaintDummyGraphic();
532: }
533:
534: repaint();
535: }
536:
537: // XXX PENDING used in DnD only.
538: public Component getDesktop() {
539: return desktop;
540: }
541:
542: public boolean hasDesktop() {
543: return desktop != null;
544: }
545:
546: /** #112408: Single access point for desktopPanel to ensure it's never null */
547: private JPanel getDesktopPanel() {
548: if (desktopPanel == null) {
549: // initialize desktop panel
550: desktopPanel = new JPanel();
551: desktopPanel.setBorder(getDesktopBorder());
552: desktopPanel.setLayout(new BorderLayout());
553: }
554: return desktopPanel;
555: }
556:
557: // XXX
558: /** Gets bounds of main window without the dektop component. */
559: public Rectangle getPureMainWindowBounds() {
560: Rectangle bounds = getBounds();
561:
562: // XXX Substract the desktop height, we know the pure main window
563: // is always at the top, the width is same.
564: if (desktop != null) {
565: Dimension desktopSize = desktop.getSize();
566: bounds.height -= desktopSize.height;
567: }
568:
569: return bounds;
570: }
571:
572: // [dafe] Start of #24291 hacky fix, to prevent from main window flicking on
573: // JDK 1.5.x and older. Can be freely deleted when we will drop JDK 1.5.x
574: // support in future
575:
576: private Image waitingForPaintDummyImage;
577: private Graphics waitingForPaintDummyGraphic;
578: boolean isOlderJDK = System.getProperty("java.version").startsWith(
579: "1.5");
580:
581: public void setVisible(boolean flag) {
582: // The setVisible will cause a PaintEvent to be queued up, as a LOW_PRIORITY one
583: // As the painting of my child components occurs, they cause painting of their own
584: // When the PaintEvent queued from the setVisible is finally processed, it assumes
585: // nothing has been displayed and redraws the whole window.
586: // So we make it such that, UNTIL there is the repaint is dispatched, return a graphics
587: // which goes nowhere.
588: if (flag && isOlderJDK) {
589: waitingForPaintDummyImage = new BufferedImage(1, 1,
590: BufferedImage.TYPE_INT_RGB);
591: waitingForPaintDummyGraphic = waitingForPaintDummyImage
592: .getGraphics();
593: }
594: super .setVisible(flag);
595: }
596:
597: public void paint(Graphics g) {
598: // As a safeguard, always release the dummy graphic when we get a paint
599: if (waitingForPaintDummyGraphic != null) {
600: releaseWaitingForPaintDummyGraphic();
601: // Since the release did not occur before the getGraphics() call,
602: // I need to get the actual graphics now that I've released
603: g = getGraphics();
604: }
605: super .paint(g);
606: }
607:
608: /** Overrides parent version to return fake dummy graphic in certain time
609: * during startup
610: */
611: public Graphics getGraphics() {
612: // Return the dummy graphics that paint nowhere, until we receive a paint()
613: if (waitingForPaintDummyGraphic != null) {
614: // If we are the PaintEvent we are waiting for is being dispatched
615: // we better return the correct graphics.
616: AWTEvent event = EventQueue.getCurrentEvent();
617: if (event == null
618: || (event.getID() != PaintEvent.PAINT && event
619: .getSource() != this )) {
620: return waitingForPaintDummyGraphic;
621: }
622: releaseWaitingForPaintDummyGraphic();
623: }
624: return super .getGraphics();
625: }
626:
627: private void releaseWaitingForPaintDummyGraphic() {
628: if (waitingForPaintDummyGraphic != null) {
629: waitingForPaintDummyGraphic.dispose();
630: waitingForPaintDummyGraphic = null;
631: waitingForPaintDummyImage = null;
632: }
633: }
634:
635: // end of #24291 hacky fix
636:
637: // Full Screen Mode
638: private boolean isFullScreenMode = false;
639: private Rectangle restoreBounds;
640: private int restoreExtendedState = JFrame.NORMAL;
641: private boolean isSwitchingFullScreenMode = false;
642: private boolean isUndecorated = true;
643: private int windowDecorationStyle = JRootPane.FRAME;
644:
645: public void setFullScreenMode(boolean fullScreenMode) {
646: if (isFullScreenMode == fullScreenMode
647: || isSwitchingFullScreenMode) {
648: return;
649: }
650: isSwitchingFullScreenMode = true;
651: if (!isFullScreenMode) {
652: restoreExtendedState = getExtendedState();
653: restoreBounds = getBounds();
654: isUndecorated = isUndecorated();
655: windowDecorationStyle = getRootPane()
656: .getWindowDecorationStyle();
657: }
658: isFullScreenMode = fullScreenMode;
659: if (Utilities.isWindows())
660: setVisible(false);
661: else
662: WindowManagerImpl.getInstance().setVisible(false);
663:
664: dispose();
665:
666: setUndecorated(isFullScreenMode || isUndecorated);
667: // Added to support Custom Look and Feel with Decorations
668: getRootPane().setWindowDecorationStyle(
669: isFullScreenMode ? JRootPane.NONE
670: : windowDecorationStyle);
671:
672: final String toolbarConfigName = ToolbarPool.getDefault()
673: .getConfiguration();
674: if (null != toolbarConfigName) {
675: ToolbarConfiguration tc = ToolbarConfiguration
676: .findConfiguration(toolbarConfigName);
677: if (null != tc)
678: tc.rebuildMenu();
679: }
680: getToolbarComponent().setVisible(!isFullScreenMode);
681: final boolean updateBounds = (!isFullScreenMode);//&& restoreExtendedState != JFrame.MAXIMIZED_BOTH );
682:
683: GraphicsDevice device = null;
684: if (getGraphics() instanceof Graphics2D) {
685: device = ((Graphics2D) getGraphics())
686: .getDeviceConfiguration().getDevice();
687: }
688: if (null != device && device.isFullScreenSupported()) {
689: device.setFullScreenWindow(isFullScreenMode ? this : null);
690: } else {
691: setExtendedState(isFullScreenMode ? JFrame.MAXIMIZED_BOTH
692: : restoreExtendedState);
693: }
694:
695: if (updateBounds
696: || (isFullScreenMode() && !Utilities.isWindows())) {
697: if (updateBounds) {
698: forcedBounds = restoreBounds;
699: } else {
700: GraphicsEnvironment ge = GraphicsEnvironment
701: .getLocalGraphicsEnvironment();
702: forcedBounds = ge.getMaximumWindowBounds();
703: }
704: }
705: if (Utilities.isWindows()) {
706: setVisible(true);
707: SwingUtilities.invokeLater(new Runnable() {
708: public void run() {
709: invalidate();
710: validate();
711: repaint();
712: if (updateBounds) {
713: setPreferredSize(restoreBounds.getSize());
714: setBounds(restoreBounds);
715: }
716: ToolbarPool.getDefault().setConfiguration(
717: toolbarConfigName);
718: isSwitchingFullScreenMode = false;
719: }
720: });
721: } else {
722: WindowManagerImpl.getInstance().setVisible(true);
723: SwingUtilities.invokeLater(new Runnable() {
724: public void run() {
725: invalidate();
726: validate();
727: repaint();
728: ToolbarPool.getDefault().setConfiguration(
729: toolbarConfigName);
730: isSwitchingFullScreenMode = false;
731: }
732: });
733: }
734: }
735:
736: public boolean isFullScreenMode() {
737: return isFullScreenMode;
738: }
739: }
|