0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package javax.swing;
0018:
0019: import java.awt.AWTEvent;
0020: import java.awt.BorderLayout;
0021: import java.awt.Component;
0022: import java.awt.Container;
0023: import java.awt.Dimension;
0024: import java.awt.Graphics;
0025: import java.awt.KeyboardFocusManager;
0026: import java.awt.LayoutManager;
0027: import java.awt.Rectangle;
0028: import java.beans.PropertyVetoException;
0029: import javax.accessibility.Accessible;
0030: import javax.accessibility.AccessibleContext;
0031: import javax.accessibility.AccessibleRole;
0032: import javax.accessibility.AccessibleValue;
0033: import javax.swing.event.InternalFrameEvent;
0034: import javax.swing.event.InternalFrameListener;
0035: import javax.swing.plaf.DesktopIconUI;
0036: import javax.swing.plaf.InternalFrameUI;
0037: import org.apache.harmony.x.swing.BlitSupport;
0038: import org.apache.harmony.x.swing.StringConstants;
0039:
0040: /**
0041: * <p>
0042: * <i>JInternalFrame</i>
0043: * </p>
0044: * <h3>Implementation Notes:</h3>
0045: * <ul>
0046: * <li>The <code>serialVersionUID</code> fields are explicitly declared as a performance
0047: * optimization, not as a guarantee of serialization compatibility.</li>
0048: * </ul>
0049: */
0050: public class JInternalFrame extends JComponent implements Accessible,
0051: WindowConstants, RootPaneContainer {
0052: private static final long serialVersionUID = 3837984427982803247L;
0053:
0054: /**
0055: * This class represents the internal frame when it is iconified.
0056: */
0057: public static class JDesktopIcon extends JComponent implements
0058: Accessible {
0059: private static final long serialVersionUID = -4923863980546870453L;
0060:
0061: // The internal frame for this icon.
0062: private JInternalFrame internalFrame;
0063:
0064: /**
0065: * Creates the desktop icon for the internal frame.
0066: *
0067: * @param frame the internal frame of the created desktop icon
0068: */
0069: public JDesktopIcon(final JInternalFrame frame) {
0070: setLayout(new BorderLayout());
0071: setVisible(frame.isVisible());
0072: setInternalFrame(frame);
0073: updateUIForIcon();
0074: }
0075:
0076: /**
0077: * This class implements accessibility support for
0078: * <code>JDesktopIcon</code>.
0079: */
0080: protected class AccessibleJDesktopIcon extends
0081: AccessibleJComponent implements AccessibleValue {
0082: private static final long serialVersionUID = -7418555324455474398L;
0083:
0084: private Number currentAccessibleValue = new Integer(0);
0085:
0086: protected AccessibleJDesktopIcon() {
0087: }
0088:
0089: @Override
0090: public AccessibleRole getAccessibleRole() {
0091: return AccessibleRole.DESKTOP_ICON;
0092: }
0093:
0094: @Override
0095: public AccessibleValue getAccessibleValue() {
0096: return this ;
0097: }
0098:
0099: public Number getCurrentAccessibleValue() {
0100: return currentAccessibleValue;
0101: }
0102:
0103: public boolean setCurrentAccessibleValue(final Number n) {
0104: if (n == null) {
0105: return false;
0106: }
0107: if (n instanceof Integer) {
0108: currentAccessibleValue = n;
0109: } else {
0110: // XXX: 1.5 migration: replace this line with the commented line
0111: currentAccessibleValue = new Integer(n.intValue());
0112: //currentAccessibleValue = Integer.valueOf(n.intValue());
0113: }
0114: return true;
0115: }
0116:
0117: public Number getMinimumAccessibleValue() {
0118: return MIN_VALUE;
0119: }
0120:
0121: public Number getMaximumAccessibleValue() {
0122: return MAX_VALUE;
0123: }
0124: }
0125:
0126: /**
0127: * Sets the UI object for this component.
0128: *
0129: * @param ui
0130: */
0131: public void setUI(final DesktopIconUI ui) {
0132: // setUI() from super (JComponent) should always be called
0133: super .setUI(ui);
0134: }
0135:
0136: /**
0137: * Returns the UI object for this component.
0138: *
0139: * @return UI object for this component
0140: */
0141: public DesktopIconUI getUI() {
0142: return (DesktopIconUI) ui;
0143: }
0144:
0145: /**
0146: * Sets the internal frame for this desktop icon
0147: *
0148: * @param frame the internal frame for this desktop icon
0149: */
0150: public void setInternalFrame(final JInternalFrame frame) {
0151: internalFrame = frame;
0152: }
0153:
0154: /**
0155: * Returns the internal frame for this desktop icon
0156: *
0157: * @return the internal frame for this desktop icon
0158: */
0159: public JInternalFrame getInternalFrame() {
0160: return internalFrame;
0161: }
0162:
0163: /**
0164: * Returns the desktop pane that contains the desktop icon.
0165: *
0166: * @return the desktop pane that contains the desktop icon
0167: */
0168: public JDesktopPane getDesktopPane() {
0169: // its theoretically possible that
0170: // this.getInternalFrame().getDesktopIcon() != this;
0171: // so, we cannot write here just
0172: // return getInternalFrame().getDesktopPane();
0173: Container result = SwingUtilities.getAncestorOfClass(
0174: JDesktopPane.class, this );
0175:
0176: if (result == null) {
0177: if (getInternalFrame() != null) {
0178: result = getInternalFrame().getDesktopPane();
0179: }
0180: }
0181:
0182: return (JDesktopPane) result;
0183: }
0184:
0185: /**
0186: * Returns the accessible context for the icon.
0187: *
0188: * @return the accessible context for the icon
0189: */
0190: @Override
0191: public AccessibleContext getAccessibleContext() {
0192: if (accessibleContext == null) {
0193: accessibleContext = new AccessibleJDesktopIcon();
0194: }
0195: return accessibleContext;
0196: }
0197:
0198: /**
0199: * Returns the name of the L&F class that renders this component.
0200: *
0201: * @return the string "DesktopIconUI"
0202: */
0203: @Override
0204: public String getUIClassID() {
0205: return "DesktopIconUI";
0206: }
0207:
0208: /**
0209: * Updates <code>UI's</code> for both <code>JInternalFrame</code>
0210: * and <code>JDesktopIcon</code>.
0211: */
0212: @Override
0213: public void updateUI() {
0214: updateUIForIcon();
0215: getInternalFrame().updateUI();
0216: }
0217:
0218: void updateUIForIcon() {
0219: setUI((DesktopIconUI) UIManager.getUI(this ));
0220: }
0221: }
0222:
0223: /**
0224: * The name of the bound property.
0225: */
0226: public static final String CONTENT_PANE_PROPERTY = "contentPane";
0227:
0228: /**
0229: * The name of the bound property.
0230: */
0231: public static final String MENU_BAR_PROPERTY = "JMenuBar";
0232:
0233: /**
0234: * The name of the bound property.
0235: */
0236: public static final String TITLE_PROPERTY = "title";
0237:
0238: /**
0239: * The name of the bound property.
0240: */
0241: public static final String LAYERED_PANE_PROPERTY = "layeredPane";
0242:
0243: /**
0244: * The name of the bound property.
0245: */
0246: public static final String ROOT_PANE_PROPERTY = "rootPane";
0247:
0248: /**
0249: * The name of the bound property.
0250: */
0251: public static final String GLASS_PANE_PROPERTY = "glassPane";
0252:
0253: /**
0254: * The name of the bound property.
0255: */
0256: public static final String FRAME_ICON_PROPERTY = "frameIcon";
0257:
0258: /**
0259: * The name of the constrained property which indicates whether
0260: * the internal frame is selected.
0261: */
0262: public static final String IS_SELECTED_PROPERTY = "selected";
0263:
0264: /**
0265: * The name of the constrained property which indicates whether
0266: * the internal frame is closed.
0267: */
0268: public static final String IS_CLOSED_PROPERTY = "closed";
0269:
0270: /**
0271: * The name of the constrained property which indicates whether
0272: * the internal frame is maximized.
0273: */
0274: public static final String IS_MAXIMUM_PROPERTY = "maximum";
0275:
0276: /**
0277: * The name of the constrained property which indicates whether
0278: * the internal frame is iconified.
0279: */
0280: public static final String IS_ICON_PROPERTY = "icon";
0281:
0282: private static final Integer MIN_VALUE = new Integer(
0283: Integer.MIN_VALUE);
0284:
0285: private static final Integer MAX_VALUE = new Integer(
0286: Integer.MAX_VALUE);
0287:
0288: /**
0289: * <code>JRootPane</code> containter of the internal frame.
0290: */
0291: protected JRootPane rootPane;
0292:
0293: protected boolean rootPaneCheckingEnabled;
0294:
0295: /**
0296: * The frame can be closed.
0297: */
0298: protected boolean closable;
0299:
0300: /**
0301: * The frame is closed.
0302: */
0303: protected boolean isClosed = false;
0304:
0305: /**
0306: * The frame can be maximized.
0307: */
0308: protected boolean maximizable;
0309:
0310: /**
0311: * The frame is maximized.
0312: */
0313: protected boolean isMaximum;
0314:
0315: /**
0316: * The frame can be icinified.
0317: */
0318: protected boolean iconable;
0319:
0320: /**
0321: * The frame is iconified.
0322: */
0323: protected boolean isIcon;
0324:
0325: /**
0326: * The frame is resizable.
0327: */
0328: protected boolean resizable;
0329:
0330: /**
0331: * The frame is selected now.
0332: */
0333: protected boolean isSelected;
0334:
0335: /**
0336: * The icon shown in the top-left corner of the frame.
0337: */
0338: protected Icon frameIcon;
0339:
0340: /**
0341: * The title of the frame.
0342: */
0343: protected String title = "";
0344:
0345: /**
0346: * The icon that is displayed when the frame is iconified.
0347: */
0348: protected JDesktopIcon desktopIcon;
0349:
0350: // normalBounds property
0351: private Rectangle normalBounds = new Rectangle();
0352:
0353: // defauld close operation
0354: private int defaultCloseOperation = DISPOSE_ON_CLOSE;
0355:
0356: // most recent focus owner
0357: private Component mostRecentFocusOwner;
0358:
0359: // shows if the internal frame is opened the first time
0360: private boolean firstTimeOpen = true;
0361:
0362: private BlitSupport blitSupport;
0363:
0364: /**
0365: * Constructs a non-resizable, non-closable, non-maximizable,
0366: * non-iconifiable internal frame with no title.
0367: */
0368: public JInternalFrame() {
0369: this ("", false, false, false, false);
0370: }
0371:
0372: /**
0373: * Constructs a non-resizable, non-closable, non-maximizable,
0374: * non-iconifiable internal frame with the specified title.
0375: *
0376: * @param title the title of the internal frame
0377: */
0378: public JInternalFrame(final String title) {
0379: this (title, false, false, false, false);
0380: }
0381:
0382: /**
0383: * Constructs a non-closable, non-maximizable, non-iconifiable internal
0384: * frame with the specified title and resizability.
0385: *
0386: * @param title the title of the internal frame
0387: * @param resizable
0388: */
0389: public JInternalFrame(final String title, final boolean resizable) {
0390: this (title, resizable, false, false, false);
0391: }
0392:
0393: /**
0394: * Constructs a non-maximizable, non-iconifiable internal frame
0395: * with the specified title, resizability and closability.
0396: *
0397: * @param title the title of the internal frame
0398: * @param resizable
0399: * @param closable
0400: */
0401: public JInternalFrame(final String title, final boolean resizable,
0402: final boolean closable) {
0403: this (title, resizable, closable, false, false);
0404: }
0405:
0406: /**
0407: * Constructs a non-iconifiable internal frame with the specified title,
0408: * resizability, closability and maximizability.
0409: *
0410: * @param title the title of the internal frame
0411: * @param resizable
0412: * @param closable
0413: * @param maximizable
0414: */
0415: public JInternalFrame(final String title, final boolean resizable,
0416: final boolean closable, final boolean maximizable) {
0417: this (title, resizable, closable, maximizable, false);
0418: }
0419:
0420: /**
0421: * Constructs an internal frame with the specified title,
0422: * resizability, closability, maximizability and iconifiability.
0423: *
0424: * @param title the title of the internal frame
0425: * @param resizable
0426: * @param closable
0427: * @param maximizable
0428: * @param iconifiable
0429: */
0430: public JInternalFrame(final String title, final boolean resizable,
0431: final boolean closable, final boolean maximizable,
0432: final boolean iconifiable) {
0433: //super.hide();
0434: super .setVisible(false);
0435: this .title = title;
0436: this .resizable = resizable;
0437: this .closable = closable;
0438: this .maximizable = maximizable;
0439: this .iconable = iconifiable;
0440: // from frameInit()
0441: setRootPane(createRootPane());
0442: setLocale(JComponent.getDefaultLocale());
0443: // check isDefaultLookAndFeelDecorated()
0444: //if (isDefaultLookAndFeelDecorated()) {
0445: // setUndecorated(true);
0446: //getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
0447: // }
0448: setBackground(getContentPane().getBackground());
0449: // enable events
0450: enableEvents(AWTEvent.WINDOW_EVENT_MASK);
0451: enableEvents(AWTEvent.KEY_EVENT_MASK);
0452: setFocusTraversalPolicy(KeyboardFocusManager
0453: .getCurrentKeyboardFocusManager()
0454: .getDefaultFocusTraversalPolicy());
0455: updateUI();
0456: this .desktopIcon = new JDesktopIcon(this );
0457: setRootPaneCheckingEnabled(true);
0458: // non-selected internalFrame must have visible glassPane
0459: getGlassPane().setVisible(true);
0460: // just to be sure
0461: super .setFocusCycleRoot(true);
0462: }
0463:
0464: /**
0465: * This class implements accessibility support for
0466: * <code>JInternalFrame</code>.
0467: */
0468: protected class AccessibleJInternalFrame extends
0469: AccessibleJComponent implements AccessibleValue {
0470: private static final long serialVersionUID = 8391910997005202445L;
0471:
0472: private Number currentAccessibleValue = new Integer(0);
0473:
0474: protected AccessibleJInternalFrame() {
0475: }
0476:
0477: @Override
0478: public String getAccessibleName() {
0479: return getTitle();
0480: }
0481:
0482: @Override
0483: public AccessibleRole getAccessibleRole() {
0484: return AccessibleRole.INTERNAL_FRAME;
0485: }
0486:
0487: @Override
0488: public AccessibleValue getAccessibleValue() {
0489: return this ;
0490: }
0491:
0492: public Number getCurrentAccessibleValue() {
0493: return currentAccessibleValue;
0494: }
0495:
0496: public boolean setCurrentAccessibleValue(final Number n) {
0497: if (n == null) {
0498: return false;
0499: }
0500: if (n instanceof Integer) {
0501: currentAccessibleValue = n;
0502: } else {
0503: // XXX: 1.5 migration: replace this line with the commented line
0504: currentAccessibleValue = new Integer(n.intValue());
0505: //currentAccessibleValue = Integer.valueOf(n.intValue());
0506: }
0507: return true;
0508: }
0509:
0510: public Number getMinimumAccessibleValue() {
0511: return MIN_VALUE;
0512: }
0513:
0514: public Number getMaximumAccessibleValue() {
0515: return MAX_VALUE;
0516: }
0517: }
0518:
0519: /**
0520: * Children may not be added directly to the internal frame by default.
0521: * They must be added to its <code>contentPane</code>.
0522: *
0523: * @param comp - the component to be added
0524: * @param constraints - the constraints to be kept
0525: * @param index - the index
0526: */
0527: @Override
0528: protected void addImpl(final Component comp,
0529: final Object constraints, final int index) {
0530: if (isRootPaneCheckingEnabled()) {
0531: getContentPane().add(comp, constraints, index);
0532: return;
0533: }
0534: super .addImpl(comp, constraints, index);
0535: }
0536:
0537: /**
0538: * Sets the UI object for this component.
0539: *
0540: * @param ui the UI object to set
0541: */
0542: public void setUI(final InternalFrameUI ui) {
0543: // setUI() from super (JComponent) should always be called
0544: // strange manipulations with 'enabled', but they are necessary
0545: boolean enabled = isRootPaneCheckingEnabled();
0546: setRootPaneCheckingEnabled(false);
0547: super .setUI(ui);
0548: setRootPaneCheckingEnabled(enabled);
0549: }
0550:
0551: /**
0552: * Returns the UI object for this component.
0553: *
0554: * @return UI object for this component
0555: */
0556: public InternalFrameUI getUI() {
0557: return (InternalFrameUI) ui;
0558: }
0559:
0560: /**
0561: * Updates <code>UI's</code> for both <code>JInternalFrame</code>
0562: * and <code>JDesktopIcon</code>.
0563: */
0564: @Override
0565: public void updateUI() {
0566: setUI((InternalFrameUI) UIManager.getUI(this ));
0567:
0568: if (getDesktopIcon() != null) {
0569: getDesktopIcon().updateUIForIcon();
0570: }
0571: }
0572:
0573: /**
0574: * Removes the internal frame listener.
0575: *
0576: * @param l internal frame listener to remove
0577: */
0578: public void removeInternalFrameListener(
0579: final InternalFrameListener l) {
0580: listenerList.remove(InternalFrameListener.class, l);
0581: }
0582:
0583: /**
0584: * Adds the internal frame listener.
0585: *
0586: * @param l internal frame listener to add
0587: */
0588: public void addInternalFrameListener(final InternalFrameListener l) {
0589: listenerList.add(InternalFrameListener.class, l);
0590: }
0591:
0592: /**
0593: * Returns all registered internal frame listeners.
0594: *
0595: * @return all registered internal frame listeners
0596: */
0597: public InternalFrameListener[] getInternalFrameListeners() {
0598: return listenerList.getListeners(InternalFrameListener.class);
0599: }
0600:
0601: /**
0602: * Fires the internal frame event.
0603: *
0604: * @param id identifier of the event to fire
0605: */
0606: protected void fireInternalFrameEvent(final int id) {
0607: Object[] listeners = listenerList.getListenerList();
0608: InternalFrameEvent e = null;
0609: for (int i = listeners.length - 2; i >= 0; i -= 2) {
0610: if (listeners[i] == InternalFrameListener.class) {
0611: if (e == null) {
0612: e = new InternalFrameEvent(this , id);
0613: }
0614: InternalFrameListener l = (InternalFrameListener) listeners[i + 1];
0615: switch (id) {
0616: case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
0617: l.internalFrameActivated(e);
0618: break;
0619: case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
0620: l.internalFrameDeactivated(e);
0621: break;
0622: case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
0623: l.internalFrameIconified(e);
0624: break;
0625: case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
0626: l.internalFrameDeiconified(e);
0627: break;
0628: case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
0629: l.internalFrameClosing(e);
0630: break;
0631: case InternalFrameEvent.INTERNAL_FRAME_OPENED:
0632: l.internalFrameOpened(e);
0633: break;
0634: case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
0635: l.internalFrameClosed(e);
0636: break;
0637: }
0638: }
0639: }
0640: }
0641:
0642: /**
0643: * Set rootPane property.
0644: *
0645: * @param root the new rootPane property value
0646: */
0647: protected void setRootPane(final JRootPane root) {
0648: JRootPane oldValue = getRootPane();
0649: if (rootPane != null) {
0650: remove(rootPane);
0651: }
0652: rootPane = root;
0653: if (root != null) {
0654: super .addImpl(root, null, 0);
0655: }
0656: firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
0657: }
0658:
0659: /**
0660: * Get rootPane property.
0661: *
0662: * @return rootPane property
0663: */
0664: @Override
0665: public JRootPane getRootPane() {
0666: return rootPane;
0667: }
0668:
0669: /**
0670: * Called by the constructors to create the default <code>rootPane</code>
0671: * property.
0672: *
0673: * @return default <code>rootPane</code>
0674: */
0675: protected JRootPane createRootPane() {
0676: return new JRootPane();
0677: }
0678:
0679: /**
0680: * @deprecated
0681: */
0682: @Deprecated
0683: public void setMenuBar(final JMenuBar menuBar) {
0684: setJMenuBar(menuBar);
0685: }
0686:
0687: /**
0688: * @deprecated
0689: */
0690: @Deprecated
0691: public JMenuBar getMenuBar() {
0692: return getJMenuBar();
0693: }
0694:
0695: /**
0696: * Sets the menu bar for the frame.
0697: *
0698: * @param menuBar the menu bar to be placed in the frame
0699: */
0700: public void setJMenuBar(final JMenuBar menuBar) {
0701: JMenuBar oldValue = getJMenuBar();
0702: getRootPane().setJMenuBar(menuBar);
0703: firePropertyChange(MENU_BAR_PROPERTY, oldValue, menuBar);
0704: }
0705:
0706: /**
0707: * Returns the menu bar for the frame.
0708: *
0709: * @return the menu bar for the frame
0710: */
0711: public JMenuBar getJMenuBar() {
0712: return getRootPane().getJMenuBar();
0713: }
0714:
0715: /**
0716: * Sets layeredPane property. This is a bound property.
0717: *
0718: * @param layeredPane the new layeredPane property value
0719: */
0720: public void setLayeredPane(final JLayeredPane layeredPane) {
0721: JLayeredPane oldValue = getLayeredPane();
0722: getRootPane().setLayeredPane(layeredPane);
0723: firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layeredPane);
0724: }
0725:
0726: /**
0727: * Returns layeredPane property.
0728: *
0729: * @return layeredPane property
0730: */
0731: public JLayeredPane getLayeredPane() {
0732: return getRootPane().getLayeredPane();
0733: }
0734:
0735: /**
0736: * Sets the desktop icon to be used when the internal frame is iconified.
0737: *
0738: * @param icon the desktop icon to be used when the internal frame is
0739: * iconified
0740: */
0741: public void setDesktopIcon(final JDesktopIcon icon) {
0742: desktopIcon = icon;
0743: }
0744:
0745: /**
0746: * Returns the desktop icon used when the internal frame is iconified.
0747: *
0748: * @return the desktop icon used when the internal frame is iconified
0749: */
0750: public JDesktopIcon getDesktopIcon() {
0751: return desktopIcon;
0752: }
0753:
0754: /**
0755: * Returns the desktop pane that contains the internal frame
0756: * or <code>desktoIcon</code>.
0757: *
0758: * @return desktop pane that contains the internal frame or
0759: * <code>desktoIcon</code>
0760: */
0761: public JDesktopPane getDesktopPane() {
0762: Container result = SwingUtilities.getAncestorOfClass(
0763: JDesktopPane.class, this );
0764: if (result == null) {
0765: result = SwingUtilities.getAncestorOfClass(
0766: JDesktopPane.class, getDesktopIcon());
0767: }
0768: return (JDesktopPane) result;
0769: }
0770:
0771: /**
0772: * Returns the accessible context for the internal frame.
0773: *
0774: * @return the accessible context for the internal frame
0775: */
0776: @Override
0777: public AccessibleContext getAccessibleContext() {
0778: if (accessibleContext == null) {
0779: accessibleContext = new AccessibleJInternalFrame();
0780: }
0781: return accessibleContext;
0782: }
0783:
0784: /**
0785: * Sets the icon to be displayed in the title bar of the internal frame.
0786: *
0787: * @param icon the icon to be displayed in the title bar of the internal
0788: * frame
0789: */
0790: public void setFrameIcon(final Icon icon) {
0791: Icon oldValue = getFrameIcon();
0792: frameIcon = icon;
0793: firePropertyChange(FRAME_ICON_PROPERTY, oldValue, frameIcon);
0794: }
0795:
0796: /**
0797: * Returns the icon displayed in the title bar of the internal frame.
0798: *
0799: * @return the icon displayed in the title bar of the internal frame
0800: */
0801: public Icon getFrameIcon() {
0802: return frameIcon;
0803: }
0804:
0805: /**
0806: * Sets the title of the frame.
0807: * <code>title</code> can be <code>null</code>.
0808: * This is a bound property.
0809: *
0810: * @param title the title of the frame to be set
0811: */
0812: public void setTitle(final String title) {
0813: String oldValue = getTitle();
0814: this .title = title;
0815: firePropertyChange(TITLE_PROPERTY, oldValue, title);
0816: }
0817:
0818: /**
0819: * Returns the title of the frame.
0820: *
0821: * @return the title of the frame
0822: */
0823: public String getTitle() {
0824: return title;
0825: }
0826:
0827: /**
0828: * Returns string representation of this frame.
0829: *
0830: * @return string representation of this frame
0831: */
0832: @Override
0833: protected String paramString() {
0834: return super .paramString();
0835: }
0836:
0837: /**
0838: * Gets the warning string that is displayed with this internal frame.
0839: * Since internal frame is always fully contained within a window, this
0840: * method always returns <code>null</code>.
0841: *
0842: * @return <code>null</code>
0843: */
0844: public final String getWarningString() {
0845: return null;
0846: }
0847:
0848: /**
0849: * Returns the name of the L&F class that renders this component.
0850: *
0851: * @return the string "InternalFrameUI"
0852: */
0853: @Override
0854: public String getUIClassID() {
0855: return "InternalFrameUI";
0856: }
0857:
0858: /**
0859: * Sets the layer attribute of the internal frame.
0860: *
0861: * @param layer the value of layer attribute to be set
0862: */
0863: public void setLayer(final Integer layer) {
0864: setLayer(layer.intValue());
0865: }
0866:
0867: /**
0868: * Sets the layer attribute of the internal frame. The method
0869: * <code>setLayer(Integer)</code> should be used for layer values
0870: * predefined in <code>JLayeredPane</code>.
0871: *
0872: * @param layer the value of layer attribute to be set
0873: */
0874: public void setLayer(final int layer) {
0875: //if (getDesktopPane() == null) {
0876: if (getParent() instanceof JLayeredPane) {
0877: ((JLayeredPane) getParent()).setLayer(this , layer);
0878: } else {
0879: JLayeredPane.putLayer(this , layer);
0880: }
0881: }
0882:
0883: /**
0884: * Returns the layer attribute of the internal frame.
0885: *
0886: * @return the layer attribute of the internal frame
0887: */
0888: public int getLayer() {
0889: return JLayeredPane.getLayer(this );
0890: }
0891:
0892: /**
0893: * Sets normal bounds of this internal frame, the bounds that this frame
0894: * will be restored to from its maximized state.
0895: *
0896: * @param rect - normal bounds value
0897: */
0898: public void setNormalBounds(final Rectangle rect) {
0899: normalBounds = rect;
0900: }
0901:
0902: /**
0903: * Returns the normal bounds of this internal frame.
0904: *
0905: * @return the normal bounds of this internal frame
0906: */
0907: public Rectangle getNormalBounds() {
0908: return normalBounds;
0909: }
0910:
0911: @Override
0912: public void setLayout(final LayoutManager layout) {
0913: if (isRootPaneCheckingEnabled()) {
0914: getContentPane().setLayout(layout);
0915: } else {
0916: super .setLayout(layout);
0917: }
0918: }
0919:
0920: /**
0921: * Is overridden to allow optimized painting when the internal
0922: * frame is being dragged.
0923: *
0924: * @param g the <code>Graphics</code> object to paint
0925: */
0926: @Override
0927: protected void paintComponent(final Graphics g) {
0928: if (blitSupport != null) {
0929: blitSupport.onPaint();
0930: }
0931: super .paintComponent(g);
0932: }
0933:
0934: /**
0935: * Sets contentPane property. This is a bound property.
0936: *
0937: * @param contentPane the new contentPane property value
0938: */
0939: public void setContentPane(final Container contentPane) {
0940: Container oldValue = getContentPane();
0941: getRootPane().setContentPane(contentPane);
0942: firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, contentPane);
0943: }
0944:
0945: /**
0946: * Returns the contentPane property.
0947: *
0948: * @return the contentPane property
0949: */
0950: public Container getContentPane() {
0951: return getRootPane().getContentPane();
0952: }
0953:
0954: /**
0955: * Set glassPane property. This is a bound property.
0956: *
0957: * @param glassPane the new glassPane property value
0958: */
0959: public void setGlassPane(final Component glassPane) {
0960: Component oldValue = getGlassPane();
0961: getRootPane().setGlassPane(glassPane);
0962: firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glassPane);
0963: }
0964:
0965: /**
0966: * Returns glassPane property.
0967: *
0968: * @return glassPane property
0969: */
0970: public Component getGlassPane() {
0971: return getRootPane().getGlassPane();
0972: }
0973:
0974: @Override
0975: public void remove(final Component comp) {
0976: if (comp.getParent() == this ) {
0977: // remove directly from JInternalFrame
0978: super .remove(comp);
0979: } else {
0980: getContentPane().remove(comp);
0981: }
0982: }
0983:
0984: /*
0985: * Remembers the focused component when the internal frame is unselected.
0986: */
0987: private void setMostRecentFocusOwner(final Component c) {
0988: // we really need this 'if' before the assignment.
0989: // Suppose we have JInternalFrame on
0990: // JDesktopPane inside of some window, which has JMenu.
0991: // If the user selects menu, JInternalFrame becomes unselected,
0992: // but this method is call with c == JRootPane of the global window.
0993: // We must not remember this component as mostRecentFocusOwner.
0994: if (this .isAncestorOf(c)) {
0995: mostRecentFocusOwner = c;
0996: }
0997: }
0998:
0999: /**
1000: * Returns the component that will receive the focus when the
1001: * internal frame is selected.
1002: *
1003: * @return the component that will receive the focus when the
1004: * internal frame is selected
1005: */
1006: public Component getMostRecentFocusOwner() {
1007: if (isSelected()) {
1008: return getFocusOwner();
1009: }
1010: if (mostRecentFocusOwner != null) {
1011: return mostRecentFocusOwner;
1012: }
1013: Component result = null;
1014: if (getFocusTraversalPolicy() instanceof InternalFrameFocusTraversalPolicy) {
1015: result = ((InternalFrameFocusTraversalPolicy) getFocusTraversalPolicy())
1016: .getInitialComponent(this );
1017: }
1018: if (result == null) {
1019: return getFocusTraversalPolicy().getDefaultComponent(this );
1020: }
1021: return result;
1022: }
1023:
1024: /**
1025: * Returns the component that currently has the focus.
1026: *
1027: * @return the component that currently has the focus, if the internal
1028: * frame is selected; otherwise returns <code>null</code>
1029: */
1030: public Component getFocusOwner() {
1031: if (!isSelected()) {
1032: return null;
1033: }
1034: Component focusOwner = KeyboardFocusManager
1035: .getCurrentKeyboardFocusManager().getFocusOwner();
1036: return isAncestorOf(focusOwner) ? focusOwner : null;
1037: }
1038:
1039: /**
1040: * Restores focus to the last subcomponent that had focus.
1041: */
1042: public void restoreSubcomponentFocus() {
1043: Component comp = getMostRecentFocusOwner();
1044: if (comp != null) {
1045: comp.requestFocus();
1046: } else {
1047: getContentPane().requestFocus();
1048: }
1049: }
1050:
1051: /**
1052: * Selects or deselects the internal frame. If the internal frame is selected,
1053: * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event is fired.
1054: * If the internal frame is deselected,
1055: * <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event is fired.
1056: *
1057: * @param b shows whether select or deselect the internal frame
1058: *
1059: * @throws PropertyVetoException if the attempt to set the property is vetoed
1060: */
1061: public void setSelected(final boolean b)
1062: throws PropertyVetoException {
1063: if (b && !isShowing() && !getDesktopIcon().isShowing()) {
1064: return; // can't select if the internal frame is not showing
1065: }
1066: if (b == isSelected()) {
1067: return;
1068: }
1069: Boolean oldValue = Boolean.valueOf(isSelected());
1070: Boolean newValue = Boolean.valueOf(b);
1071: fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1072: // remember the focused component for the deactivated frame;
1073: // recall the last focused component for the activated frame;
1074: setMostRecentFocusOwner(getMostRecentFocusOwner());
1075: isSelected = b;
1076: if (isSelected()) {
1077: isSelected = false;
1078: restoreSubcomponentFocus();
1079: isSelected = true;
1080: }
1081: firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1082: // fire internal frame events
1083: fireInternalFrameEvent(isSelected() ? InternalFrameEvent.INTERNAL_FRAME_ACTIVATED
1084: : InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
1085: }
1086:
1087: /**
1088: * Returns whether the internal frame is selected.
1089: *
1090: * @return whether the internal frame is selected
1091: */
1092: public boolean isSelected() {
1093: return isSelected;
1094: }
1095:
1096: /**
1097: * Sets <code>rootPaneCheckingEnabled</code> property.
1098: *
1099: * @param enabled the new <code>rootPaneCheckingEnabled</code> value
1100: */
1101: protected void setRootPaneCheckingEnabled(final boolean enabled) {
1102: LookAndFeel.markPropertyNotInstallable(this ,
1103: "rootPaneCheckingEnabled");
1104: rootPaneCheckingEnabled = enabled;
1105: }
1106:
1107: /**
1108: * Returns <code>rootPaneCheckingEnabled</code> value.
1109: *
1110: * @return the value of <code>rootPaneCheckingEnabled</code>
1111: */
1112: protected boolean isRootPaneCheckingEnabled() {
1113: return rootPaneCheckingEnabled;
1114: }
1115:
1116: /**
1117: * Sets the <code>resizable</code> property.
1118: *
1119: * @param b new value for the <code>resizable</code> property
1120: */
1121: public void setResizable(final boolean b) {
1122: boolean oldValue = isResizable();
1123: resizable = b;
1124: LookAndFeel.markPropertyNotInstallable(this ,
1125: StringConstants.INTERNAL_FRAME_RESIZABLE_PROPERTY);
1126: firePropertyChange(
1127: StringConstants.INTERNAL_FRAME_RESIZABLE_PROPERTY,
1128: oldValue, b);
1129: }
1130:
1131: /**
1132: * Get the <code>resizable</code> property value.
1133: *
1134: * @return the <code>resizable</code> property value
1135: */
1136: public boolean isResizable() {
1137: return resizable;
1138: }
1139:
1140: /**
1141: * Maximizes or restores the internal frame.
1142: *
1143: * @param b indicates whether to maximize or restore the internal frame
1144: *
1145: * @throws PropertyVetoException
1146: */
1147: public void setMaximum(final boolean b)
1148: throws PropertyVetoException {
1149: Boolean oldValue = Boolean.valueOf(isMaximum());
1150: Boolean newValue = Boolean.valueOf(b);
1151: fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1152: if (b && !isMaximum()) {
1153: setNormalBounds(getBounds());
1154: }
1155: isMaximum = b;
1156: firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1157: }
1158:
1159: /**
1160: * Returns whether the internal frame is currently maximized.
1161: *
1162: * @return whether the internal frame is currently maximized
1163: */
1164: public boolean isMaximum() {
1165: return isMaximum;
1166: }
1167:
1168: /**
1169: * Sets the <code>maximizable</code> property.
1170: *
1171: * @param b the new value for the <code>maximizable</code> property
1172: */
1173: public void setMaximizable(final boolean b) {
1174: boolean oldValue = isMaximizable();
1175: maximizable = b;
1176: LookAndFeel.markPropertyNotInstallable(this ,
1177: StringConstants.INTERNAL_FRAME_MAXIMIZABLE_PROPERTY);
1178: firePropertyChange(
1179: StringConstants.INTERNAL_FRAME_MAXIMIZABLE_PROPERTY,
1180: oldValue, b);
1181: }
1182:
1183: /**
1184: * Get the <code>maximizable</code> property value.
1185: *
1186: * @return the <code>maximizable</code> property value
1187: */
1188: public boolean isMaximizable() {
1189: return maximizable;
1190: }
1191:
1192: /**
1193: * Sets the <code>iconable</code> property.
1194: *
1195: * @param b new value for the <code>iconable</code> property
1196: */
1197: public void setIconifiable(final boolean b) {
1198: boolean oldValue = isIconifiable();
1199: iconable = b;
1200: LookAndFeel.markPropertyNotInstallable(this ,
1201: StringConstants.INTERNAL_FRAME_ICONABLE_PROPERTY);
1202: firePropertyChange(
1203: StringConstants.INTERNAL_FRAME_ICONABLE_PROPERTY,
1204: oldValue, b);
1205: }
1206:
1207: /**
1208: * Get the <code>iconable</code> property value.
1209: *
1210: * @return the <code>iconable</code> property value
1211: */
1212: public boolean isIconifiable() {
1213: return iconable;
1214: }
1215:
1216: /**
1217: * Iconifies or deiconifies the internal frame, if the L&F supports iconification.
1218: * If the internal frame state is iconified, this method fires an
1219: * <code>INTERNAL_FRAME_ICONIFIED</code> event.
1220: * If the internal frame is deiconified, an <code>INTERNAL_FRAME_DEICONIFIED</code>
1221: * event is fired.
1222: *
1223: * @param b shows whether iconify or deiconify the internal frame
1224: *
1225: * @throws PropertyVetoException if the attempt to set the property is vetoed
1226: */
1227: public void setIcon(final boolean b) throws PropertyVetoException {
1228: Boolean oldValue = Boolean.valueOf(isIcon());
1229: Boolean newValue = Boolean.valueOf(b);
1230: fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
1231: isIcon = b;
1232: firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
1233: // fire internal frame events
1234: if (oldValue.booleanValue() != b) {
1235: if (oldValue.booleanValue()) {
1236: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
1237: } else {
1238: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
1239: }
1240: }
1241: }
1242:
1243: /**
1244: * Returns whether the frame is currently iconified.
1245: *
1246: * @return whether the frame is currently iconified
1247: */
1248: public boolean isIcon() {
1249: return isIcon;
1250: }
1251:
1252: /**
1253: * Does nothing because <code>JInternalFrame</code> must be always
1254: * a focus cycle root.
1255: *
1256: * @param b the value is ignored
1257: */
1258: @Override
1259: public final void setFocusCycleRoot(final boolean b) {
1260: // do nothing
1261: }
1262:
1263: /**
1264: * Always returns true because <code>JInternalFrame</code> is always
1265: * a focus cycle root.
1266: *
1267: * @return true
1268: */
1269: @Override
1270: public final boolean isFocusCycleRoot() {
1271: return true;
1272: }
1273:
1274: /**
1275: * Always returns null because <code>JInternalFrame</code> is always
1276: * a focus cycle root.
1277: *
1278: * @return null
1279: */
1280: @Override
1281: public final Container getFocusCycleRootAncestor() {
1282: return null;
1283: }
1284:
1285: /**
1286: * Closes the internal frame if <code>b</code> is <code>true</code>.
1287: *
1288: * @param b must be <code>true</code>
1289: *
1290: * @throws PropertyVetoException if the attempt to close the internal frame
1291: * is vetoed
1292: */
1293: public void setClosed(final boolean b) throws PropertyVetoException {
1294: if (isClosed() || !b) {
1295: return;
1296: }
1297: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1298: fireVetoableChange(IS_CLOSED_PROPERTY, Boolean
1299: .valueOf(isClosed()), Boolean.valueOf(b));
1300: dispose();
1301: }
1302:
1303: /**
1304: * Returns <code>true</code> if the internal frame is closed, otherwise
1305: * returns <code>false</code>.
1306: *
1307: * @return <code>true</code> if the internal frame is closed, otherwise
1308: * returns <code>false</code>
1309: */
1310: public boolean isClosed() {
1311: return isClosed;
1312: }
1313:
1314: /**
1315: * Sets the <code>closable</code> property.
1316: *
1317: * @param b new value for the <code>closable</code> property
1318: */
1319: public void setClosable(final boolean b) {
1320: boolean oldValue = isClosable();
1321: closable = b;
1322: LookAndFeel.markPropertyNotInstallable(this ,
1323: StringConstants.INTERNAL_FRAME_CLOSABLE_PROPERTY);
1324: firePropertyChange(
1325: StringConstants.INTERNAL_FRAME_CLOSABLE_PROPERTY,
1326: oldValue, b);
1327: }
1328:
1329: /**
1330: * Get the <code>closable</code> property value.
1331: *
1332: * @return the <code>closable</code> property value
1333: */
1334: public boolean isClosable() {
1335: return closable;
1336: }
1337:
1338: /**
1339: * Sets the <code>defaultCloseOperation</code> property.
1340: *
1341: * @param operation the new <code>defaultCloseOperation</code> value
1342: */
1343: public void setDefaultCloseOperation(final int operation) {
1344: defaultCloseOperation = operation;
1345: }
1346:
1347: /**
1348: * Returns <code>defaultCloseOperation</code> value.
1349: *
1350: * @return the <code>defaultCloseOperation</code> value
1351: */
1352: public int getDefaultCloseOperation() {
1353: return defaultCloseOperation;
1354: }
1355:
1356: /**
1357: * Fires an <code>INTERNAL_FRAME_CLOSING</code> event and then performs
1358: * the action defined by the default close operation.
1359: */
1360: public void doDefaultCloseAction() {
1361: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1362: switch (getDefaultCloseOperation()) {
1363: case DISPOSE_ON_CLOSE: // dispose
1364: dispose();
1365: break;
1366: case HIDE_ON_CLOSE: // hide
1367: setVisible(false);
1368: break;
1369: case DO_NOTHING_ON_CLOSE: // do nothing
1370: break;
1371: }
1372: }
1373:
1374: /**
1375: * Moves the internal frame to the position 0 if its parent is
1376: * <code>JLayeredPane</code>
1377: */
1378: public void moveToFront() {
1379: if (getParent() instanceof JLayeredPane) {
1380: ((JLayeredPane) getParent()).setPosition(this , 0);
1381: }
1382: }
1383:
1384: /**
1385: * Moves the internal frame to the position -1 if its parent is
1386: * <code>JLayeredPane</code>
1387: */
1388: public void moveToBack() {
1389: if (getParent() instanceof JLayeredPane) {
1390: ((JLayeredPane) getParent()).setPosition(this , -1);
1391: }
1392: }
1393:
1394: /**
1395: * Moves the internal frame to the front.
1396: */
1397: public void toFront() {
1398: moveToFront();
1399: // Note: is there any difference between moveToFront() and toFront()
1400: }
1401:
1402: /**
1403: * Moves the internal frame to the back.
1404: */
1405: public void toBack() {
1406: moveToBack();
1407: // Note: is there any difference between moveToBack() and toBack()
1408: }
1409:
1410: /**
1411: * Subcomponents are layed out to their preferred sizes.
1412: */
1413: public void pack() {
1414: setSize(getPreferredSize());
1415: doLayout();
1416: }
1417:
1418: /**
1419: * If the internal frame is not visible, moves it to the front,
1420: * makes it visible, and attempts to select it. If the internal frame
1421: * is shown the first time, <code>INTERNAL_FRAME_OPENED</code> event
1422: * is fired. The method does nothing if the internal frame is already
1423: * visible.
1424: */
1425: @SuppressWarnings("deprecation")
1426: @Override
1427: @Deprecated
1428: public void show() {
1429: if (isVisible()) {
1430: return;
1431: }
1432: if (blitSupport == null) {
1433: blitSupport = new BlitSupport(this );
1434: }
1435: if (getDesktopIcon() != null) {
1436: getDesktopIcon().setVisible(true);
1437: }
1438: moveToFront();
1439: // Note: how to set isVisible to true without calling of obsolete method?
1440: // cannot use super.setVisibile(true) - stack overflow will occur
1441: super .show();
1442: try {
1443: setSelected(true);
1444: } catch (final PropertyVetoException e) {
1445: }
1446: // fire INTERNAL_FRAME_OPENED when opening the first time
1447: if (firstTimeOpen) {
1448: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
1449: firstTimeOpen = false;
1450: }
1451: }
1452:
1453: @SuppressWarnings("deprecation")
1454: @Override
1455: @Deprecated
1456: public void hide() {
1457: super .hide();
1458: // the desktop icon becomes visible when the internal frame becomes
1459: // visible; the same is correct for hiding
1460: if (getDesktopIcon() != null) {
1461: getDesktopIcon().setVisible(false);
1462: }
1463: }
1464:
1465: /**
1466: * Makes the internal frame invisible, unselected and closed. If
1467: * the internal fram was not already closed, <code>INTERNAL_FRAME_CLOSED</code>
1468: * event is fired.
1469: */
1470: public void dispose() {
1471: setVisible(false);
1472: try {
1473: setSelected(false);
1474: } catch (final PropertyVetoException e) {
1475: }
1476: boolean oldValue = isClosed();
1477: isClosed = true;
1478: firePropertyChange(IS_CLOSED_PROPERTY, oldValue, true);
1479: if (!oldValue) {
1480: fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
1481: }
1482: }
1483:
1484: @Override
1485: public void setBounds(final int x, final int y, final int w,
1486: final int h) {
1487: Dimension oldSize = getSize();
1488: super.setBounds(x, y, w, h);
1489: if (oldSize.width != w || oldSize.height != h) {
1490: validate();
1491: return;
1492: }
1493: if (blitSupport != null) {
1494: blitSupport.paint();
1495: }
1496: }
1497: }
|