home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
JInternalFrame.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
53KB
|
1,639 lines
/* @(#)JInternalFrame.java 1.54 98/02/05
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyVetoException;
import java.beans.PropertyChangeEvent;
import com.sun.java.swing.border.Border;
import com.sun.java.swing.event.InternalFrameEvent;
import com.sun.java.swing.event.InternalFrameListener;
import com.sun.java.swing.plaf.*;
import com.sun.java.accessibility.*;
/** A lightweight object that provides many of the features of
* a native frame, including dragging, closing, becoming an icon,
* resizing, title display, and support for a menu bar. Generally,
* you will create an instance and add it to a JDesktopPane.
* <p>
* The JInternalFrame has a 'contentPane' that is used to describe the
* area of the component where normal child components should be placed.
* So, if you wanted build a JInternalFrame that had a number of buttons
* arranged through a BorderLayout object, you might do something like:
* <PRE>
* JComponent c = frame.getContentPane();
* c.setLayoutManager(new BorderLayout());
* c.add(new JButton(), BorderLayout.NORTH);
* c.add(new JButton(), BorderLayout.CENTER);
* <PRE>
*
* <p>
* Please see the JRootPane documentation for a complete description of
* the contentPane(), glassPane(), and layeredPane() components.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @see JDesktopPane
* @see JDesktopIcon
* @see DesktopManager
* @see JRootPane
*
* @version 1.54 02/05/98
* @author David Kloba
* @beaninfo
* attribute: isContainer true
* attribute: containerDelegate getContentPane
* description: A frame container which is contained within
* another window.
*/
public class JInternalFrame extends JComponent implements
Accessible, MouseListener, MouseMotionListener, WindowConstants,
RootPaneContainer, ComponentListener
{
/**
* @see #getRootPane
* @see #setRootPane
*/
protected JRootPane rootPane;
/**
* @see #isRootPaneCheckingEnabled
* @see #setRootPaneCheckingEnabled
*/
protected boolean rootPaneCheckingEnabled = false;
protected boolean closable;
protected boolean isClosed;
protected boolean maximizable;
protected boolean isMaximum;
protected boolean iconable;
protected boolean isIcon;
protected boolean resizable;
protected boolean isSelected;
protected Icon frameIcon;
protected String title;
protected JDesktopIcon desktopIcon;
transient InternalFrameListener internalFrameListener;
private boolean opened;
private int defaultCloseOperation = HIDE_ON_CLOSE;
/** Bound property name. */
public final static String CONTENT_PANE_PROPERTY = "contentPane";
/** Bound property name. */
public final static String MENU_BAR_PROPERTY = "menuBar";
/** Bound property name. */
public final static String TITLE_PROPERTY = "title";
/** Bound property name. */
public final static String LAYERED_PANE_PROPERTY = "layeredPane";
/** Bound property name. */
public final static String ROOT_PANE_PROPERTY = "rootPane";
/** Bound property name. */
public final static String GLASS_PANE_PROPERTY = "glassPane";
/** Constrained property name indicated that this frame has selected status. */
public final static String IS_SELECTED_PROPERTY = "isSelected";
/** Constrained property name indicating that the frame is closed. */
public final static String IS_CLOSED_PROPERTY = "isClosed";
/** Constrained property name indicating that the frame is maximized. */
public final static String IS_MAXIMUM_PROPERTY = "isMaximum";
/** Constrained property name indicating that the frame is iconified. */
public final static String IS_ICON_PROPERTY = "isIcon";
/** Creates a JInternalFrame with no title, and all boolean setting false.*/
public JInternalFrame() {
this("", false, false, false, false);
}
/** Creates a JInternalFrame with <b>title</b>, and all boolean setting false.*/
public JInternalFrame(String title) {
this(title, false, false, false, false);
}
public JInternalFrame(String title, boolean resizable) {
this(title, resizable, false, false, false);
}
public JInternalFrame(String title, boolean resizable, boolean closable) {
this(title, resizable, closable, false, false);
}
public JInternalFrame(String title, boolean resizable, boolean closable,
boolean maximizable) {
this(title, resizable, closable, maximizable, false);
}
/** Primitive creation method that sets the appropriate values.
*/
public JInternalFrame(String title, boolean resizable, boolean closable,
boolean maximizable, boolean iconifiable) {
setRootPane(createRootPane());
setLayout(new BorderLayout());
this.title = title;
this.resizable = resizable;
this.closable = closable;
this.maximizable = maximizable;
isMaximum = false;
this.iconable = iconifiable;
isIcon = false;
updateUI();
setRootPaneCheckingEnabled(true);
desktopIcon = new JDesktopIcon(this);
if (isVisible()) {
postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
opened = true;
}
}
protected JRootPane createRootPane() {
return new JRootPane();
}
public InternalFrameUI getUI() {
return (InternalFrameUI)ui;
}
/**
* Sets the UI delegate for this JInternalFrame.
* @beaninfo
* expert: true
* description: The InternalFrameUI implementation that
* defines the labels look and feel.
*/
public void setUI(InternalFrameUI ui) {
boolean checkingEnabled = isRootPaneCheckingEnabled();
try {
setRootPaneCheckingEnabled(false);
super.setUI(ui);
}
finally {
setRootPaneCheckingEnabled(checkingEnabled);
}
}
public void updateUI() {
setUI((InternalFrameUI)UIManager.getUI(this));
invalidate();
if (desktopIcon != null) {
desktopIcon.updateUIWhenHidden();
}
}
/* This method is called if updateUI was called on the associated
* JDesktopIcon. It's necessary to avoid infinite recursion.
*/
void updateUIWhenHidden() {
setUI((InternalFrameUI)UIManager.getUI(this));
invalidate();
Component[] children = getComponents();
if (children != null) {
for(int i = 0; i < children.length; i++) {
SwingUtilities.updateComponentTreeUI(children[i]);
}
}
}
/**
* @return "InternalFrameUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
* @beaninfo
* description: UIClassID
*/
public String getUIClassID() {
return "InternalFrameUI";
}
/**
* @return true if add and setLayout should be checked
* @see #addImpl
* @see #setLayout
* @see #setRootPaneCheckingEnabled
*/
protected boolean isRootPaneCheckingEnabled() {
return rootPaneCheckingEnabled;
}
/**
* If true then calls to add() and setLayout() will cause an exception
* to be thrown.
*
* @see #addImpl
* @see #setLayout
* @see #isRootPaneCheckingEnabled
*/
protected void setRootPaneCheckingEnabled(boolean enabled) {
rootPaneCheckingEnabled = enabled;
}
/**
* Create an runtime exception with a message like:
* <pre>
* "Do not use JFrame.add() use JFrame.getContentPane().add() instead"
* </pre>
*/
private Error createRootPaneException(String op) {
String type = getClass().getName();
return new Error(
"Do not use " + type + "." + op + "() use "
+ type + ".getContentPane()." + op + "() instead");
}
/**
* By default, children may not be added directly to a this component,
* they must be added to its contentPane instead. For example:
* <pre>
* thisComponent.getContentPane().add(child)
* </pre>
* An attempt to add to directly to this component will cause an
* runtime exception to be thrown. Subclasses can disable this
* behavior.
*
* @see #setRootPaneCheckingEnabled
* @exception Error if called with rootPaneChecking true
*/
protected void addImpl(Component comp, Object constraints, int index)
{
if(isRootPaneCheckingEnabled()) {
throw createRootPaneException("add");
}
else {
super.addImpl(comp, constraints, index);
}
}
/**
* By default the layout of this component may not be set,
* the layout of its contentPane should be set instead.
* For example:
* <pre>
* thiComponent.getContentPane().setLayout(new BorderLayout())
* </pre>
* An attempt to set the layout of this component will cause an
* runtime exception to be thrown. Subclasses can disable this
* behavior.
*
* @see #setRootPaneCheckingEnabled
* @exception Error if called with rootPaneChecking true
*/
public void setLayout(LayoutManager manager) {
if(isRootPaneCheckingEnabled()) {
throw createRootPaneException("setLayout");
}
else {
super.setLayout(manager);
}
}
//////////////////////////////////////////////////////////////////////////
/// Property Methods
//////////////////////////////////////////////////////////////////////////
/**
* Returns the current JMenuBar for this JInternalFrame, or null
* if no menu bar has been set.
* @see setMenuBar
*/
public JMenuBar getMenuBar() {
return getRootPane().getMenuBar();
}
/**
* Sets the JMenuBar for this JInternalFrame.
* @see getMenuBar
* @beaninfo
* preferred: true
* description: The menubar for accessing pulldown menus
* from this frame.
*/
public void setMenuBar(JMenuBar m) {
JMenuBar oldValue = getMenuBar();
getRootPane().setMenuBar(m);
firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
}
/**
* @see RootPaneContainer#getContentPane
*/
public Container getContentPane() {
return getRootPane().getContentPane();
}
/**
* Sets this JInternalFrame's content pane.
* @see RootPaneContainer#getContentPane
* @beaninfo
* bound: true
* hidden: true
* description: The client area of the frame where child
* components are normally inserted.
*/
public void setContentPane(Container c) {
Container oldValue = getContentPane();
getRootPane().setContentPane(c);
firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
}
/**
* @see RootPaneContainer#setLayeredPane
*/
public JLayeredPane getLayeredPane() {
return getRootPane().getLayeredPane();
}
/**
* @see RootPaneContainer#setLayeredPane
* @beaninfo
* hidden: true
* bound: true
* description: The pane which holds the various desktop layers.
*/
public void setLayeredPane(JLayeredPane layered) {
JLayeredPane oldValue = getLayeredPane();
getRootPane().setLayeredPane(layered);
firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
}
/**
* @see RootPaneContainer#setGlassPane
*/
public Component getGlassPane() {
return getRootPane().getGlassPane();
}
/**
* @see RootPaneContainer#getGlassPane
* @beaninfo
* hidden: true
* description: A transparent pane used for menu rendering.
*/
public void setGlassPane(Component glass) {
Component oldValue = getGlassPane();
getRootPane().setGlassPane(glass);
firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
}
/**
* @see RootPaneContainer#getRootPane
*/
public JRootPane getRootPane() {
return rootPane;
}
/**
* Set the rootPane property. This method is called by the constructor.
* @beaninfo
* hidden: true
* beaninfo: The rootPane used by this frame.
*/
protected void setRootPane(JRootPane root) {
if(rootPane != null) {
remove(rootPane);
}
JRootPane oldValue = getRootPane();
rootPane = root;
if(rootPane != null) {
boolean checkingEnabled = isRootPaneCheckingEnabled();
try {
setRootPaneCheckingEnabled(false);
add(rootPane, BorderLayout.CENTER);
}
finally {
setRootPaneCheckingEnabled(checkingEnabled);
}
}
firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
}
/**
* Set the visible state of the object.
*
* @param b if true, shows this object; otherwise, hides it
*/
public void setVisible(boolean b) {
super.setVisible(b);
// If first time shown, generate InternalFrameOpened event
if (!opened) {
postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
opened = true;
}
}
/**
* Set that this JInternalFrame can be closed by some user action.
* @beaninfo
* preferred: true
* description: Indicates whether this frame can be closed.
*/
public void setClosable(boolean b) {
closable = b;
}
/**
* Returns whether this JInternalFrame be closed by some user action.
*/
public boolean isClosable() {
return closable;
}
public boolean isClosed() {
return isClosed;
}
/** Calling this method with true, will cause the frame to close.
*
* @exception PropertyVetoException when the attempt to set the
* property is vetoed by the receiver.
* @beaninfo
* constrained: true
* description: Indicates that the frame has been closed.
*/
public void setClosed(boolean b) throws PropertyVetoException {
if (isClosed == b) {
return;
}
Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
isClosed = b;
if (isClosed) {
/* Dispatch a closed event to any listeners. We can't post
* an event since firing IS_CLOSED_PROPERTY causes this
* frame to be removed from its parent, which causes any
* of its events on the EventQueue to get purged.
*/
synchronized (this) {
if (internalFrameListener != null) {
InternalFrameEvent e = new InternalFrameEvent(
this, InternalFrameEvent.INTERNAL_FRAME_CLOSED);
dispatchEvent(e);
}
}
opened = false;
} else if (!opened) {
postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
opened = true;
}
firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
}
/**
* Set that the JInternalFrame resizable by some user action.
* @beaninfo
* preferred: true
* description: Determines whether the frame can be resized
* by the user.
*/
public void setResizable(boolean b) {
resizable = b;
}
public boolean isResizable() {
// don't allow resizing when maximized.
return isMaximum ? false : resizable;
}
/**
* Set that the JInternalFrame can be made an icon by some user action.
* @beaninfo:
* preferred: true
* bound: false
* description: Determines whether this frame can be iconified.
*/
public void setIconifiable(boolean b) {
iconable = b;
}
public boolean isIconifiable() {
return iconable;
}
public boolean isIcon() {
return isIcon;
}
/**
* Setting this property to true will iconify the frame, false will
* deiconify.
*
* @exception PropertyVetoException when the attempt to set the
* property is vetoed by the receiver.
* @beaninfo
* constrained: true
* description: The image displayed when this frame is minimized.
*/
public void setIcon(boolean b) throws PropertyVetoException {
if (isIcon == b) {
return;
}
Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
isIcon = b;
firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
postInternalFrameEvent(
b ? InternalFrameEvent.INTERNAL_FRAME_ICONIFIED :
InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
}
/**
* Set that the JInternalFrame can be maximized by some user action.
* @beaninfo
* preferred: true
* description: Determines whether this frame can be maximized.
*/
public void setMaximizable(boolean b) {
maximizable = b;
}
public boolean isMaximizable() {
return maximizable;
}
public boolean isMaximum() {
return isMaximum;
}
/**
* Setting this property to true will maximize the frame,
* false will minimize.
*
* @exception PropertyVetoException when the attempt to set the
* property is vetoed by the receiver.
* @beaninfo
* constrained: true
* description: Indicates whether the frame is maximized.
*/
public void setMaximum(boolean b) throws PropertyVetoException {
if (isMaximum == b) {
return;
}
Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
isMaximum = b;
if (b) {
getDesktopPane().addComponentListener(this);
} else {
JDesktopPane pane = getDesktopPane();
if (pane != null) {
pane.removeComponentListener(this);
}
}
firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
}
/**
* Returns the current JInternalFrame title.
* @see setTitle
*/
public String getTitle() {
return title;
}
/**
* Sets the JInternalFrame title.
* @see getTitle
* @beaninfo:
* preferred: true
* bound: true
* description: The text displayed in the title bar.
*/
public void setTitle(String title) {
String oldValue = this.title;
this.title = title;
firePropertyChange(TITLE_PROPERTY, oldValue, title);
}
/**
* A JInternalFrame normally draws it's title bar differently if it is the
* selected frame. This normally indicates that this internalFrame has
* focus for the user.
*
* @exception PropertyVetoException when the attempt to set the
* property is vetoed by the receiver.
* @beaninfo
* constrained: true
* description: Indicates whether this frame is currently
* the active frame.
*/
public void setSelected(boolean selected) throws PropertyVetoException {
if (isSelected == selected) {
return;
}
Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
isSelected = selected;
Component glassPane = getGlassPane();
if (isSelected) {
// Turn off mouse event forwarding (see below).
glassPane.removeMouseListener(this);
glassPane.removeMouseMotionListener(this);
glassPane.setVisible(false);
} else {
// Forward mouse events on to UI, so it can activate this frame.
glassPane.addMouseListener(this);
glassPane.addMouseMotionListener(this);
glassPane.setVisible(true);
}
firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
postInternalFrameEvent(
isSelected ? InternalFrameEvent.INTERNAL_FRAME_ACTIVATED :
InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
repaint();
}
public boolean isSelected() {
return isSelected;
}
/**
* Sets an image to be displayed in the titlebar of the frame.
* Do not confuse this with the desktopIcon object, which describes
* what is displayed in the JDesktop when the frame is iconified.
* @beaninfo
* description: The icon shown in the top-left corner of the frame.
*/
public void setFrameIcon(Icon icon) {
frameIcon = icon;
}
public Icon getFrameIcon() {
return frameIcon;
}
/**
* Get the background color of this object.
*
* @return the background color, if supported, of the object;
* otherwise, null
*/
public Color getBackground() {
return getContentPane().getBackground();
}
/**
* Set the background color of this object.
* (For transparency, see <code>isOpaque</code>.)
*
* @param c the new Color for the background
* @see #isOpaque
*/
public void setBackground(Color c) {
getContentPane().setBackground(c);
}
/**
* Get the foreground color of this object.
*
* @return the foreground color, if supported, of the object;
* otherwise, null
*/
public Color getForeground() {
return getContentPane().getForeground();
}
/**
* Set the foreground color of this object.
*
* @param c the new Color for the foreground
*/
public void setForeground(Color c) {
getContentPane().setForeground(c);
}
/** Convenience method that moves this component to position 0 if it's
* parent is a JLayeredPane.
*/
public void moveToFront() {
if(getParent() != null && getParent() instanceof JLayeredPane) {
JLayeredPane l = (JLayeredPane)getParent();
l.moveToFront(this);
}
}
/** Convenience method that moves this component to position -1 if it's
* parent is a JLayeredPane.
*/
public void moveToBack() {
if(getParent() != null && getParent() instanceof JLayeredPane) {
JLayeredPane l = (JLayeredPane)getParent();
l.moveToBack(this);
}
}
/**
* Convenience method for setting the layer attribute of this component.
* @beaninfo
* expert: true
* description: Specifies what desktop layer is used.
*/
public void setLayer(Integer layer) {
if(getParent() != null && getParent() instanceof JLayeredPane) {
// Normally we want to do this, as it causes the LayeredPane
// to draw properly.
JLayeredPane p = (JLayeredPane)getParent();
p.setLayer(this, layer.intValue(), p.getPosition(this));
} else {
// Try to do the right thing
JLayeredPane.putLayer(this, layer.intValue());
if(getParent() != null)
getParent().repaint(_bounds.x, _bounds.y,
_bounds.width, _bounds.height);
}
}
/** Convenience method for getting the layer attribute of this component.
*/
public int getLayer() {
return JLayeredPane.getLayer(this);
}
/** Convenience method that searchs the anscestor heirarchy for a JDesktop
* instance. If JInternalFrame finds none, the desktopIcon tree is
* searched.
*/
public JDesktopPane getDesktopPane() {
Container p;
// Search upward for desktop
p = getParent();
while(p != null && !(p instanceof JDesktopPane))
p = p.getParent();
if(p == null) {
// search it's icon parent for desktop
p = getDesktopIcon().getParent();
while(p != null && !(p instanceof JDesktopPane))
p = p.getParent();
}
return (JDesktopPane)p;
}
/**
* Sets the JDesktopIcon associated with this JInternalFrame.
* @see getDesktopIcon
* @beaninfo
* description: The icon shown when this frame is minimized.
*/
public void setDesktopIcon(JDesktopIcon d) { desktopIcon = d; }
/**
* Returns the JDesktopIcon used when this JInternalFrame is iconified.
* @see setDesktopIcon
*/
public JDesktopIcon getDesktopIcon() {
return desktopIcon;
}
/*
* Creates a new EventDispatchThread to dispatch events from. This
* method will return when stopModal is invoked.
*/
synchronized void startModal() {
try {
// can't use instanceof EventDispatchThread because the class isn't public
if (Thread.currentThread().getClass().getName().endsWith("EventDispatchThread")) {
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
// This is essentially the body of EventDispatchThread
AWTEvent event = theQueue.getNextEvent();
Object src = event.getSource();
// can't call theQueue.dispatchEvent, so I pasted it's body here
/*if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else */ if (src instanceof Component) {
((Component) src).dispatchEvent(event);
} else if (src instanceof MenuComponent) {
((MenuComponent) src).dispatchEvent(event);
} else {
System.err.println("unable to dispatch event: " + event);
}
}
} else
while (isVisible())
wait();
} catch(InterruptedException e){}
}
/*
* Stops the event dispatching loop created in a previous call to
* start.
*/
synchronized void stopModal() {
notifyAll();
}
/**
* Moves and resizes this component. Unlike other components,
* this implementation also forces re-layout, so that frame
* decorations such as the title bar are always redisplayed.
*/
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
validate();
repaint();
}
///////////////////////////
// Frame/Window equivalents
///////////////////////////
/**
* Adds the specified internal frame listener to receive internal frame events from
* this internal frame.
* @param l the internal frame listener
*/
public synchronized void addInternalFrameListener(InternalFrameListener l) {
internalFrameListener = MyEventMulticaster.add(
internalFrameListener, l);
enableEvents(0); // turn on the newEventsOnly flag in Component.
}
/**
* Removes the specified internal frame listener so that it no longer
* receives internal frame events from this internal frame.
* @param l the internal frame listener
*/
public synchronized void removeInternalFrameListener(InternalFrameListener l) {
internalFrameListener = MyEventMulticaster.remove(
internalFrameListener, l);
}
private synchronized void postInternalFrameEvent(int id) {
if (internalFrameListener != null) {
InternalFrameEvent e = new InternalFrameEvent(this, id);
/* Try posting event, but don't bother if there's a
* SecurityManager since in most environments it will
* display a harmless stacktrace when creating the
* SecurityException which developers find scary.
*/
if (JInternalFrame.class.getClassLoader() == null) {
try {
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
return;
} catch (SecurityException se) {
// Use dispatchEvent instead.
}
}
dispatchEvent(e);
}
}
private void doDefaultCloseAction() {
switch(defaultCloseOperation) {
case HIDE_ON_CLOSE:
try {
setClosed(true);
} catch (PropertyVetoException pve) {}
break;
case DISPOSE_ON_CLOSE:
try {
setClosed(true);
dispose(); // only executes if close wasn't vetoed.
} catch (PropertyVetoException pve) {}
break;
case DO_NOTHING_ON_CLOSE:
default:
break;
}
}
/**
* Processes events on this internal frame. If the event has a
* InternalFrameEvent id, it notifies its internalFrameListener, else it
* invokes its superclass's processEvent.
* @param e the event
*/
protected void processEvent(AWTEvent e) {
synchronized (this) {
if (internalFrameListener != null) {
switch(e.getID()) {
case InternalFrameEvent.INTERNAL_FRAME_OPENED:
internalFrameListener.internalFrameOpened(
(InternalFrameEvent)e);
return;
case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
internalFrameListener.internalFrameClosing(
(InternalFrameEvent)e);
doDefaultCloseAction();
return;
case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
internalFrameListener.internalFrameClosed(
(InternalFrameEvent)e);
return;
case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
internalFrameListener.internalFrameIconified(
(InternalFrameEvent)e);
return;
case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
internalFrameListener.internalFrameDeiconified(
(InternalFrameEvent)e);
return;
case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
internalFrameListener.internalFrameActivated(
(InternalFrameEvent)e);
return;
case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
internalFrameListener.internalFrameDeactivated(
(InternalFrameEvent)e);
return;
default:
break;
}
} else if (e.getID() == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
doDefaultCloseAction();
}
}
super.processEvent(e);
}
/**
* Sets the operation which will happen by default when
* the user initiates a "close" on this window.
* The possible choices are:
* <p>
* <ul>
* <li>DO_NOTHING_ON_CLOSE - do not do anything - require the
* program to handle the operation in the windowClosing
* method of a registered InternalFrameListener object.
* <li>HIDE_ON_CLOSE - automatically hide the window after
* invoking any registered InternalFrameListener objects
* <li>DISPOSE_ON_CLOSE - automatically hide and dispose the
* window after invoking any registered InternalFrameListener objects
* </ul>
* <p>
* The value is set to HIDE_ON_CLOSE by default.
* @see #addInternalFrameListener
* @see #getDefaultCloseOperation
*/
public void setDefaultCloseOperation(int operation) {
this.defaultCloseOperation = operation;
}
/**
* Returns the default operation which occurs when the user
* initiates a "close" on this window.
* @see #setDefaultCloseOperation
*/
public int getDefaultCloseOperation() {
return defaultCloseOperation;
}
/**
* Causes subcomponents of this JInternalFrame to be laid out at their
* preferred size.
* @see java.awt.Window#pack
*/
public void pack() {
Container parent = getParent();
if (parent != null && parent.getPeer() == null) {
parent.addNotify();
addNotify();
}
setSize(getPreferredSize());
validate();
}
/**
* Shows this internal frame, and brings it to the front.
* <p>
* If this window is not yet visible, <code>show</code>
* makes it visible. If this window is already visible,
* then this method brings it to the front.
* @see java.awt.Window#show
* @see java.awt.Window#toFront
* @see java.awt.Component#setVisible
*/
public void show() {
pack();
if (!isVisible()) {
setVisible(true);
}
if (!isSelected()) {
try {
setSelected(true);
} catch (PropertyVetoException pve) {}
}
}
/**
* Disposes of this internal frame.
*/
public void dispose() {
if (isVisible()) {
setVisible(false);
}
if (isSelected()) {
try {
setSelected(false);
} catch (PropertyVetoException pve) {}
}
if (!isClosed) {
postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
}
}
/**
* Brings this internal frame to the front.
* @see java.awt.Window#toFront
* @see #moveToFront
*/
public void toFront() {
moveToFront();
}
/**
* Sends this internal frame to the back.
* Places this internal frame at the bottom of the stacking order
* and makes the corresponding adjustment to other visible windows.
* @see java.awt.Window#toBack
* @see #moveToBack
*/
public void toBack() {
moveToBack();
}
/**
* Gets the warning string that is displayed with this window.
* Since an internal frame is always secure (since it's fully
* contained within a window which might need a warning string)
* this method always returns null.
* @return null.
* @see java.awt.Window#getWarningString
*/
public final String getWarningString() {
return null;
}
/////////////////
// Mouse support
////////////////
/*
* When inactive, mouse events are forwarded as appropriate either to
* the UI to activate the frame or to the underlying child component.
*
* In keeping with the MDI messaging model (which JInternalFrame
* emulates), only the mousePressed event is forwarded to the UI
* to activate the frame. The mouseEntered, mouseMoved, and
* MouseExited events are forwarded to the underlying child
* component, using methods derived from those in Container.
* The other mouse events are purposely ignored, since they have
* no meaning to either the frame or its children when the frame
* is inactive.
*/
public void mousePressed(MouseEvent e) {
((MouseListener)ui).mousePressed(e);
}
public void mouseEntered(MouseEvent e) {
forwardMouseEvent(e);
}
public void mouseMoved(MouseEvent e) {
forwardMouseEvent(e);
}
public void mouseExited(MouseEvent e) {
forwardMouseEvent(e);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
/*
* Forward a mouse event to the current mouse target, setting it
* if necessary.
*/
private void forwardMouseEvent(MouseEvent e) {
Component target = findComponentAt(getContentPane(),
e.getX(), e.getY());
if (target != mouseEventTarget) {
setMouseTarget(target, e);
}
retargetMouseEvent(e.getID(), e);
}
private Component mouseEventTarget = null;
/*
* Find the lightweight child component which corresponds to the
* specified location. This is similar to the new 1.2 API in
* Container, but we need to run on 1.1. The other changes are
* due to Container.findComponentAt's use of package-private data.
*/
private static Component findComponentAt(Container c, int x, int y) {
if (!c.contains(x, y)) {
return c;
}
int ncomponents = c.getComponentCount();
Component component[] = c.getComponents();
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = component[i];
Point loc = comp.getLocation();
if ((comp != null) && (comp.contains(x - loc.x, y - loc.y)) &&
(comp.getPeer() instanceof java.awt.peer.LightweightPeer) &&
(comp.isVisible() == true)) {
// found a component that intersects the point, see if there
// is a deeper possibility.
if (comp instanceof Container) {
Container child = (Container) comp;
Point childLoc = child.getLocation();
Component deeper = findComponentAt(child,
x - childLoc.x, y - childLoc.y);
if (deeper != null) {
return deeper;
}
} else {
return comp;
}
}
}
return c;
}
/*
* Set the child component to which events are forwarded, and
* synthesize the appropriate mouseEntered and mouseExited events.
*/
private void setMouseTarget(Component target, MouseEvent e) {
if (mouseEventTarget != null) {
retargetMouseEvent(MouseEvent.MOUSE_EXITED, e);
}
mouseEventTarget = target;
if (mouseEventTarget != null) {
retargetMouseEvent(MouseEvent.MOUSE_ENTERED, e);
}
}
/*
* Dispatch an event clone, retargeted for the current mouse target.
*/
void retargetMouseEvent(int id, MouseEvent e) {
MouseEvent retargeted = new MouseEvent(mouseEventTarget,
id,
e.getWhen(),
e.getModifiers(),
e.getX(),
e.getY(),
e.getClickCount(),
e.isPopupTrigger());
mouseEventTarget.dispatchEvent(retargeted);
}
/**
* Invoked when a maximized JInternalFrame's parent's size changes.
*/
public void componentResized(ComponentEvent e) {
Dimension d = ((Component)e.getSource()).getSize();
setBounds(0, 0, d.width, d.height);
validate();
}
/* Unused */
public void componentMoved(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
/////////////////
// Accessibility support
////////////////
/**
* Get the AccessibleContext associated with this JComponent
*
* @return the AccessibleContext of this JComponent
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJInternalFrame();
}
return accessibleContext;
}
/**
* The class used to obtain the accessible role for this object.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*/
protected class AccessibleJInternalFrame extends AccessibleJComponent
implements AccessibleValue {
/**
* Get the accessible name of this object. This should almost never
* return java.awt.Component.getName(), as that generally isn't
* a localized name, and doesn't have meaning for the user. If the
* object is fundamentally a text object (e.g. a menu item), the
* accessible name should be the text of the object (e.g. "save").
* If the object has a tooltip, the tooltip text may also be an
* appropriate String to return.
*
* @return the localized name of the object -- can be null if this
* object does not have a name
* @see #setAccessibleName
*/
public String getAccessibleName() {
if (accessibleName != null) {
return accessibleName;
} else {
return getTitle();
}
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.INTERNAL_FRAME;
}
/**
* Get the AccessibleValue associated with this object if one
* exists. Otherwise return null.
*/
public AccessibleValue getAccessibleValue() {
return this;
}
//
// AccessibleValue methods
//
/**
* Get the value of this object as a Number.
*
* @return value of the object -- can be null if this object does not
* have a value
*/
public Number getCurrentAccessibleValue() {
return new Integer(getLayer());
}
/**
* Set the value of this object as a Number.
*
* @return True if the value was set.
*/
public boolean setCurrentAccessibleValue(Number n) {
if (n instanceof Integer) {
setLayer((Integer) n);
return true;
} else {
return false;
}
}
/**
* Get the minimum value of this object as a Number.
*
* @return Minimum value of the object; null if this object does not
* have a minimum value
*/
public Number getMinimumAccessibleValue() {
return new Integer(Integer.MIN_VALUE);
}
/**
* Get the maximum value of this object as a Number.
*
* @return Maximum value of the object; null if this object does not
* have a maximum value
*/
public Number getMaximumAccessibleValue() {
return new Integer(Integer.MAX_VALUE);
}
} // AccessibleJInternalFrame
private static class MyEventMulticaster extends AWTEventMulticaster
implements InternalFrameListener {
public MyEventMulticaster(InternalFrameListener a,
InternalFrameListener b) {
super(a, b);
}
public static InternalFrameListener add(InternalFrameListener a,
InternalFrameListener b) {
return (InternalFrameListener)addInternal(a, b);
}
public static InternalFrameListener remove(InternalFrameListener l,
InternalFrameListener oldl){
return (InternalFrameListener) removeInternal(l, oldl);
}
public void internalFrameOpened(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameOpened(e);
((InternalFrameListener)b).internalFrameOpened(e);
}
public void internalFrameClosing(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameClosing(e);
((InternalFrameListener)b).internalFrameClosing(e);
}
public void internalFrameClosed(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameClosed(e);
((InternalFrameListener)b).internalFrameClosed(e);
}
public void internalFrameIconified(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameIconified(e);
((InternalFrameListener)b).internalFrameIconified(e);
}
public void internalFrameDeiconified(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameDeiconified(e);
((InternalFrameListener)b).internalFrameDeiconified(e);
}
public void internalFrameActivated(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameActivated(e);
((InternalFrameListener)b).internalFrameActivated(e);
}
public void internalFrameDeactivated(InternalFrameEvent e) {
((InternalFrameListener)a).internalFrameDeactivated(e);
((InternalFrameListener)b).internalFrameDeactivated(e);
}
}
/**
* This component represents an iconified version of a JInternalFrame.
* This API should NOT BE USED by Swing applications, as it will go
* away in future versions of Swing as its functionality is moved into
* JInternalFrame. This class is public only so that UI objects can
* display a desktop icon. If an application wants to display a
* desktop icon, it should create a JInternalFrame instance and
* iconify it.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @author David Kloba
*/
static public class JDesktopIcon extends JComponent implements Accessible
{
JInternalFrame internalFrame;
public JDesktopIcon(JInternalFrame f) {
setInternalFrame(f);
updateUI();
}
public DesktopIconUI getUI() {
return (DesktopIconUI)ui;
}
public void setUI(DesktopIconUI ui) {
super.setUI(ui);
}
/**
* Returns the JInternalFrame that this DesktopIcon is
* associated with.
*/
public JInternalFrame getInternalFrame() {
return internalFrame;
}
public void setInternalFrame(JInternalFrame f) {
internalFrame = f;
}
/** Convience method to ask the appropriate JInternalFrame
* for the Desktop object.
*/
public JDesktopPane getDesktopPane() {
if(getInternalFrame() != null)
return getInternalFrame().getDesktopPane();
return null;
}
/**
* Called to replace the UI with the latest version from the
* default UIFactory.
*/
public void updateUI() {
boolean hadUI = (ui != null);
setUI((DesktopIconUI)UIManager.getUI(this));
invalidate();
Dimension r = getPreferredSize();
setSize(r.width, r.height);
if (internalFrame != null) {
SwingUtilities.updateComponentTreeUI(internalFrame);
}
}
/* This method is called if updateUI was called on the associated
* JInternalFrame. It's necessary to avoid infinite recursion.
*/
void updateUIWhenHidden() {
/* Update this UI and any associated internal frame */
setUI((DesktopIconUI)UIManager.getUI(this));
invalidate();
Component[] children = getComponents();
if (children != null) {
for(int i = 0; i < children.length; i++) {
SwingUtilities.updateComponentTreeUI(children[i]);
}
}
}
/**
* @return "DesktopIconUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return "DesktopIconUI";
}
/////////////////
// Accessibility support
////////////////
/**
* Get the AccessibleContext associated with this JComponent
*
* @return the AccessibleContext of this JComponent
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJDesktopIcon();
}
return accessibleContext;
}
/**
* The class used to obtain the accessible role for this object.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*/
protected class AccessibleJDesktopIcon extends AccessibleJComponent
implements AccessibleValue {
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.DESKTOP_ICON;
}
/**
* Get the AccessibleValue associated with this object if one
* exists. Otherwise return null.
*/
public AccessibleValue getAccessibleValue() {
return this;
}
//
// AccessibleValue methods
//
/**
* Get the value of this object as a Number.
*
* @return value of the object -- can be null if this object does not
* have a value
*/
public Number getCurrentAccessibleValue() {
AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
AccessibleValue v = a.getAccessibleValue();
if (v != null) {
return v.getCurrentAccessibleValue();
} else {
return null;
}
}
/**
* Set the value of this object as a Number.
*
* @return True if the value was set.
*/
public boolean setCurrentAccessibleValue(Number n) {
AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
AccessibleValue v = a.getAccessibleValue();
if (v != null) {
return v.setCurrentAccessibleValue(n);
} else {
return false;
}
}
/**
* Get the minimum value of this object as a Number.
*
* @return Minimum value of the object; null if this object does not
* have a minimum value
*/
public Number getMinimumAccessibleValue() {
AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
if (a instanceof AccessibleValue) {
return ((AccessibleValue)a).getMinimumAccessibleValue();
} else {
return null;
}
}
/**
* Get the maximum value of this object as a Number.
*
* @return Maximum value of the object; null if this object does not
* have a maximum value
*/
public Number getMaximumAccessibleValue() {
AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
if (a instanceof AccessibleValue) {
return ((AccessibleValue)a).getMaximumAccessibleValue();
} else {
return null;
}
}
} // AccessibleJDesktopIcon
}
}