|
true
is
* returned, the request will succeed <b>unless it is vetoed, or an
* extraordinary event, such as disposal of the component's peer, occurs
* before the request can be granted by the native windowing system. Again,
* while a return value of <code>true indicates that the request is
* likely to succeed, developers must never assume that this component is
* the focus owner until this component receives a FOCUS_GAINED event.
* <p>
* This method cannot be used to set the focus owner to no component at
* all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner
* instead.
* <p>
* Because the focus behavior of this method is platform-dependent,
* developers are strongly encouraged to use
* <code>requestFocusInWindow when possible.
* <p>
* Every effort will be made to ensure that <code>FocusEvents
* generated as a
* result of this request will have the specified temporary value. However,
* because specifying an arbitrary temporary state may not be implementable
* on all native windowing systems, correct behavior for this method can be
* guaranteed only for lightweight <code>Components.
* This method is not intended
* for general use, but exists instead as a hook for lightweight component
* libraries, such as Swing.
*
* <p>Note: Not all focus transfers result from invoking this method. As
* such, a component may receive focus without this or any of the other
* {@code requestFocus} methods of {@code Component} being invoked.
*
* @param temporary true if the focus change is temporary,
* such as when the window loses the focus; for
* more information on temporary focus changes see the
*<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification
* @return <code>false if the focus change request is guaranteed to
* fail; <code>true if it is likely to succeed
* @see java.awt.event.FocusEvent
* @see #addFocusListener
* @see #isFocusable
* @see #isDisplayable
* @see KeyboardFocusManager#clearGlobalFocusOwner
* @since 1.4
*/
protected boolean requestFocus(boolean temporary) {
return requestFocusHelper(temporary, true);
}
boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) {
return requestFocusHelper(temporary, true, cause);
}
/**
* Requests that this Component get the input focus, if this
* Component's top-level ancestor is already the focused
* Window. This component must be displayable, focusable, visible
* and all of its ancestors (with the exception of the top-level
* Window) must be visible for the request to be granted. Every
* effort will be made to honor the request; however, in some
* cases it may be impossible to do so. Developers must never
* assume that this Component is the focus owner until this
* Component receives a FOCUS_GAINED event.
* <p>
* This method returns a boolean value. If <code>false is returned,
* the request is <b>guaranteed to fail. If true
is
* returned, the request will succeed <b>unless it is vetoed, or an
* extraordinary event, such as disposal of the Component's peer, occurs
* before the request can be granted by the native windowing system. Again,
* while a return value of <code>true indicates that the request is
* likely to succeed, developers must never assume that this Component is
* the focus owner until this Component receives a FOCUS_GAINED event.
* <p>
* This method cannot be used to set the focus owner to no Component at
* all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()
* instead.
* <p>
* The focus behavior of this method can be implemented uniformly across
* platforms, and thus developers are strongly encouraged to use this
* method over <code>requestFocus when possible. Code which relies
* on <code>requestFocus may exhibit different focus behavior on
* different platforms.
*
* <p>Note: Not all focus transfers result from invoking this method. As
* such, a component may receive focus without this or any of the other
* {@code requestFocus} methods of {@code Component} being invoked.
*
* @return <code>false if the focus change request is guaranteed to
* fail; <code>true if it is likely to succeed
* @see #requestFocus
* @see java.awt.event.FocusEvent
* @see #addFocusListener
* @see #isFocusable
* @see #isDisplayable
* @see KeyboardFocusManager#clearGlobalFocusOwner
* @since 1.4
*/
public boolean requestFocusInWindow() {
return requestFocusHelper(false, false);
}
boolean requestFocusInWindow(CausedFocusEvent.Cause cause) {
return requestFocusHelper(false, false, cause);
}
/**
* Requests that this <code>Component get the input focus,
* if this <code>Component's top-level ancestor is already
* the focused <code>Window. This component must be
* displayable, focusable, visible and all of its ancestors (with
* the exception of the top-level Window) must be visible for the
* request to be granted. Every effort will be made to honor the
* request; however, in some cases it may be impossible to do
* so. Developers must never assume that this component is the
* focus owner until this component receives a FOCUS_GAINED event.
* <p>
* This method returns a boolean value. If <code>false is returned,
* the request is <b>guaranteed to fail. If true
is
* returned, the request will succeed <b>unless it is vetoed, or an
* extraordinary event, such as disposal of the component's peer, occurs
* before the request can be granted by the native windowing system. Again,
* while a return value of <code>true indicates that the request is
* likely to succeed, developers must never assume that this component is
* the focus owner until this component receives a FOCUS_GAINED event.
* <p>
* This method cannot be used to set the focus owner to no component at
* all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner
* instead.
* <p>
* The focus behavior of this method can be implemented uniformly across
* platforms, and thus developers are strongly encouraged to use this
* method over <code>requestFocus when possible. Code which relies
* on <code>requestFocus may exhibit different focus behavior on
* different platforms.
* <p>
* Every effort will be made to ensure that <code>FocusEvents
* generated as a
* result of this request will have the specified temporary value. However,
* because specifying an arbitrary temporary state may not be implementable
* on all native windowing systems, correct behavior for this method can be
* guaranteed only for lightweight components. This method is not intended
* for general use, but exists instead as a hook for lightweight component
* libraries, such as Swing.
*
* <p>Note: Not all focus transfers result from invoking this method. As
* such, a component may receive focus without this or any of the other
* {@code requestFocus} methods of {@code Component} being invoked.
*
* @param temporary true if the focus change is temporary,
* such as when the window loses the focus; for
* more information on temporary focus changes see the
*<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification
* @return <code>false if the focus change request is guaranteed to
* fail; <code>true if it is likely to succeed
* @see #requestFocus
* @see java.awt.event.FocusEvent
* @see #addFocusListener
* @see #isFocusable
* @see #isDisplayable
* @see KeyboardFocusManager#clearGlobalFocusOwner
* @since 1.4
*/
protected boolean requestFocusInWindow(boolean temporary) {
return requestFocusHelper(temporary, false);
}
boolean requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause) {
return requestFocusHelper(temporary, false, cause);
}
final boolean requestFocusHelper(boolean temporary,
boolean focusedWindowChangeAllowed) {
return requestFocusHelper(temporary, focusedWindowChangeAllowed, CausedFocusEvent.Cause.UNKNOWN);
}
final boolean requestFocusHelper(boolean temporary,
boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause)
{
// 1) Check if the event being dispatched is a system-generated mouse event.
AWTEvent currentEvent = EventQueue.getCurrentEvent();
if (currentEvent instanceof MouseEvent &&
SunToolkit.isSystemGenerated(currentEvent))
{
// 2) Sanity check: if the mouse event component source belongs to the same containing window.
Component source = ((MouseEvent)currentEvent).getComponent();
if (source == null || source.getContainingWindow() == getContainingWindow()) {
focusLog.finest("requesting focus by mouse event \"in window\"");
// If both the conditions are fulfilled the focus request should be strictly
// bounded by the toplevel window. It's assumed that the mouse event activates
// the window (if it wasn't active) and this makes it possible for a focus
// request with a strong in-window requirement to change focus in the bounds
// of the toplevel. If, by any means, due to asynchronous nature of the event
// dispatching mechanism, the window happens to be natively inactive by the time
// this focus request is eventually handled, it should not re-activate the
// toplevel. Otherwise the result may not meet user expectations. See 6981400.
focusedWindowChangeAllowed = false;
}
}
if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("requestFocus is not accepted");
}
return false;
}
// Update most-recent map
KeyboardFocusManager.setMostRecentFocusOwner(this);
Component window = this;
while ( (window != null) && !(window instanceof Window)) {
if (!window.isVisible()) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("component is recurively invisible");
}
return false;
}
window = window.parent;
}
ComponentPeer peer = this.peer;
Component heavyweight = (peer instanceof LightweightPeer)
? getNativeContainer() : this;
if (heavyweight == null || !heavyweight.isVisible()) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Component is not a part of visible hierarchy");
}
return false;
}
peer = heavyweight.peer;
if (peer == null) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Peer is null");
}
return false;
}
// Focus this Component
long time = 0;
if (EventQueue.isDispatchThread()) {
time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
} else {
// A focus request made from outside EDT should not be associated with any event
// and so its time stamp is simply set to the current time.
time = System.currentTimeMillis();
}
boolean success = peer.requestFocus
(this, temporary, focusedWindowChangeAllowed, time, cause);
if (!success) {
KeyboardFocusManager.getCurrentKeyboardFocusManager
(appContext).dequeueKeyEvents(time, this);
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Peer request failed");
}
} else {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Pass for " + this);
}
}
return success;
}
private boolean isRequestFocusAccepted(boolean temporary,
boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause)
{
if (!isFocusable() || !isVisible()) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Not focusable or not visible");
}
return false;
}
ComponentPeer peer = this.peer;
if (peer == null) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("peer is null");
}
return false;
}
Window window = getContainingWindow();
if (window == null || !window.isFocusableWindow()) {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Component doesn't have toplevel");
}
return false;
}
// We have passed all regular checks for focus request,
// now let's call RequestFocusController and see what it says.
Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);
if (focusOwner == null) {
// sometimes most recent focus owner may be null, but focus owner is not
// e.g. we reset most recent focus owner if user removes focus owner
focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner != null && focusOwner.getContainingWindow() != window) {
focusOwner = null;
}
}
if (focusOwner == this || focusOwner == null) {
// Controller is supposed to verify focus transfers and for this it
// should know both from and to components. And it shouldn't verify
// transfers from when these components are equal.
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("focus owner is null or this");
}
return true;
}
if (CausedFocusEvent.Cause.ACTIVATION == cause) {
// we shouldn't call RequestFocusController in case we are
// in activation. We do request focus on component which
// has got temporary focus lost and then on component which is
// most recent focus owner. But most recent focus owner can be
// changed by requestFocsuXXX() call only, so this transfer has
// been already approved.
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("cause is activation");
}
return true;
}
boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
this,
temporary,
focusedWindowChangeAllowed,
cause);
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("RequestFocusController returns {0}", ret);
}
return ret;
}
private static RequestFocusController requestFocusController = new DummyRequestFocusController();
// Swing access this method through reflection to implement InputVerifier's functionality.
// Perhaps, we should make this method public (later ;)
private static class DummyRequestFocusController implements RequestFocusController {
public boolean acceptRequestFocus(Component from, Component to,
boolean temporary, boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause)
{
return true;
}
};
synchronized static void setRequestFocusController(RequestFocusController requestController)
{
if (requestController == null) {
requestFocusController = new DummyRequestFocusController();
} else {
requestFocusController = requestController;
}
}
/**
* Returns the Container which is the focus cycle root of this Component's
* focus traversal cycle. Each focus traversal cycle has only a single
* focus cycle root and each Component which is not a Container belongs to
* only a single focus traversal cycle. Containers which are focus cycle
* roots belong to two cycles: one rooted at the Container itself, and one
* rooted at the Container's nearest focus-cycle-root ancestor. For such
* Containers, this method will return the Container's nearest focus-cycle-
* root ancestor.
*
* @return this Component's nearest focus-cycle-root ancestor
* @see Container#isFocusCycleRoot()
* @since 1.4
*/
public Container getFocusCycleRootAncestor() {
Container rootAncestor = this.parent;
while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
rootAncestor = rootAncestor.parent;
}
return rootAncestor;
}
/**
* Returns whether the specified Container is the focus cycle root of this
* Component's focus traversal cycle. Each focus traversal cycle has only
* a single focus cycle root and each Component which is not a Container
* belongs to only a single focus traversal cycle.
*
* @param container the Container to be tested
* @return <code>true if the specified Container is a focus-cycle-
* root of this Component; <code>false otherwise
* @see Container#isFocusCycleRoot()
* @since 1.4
*/
public boolean isFocusCycleRoot(Container container) {
Container rootAncestor = getFocusCycleRootAncestor();
return (rootAncestor == container);
}
Container getTraversalRoot() {
return getFocusCycleRootAncestor();
}
/**
* Transfers the focus to the next component, as though this Component were
* the focus owner.
* @see #requestFocus()
* @since JDK1.1
*/
public void transferFocus() {
nextFocus();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by transferFocus().
*/
@Deprecated
public void nextFocus() {
transferFocus(false);
}
boolean transferFocus(boolean clearOnFailure) {
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("clearOnFailure = " + clearOnFailure);
}
Component toFocus = getNextFocusCandidate();
boolean res = false;
if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
}
if (clearOnFailure && !res) {
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("clear global focus owner");
}
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
}
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("returning result: " + res);
}
return res;
}
final Component getNextFocusCandidate() {
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
{
comp = rootAncestor;
rootAncestor = comp.getFocusCycleRootAncestor();
}
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("comp = " + comp + ", root = " + rootAncestor);
}
Component candidate = null;
if (rootAncestor != null) {
FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
Component toFocus = policy.getComponentAfter(rootAncestor, comp);
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("component after is " + toFocus);
}
if (toFocus == null) {
toFocus = policy.getDefaultComponent(rootAncestor);
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("default component is " + toFocus);
}
}
if (toFocus == null) {
Applet applet = EmbeddedFrame.getAppletIfAncestorOf(this);
if (applet != null) {
toFocus = applet;
}
}
candidate = toFocus;
}
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("Focus transfer candidate: " + candidate);
}
return candidate;
}
/**
* Transfers the focus to the previous component, as though this Component
* were the focus owner.
* @see #requestFocus()
* @since 1.4
*/
public void transferFocusBackward() {
transferFocusBackward(false);
}
boolean transferFocusBackward(boolean clearOnFailure) {
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
{
comp = rootAncestor;
rootAncestor = comp.getFocusCycleRootAncestor();
}
boolean res = false;
if (rootAncestor != null) {
FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
Component toFocus = policy.getComponentBefore(rootAncestor, comp);
if (toFocus == null) {
toFocus = policy.getDefaultComponent(rootAncestor);
}
if (toFocus != null) {
res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
}
}
if (clearOnFailure && !res) {
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("clear global focus owner");
}
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
}
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
focusLog.finer("returning result: " + res);
}
return res;
}
/**
* Transfers the focus up one focus traversal cycle. Typically, the focus
* owner is set to this Component's focus cycle root, and the current focus
* cycle root is set to the new focus owner's focus cycle root. If,
* however, this Component's focus cycle root is a Window, then the focus
* owner is set to the focus cycle root's default Component to focus, and
* the current focus cycle root is unchanged.
*
* @see #requestFocus()
* @see Container#isFocusCycleRoot()
* @see Container#setFocusCycleRoot(boolean)
* @since 1.4
*/
public void transferFocusUpCycle() {
Container rootAncestor;
for (rootAncestor = getFocusCycleRootAncestor();
rootAncestor != null && !(rootAncestor.isShowing() &&
rootAncestor.isFocusable() &&
rootAncestor.isEnabled());
rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
}
if (rootAncestor != null) {
Container rootAncestorRootAncestor =
rootAncestor.getFocusCycleRootAncestor();
Container fcr = (rootAncestorRootAncestor != null) ?
rootAncestorRootAncestor : rootAncestor;
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalCurrentFocusCycleRootPriv(fcr);
rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
} else {
Window window = getContainingWindow();
if (window != null) {
Component toFocus = window.getFocusTraversalPolicy().
getDefaultComponent(window);
if (toFocus != null) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalCurrentFocusCycleRootPriv(window);
toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
}
}
}
}
/**
* Returns <code>true if this Component
is the
* focus owner. This method is obsolete, and has been replaced by
* <code>isFocusOwner().
*
* @return <code>true if this Component
is the
* focus owner; <code>false otherwise
* @since 1.2
*/
public boolean hasFocus() {
return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
getFocusOwner() == this);
}
/**
* Returns <code>true if this Component
is the
* focus owner.
*
* @return <code>true if this Component
is the
* focus owner; <code>false otherwise
* @since 1.4
*/
public boolean isFocusOwner() {
return hasFocus();
}
/*
* Used to disallow auto-focus-transfer on disposal of the focus owner
* in the process of disposing its parent container.
*/
private boolean autoFocusTransferOnDisposal = true;
void setAutoFocusTransferOnDisposal(boolean value) {
autoFocusTransferOnDisposal = value;
}
boolean isAutoFocusTransferOnDisposal() {
return autoFocusTransferOnDisposal;
}
/**
* Adds the specified popup menu to the component.
* @param popup the popup menu to be added to the component.
* @see #remove(MenuComponent)
* @exception NullPointerException if {@code popup} is {@code null}
* @since JDK1.1
*/
public void add(PopupMenu popup) {
synchronized (getTreeLock()) {
if (popup.parent != null) {
popup.parent.remove(popup);
}
if (popups == null) {
popups = new Vector<PopupMenu>();
}
popups.addElement(popup);
popup.parent = this;
if (peer != null) {
if (popup.peer == null) {
popup.addNotify();
}
}
}
}
/**
* Removes the specified popup menu from the component.
* @param popup the popup menu to be removed
* @see #add(PopupMenu)
* @since JDK1.1
*/
@SuppressWarnings("unchecked")
public void remove(MenuComponent popup) {
synchronized (getTreeLock()) {
if (popups == null) {
return;
}
int index = popups.indexOf(popup);
if (index >= 0) {
PopupMenu pmenu = (PopupMenu)popup;
if (pmenu.peer != null) {
pmenu.removeNotify();
}
pmenu.parent = null;
popups.removeElementAt(index);
if (popups.size() == 0) {
popups = null;
}
}
}
}
/**
* Returns a string representing the state of this component. This
* method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null.
*
* @return a string representation of this component's state
* @since JDK1.0
*/
protected String paramString() {
String thisName = getName();
String str = (thisName != null? thisName : "") + "," + x + "," + y + "," + width + "x" + height;
if (!isValid()) {
str += ",invalid";
}
if (!visible) {
str += ",hidden";
}
if (!enabled) {
str += ",disabled";
}
return str;
}
/**
* Returns a string representation of this component and its values.
* @return a string representation of this component
* @since JDK1.0
*/
public String toString() {
return getClass().getName() + "[" + paramString() + "]";
}
/**
* Prints a listing of this component to the standard system output
* stream <code>System.out.
* @see java.lang.System#out
* @since JDK1.0
*/
public void list() {
list(System.out, 0);
}
/**
* Prints a listing of this component to the specified output
* stream.
* @param out a print stream
* @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.0
*/
public void list(PrintStream out) {
list(out, 0);
}
/**
* Prints out a list, starting at the specified indentation, to the
* specified print stream.
* @param out a print stream
* @param indent number of spaces to indent
* @see java.io.PrintStream#println(java.lang.Object)
* @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.0
*/
public void list(PrintStream out, int indent) {
for (int i = 0 ; i < indent ; i++) {
out.print(" ");
}
out.println(this);
}
/**
* Prints a listing to the specified print writer.
* @param out the print writer to print to
* @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.1
*/
public void list(PrintWriter out) {
list(out, 0);
}
/**
* Prints out a list, starting at the specified indentation, to
* the specified print writer.
* @param out the print writer to print to
* @param indent the number of spaces to indent
* @throws NullPointerException if {@code out} is {@code null}
* @see java.io.PrintStream#println(java.lang.Object)
* @since JDK1.1
*/
public void list(PrintWriter out, int indent) {
for (int i = 0 ; i < indent ; i++) {
out.print(" ");
}
out.println(this);
}
/*
* Fetches the native container somewhere higher up in the component
* tree that contains this component.
*/
final Container getNativeContainer() {
Container p = getContainer();
while (p != null && p.peer instanceof LightweightPeer) {
p = p.getContainer();
}
return p;
}
/**
* Adds a PropertyChangeListener to the listener list. The listener is
* registered for all bound properties of this class, including the
* following:
* <ul>
* <li>this Component's font ("font")
* <li>this Component's background color ("background")
* <li>this Component's foreground color ("foreground")
* <li>this Component's focusability ("focusable")
* <li>this Component's focus traversal keys enabled state
* ("focusTraversalKeysEnabled")</li>
* <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
* ("forwardFocusTraversalKeys")</li>
* <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
* ("backwardFocusTraversalKeys")</li>
* <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
* ("upCycleFocusTraversalKeys")</li>
* <li>this Component's preferred size ("preferredSize")
* <li>this Component's minimum size ("minimumSize")
* <li>this Component's maximum size ("maximumSize")
* <li>this Component's name ("name")
* </ul>
* Note that if this <code>Component is inheriting a bound property, then no
* event will be fired in response to a change in the inherited property.
* <p>
* If <code>listener is null
,
* no exception is thrown and no action is performed.
*
* @param listener the property change listener to be added
*
* @see #removePropertyChangeListener
* @see #getPropertyChangeListeners
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
*/
public void addPropertyChangeListener(
PropertyChangeListener listener) {
synchronized (getObjectLock()) {
if (listener == null) {
return;
}
if (changeSupport == null) {
changeSupport = new PropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(listener);
}
}
/**
* Removes a PropertyChangeListener from the listener list. This method
* should be used to remove PropertyChangeListeners that were registered
* for all bound properties of this class.
* <p>
* If listener is null, no exception is thrown and no action is performed.
*
* @param listener the PropertyChangeListener to be removed
*
* @see #addPropertyChangeListener
* @see #getPropertyChangeListeners
* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
*/
public void removePropertyChangeListener(
PropertyChangeListener listener) {
synchronized (getObjectLock()) {
if (listener == null || changeSupport == null) {
return;
}
changeSupport.removePropertyChangeListener(listener);
}
}
/**
* Returns an array of all the property change listeners
* registered on this component.
*
* @return all of this component's <code>PropertyChangeListeners
* or an empty array if no property change
* listeners are currently registered
*
* @see #addPropertyChangeListener
* @see #removePropertyChangeListener
* @see #getPropertyChangeListeners(java.lang.String)
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
* @since 1.4
*/
public PropertyChangeListener[] getPropertyChangeListeners() {
synchronized (getObjectLock()) {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
return changeSupport.getPropertyChangeListeners();
}
}
/**
* Adds a PropertyChangeListener to the listener list for a specific
* property. The specified property may be user-defined, or one of the
* following:
* <ul>
* <li>this Component's font ("font")
* <li>this Component's background color ("background")
* <li>this Component's foreground color ("foreground")
* <li>this Component's focusability ("focusable")
* <li>this Component's focus traversal keys enabled state
* ("focusTraversalKeysEnabled")</li>
* <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
* ("forwardFocusTraversalKeys")</li>
* <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
* ("backwardFocusTraversalKeys")</li>
* <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
* ("upCycleFocusTraversalKeys")</li>
* </ul>
* Note that if this <code>Component is inheriting a bound property, then no
* event will be fired in response to a change in the inherited property.
* <p>
* If <code>propertyName or listener
is null
,
* no exception is thrown and no action is taken.
*
* @param propertyName one of the property names listed above
* @param listener the property change listener to be added
*
* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
* @see #getPropertyChangeListeners(java.lang.String)
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
*/
public void addPropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
synchronized (getObjectLock()) {
if (listener == null) {
return;
}
if (changeSupport == null) {
changeSupport = new PropertyChangeSupport(this);
}
changeSupport.addPropertyChangeListener(propertyName, listener);
}
}
/**
* Removes a <code>PropertyChangeListener from the listener
* list for a specific property. This method should be used to remove
* <code>PropertyChangeListeners
* that were registered for a specific bound property.
* <p>
* If <code>propertyName or listener
is null
,
* no exception is thrown and no action is taken.
*
* @param propertyName a valid property name
* @param listener the PropertyChangeListener to be removed
*
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
* @see #getPropertyChangeListeners(java.lang.String)
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
*/
public void removePropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
synchronized (getObjectLock()) {
if (listener == null || changeSupport == null) {
return;
}
changeSupport.removePropertyChangeListener(propertyName, listener);
}
}
/**
* Returns an array of all the listeners which have been associated
* with the named property.
*
* @return all of the <code>PropertyChangeListeners associated with
* the named property; if no such listeners have been added or
* if <code>propertyName is null
, an empty
* array is returned
*
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
* @see #getPropertyChangeListeners
* @since 1.4
*/
public PropertyChangeListener[] getPropertyChangeListeners(
String propertyName) {
synchronized (getObjectLock()) {
if (changeSupport == null) {
return new PropertyChangeListener[0];
}
return changeSupport.getPropertyChangeListeners(propertyName);
}
}
/**
* Support for reporting bound property changes for Object properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
*/
protected void firePropertyChange(String propertyName,
Object oldValue, Object newValue) {
PropertyChangeSupport changeSupport;
synchronized (getObjectLock()) {
changeSupport = this.changeSupport;
}
if (changeSupport == null ||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
return;
}
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
/**
* Support for reporting bound property changes for boolean properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
* @since 1.4
*/
protected void firePropertyChange(String propertyName,
boolean oldValue, boolean newValue) {
PropertyChangeSupport changeSupport = this.changeSupport;
if (changeSupport == null || oldValue == newValue) {
return;
}
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
/**
* Support for reporting bound property changes for integer properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
* @since 1.4
*/
protected void firePropertyChange(String propertyName,
int oldValue, int newValue) {
PropertyChangeSupport changeSupport = this.changeSupport;
if (changeSupport == null || oldValue == newValue) {
return;
}
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a byte)
* @param newValue the new value of the property (as a byte)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte.valueOf(newValue));
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a char)
* @param newValue the new value of the property (as a char)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, char oldValue, char newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, new Character(oldValue), new Character(newValue));
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a short)
* @param newValue the old value of the property (as a short)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, short oldValue, short newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, Short.valueOf(oldValue), Short.valueOf(newValue));
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a long)
* @param newValue the new value of the property (as a long)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, long oldValue, long newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, Long.valueOf(oldValue), Long.valueOf(newValue));
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a float)
* @param newValue the new value of the property (as a float)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, float oldValue, float newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, Float.valueOf(oldValue), Float.valueOf(newValue));
}
/**
* Reports a bound property change.
*
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a double)
* @param newValue the new value of the property (as a double)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
*/
public void firePropertyChange(String propertyName, double oldValue, double newValue) {
if (changeSupport == null || oldValue == newValue) {
return;
}
firePropertyChange(propertyName, Double.valueOf(oldValue), Double.valueOf(newValue));
}
// Serialization support.
/**
* Component Serialized Data Version.
*
* @serial
*/
private int componentSerializedDataVersion = 4;
/**
* This hack is for Swing serialization. It will invoke
* the Swing package private method <code>compWriteObjectNotify.
*/
private void doSwingSerialization() {
Package swingPackage = Package.getPackage("javax.swing");
// For Swing serialization to correctly work Swing needs to
// be notified before Component does it's serialization. This
// hack accomodates this.
//
// Swing classes MUST be loaded by the bootstrap class loader,
// otherwise we don't consider them.
for (Class<?> klass = Component.this.getClass(); klass != null;
klass = klass.getSuperclass()) {
if (klass.getPackage() == swingPackage &&
klass.getClassLoader() == null) {
final Class<?> swingClass = klass;
// Find the first override of the compWriteObjectNotify method
Method[] methods = AccessController.doPrivileged(
new PrivilegedAction<Method[]>() {
public Method[] run() {
return swingClass.getDeclaredMethods();
}
});
for (int counter = methods.length - 1; counter >= 0;
counter--) {
final Method method = methods[counter];
if (method.getName().equals("compWriteObjectNotify")){
// We found it, use doPrivileged to make it accessible
// to use.
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
method.setAccessible(true);
return null;
}
});
// Invoke the method
try {
method.invoke(this, (Object[]) null);
} catch (IllegalAccessException iae) {
} catch (InvocationTargetException ite) {
}
// We're done, bail.
return;
}
}
}
}
}
/**
* Writes default serializable fields to stream. Writes
* a variety of serializable listeners as optional data.
* The non-serializable listeners are detected and
* no attempt is made to serialize them.
*
* @param s the <code>ObjectOutputStream to write
* @serialData <code>null terminated sequence of
* 0 or more pairs; the pair consists of a <code>String
* and an <code>Object; the String
indicates
* the type of object and is one of the following (as of 1.4):
* <code>componentListenerK indicating an
* <code>ComponentListener object;
* <code>focusListenerK indicating an
* <code>FocusListener object;
* <code>keyListenerK indicating an
* <code>KeyListener object;
* <code>mouseListenerK indicating an
* <code>MouseListener object;
* <code>mouseMotionListenerK indicating an
* <code>MouseMotionListener object;
* <code>inputMethodListenerK indicating an
* <code>InputMethodListener object;
* <code>hierarchyListenerK indicating an
* <code>HierarchyListener object;
* <code>hierarchyBoundsListenerK indicating an
* <code>HierarchyBoundsListener object;
* <code>mouseWheelListenerK indicating an
* <code>MouseWheelListener object
* @serialData an optional <code>ComponentOrientation
* (after <code>inputMethodListener, as of 1.2)
*
* @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
* @see #componentListenerK
* @see #focusListenerK
* @see #keyListenerK
* @see #mouseListenerK
* @see #mouseMotionListenerK
* @see #inputMethodListenerK
* @see #hierarchyListenerK
* @see #hierarchyBoundsListenerK
* @see #mouseWheelListenerK
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
doSwingSerialization();
s.defaultWriteObject();
AWTEventMulticaster.save(s, componentListenerK, componentListener);
AWTEventMulticaster.save(s, focusListenerK, focusListener);
AWTEventMulticaster.save(s, keyListenerK, keyListener);
AWTEventMulticaster.save(s, mouseListenerK, mouseListener);
AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener);
AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener);
s.writeObject(null);
s.writeObject(componentOrientation);
AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener);
AWTEventMulticaster.save(s, hierarchyBoundsListenerK,
hierarchyBoundsListener);
s.writeObject(null);
AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener);
s.writeObject(null);
}
/**
* Reads the <code>ObjectInputStream and if it isn't
* <code>null adds a listener to receive a variety
* of events fired by the component.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream to read
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException
{
objectLock = new Object();
acc = AccessController.getContext();
s.defaultReadObject();
appContext = AppContext.getAppContext();
coalescingEnabled = checkCoalescing();
if (componentSerializedDataVersion < 4) {
// These fields are non-transient and rely on default
// serialization. However, the default values are insufficient,
// so we need to set them explicitly for object data streams prior
// to 1.4.
focusable = true;
isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
initializeFocusTraversalKeys();
focusTraversalKeysEnabled = true;
}
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (componentListenerK == key)
addComponentListener((ComponentListener)(s.readObject()));
else if (focusListenerK == key)
addFocusListener((FocusListener)(s.readObject()));
else if (keyListenerK == key)
addKeyListener((KeyListener)(s.readObject()));
else if (mouseListenerK == key)
addMouseListener((MouseListener)(s.readObject()));
else if (mouseMotionListenerK == key)
addMouseMotionListener((MouseMotionListener)(s.readObject()));
else if (inputMethodListenerK == key)
addInputMethodListener((InputMethodListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
// Read the component's orientation if it's present
Object orient = null;
try {
orient = s.readObject();
} catch (java.io.OptionalDataException e) {
// JDK 1.1 instances will not have this optional data.
// e.eof will be true to indicate that there is no more
// data available for this object.
// If e.eof is not true, throw the exception as it
// might have been caused by reasons unrelated to
// componentOrientation.
if (!e.eof) {
throw (e);
}
}
if (orient != null) {
componentOrientation = (ComponentOrientation)orient;
} else {
componentOrientation = ComponentOrientation.UNKNOWN;
}
try {
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (hierarchyListenerK == key) {
addHierarchyListener((HierarchyListener)(s.readObject()));
}
else if (hierarchyBoundsListenerK == key) {
addHierarchyBoundsListener((HierarchyBoundsListener)
(s.readObject()));
}
else {
// skip value for unrecognized key
s.readObject();
}
}
} catch (java.io.OptionalDataException e) {
// JDK 1.1/1.2 instances will not have this optional data.
// e.eof will be true to indicate that there is no more
// data available for this object.
// If e.eof is not true, throw the exception as it
// might have been caused by reasons unrelated to
// hierarchy and hierarchyBounds listeners.
if (!e.eof) {
throw (e);
}
}
try {
while (null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (mouseWheelListenerK == key) {
addMouseWheelListener((MouseWheelListener)(s.readObject()));
}
else {
// skip value for unrecognized key
s.readObject();
}
}
} catch (java.io.OptionalDataException e) {
// pre-1.3 instances will not have this optional data.
// e.eof will be true to indicate that there is no more
// data available for this object.
// If e.eof is not true, throw the exception as it
// might have been caused by reasons unrelated to
// mouse wheel listeners
if (!e.eof) {
throw (e);
}
}
if (popups != null) {
int npopups = popups.size();
for (int i = 0 ; i < npopups ; i++) {
PopupMenu popup = popups.elementAt(i);
popup.parent = this;
}
}
}
/**
* Sets the language-sensitive orientation that is to be used to order
* the elements or text within this component. Language-sensitive
* <code>LayoutManager and Component
* subclasses will use this property to
* determine how to lay out and draw components.
* <p>
* At construction time, a component's orientation is set to
* <code>ComponentOrientation.UNKNOWN,
* indicating that it has not been specified
* explicitly. The UNKNOWN orientation behaves the same as
* <code>ComponentOrientation.LEFT_TO_RIGHT.
* <p>
* To set the orientation of a single component, use this method.
* To set the orientation of an entire component
* hierarchy, use
* {@link #applyComponentOrientation applyComponentOrientation}.
* <p>
* This method changes layout-related information, and therefore,
* invalidates the component hierarchy.
*
*
* @see ComponentOrientation
* @see #invalidate
*
* @author Laura Werner, IBM
* @beaninfo
* bound: true
*/
public void setComponentOrientation(ComponentOrientation o) {
ComponentOrientation oldValue = componentOrientation;
componentOrientation = o;
// This is a bound property, so report the change to
// any registered listeners. (Cheap if there are none.)
firePropertyChange("componentOrientation", oldValue, o);
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Retrieves the language-sensitive orientation that is to be used to order
* the elements or text within this component. <code>LayoutManager
* and <code>Component
* subclasses that wish to respect orientation should call this method to
* get the component's orientation before performing layout or drawing.
*
* @see ComponentOrientation
*
* @author Laura Werner, IBM
*/
public ComponentOrientation getComponentOrientation() {
return componentOrientation;
}
/**
* Sets the <code>ComponentOrientation property of this component
* and all components contained within it.
* <p>
* This method changes layout-related information, and therefore,
* invalidates the component hierarchy.
*
*
* @param orientation the new component orientation of this component and
* the components contained within it.
* @exception NullPointerException if <code>orientation is null.
* @see #setComponentOrientation
* @see #getComponentOrientation
* @see #invalidate
* @since 1.4
*/
public void applyComponentOrientation(ComponentOrientation orientation) {
if (orientation == null) {
throw new NullPointerException();
}
setComponentOrientation(orientation);
}
final boolean canBeFocusOwner() {
// It is enabled, visible, focusable.
if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
return true;
}
return false;
}
/**
* Checks that this component meets the prerequesites to be focus owner:
* - it is enabled, visible, focusable
* - it's parents are all enabled and showing
* - top-level window is focusable
* - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
* this component as focus owner
* @since 1.5
*/
final boolean canBeFocusOwnerRecursively() {
// - it is enabled, visible, focusable
if (!canBeFocusOwner()) {
return false;
}
// - it's parents are all enabled and showing
synchronized(getTreeLock()) {
if (parent != null) {
return parent.canContainFocusOwner(this);
}
}
return true;
}
/**
* Fix the location of the HW component in a LW container hierarchy.
*/
final void relocateComponent() {
synchronized (getTreeLock()) {
if (peer == null) {
return;
}
int nativeX = x;
int nativeY = y;
for (Component cont = getContainer();
cont != null && cont.isLightweight();
cont = cont.getContainer())
{
nativeX += cont.x;
nativeY += cont.y;
}
peer.setBounds(nativeX, nativeY, width, height,
ComponentPeer.SET_LOCATION);
}
}
/**
* Returns the <code>Window ancestor of the component.
* @return Window ancestor of the component or component by itself if it is Window;
* null, if component is not a part of window hierarchy
*/
Window getContainingWindow() {
return SunToolkit.getContainingWindow(this);
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/*
* --- Accessibility Support ---
*
* Component will contain all of the methods in interface Accessible,
* though it won't actually implement the interface - that will be up
* to the individual objects which extend Component.
*/
/**
* The {@code AccessibleContext} associated with this {@code Component}.
*/
protected AccessibleContext accessibleContext = null;
/**
* Gets the <code>AccessibleContext associated
* with this <code>Component.
* The method implemented by this base
* class returns null. Classes that extend <code>Component
* should implement this method to return the
* <code>AccessibleContext associated with the subclass.
*
*
* @return the <code>AccessibleContext of this
* <code>Component
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
return accessibleContext;
}
/**
* Inner class of Component used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by component developers.
* <p>
* The class used to obtain the accessible role for this object.
* @since 1.3
*/
protected abstract class AccessibleAWTComponent extends AccessibleContext
implements Serializable, AccessibleComponent {
private static final long serialVersionUID = 642321655757800191L;
/**
* Though the class is abstract, this should be called by
* all sub-classes.
*/
protected AccessibleAWTComponent() {
}
/**
* Number of PropertyChangeListener objects registered. It's used
* to add/remove ComponentListener and FocusListener to track
* target Component's state.
*/
private volatile transient int propertyListenersCount = 0;
protected ComponentListener accessibleAWTComponentHandler = null;
protected FocusListener accessibleAWTFocusHandler = null;
/**
* Fire PropertyChange listener, if one is registered,
* when shown/hidden..
* @since 1.3
*/
protected class AccessibleAWTComponentHandler implements ComponentListener {
public void componentHidden(ComponentEvent e) {
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.VISIBLE, null);
}
}
public void componentShown(ComponentEvent e) {
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.VISIBLE);
}
}
public void componentMoved(ComponentEvent e) {
}
public void componentResized(ComponentEvent e) {
}
} // inner class AccessibleAWTComponentHandler
/**
* Fire PropertyChange listener, if one is registered,
* when focus events happen
* @since 1.3
*/
protected class AccessibleAWTFocusHandler implements FocusListener {
public void focusGained(FocusEvent event) {
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.FOCUSED);
}
}
public void focusLost(FocusEvent event) {
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.FOCUSED, null);
}
}
} // inner class AccessibleAWTFocusHandler
/**
* Adds a <code>PropertyChangeListener to the listener list.
*
* @param listener the property change listener to be added
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
if (accessibleAWTComponentHandler == null) {
accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
}
if (accessibleAWTFocusHandler == null) {
accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
}
if (propertyListenersCount++ == 0) {
Component.this.addComponentListener(accessibleAWTComponentHandler);
Component.this.addFocusListener(accessibleAWTFocusHandler);
}
super.addPropertyChangeListener(listener);
}
/**
* Remove a PropertyChangeListener from the listener list.
* This removes a PropertyChangeListener that was registered
* for all properties.
*
* @param listener The PropertyChangeListener to be removed
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
if (--propertyListenersCount == 0) {
Component.this.removeComponentListener(accessibleAWTComponentHandler);
Component.this.removeFocusListener(accessibleAWTFocusHandler);
}
super.removePropertyChangeListener(listener);
}
// AccessibleContext methods
//
/**
* Gets the accessible name of this object. This should almost never
* return <code>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
* <code>null if this
* object does not have a name
* @see javax.accessibility.AccessibleContext#setAccessibleName
*/
public String getAccessibleName() {
return accessibleName;
}
/**
* Gets the accessible description of this object. This should be
* a concise, localized description of what this object is - what
* is its meaning to the user. If the object has a tooltip, the
* tooltip text may be an appropriate string to return, assuming
* it contains a concise description of the object (instead of just
* the name of the object - e.g. a "Save" icon on a toolbar that
* had "save" as the tooltip text shouldn't return the tooltip
* text as the description, but something like "Saves the current
* text document" instead).
*
* @return the localized description of the object -- can be
* <code>null if this object does not have a description
* @see javax.accessibility.AccessibleContext#setAccessibleDescription
*/
public String getAccessibleDescription() {
return accessibleDescription;
}
/**
* Gets the role of this object.
*
* @return an instance of <code>AccessibleRole
* describing the role of the object
* @see javax.accessibility.AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.AWT_COMPONENT;
}
/**
* Gets the state of this object.
*
* @return an instance of <code>AccessibleStateSet
* containing the current state set of the object
* @see javax.accessibility.AccessibleState
*/
public AccessibleStateSet getAccessibleStateSet() {
return Component.this.getAccessibleStateSet();
}
/**
* Gets the <code>Accessible parent of this object.
* If the parent of this object implements <code>Accessible,
* this method should simply return <code>getParent.
*
* @return the <code>Accessible parent of this
* object -- can be <code>null if this
* object does not have an <code>Accessible parent
*/
public Accessible getAccessibleParent() {
if (accessibleParent != null) {
return accessibleParent;
} else {
Container parent = getParent();
if (parent instanceof Accessible) {
return (Accessible) parent;
}
}
return null;
}
/**
* Gets the index of this object in its accessible parent.
*
* @return the index of this object in its parent; or -1 if this
* object does not have an accessible parent
* @see #getAccessibleParent
*/
public int getAccessibleIndexInParent() {
return Component.this.getAccessibleIndexInParent();
}
/**
* Returns the number of accessible children in the object. If all
* of the children of this object implement <code>Accessible,
* then this method should return the number of children of this object.
*
* @return the number of accessible children in the object
*/
public int getAccessibleChildrenCount() {
return 0; // Components don't have children
}
/**
* Returns the nth <code>Accessible child of the object.
*
* @param i zero-based index of child
* @return the nth <code>Accessible child of the object
*/
public Accessible getAccessibleChild(int i) {
return null; // Components don't have children
}
/**
* Returns the locale of this object.
*
* @return the locale of this object
*/
public Locale getLocale() {
return Component.this.getLocale();
}
/**
* Gets the <code>AccessibleComponent associated
* with this object if one exists.
* Otherwise return <code>null.
*
* @return the component
*/
public AccessibleComponent getAccessibleComponent() {
return this;
}
// AccessibleComponent methods
//
/**
* Gets the background color of this object.
*
* @return the background color, if supported, of the object;
* otherwise, <code>null
*/
public Color getBackground() {
return Component.this.getBackground();
}
/**
* Sets the background color of this object.
* (For transparency, see <code>isOpaque.)
*
* @param c the new <code>Color for the background
* @see Component#isOpaque
*/
public void setBackground(Color c) {
Component.this.setBackground(c);
}
/**
* Gets the foreground color of this object.
*
* @return the foreground color, if supported, of the object;
* otherwise, <code>null
*/
public Color getForeground() {
return Component.this.getForeground();
}
/**
* Sets the foreground color of this object.
*
* @param c the new <code>Color for the foreground
*/
public void setForeground(Color c) {
Component.this.setForeground(c);
}
/**
* Gets the <code>Cursor of this object.
*
* @return the <code>Cursor, if supported,
* of the object; otherwise, <code>null
*/
public Cursor getCursor() {
return Component.this.getCursor();
}
/**
* Sets the <code>Cursor of this object.
* <p>
* The method may have no visual effect if the Java platform
* implementation and/or the native system do not support
* changing the mouse cursor shape.
* @param cursor the new <code>Cursor for the object
*/
public void setCursor(Cursor cursor) {
Component.this.setCursor(cursor);
}
/**
* Gets the <code>Font of this object.
*
* @return the <code>Font, if supported,
* for the object; otherwise, <code>null
*/
public Font getFont() {
return Component.this.getFont();
}
/**
* Sets the <code>Font of this object.
*
* @param f the new <code>Font for the object
*/
public void setFont(Font f) {
Component.this.setFont(f);
}
/**
* Gets the <code>FontMetrics of this object.
*
* @param f the <code>Font
* @return the <code>FontMetrics, if supported,
* the object; otherwise, <code>null
* @see #getFont
*/
public FontMetrics getFontMetrics(Font f) {
if (f == null) {
return null;
} else {
return Component.this.getFontMetrics(f);
}
}
/**
* Determines if the object is enabled.
*
* @return true if object is enabled; otherwise, false
*/
public boolean isEnabled() {
return Component.this.isEnabled();
}
/**
* Sets the enabled state of the object.
*
* @param b if true, enables this object; otherwise, disables it
*/
public void setEnabled(boolean b) {
boolean old = Component.this.isEnabled();
Component.this.setEnabled(b);
if (b != old) {
if (accessibleContext != null) {
if (b) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.ENABLED);
} else {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.ENABLED, null);
}
}
}
}
/**
* Determines if the object is visible. Note: this means that the
* object intends to be visible; however, it may not in fact be
* showing on the screen because one of the objects that this object
* is contained by is not visible. To determine if an object is
* showing on the screen, use <code>isShowing.
*
* @return true if object is visible; otherwise, false
*/
public boolean isVisible() {
return Component.this.isVisible();
}
/**
* Sets the visible state of the object.
*
* @param b if true, shows this object; otherwise, hides it
*/
public void setVisible(boolean b) {
boolean old = Component.this.isVisible();
Component.this.setVisible(b);
if (b != old) {
if (accessibleContext != null) {
if (b) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.VISIBLE);
} else {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.VISIBLE, null);
}
}
}
}
/**
* Determines if the object is showing. This is determined by checking
* the visibility of the object and ancestors of the object. Note:
* this will return true even if the object is obscured by another
* (for example, it happens to be underneath a menu that was pulled
* down).
*
* @return true if object is showing; otherwise, false
*/
public boolean isShowing() {
return Component.this.isShowing();
}
/**
* Checks whether the specified point is within this object's bounds,
* where the point's x and y coordinates are defined to be relative to
* the coordinate system of the object.
*
* @param p the <code>Point relative to the
* coordinate system of the object
* @return true if object contains <code>Point; otherwise false
*/
public boolean contains(Point p) {
return Component.this.contains(p);
}
/**
* Returns the location of the object on the screen.
*
* @return location of object on screen -- can be
* <code>null if this object is not on the screen
*/
public Point getLocationOnScreen() {
synchronized (Component.this.getTreeLock()) {
if (Component.this.isShowing()) {
return Component.this.getLocationOnScreen();
} else {
return null;
}
}
}
/**
* Gets the location of the object relative to the parent in the form
* of a point specifying the object's top-left corner in the screen's
* coordinate space.
*
* @return an instance of Point representing the top-left corner of
* the object's bounds in the coordinate space of the screen;
* <code>null if this object or its parent are not on the screen
*/
public Point getLocation() {
return Component.this.getLocation();
}
/**
* Sets the location of the object relative to the parent.
* @param p the coordinates of the object
*/
public void setLocation(Point p) {
Component.this.setLocation(p);
}
/**
* Gets the bounds of this object in the form of a Rectangle object.
* The bounds specify this object's width, height, and location
* relative to its parent.
*
* @return a rectangle indicating this component's bounds;
* <code>null if this object is not on the screen
*/
public Rectangle getBounds() {
return Component.this.getBounds();
}
/**
* Sets the bounds of this object in the form of a
* <code>Rectangle object.
* The bounds specify this object's width, height, and location
* relative to its parent.
*
* @param r a rectangle indicating this component's bounds
*/
public void setBounds(Rectangle r) {
Component.this.setBounds(r);
}
/**
* Returns the size of this object in the form of a
* <code>Dimension object. The height field of the
* <code>Dimension object contains this objects's
* height, and the width field of the <code>Dimension
* object contains this object's width.
*
* @return a <code>Dimension object that indicates
* the size of this component; <code>null if
* this object is not on the screen
*/
public Dimension getSize() {
return Component.this.getSize();
}
/**
* Resizes this object so that it has width and height.
*
* @param d - the dimension specifying the new size of the object
*/
public void setSize(Dimension d) {
Component.this.setSize(d);
}
/**
* Returns the <code>Accessible child,
* if one exists, contained at the local
* coordinate <code>Point. Otherwise returns
* <code>null.
*
* @param p the point defining the top-left corner of
* the <code>Accessible, given in the
* coordinate space of the object's parent
* @return the <code>Accessible, if it exists,
* at the specified location; else <code>null
*/
public Accessible getAccessibleAt(Point p) {
return null; // Components don't have children
}
/**
* Returns whether this object can accept focus or not.
*
* @return true if object can accept focus; otherwise false
*/
public boolean isFocusTraversable() {
return Component.this.isFocusTraversable();
}
/**
* Requests focus for this object.
*/
public void requestFocus() {
Component.this.requestFocus();
}
/**
* Adds the specified focus listener to receive focus events from this
* component.
*
* @param l the focus listener
*/
public void addFocusListener(FocusListener l) {
Component.this.addFocusListener(l);
}
/**
* Removes the specified focus listener so it no longer receives focus
* events from this component.
*
* @param l the focus listener
*/
public void removeFocusListener(FocusListener l) {
Component.this.removeFocusListener(l);
}
} // inner class AccessibleAWTComponent
/**
* Gets the index of this object in its accessible parent.
* If this object does not have an accessible parent, returns
* -1.
*
* @return the index of this object in its accessible parent
*/
int getAccessibleIndexInParent() {
synchronized (getTreeLock()) {
int index = -1;
Container parent = this.getParent();
if (parent != null && parent instanceof Accessible) {
Component ca[] = parent.getComponents();
for (int i = 0; i < ca.length; i++) {
if (ca[i] instanceof Accessible) {
index++;
}
if (this.equals(ca[i])) {
return index;
}
}
}
return -1;
}
}
/**
* Gets the current state set of this object.
*
* @return an instance of <code>AccessibleStateSet
* containing the current state set of the object
* @see AccessibleState
*/
AccessibleStateSet getAccessibleStateSet() {
synchronized (getTreeLock()) {
AccessibleStateSet states = new AccessibleStateSet();
if (this.isEnabled()) {
states.add(AccessibleState.ENABLED);
}
if (this.isFocusTraversable()) {
states.add(AccessibleState.FOCUSABLE);
}
if (this.isVisible()) {
states.add(AccessibleState.VISIBLE);
}
if (this.isShowing()) {
states.add(AccessibleState.SHOWING);
}
if (this.isFocusOwner()) {
states.add(AccessibleState.FOCUSED);
}
if (this instanceof Accessible) {
AccessibleContext ac = ((Accessible) this).getAccessibleContext();
if (ac != null) {
Accessible ap = ac.getAccessibleParent();
if (ap != null) {
AccessibleContext pac = ap.getAccessibleContext();
if (pac != null) {
AccessibleSelection as = pac.getAccessibleSelection();
if (as != null) {
states.add(AccessibleState.SELECTABLE);
int i = ac.getAccessibleIndexInParent();
if (i >= 0) {
if (as.isAccessibleChildSelected(i)) {
states.add(AccessibleState.SELECTED);
}
}
}
}
}
}
}
if (Component.isInstanceOf(this, "javax.swing.JComponent")) {
if (((javax.swing.JComponent) this).isOpaque()) {
states.add(AccessibleState.OPAQUE);
}
}
return states;
}
}
/**
* Checks that the given object is instance of the given class.
* @param obj Object to be checked
* @param className The name of the class. Must be fully-qualified class name.
* @return true, if this object is instanceof given class,
* false, otherwise, or if obj or className is null
*/
static boolean isInstanceOf(Object obj, String className) {
if (obj == null) return false;
if (className == null) return false;
Class<?> cls = obj.getClass();
while (cls != null) {
if (cls.getName().equals(className)) {
return true;
}
cls = cls.getSuperclass();
}
return false;
}
// ************************** MIXING CODE *******************************
/**
* Check whether we can trust the current bounds of the component.
* The return value of false indicates that the container of the
* component is invalid, and therefore needs to be layed out, which would
* probably mean changing the bounds of its children.
* Null-layout of the container or absence of the container mean
* the bounds of the component are final and can be trusted.
*/
final boolean areBoundsValid() {
Container cont = getContainer();
return cont == null || cont.isValid() || cont.getLayout() == null;
}
/**
* Applies the shape to the component
* @param shape Shape to be applied to the component
*/
void applyCompoundShape(Region shape) {
checkTreeLock();
if (!areBoundsValid()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
}
return;
}
if (!isLightweight()) {
ComponentPeer peer = getPeer();
if (peer != null) {
// The Region class has some optimizations. That's why
// we should manually check whether it's empty and
// substitute the object ourselves. Otherwise we end up
// with some incorrect Region object with loX being
// greater than the hiX for instance.
if (shape.isEmpty()) {
shape = Region.EMPTY_REGION;
}
// Note: the shape is not really copied/cloned. We create
// the Region object ourselves, so there's no any possibility
// to modify the object outside of the mixing code.
// Nullifying compoundShape means that the component has normal shape
// (or has no shape at all).
if (shape.equals(getNormalShape())) {
if (this.compoundShape == null) {
return;
}
this.compoundShape = null;
peer.applyShape(null);
} else {
if (shape.equals(getAppliedShape())) {
return;
}
this.compoundShape = shape;
Point compAbsolute = getLocationOnWindow();
if (mixingLog.isLoggable(PlatformLogger.Level.FINER)) {
mixingLog.fine("this = " + this +
"; compAbsolute=" + compAbsolute + "; shape=" + shape);
}
peer.applyShape(shape.getTranslatedRegion(-compAbsolute.x, -compAbsolute.y));
}
}
}
}
/**
* Returns the shape previously set with applyCompoundShape().
* If the component is LW or no shape was applied yet,
* the method returns the normal shape.
*/
private Region getAppliedShape() {
checkTreeLock();
//XXX: if we allow LW components to have a shape, this must be changed
return (this.compoundShape == null || isLightweight()) ? getNormalShape() : this.compoundShape;
}
Point getLocationOnWindow() {
checkTreeLock();
Point curLocation = getLocation();
for (Container parent = getContainer();
parent != null && !(parent instanceof Window);
parent = parent.getContainer())
{
curLocation.x += parent.getX();
curLocation.y += parent.getY();
}
return curLocation;
}
/**
* Returns the full shape of the component located in window coordinates
*/
final Region getNormalShape() {
checkTreeLock();
//XXX: we may take into account a user-specified shape for this component
Point compAbsolute = getLocationOnWindow();
return
Region.getInstanceXYWH(
compAbsolute.x,
compAbsolute.y,
getWidth(),
getHeight()
);
}
/**
* Returns the "opaque shape" of the component.
*
* The opaque shape of a lightweight components is the actual shape that
* needs to be cut off of the heavyweight components in order to mix this
* lightweight component correctly with them.
*
* The method is overriden in the java.awt.Container to handle non-opaque
* containers containing opaque children.
*
* See 6637655 for details.
*/
Region getOpaqueShape() {
checkTreeLock();
if (mixingCutoutRegion != null) {
return mixingCutoutRegion;
} else {
return getNormalShape();
}
}
final int getSiblingIndexAbove() {
checkTreeLock();
Container parent = getContainer();
if (parent == null) {
return -1;
}
int nextAbove = parent.getComponentZOrder(this) - 1;
return nextAbove < 0 ? -1 : nextAbove;
}
final ComponentPeer getHWPeerAboveMe() {
checkTreeLock();
Container cont = getContainer();
int indexAbove = getSiblingIndexAbove();
while (cont != null) {
for (int i = indexAbove; i > -1; i--) {
Component comp = cont.getComponent(i);
if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
return comp.getPeer();
}
}
// traversing the hierarchy up to the closest HW container;
// further traversing may return a component that is not actually
// a native sibling of this component and this kind of z-order
// request may not be allowed by the underlying system (6852051).
if (!cont.isLightweight()) {
break;
}
indexAbove = cont.getSiblingIndexAbove();
cont = cont.getContainer();
}
return null;
}
final int getSiblingIndexBelow() {
checkTreeLock();
Container parent = getContainer();
if (parent == null) {
return -1;
}
int nextBelow = parent.getComponentZOrder(this) + 1;
return nextBelow >= parent.getComponentCount() ? -1 : nextBelow;
}
final boolean isNonOpaqueForMixing() {
return mixingCutoutRegion != null &&
mixingCutoutRegion.isEmpty();
}
private Region calculateCurrentShape() {
checkTreeLock();
Region s = getNormalShape();
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; normalShape=" + s);
}
if (getContainer() != null) {
Component comp = this;
Container cont = comp.getContainer();
while (cont != null) {
for (int index = comp.getSiblingIndexAbove(); index != -1; --index) {
/* It is assumed that:
*
* getComponent(getContainer().getComponentZOrder(comp)) == comp
*
* The assumption has been made according to the current
* implementation of the Container class.
*/
Component c = cont.getComponent(index);
if (c.isLightweight() && c.isShowing()) {
s = s.getDifference(c.getOpaqueShape());
}
}
if (cont.isLightweight()) {
s = s.getIntersection(cont.getNormalShape());
} else {
break;
}
comp = cont;
cont = cont.getContainer();
}
}
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("currentShape=" + s);
}
return s;
}
void applyCurrentShape() {
checkTreeLock();
if (!areBoundsValid()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
}
return; // Because applyCompoundShape() ignores such components anyway
}
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this);
}
applyCompoundShape(calculateCurrentShape());
}
final void subtractAndApplyShape(Region s) {
checkTreeLock();
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; s=" + s);
}
applyCompoundShape(getAppliedShape().getDifference(s));
}
private final void applyCurrentShapeBelowMe() {
checkTreeLock();
Container parent = getContainer();
if (parent != null && parent.isShowing()) {
// First, reapply shapes of my siblings
parent.recursiveApplyCurrentShape(getSiblingIndexBelow());
// Second, if my container is non-opaque, reapply shapes of siblings of my container
Container parent2 = parent.getContainer();
while (!parent.isOpaque() && parent2 != null) {
parent2.recursiveApplyCurrentShape(parent.getSiblingIndexBelow());
parent = parent2;
parent2 = parent.getContainer();
}
}
}
final void subtractAndApplyShapeBelowMe() {
checkTreeLock();
Container parent = getContainer();
if (parent != null && isShowing()) {
Region opaqueShape = getOpaqueShape();
// First, cut my siblings
parent.recursiveSubtractAndApplyShape(opaqueShape, getSiblingIndexBelow());
// Second, if my container is non-opaque, cut siblings of my container
Container parent2 = parent.getContainer();
while (!parent.isOpaque() && parent2 != null) {
parent2.recursiveSubtractAndApplyShape(opaqueShape, parent.getSiblingIndexBelow());
parent = parent2;
parent2 = parent.getContainer();
}
}
}
void mixOnShowing() {
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this);
}
if (!isMixingNeeded()) {
return;
}
if (isLightweight()) {
subtractAndApplyShapeBelowMe();
} else {
applyCurrentShape();
}
}
}
void mixOnHiding(boolean isLightweight) {
// We cannot be sure that the peer exists at this point, so we need the argument
// to find out whether the hiding component is (well, actually was) a LW or a HW.
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; isLightweight = " + isLightweight);
}
if (!isMixingNeeded()) {
return;
}
if (isLightweight) {
applyCurrentShapeBelowMe();
}
}
}
void mixOnReshaping() {
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this);
}
if (!isMixingNeeded()) {
return;
}
if (isLightweight()) {
applyCurrentShapeBelowMe();
} else {
applyCurrentShape();
}
}
}
void mixOnZOrderChanging(int oldZorder, int newZorder) {
synchronized (getTreeLock()) {
boolean becameHigher = newZorder < oldZorder;
Container parent = getContainer();
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this +
"; oldZorder=" + oldZorder + "; newZorder=" + newZorder + "; parent=" + parent);
}
if (!isMixingNeeded()) {
return;
}
if (isLightweight()) {
if (becameHigher) {
if (parent != null && isShowing()) {
parent.recursiveSubtractAndApplyShape(getOpaqueShape(), getSiblingIndexBelow(), oldZorder);
}
} else {
if (parent != null) {
parent.recursiveApplyCurrentShape(oldZorder, newZorder);
}
}
} else {
if (becameHigher) {
applyCurrentShape();
} else {
if (parent != null) {
Region shape = getAppliedShape();
for (int index = oldZorder; index < newZorder; index++) {
Component c = parent.getComponent(index);
if (c.isLightweight() && c.isShowing()) {
shape = shape.getDifference(c.getOpaqueShape());
}
}
applyCompoundShape(shape);
}
}
}
}
}
void mixOnValidating() {
// This method gets overriden in the Container. Obviously, a plain
// non-container components don't need to handle validation.
}
final boolean isMixingNeeded() {
if (SunToolkit.getSunAwtDisableMixing()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINEST)) {
mixingLog.finest("this = " + this + "; Mixing disabled via sun.awt.disableMixing");
}
return false;
}
if (!areBoundsValid()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
}
return false;
}
Window window = getContainingWindow();
if (window != null) {
if (!window.hasHeavyweightDescendants() || !window.hasLightweightDescendants() || window.isDisposing()) {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("containing window = " + window +
"; has h/w descendants = " + window.hasHeavyweightDescendants() +
"; has l/w descendants = " + window.hasLightweightDescendants() +
"; disposing = " + window.isDisposing());
}
return false;
}
} else {
if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
mixingLog.fine("this = " + this + "; containing window is null");
}
return false;
}
return true;
}
// ****************** END OF MIXING CODE ********************************
// Note that the method is overriden in the Window class,
// a window doesn't need to be updated in the Z-order.
void updateZOrder() {
peer.setZOrder(getHWPeerAboveMe());
}
}
Here is a short list of links related to this Java Component.java source code file:
Java example source code file (Component.java)
The Component.java Java example source code/* * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.awt; import java.io.PrintStream; import java.io.PrintWriter; import java.util.Vector; import java.util.Locale; import java.util.EventListener; import java.util.Iterator; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.Collections; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; import java.awt.image.BufferStrategy; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.ColorModel; import java.awt.image.VolatileImage; import java.awt.event.*; import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.beans.Transient; import java.awt.event.InputMethodListener; import java.awt.event.InputMethodEvent; import java.awt.im.InputContext; import java.awt.im.InputMethodRequests; import java.awt.dnd.DropTarget; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.AccessControlContext; import javax.accessibility.*; import java.applet.Applet; import sun.security.action.GetPropertyAction; import sun.awt.AppContext; import sun.awt.AWTAccessor; import sun.awt.ConstrainableGraphics; import sun.awt.SubRegionShowable; import sun.awt.SunToolkit; import sun.awt.WindowClosingListener; import sun.awt.CausedFocusEvent; import sun.awt.EmbeddedFrame; import sun.awt.dnd.SunDropTargetEvent; import sun.awt.im.CompositionArea; import sun.font.FontManager; import sun.font.FontManagerFactory; import sun.font.SunFontManager; import sun.java2d.SunGraphics2D; import sun.java2d.pipe.Region; import sun.awt.image.VSyncedBSManager; import sun.java2d.pipe.hw.ExtendedBufferCapabilities; import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*; import sun.awt.RequestFocusController; import sun.java2d.SunGraphicsEnvironment; import sun.util.logging.PlatformLogger; /** * A <em>component is an object having a graphical representation * that can be displayed on the screen and that can interact with the * user. Examples of components are the buttons, checkboxes, and scrollbars * of a typical graphical user interface. <p> * The <code>Component class is the abstract superclass of * the nonmenu-related Abstract Window Toolkit components. Class * <code>Component can also be extended directly to create a * lightweight component. A lightweight component is a component that is * not associated with a native window. On the contrary, a heavyweight * component is associated with a native window. The {@link #isLightweight()} * method may be used to distinguish between the two kinds of the components. * <p> * Lightweight and heavyweight components may be mixed in a single component * hierarchy. However, for correct operating of such a mixed hierarchy of * components, the whole hierarchy must be valid. When the hierarchy gets * invalidated, like after changing the bounds of components, or * adding/removing components to/from containers, the whole hierarchy must be * validated afterwards by means of the {@link Container#validate()} method * invoked on the top-most invalid container of the hierarchy. * * <h3>Serialization * It is important to note that only AWT listeners which conform * to the <code>Serializable protocol will be saved when * the object is stored. If an AWT object has listeners that * aren't marked serializable, they will be dropped at * <code>writeObject time. Developers will need, as always, * to consider the implications of making an object serializable. * One situation to watch out for is this: * <pre> * import java.awt.*; * import java.awt.event.*; * import java.io.Serializable; * * class MyApp implements ActionListener, Serializable * { * BigObjectThatShouldNotBeSerializedWithAButton bigOne; * Button aButton = new Button(); * * MyApp() * { * // Oops, now aButton has a listener with a reference * // to bigOne! * aButton.addActionListener(this); * } * * public void actionPerformed(ActionEvent e) * { * System.out.println("Hello There"); * } * } * </pre> * In this example, serializing <code>aButton by itself * will cause <code>MyApp and everything it refers to * to be serialized as well. The problem is that the listener * is serializable by coincidence, not by design. To separate * the decisions about <code>MyApp and the * <code>ActionListener being serializable one can use a * nested class, as in the following example: * <pre> * import java.awt.*; * import java.awt.event.*; * import java.io.Serializable; * * class MyApp implements java.io.Serializable * { * BigObjectThatShouldNotBeSerializedWithAButton bigOne; * Button aButton = new Button(); * * static class MyActionListener implements ActionListener * { * public void actionPerformed(ActionEvent e) * { * System.out.println("Hello There"); * } * } * * MyApp() * { * aButton.addActionListener(new MyActionListener()); * } * } * </pre> * <p> * <b>Note: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing. * <p> * For details on the focus subsystem, see * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification * for more information. * * @author Arthur van Hoff * @author Sami Shaio */ public abstract class Component implements ImageObserver, MenuContainer, Serializable { private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component"); private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component"); private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.Component"); private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Component"); /** * The peer of the component. The peer implements the component's * behavior. The peer is set when the <code>Component is * added to a container that also is a peer. * @see #addNotify * @see #removeNotify */ transient ComponentPeer peer; /** * The parent of the object. It may be <code>null * for top-level components. * @see #getParent */ transient Container parent; /** * The <code>AppContext of the component. Applets/Plugin may * change the AppContext. */ transient AppContext appContext; /** * The x position of the component in the parent's coordinate system. * * @serial * @see #getLocation */ int x; /** * The y position of the component in the parent's coordinate system. * * @serial * @see #getLocation */ int y; /** * The width of the component. * * @serial * @see #getSize */ int width; /** * The height of the component. * * @serial * @see #getSize */ int height; /** * The foreground color for this component. * <code>foreground can be* * If no such listeners exist, this method returns an empty array. * * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from * <code>java.util.EventListener * @return an array of all objects registered as * <code>FooListeners on this component, * or an empty array if no such listeners have been added * @exception ClassCastException if <code>listenerType * doesn't specify a class or interface that implements * <code>java.util.EventListener * @throws NullPointerException if {@code listenerType} is {@code null} * @see #getComponentListeners * @see #getFocusListeners * @see #getHierarchyListeners * @see #getHierarchyBoundsListeners * @see #getKeyListeners * @see #getMouseListeners * @see #getMouseMotionListeners * @see #getMouseWheelListeners * @see #getInputMethodListeners * @see #getPropertyChangeListeners * * @since 1.3 */ @SuppressWarnings("unchecked") public <T extends EventListener> T[] getListeners(Class null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see #processComponentEvent
* @see #processFocusEvent
* @see #processKeyEvent
* @see #processMouseEvent
* @see #processMouseMotionEvent
* @see #processInputMethodEvent
* @see #processHierarchyEvent
* @see #processMouseWheelEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof FocusEvent) {
processFocusEvent((FocusEvent)e);
} else if (e instanceof MouseEvent) {
switch(e.getID()) {
case MouseEvent.MOUSE_PRESSED:
case MouseEvent.MOUSE_RELEASED:
case MouseEvent.MOUSE_CLICKED:
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
processMouseEvent((MouseEvent)e);
break;
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
processMouseMotionEvent((MouseEvent)e);
break;
case MouseEvent.MOUSE_WHEEL:
processMouseWheelEvent((MouseWheelEvent)e);
break;
}
} else if (e instanceof KeyEvent) {
processKeyEvent((KeyEvent)e);
} else if (e instanceof ComponentEvent) {
processComponentEvent((ComponentEvent)e);
} else if (e instanceof InputMethodEvent) {
processInputMethodEvent((InputMethodEvent)e);
} else if (e instanceof HierarchyEvent) {
switch (e.getID()) {
case HierarchyEvent.HIERARCHY_CHANGED:
processHierarchyEvent((HierarchyEvent)e);
break;
case HierarchyEvent.ANCESTOR_MOVED:
case HierarchyEvent.ANCESTOR_RESIZED:
processHierarchyBoundsEvent((HierarchyEvent)e);
break;
}
}
}
/**
* Processes component events occurring on this component by
* dispatching them to any registered
* <code>ComponentListener objects.
* <p>
* This method is not called unless component events are
* enabled for this component. Component events are enabled
* when one of the following occurs:
* <ul>
* <li>A ComponentListener object is registered
* via <code>addComponentListener.
* <li>Component events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the component event
* @see java.awt.event.ComponentEvent
* @see java.awt.event.ComponentListener
* @see #addComponentListener
* @see #enableEvents
* @since JDK1.1
*/
protected void processComponentEvent(ComponentEvent e) {
ComponentListener listener = componentListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case ComponentEvent.COMPONENT_RESIZED:
listener.componentResized(e);
break;
case ComponentEvent.COMPONENT_MOVED:
listener.componentMoved(e);
break;
case ComponentEvent.COMPONENT_SHOWN:
listener.componentShown(e);
break;
case ComponentEvent.COMPONENT_HIDDEN:
listener.componentHidden(e);
break;
}
}
}
/**
* Processes focus events occurring on this component by
* dispatching them to any registered
* <code>FocusListener objects.
* <p>
* This method is not called unless focus events are
* enabled for this component. Focus events are enabled
* when one of the following occurs:
* <ul>
* <li>A FocusListener object is registered
* via <code>addFocusListener.
* <li>Focus events are enabled via enableEvents .
* </ul>
* <p>
* If focus events are enabled for a <code>Component,
* the current <code>KeyboardFocusManager determines
* whether or not a focus event should be dispatched to
* registered <code>FocusListener objects. If the
* events are to be dispatched, the <code>KeyboardFocusManager
* calls the <code>Component's dispatchEvent
* method, which results in a call to the <code>Component's
* <code>processFocusEvent method.
* <p>
* If focus events are enabled for a <code>Component, calling
* the <code>Component's dispatchEvent method
* with a <code>FocusEvent as the argument will result in a
* call to the <code>Component's processFocusEvent
* method regardless of the current <code>KeyboardFocusManager.
*
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the focus event
* @see java.awt.event.FocusEvent
* @see java.awt.event.FocusListener
* @see java.awt.KeyboardFocusManager
* @see #addFocusListener
* @see #enableEvents
* @see #dispatchEvent
* @since JDK1.1
*/
protected void processFocusEvent(FocusEvent e) {
FocusListener listener = focusListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case FocusEvent.FOCUS_GAINED:
listener.focusGained(e);
break;
case FocusEvent.FOCUS_LOST:
listener.focusLost(e);
break;
}
}
}
/**
* Processes key events occurring on this component by
* dispatching them to any registered
* <code>KeyListener objects.
* <p>
* This method is not called unless key events are
* enabled for this component. Key events are enabled
* when one of the following occurs:
* <ul>
* <li>A KeyListener object is registered
* via <code>addKeyListener.
* <li>Key events are enabled via enableEvents .
* </ul>
*
* <p>
* If key events are enabled for a <code>Component,
* the current <code>KeyboardFocusManager determines
* whether or not a key event should be dispatched to
* registered <code>KeyListener objects. The
* <code>DefaultKeyboardFocusManager will not dispatch
* key events to a <code>Component that is not the focus
* owner or is not showing.
* <p>
* As of J2SE 1.4, <code>KeyEvents are redirected to
* the focus owner. Please see the
* <a href="doc-files/FocusSpec.html">Focus SpecificationdispatchEvent
* method with a <code>KeyEvent as the argument will
* result in a call to the <code>Component's
* <code>processKeyEvent method regardless of the
* current <code>KeyboardFocusManager as long as the
* component is showing, focused, and enabled, and key events
* are enabled on it.
* <p>If the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the key event
* @see java.awt.event.KeyEvent
* @see java.awt.event.KeyListener
* @see java.awt.KeyboardFocusManager
* @see java.awt.DefaultKeyboardFocusManager
* @see #processEvent
* @see #dispatchEvent
* @see #addKeyListener
* @see #enableEvents
* @see #isShowing
* @since JDK1.1
*/
protected void processKeyEvent(KeyEvent e) {
KeyListener listener = keyListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case KeyEvent.KEY_TYPED:
listener.keyTyped(e);
break;
case KeyEvent.KEY_PRESSED:
listener.keyPressed(e);
break;
case KeyEvent.KEY_RELEASED:
listener.keyReleased(e);
break;
}
}
}
/**
* Processes mouse events occurring on this component by
* dispatching them to any registered
* <code>MouseListener objects.
* <p>
* This method is not called unless mouse events are
* enabled for this component. Mouse events are enabled
* when one of the following occurs:
* <ul>
* <li>A MouseListener object is registered
* via <code>addMouseListener.
* <li>Mouse events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the mouse event
* @see java.awt.event.MouseEvent
* @see java.awt.event.MouseListener
* @see #addMouseListener
* @see #enableEvents
* @since JDK1.1
*/
protected void processMouseEvent(MouseEvent e) {
MouseListener listener = mouseListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case MouseEvent.MOUSE_PRESSED:
listener.mousePressed(e);
break;
case MouseEvent.MOUSE_RELEASED:
listener.mouseReleased(e);
break;
case MouseEvent.MOUSE_CLICKED:
listener.mouseClicked(e);
break;
case MouseEvent.MOUSE_EXITED:
listener.mouseExited(e);
break;
case MouseEvent.MOUSE_ENTERED:
listener.mouseEntered(e);
break;
}
}
}
/**
* Processes mouse motion events occurring on this component by
* dispatching them to any registered
* <code>MouseMotionListener objects.
* <p>
* This method is not called unless mouse motion events are
* enabled for this component. Mouse motion events are enabled
* when one of the following occurs:
* <ul>
* <li>A MouseMotionListener object is registered
* via <code>addMouseMotionListener.
* <li>Mouse motion events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the mouse motion event
* @see java.awt.event.MouseEvent
* @see java.awt.event.MouseMotionListener
* @see #addMouseMotionListener
* @see #enableEvents
* @since JDK1.1
*/
protected void processMouseMotionEvent(MouseEvent e) {
MouseMotionListener listener = mouseMotionListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case MouseEvent.MOUSE_MOVED:
listener.mouseMoved(e);
break;
case MouseEvent.MOUSE_DRAGGED:
listener.mouseDragged(e);
break;
}
}
}
/**
* Processes mouse wheel events occurring on this component by
* dispatching them to any registered
* <code>MouseWheelListener objects.
* <p>
* This method is not called unless mouse wheel events are
* enabled for this component. Mouse wheel events are enabled
* when one of the following occurs:
* <ul>
* <li>A MouseWheelListener object is registered
* via <code>addMouseWheelListener.
* <li>Mouse wheel events are enabled via enableEvents .
* </ul>
* <p>
* For information on how mouse wheel events are dispatched, see
* the class description for {@link MouseWheelEvent}.
* <p>
* Note that if the event parameter is <code>null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the mouse wheel event
* @see java.awt.event.MouseWheelEvent
* @see java.awt.event.MouseWheelListener
* @see #addMouseWheelListener
* @see #enableEvents
* @since 1.4
*/
protected void processMouseWheelEvent(MouseWheelEvent e) {
MouseWheelListener listener = mouseWheelListener;
if (listener != null) {
int id = e.getID();
switch(id) {
case MouseEvent.MOUSE_WHEEL:
listener.mouseWheelMoved(e);
break;
}
}
}
boolean postsOldMouseEvents() {
return false;
}
/**
* Processes input method events occurring on this component by
* dispatching them to any registered
* <code>InputMethodListener objects.
* <p>
* This method is not called unless input method events
* are enabled for this component. Input method events are enabled
* when one of the following occurs:
* <ul>
* <li>An InputMethodListener object is registered
* via <code>addInputMethodListener.
* <li>Input method events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the input method event
* @see java.awt.event.InputMethodEvent
* @see java.awt.event.InputMethodListener
* @see #addInputMethodListener
* @see #enableEvents
* @since 1.2
*/
protected void processInputMethodEvent(InputMethodEvent e) {
InputMethodListener listener = inputMethodListener;
if (listener != null) {
int id = e.getID();
switch (id) {
case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
listener.inputMethodTextChanged(e);
break;
case InputMethodEvent.CARET_POSITION_CHANGED:
listener.caretPositionChanged(e);
break;
}
}
}
/**
* Processes hierarchy events occurring on this component by
* dispatching them to any registered
* <code>HierarchyListener objects.
* <p>
* This method is not called unless hierarchy events
* are enabled for this component. Hierarchy events are enabled
* when one of the following occurs:
* <ul>
* <li>An HierarchyListener object is registered
* via <code>addHierarchyListener.
* <li>Hierarchy events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the hierarchy event
* @see java.awt.event.HierarchyEvent
* @see java.awt.event.HierarchyListener
* @see #addHierarchyListener
* @see #enableEvents
* @since 1.3
*/
protected void processHierarchyEvent(HierarchyEvent e) {
HierarchyListener listener = hierarchyListener;
if (listener != null) {
int id = e.getID();
switch (id) {
case HierarchyEvent.HIERARCHY_CHANGED:
listener.hierarchyChanged(e);
break;
}
}
}
/**
* Processes hierarchy bounds events occurring on this component by
* dispatching them to any registered
* <code>HierarchyBoundsListener objects.
* <p>
* This method is not called unless hierarchy bounds events
* are enabled for this component. Hierarchy bounds events are enabled
* when one of the following occurs:
* <ul>
* <li>An HierarchyBoundsListener object is registered
* via <code>addHierarchyBoundsListener.
* <li>Hierarchy bounds events are enabled via enableEvents .
* </ul>
* <p>Note that if the event parameter is null
* the behavior is unspecified and may result in an
* exception.
*
* @param e the hierarchy event
* @see java.awt.event.HierarchyEvent
* @see java.awt.event.HierarchyBoundsListener
* @see #addHierarchyBoundsListener
* @see #enableEvents
* @since 1.3
*/
protected void processHierarchyBoundsEvent(HierarchyEvent e) {
HierarchyBoundsListener listener = hierarchyBoundsListener;
if (listener != null) {
int id = e.getID();
switch (id) {
case HierarchyEvent.ANCESTOR_MOVED:
listener.ancestorMoved(e);
break;
case HierarchyEvent.ANCESTOR_RESIZED:
listener.ancestorResized(e);
break;
}
}
}
/**
* @deprecated As of JDK version 1.1
* replaced by processEvent(AWTEvent).
*/
@Deprecated
public boolean handleEvent(Event evt) {
switch (evt.id) {
case Event.MOUSE_ENTER:
return mouseEnter(evt, evt.x, evt.y);
case Event.MOUSE_EXIT:
return mouseExit(evt, evt.x, evt.y);
case Event.MOUSE_MOVE:
return mouseMove(evt, evt.x, evt.y);
case Event.MOUSE_DOWN:
return mouseDown(evt, evt.x, evt.y);
case Event.MOUSE_DRAG:
return mouseDrag(evt, evt.x, evt.y);
case Event.MOUSE_UP:
return mouseUp(evt, evt.x, evt.y);
case Event.KEY_PRESS:
case Event.KEY_ACTION:
return keyDown(evt, evt.key);
case Event.KEY_RELEASE:
case Event.KEY_ACTION_RELEASE:
return keyUp(evt, evt.key);
case Event.ACTION_EVENT:
return action(evt, evt.arg);
case Event.GOT_FOCUS:
return gotFocus(evt, evt.arg);
case Event.LOST_FOCUS:
return lostFocus(evt, evt.arg);
}
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseEvent(MouseEvent).
*/
@Deprecated
public boolean mouseDown(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseMotionEvent(MouseEvent).
*/
@Deprecated
public boolean mouseDrag(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseEvent(MouseEvent).
*/
@Deprecated
public boolean mouseUp(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseMotionEvent(MouseEvent).
*/
@Deprecated
public boolean mouseMove(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseEvent(MouseEvent).
*/
@Deprecated
public boolean mouseEnter(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processMouseEvent(MouseEvent).
*/
@Deprecated
public boolean mouseExit(Event evt, int x, int y) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processKeyEvent(KeyEvent).
*/
@Deprecated
public boolean keyDown(Event evt, int key) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processKeyEvent(KeyEvent).
*/
@Deprecated
public boolean keyUp(Event evt, int key) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* should register this component as ActionListener on component
* which fires action events.
*/
@Deprecated
public boolean action(Event evt, Object what) {
return false;
}
/**
* Makes this <code>Component displayable by connecting it to a
* native screen resource.
* This method is called internally by the toolkit and should
* not be called directly by programs.
* <p>
* This method changes layout-related information, and therefore,
* invalidates the component hierarchy.
*
* @see #isDisplayable
* @see #removeNotify
* @see #invalidate
* @since JDK1.0
*/
public void addNotify() {
synchronized (getTreeLock()) {
ComponentPeer peer = this.peer;
if (peer == null || peer instanceof LightweightPeer){
if (peer == null) {
// Update both the Component's peer variable and the local
// variable we use for thread safety.
this.peer = peer = getToolkit().createComponent(this);
}
// This is a lightweight component which means it won't be
// able to get window-related events by itself. If any
// have been enabled, then the nearest native container must
// be enabled.
if (parent != null) {
long mask = 0;
if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
mask |= AWTEvent.MOUSE_EVENT_MASK;
}
if ((mouseMotionListener != null) ||
((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
}
if ((mouseWheelListener != null ) ||
((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
}
if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
mask |= AWTEvent.FOCUS_EVENT_MASK;
}
if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
mask |= AWTEvent.KEY_EVENT_MASK;
}
if (mask != 0) {
parent.proxyEnableEvents(mask);
}
}
} else {
// It's native. If the parent is lightweight it will need some
// help.
Container parent = getContainer();
if (parent != null && parent.isLightweight()) {
relocateComponent();
if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
{
peer.setVisible(false);
}
}
}
invalidate();
int npopups = (popups != null? popups.size() : 0);
for (int i = 0 ; i < npopups ; i++) {
PopupMenu popup = popups.elementAt(i);
popup.addNotify();
}
if (dropTarget != null) dropTarget.addNotify(peer);
peerFont = getFont();
if (getContainer() != null && !isAddNotifyComplete) {
getContainer().increaseComponentCount(this);
}
// Update stacking order
updateZOrder();
if (!isAddNotifyComplete) {
mixOnShowing();
}
isAddNotifyComplete = true;
if (hierarchyListener != null ||
(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
HierarchyEvent e =
new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
this, parent,
HierarchyEvent.DISPLAYABILITY_CHANGED |
((isRecursivelyVisible())
? HierarchyEvent.SHOWING_CHANGED
: 0));
dispatchEvent(e);
}
}
}
/**
* Makes this <code>Component undisplayable by destroying it native
* screen resource.
* <p>
* This method is called by the toolkit internally and should
* not be called directly by programs. Code overriding
* this method should call <code>super.removeNotify as
* the first line of the overriding method.
*
* @see #isDisplayable
* @see #addNotify
* @since JDK1.0
*/
public void removeNotify() {
KeyboardFocusManager.clearMostRecentFocusOwner(this);
if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
getPermanentFocusOwner() == this)
{
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setGlobalPermanentFocusOwner(null);
}
synchronized (getTreeLock()) {
clearLightweightDispatcherOnRemove(this);
if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
transferFocus(true);
}
if (getContainer() != null && isAddNotifyComplete) {
getContainer().decreaseComponentCount(this);
}
int npopups = (popups != null? popups.size() : 0);
for (int i = 0 ; i < npopups ; i++) {
PopupMenu popup = popups.elementAt(i);
popup.removeNotify();
}
// If there is any input context for this component, notify
// that this component is being removed. (This has to be done
// before hiding peer.)
if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
InputContext inputContext = getInputContext();
if (inputContext != null) {
inputContext.removeNotify(this);
}
}
ComponentPeer p = peer;
if (p != null) {
boolean isLightweight = isLightweight();
if (bufferStrategy instanceof FlipBufferStrategy) {
((FlipBufferStrategy)bufferStrategy).destroyBuffers();
}
if (dropTarget != null) dropTarget.removeNotify(peer);
// Hide peer first to stop system events such as cursor moves.
if (visible) {
p.setVisible(false);
}
peer = null; // Stop peer updates.
peerFont = null;
Toolkit.getEventQueue().removeSourceEvents(this, false);
KeyboardFocusManager.getCurrentKeyboardFocusManager().
discardKeyEvents(this);
p.dispose();
mixOnHiding(isLightweight);
isAddNotifyComplete = false;
// Nullifying compoundShape means that the component has normal shape
// (or has no shape at all).
this.compoundShape = null;
}
if (hierarchyListener != null ||
(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
HierarchyEvent e =
new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
this, parent,
HierarchyEvent.DISPLAYABILITY_CHANGED |
((isRecursivelyVisible())
? HierarchyEvent.SHOWING_CHANGED
: 0));
dispatchEvent(e);
}
}
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processFocusEvent(FocusEvent).
*/
@Deprecated
public boolean gotFocus(Event evt, Object what) {
return false;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by processFocusEvent(FocusEvent).
*/
@Deprecated
public boolean lostFocus(Event evt, Object what) {
return false;
}
/**
* Returns whether this <code>Component can become the focus
* owner.
*
* @return <code>true if this Component is
* focusable; <code>false otherwise
* @see #setFocusable
* @since JDK1.1
* @deprecated As of 1.4, replaced by <code>isFocusable().
*/
@Deprecated
public boolean isFocusTraversable() {
if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
}
return focusable;
}
/**
* Returns whether this Component can be focused.
*
* @return <code>true if this Component is focusable;
* <code>false otherwise.
* @see #setFocusable
* @since 1.4
*/
public boolean isFocusable() {
return isFocusTraversable();
}
/**
* Sets the focusable state of this Component to the specified value. This
* value overrides the Component's default focusability.
*
* @param focusable indicates whether this Component is focusable
* @see #isFocusable
* @since 1.4
* @beaninfo
* bound: true
*/
public void setFocusable(boolean focusable) {
boolean oldFocusable;
synchronized (this) {
oldFocusable = this.focusable;
this.focusable = focusable;
}
isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
firePropertyChange("focusable", oldFocusable, focusable);
if (oldFocusable && !focusable) {
if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
transferFocus(true);
}
KeyboardFocusManager.clearMostRecentFocusOwner(this);
}
}
final boolean isFocusTraversableOverridden() {
return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
}
/**
* Sets the focus traversal keys for a given traversal operation for this
* Component.
* <p>
* The default values for a Component's focus traversal keys are
* implementation-dependent. Sun recommends that all implementations for a
* particular native platform use the same default values. The
* recommendations for Windows and Unix are listed below. These
* recommendations are used in the Sun AWT implementations.
*
* <table border=1 summary="Recommended default values for a Component's focus traversal keys">
* <tr>
* <th>Identifier
* <th>Meaning
* <th>Default
* </tr>
* <tr>
* <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.