feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
367
jdkSrc/jdk8/javax/swing/AbstractAction.java
Normal file
367
jdkSrc/jdk8/javax/swing/AbstractAction.java
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.io.Serializable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.security.AccessController;
|
||||
import javax.swing.event.SwingPropertyChangeSupport;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* This class provides default implementations for the JFC <code>Action</code>
|
||||
* interface. Standard behaviors like the get and set methods for
|
||||
* <code>Action</code> object properties (icon, text, and enabled) are defined
|
||||
* here. The developer need only subclass this abstract class and
|
||||
* define the <code>actionPerformed</code> method.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @see Action
|
||||
*/
|
||||
public abstract class AbstractAction implements Action, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Whether or not actions should reconfigure all properties on null.
|
||||
*/
|
||||
private static Boolean RECONFIGURE_ON_NULL;
|
||||
|
||||
/**
|
||||
* Specifies whether action is enabled; the default is true.
|
||||
*/
|
||||
protected boolean enabled = true;
|
||||
|
||||
|
||||
/**
|
||||
* Contains the array of key bindings.
|
||||
*/
|
||||
private transient ArrayTable arrayTable;
|
||||
|
||||
/**
|
||||
* Whether or not to reconfigure all action properties from the
|
||||
* specified event.
|
||||
*/
|
||||
static boolean shouldReconfigure(PropertyChangeEvent e) {
|
||||
if (e.getPropertyName() == null) {
|
||||
synchronized(AbstractAction.class) {
|
||||
if (RECONFIGURE_ON_NULL == null) {
|
||||
RECONFIGURE_ON_NULL = Boolean.valueOf(
|
||||
AccessController.doPrivileged(new GetPropertyAction(
|
||||
"swing.actions.reconfigureOnNull", "false")));
|
||||
}
|
||||
return RECONFIGURE_ON_NULL;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled state of a component from an Action.
|
||||
*
|
||||
* @param c the Component to set the enabled state on
|
||||
* @param a the Action to set the enabled state from, may be null
|
||||
*/
|
||||
static void setEnabledFromAction(JComponent c, Action a) {
|
||||
c.setEnabled((a != null) ? a.isEnabled() : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tooltip text of a component from an Action.
|
||||
*
|
||||
* @param c the Component to set the tooltip text on
|
||||
* @param a the Action to set the tooltip text from, may be null
|
||||
*/
|
||||
static void setToolTipTextFromAction(JComponent c, Action a) {
|
||||
c.setToolTipText(a != null ?
|
||||
(String)a.getValue(Action.SHORT_DESCRIPTION) : null);
|
||||
}
|
||||
|
||||
static boolean hasSelectedKey(Action a) {
|
||||
return (a != null && a.getValue(Action.SELECTED_KEY) != null);
|
||||
}
|
||||
|
||||
static boolean isSelected(Action a) {
|
||||
return Boolean.TRUE.equals(a.getValue(Action.SELECTED_KEY));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an {@code Action}.
|
||||
*/
|
||||
public AbstractAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code Action} with the specified name.
|
||||
*
|
||||
* @param name the name ({@code Action.NAME}) for the action; a
|
||||
* value of {@code null} is ignored
|
||||
*/
|
||||
public AbstractAction(String name) {
|
||||
putValue(Action.NAME, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code Action} with the specified name and small icon.
|
||||
*
|
||||
* @param name the name ({@code Action.NAME}) for the action; a
|
||||
* value of {@code null} is ignored
|
||||
* @param icon the small icon ({@code Action.SMALL_ICON}) for the action; a
|
||||
* value of {@code null} is ignored
|
||||
*/
|
||||
public AbstractAction(String name, Icon icon) {
|
||||
this(name);
|
||||
putValue(Action.SMALL_ICON, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Object</code> associated with the specified key.
|
||||
*
|
||||
* @param key a string containing the specified <code>key</code>
|
||||
* @return the binding <code>Object</code> stored with this key; if there
|
||||
* are no keys, it will return <code>null</code>
|
||||
* @see Action#getValue
|
||||
*/
|
||||
public Object getValue(String key) {
|
||||
if (key == "enabled") {
|
||||
return enabled;
|
||||
}
|
||||
if (arrayTable == null) {
|
||||
return null;
|
||||
}
|
||||
return arrayTable.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Value</code> associated with the specified key.
|
||||
*
|
||||
* @param key the <code>String</code> that identifies the stored object
|
||||
* @param newValue the <code>Object</code> to store using this key
|
||||
* @see Action#putValue
|
||||
*/
|
||||
public void putValue(String key, Object newValue) {
|
||||
Object oldValue = null;
|
||||
if (key == "enabled") {
|
||||
// Treat putValue("enabled") the same way as a call to setEnabled.
|
||||
// If we don't do this it means the two may get out of sync, and a
|
||||
// bogus property change notification would be sent.
|
||||
//
|
||||
// To avoid dependencies between putValue & setEnabled this
|
||||
// directly changes enabled. If we instead called setEnabled
|
||||
// to change enabled, it would be possible for stack
|
||||
// overflow in the case where a developer implemented setEnabled
|
||||
// in terms of putValue.
|
||||
if (newValue == null || !(newValue instanceof Boolean)) {
|
||||
newValue = false;
|
||||
}
|
||||
oldValue = enabled;
|
||||
enabled = (Boolean)newValue;
|
||||
} else {
|
||||
if (arrayTable == null) {
|
||||
arrayTable = new ArrayTable();
|
||||
}
|
||||
if (arrayTable.containsKey(key))
|
||||
oldValue = arrayTable.get(key);
|
||||
// Remove the entry for key if newValue is null
|
||||
// else put in the newValue for key.
|
||||
if (newValue == null) {
|
||||
arrayTable.remove(key);
|
||||
} else {
|
||||
arrayTable.put(key,newValue);
|
||||
}
|
||||
}
|
||||
firePropertyChange(key, oldValue, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the action is enabled.
|
||||
*
|
||||
* @return true if the action is enabled, false otherwise
|
||||
* @see Action#isEnabled
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the {@code Action} is enabled. The default is {@code true}.
|
||||
*
|
||||
* @param newValue {@code true} to enable the action, {@code false} to
|
||||
* disable it
|
||||
* @see Action#setEnabled
|
||||
*/
|
||||
public void setEnabled(boolean newValue) {
|
||||
boolean oldValue = this.enabled;
|
||||
|
||||
if (oldValue != newValue) {
|
||||
this.enabled = newValue;
|
||||
firePropertyChange("enabled",
|
||||
Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Object</code>s which are keys for
|
||||
* which values have been set for this <code>AbstractAction</code>,
|
||||
* or <code>null</code> if no keys have values set.
|
||||
* @return an array of key objects, or <code>null</code> if no
|
||||
* keys have values set
|
||||
* @since 1.3
|
||||
*/
|
||||
public Object[] getKeys() {
|
||||
if (arrayTable == null) {
|
||||
return null;
|
||||
}
|
||||
Object[] keys = new Object[arrayTable.size()];
|
||||
arrayTable.getKeys(keys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* If any <code>PropertyChangeListeners</code> have been registered, the
|
||||
* <code>changeSupport</code> field describes them.
|
||||
*/
|
||||
protected SwingPropertyChangeSupport changeSupport;
|
||||
|
||||
/**
|
||||
* Supports reporting bound property changes. This method can be called
|
||||
* when a bound property has changed and it will send the appropriate
|
||||
* <code>PropertyChangeEvent</code> to any registered
|
||||
* <code>PropertyChangeListeners</code>.
|
||||
*/
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
if (changeSupport == null ||
|
||||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
|
||||
return;
|
||||
}
|
||||
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a <code>PropertyChangeListener</code> to the listener list.
|
||||
* The listener is registered for all properties.
|
||||
* <p>
|
||||
* A <code>PropertyChangeEvent</code> will get fired in response to setting
|
||||
* a bound property, e.g. <code>setFont</code>, <code>setBackground</code>,
|
||||
* or <code>setForeground</code>.
|
||||
* Note that if the current component is inheriting its foreground,
|
||||
* background, or font from its container, then no event will be
|
||||
* fired in response to a change in the inherited property.
|
||||
*
|
||||
* @param listener The <code>PropertyChangeListener</code> to be added
|
||||
*
|
||||
* @see Action#addPropertyChangeListener
|
||||
*/
|
||||
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new SwingPropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a <code>PropertyChangeListener</code> from the listener list.
|
||||
* This removes a <code>PropertyChangeListener</code> that was registered
|
||||
* for all properties.
|
||||
*
|
||||
* @param listener the <code>PropertyChangeListener</code> to be removed
|
||||
*
|
||||
* @see Action#removePropertyChangeListener
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
if (changeSupport == null) {
|
||||
return;
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>PropertyChangeListener</code>s added
|
||||
* to this AbstractAction with addPropertyChangeListener().
|
||||
*
|
||||
* @return all of the <code>PropertyChangeListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clones the abstract action. This gives the clone
|
||||
* its own copy of the key/value list,
|
||||
* which is not handled for you by <code>Object.clone()</code>.
|
||||
**/
|
||||
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
AbstractAction newAction = (AbstractAction)super.clone();
|
||||
synchronized(this) {
|
||||
if (arrayTable != null) {
|
||||
newAction.arrayTable = (ArrayTable)arrayTable.clone();
|
||||
}
|
||||
}
|
||||
return newAction;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
// Store the default fields
|
||||
s.defaultWriteObject();
|
||||
|
||||
// And the keys
|
||||
ArrayTable.writeArrayTable(s, arrayTable);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s) throws ClassNotFoundException,
|
||||
IOException {
|
||||
s.defaultReadObject();
|
||||
for (int counter = s.readInt() - 1; counter >= 0; counter--) {
|
||||
putValue((String)s.readObject(), s.readObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
3108
jdkSrc/jdk8/javax/swing/AbstractButton.java
Normal file
3108
jdkSrc/jdk8/javax/swing/AbstractButton.java
Normal file
File diff suppressed because it is too large
Load Diff
167
jdkSrc/jdk8/javax/swing/AbstractCellEditor.java
Normal file
167
jdkSrc/jdk8/javax/swing/AbstractCellEditor.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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 javax.swing;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import java.util.EventObject;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* A base class for <code>CellEditors</code>, providing default
|
||||
* implementations for the methods in the <code>CellEditor</code>
|
||||
* interface except <code>getCellEditorValue()</code>.
|
||||
* Like the other abstract implementations in Swing, also manages a list
|
||||
* of listeners.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Philip Milne
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
public abstract class AbstractCellEditor implements CellEditor, Serializable {
|
||||
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
transient protected ChangeEvent changeEvent = null;
|
||||
|
||||
// Force this to be implemented.
|
||||
// public Object getCellEditorValue()
|
||||
|
||||
/**
|
||||
* Returns true.
|
||||
* @param e an event object
|
||||
* @return true
|
||||
*/
|
||||
public boolean isCellEditable(EventObject e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true.
|
||||
* @param anEvent an event object
|
||||
* @return true
|
||||
*/
|
||||
public boolean shouldSelectCell(EventObject anEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>fireEditingStopped</code> and returns true.
|
||||
* @return true
|
||||
*/
|
||||
public boolean stopCellEditing() {
|
||||
fireEditingStopped();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>fireEditingCanceled</code>.
|
||||
*/
|
||||
public void cancelCellEditing() {
|
||||
fireEditingCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>CellEditorListener</code> to the listener list.
|
||||
* @param l the new listener to be added
|
||||
*/
|
||||
public void addCellEditorListener(CellEditorListener l) {
|
||||
listenerList.add(CellEditorListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a <code>CellEditorListener</code> from the listener list.
|
||||
* @param l the listener to be removed
|
||||
*/
|
||||
public void removeCellEditorListener(CellEditorListener l) {
|
||||
listenerList.remove(CellEditorListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>CellEditorListener</code>s added
|
||||
* to this AbstractCellEditor with addCellEditorListener().
|
||||
*
|
||||
* @return all of the <code>CellEditorListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public CellEditorListener[] getCellEditorListeners() {
|
||||
return listenerList.getListeners(CellEditorListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is created lazily.
|
||||
*
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireEditingStopped() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==CellEditorListener.class) {
|
||||
// Lazily create the event:
|
||||
if (changeEvent == null)
|
||||
changeEvent = new ChangeEvent(this);
|
||||
((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is created lazily.
|
||||
*
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireEditingCanceled() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==CellEditorListener.class) {
|
||||
// Lazily create the event:
|
||||
if (changeEvent == null)
|
||||
changeEvent = new ChangeEvent(this);
|
||||
((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
222
jdkSrc/jdk8/javax/swing/AbstractListModel.java
Normal file
222
jdkSrc/jdk8/javax/swing/AbstractListModel.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* The abstract definition for the data model that provides
|
||||
* a <code>List</code> with its contents.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Hans Muller
|
||||
*/
|
||||
public abstract class AbstractListModel<E> implements ListModel<E>, Serializable
|
||||
{
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
|
||||
/**
|
||||
* Adds a listener to the list that's notified each time a change
|
||||
* to the data model occurs.
|
||||
*
|
||||
* @param l the <code>ListDataListener</code> to be added
|
||||
*/
|
||||
public void addListDataListener(ListDataListener l) {
|
||||
listenerList.add(ListDataListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a listener from the list that's notified each time a
|
||||
* change to the data model occurs.
|
||||
*
|
||||
* @param l the <code>ListDataListener</code> to be removed
|
||||
*/
|
||||
public void removeListDataListener(ListDataListener l) {
|
||||
listenerList.remove(ListDataListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the list data listeners
|
||||
* registered on this <code>AbstractListModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ListDataListener</code>s,
|
||||
* or an empty array if no list data listeners
|
||||
* are currently registered
|
||||
*
|
||||
* @see #addListDataListener
|
||||
* @see #removeListDataListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ListDataListener[] getListDataListeners() {
|
||||
return listenerList.getListeners(ListDataListener.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b>
|
||||
* one or more elements of the list change. The changed elements
|
||||
* are specified by the closed interval index0, index1 -- the endpoints
|
||||
* are included. Note that
|
||||
* index0 need not be less than or equal to index1.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the new interval
|
||||
* @param index1 the other end of the new interval
|
||||
* @see EventListenerList
|
||||
* @see DefaultListModel
|
||||
*/
|
||||
protected void fireContentsChanged(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).contentsChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b>
|
||||
* one or more elements are added to the model. The new elements
|
||||
* are specified by a closed interval index0, index1 -- the enpoints
|
||||
* are included. Note that
|
||||
* index0 need not be less than or equal to index1.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the new interval
|
||||
* @param index1 the other end of the new interval
|
||||
* @see EventListenerList
|
||||
* @see DefaultListModel
|
||||
*/
|
||||
protected void fireIntervalAdded(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).intervalAdded(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>AbstractListModel</code> subclasses must call this method
|
||||
* <b>after</b> one or more elements are removed from the model.
|
||||
* <code>index0</code> and <code>index1</code> are the end points
|
||||
* of the interval that's been removed. Note that <code>index0</code>
|
||||
* need not be less than or equal to <code>index1</code>.
|
||||
*
|
||||
* @param source the <code>ListModel</code> that changed, typically "this"
|
||||
* @param index0 one end of the removed interval,
|
||||
* including <code>index0</code>
|
||||
* @param index1 the other end of the removed interval,
|
||||
* including <code>index1</code>
|
||||
* @see EventListenerList
|
||||
* @see DefaultListModel
|
||||
*/
|
||||
protected void fireIntervalRemoved(Object source, int index0, int index1)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListDataEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListDataListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
|
||||
}
|
||||
((ListDataListener)listeners[i+1]).intervalRemoved(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a list model
|
||||
* <code>m</code>
|
||||
* for its list data listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ListDataListener[] ldls = (ListDataListener[])(m.getListeners(ListDataListener.class));</pre>
|
||||
*
|
||||
* 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</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getListDataListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/javax/swing/AbstractSpinnerModel.java
Normal file
140
jdkSrc/jdk8/javax/swing/AbstractSpinnerModel.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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 javax.swing;
|
||||
|
||||
import java.util.*;
|
||||
import javax.swing.event.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* This class provides the ChangeListener part of the
|
||||
* SpinnerModel interface that should be suitable for most concrete SpinnerModel
|
||||
* implementations. Subclasses must provide an implementation of the
|
||||
* <code>setValue</code>, <code>getValue</code>, <code>getNextValue</code> and
|
||||
* <code>getPreviousValue</code> methods.
|
||||
*
|
||||
* @see JSpinner
|
||||
* @see SpinnerModel
|
||||
* @see SpinnerListModel
|
||||
* @see SpinnerNumberModel
|
||||
* @see SpinnerDateModel
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class AbstractSpinnerModel implements SpinnerModel, Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* Only one ChangeEvent is needed per model instance since the
|
||||
* event's only (read-only) state is the source property. The source
|
||||
* of events generated here is always "this".
|
||||
*/
|
||||
private transient ChangeEvent changeEvent = null;
|
||||
|
||||
|
||||
/**
|
||||
* The list of ChangeListeners for this model. Subclasses may
|
||||
* store their own listeners here.
|
||||
*/
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
|
||||
/**
|
||||
* Adds a ChangeListener to the model's listener list. The
|
||||
* ChangeListeners must be notified when the models value changes.
|
||||
*
|
||||
* @param l the ChangeListener to add
|
||||
* @see #removeChangeListener
|
||||
* @see SpinnerModel#addChangeListener
|
||||
*/
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
listenerList.add(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a ChangeListener from the model's listener list.
|
||||
*
|
||||
* @param l the ChangeListener to remove
|
||||
* @see #addChangeListener
|
||||
* @see SpinnerModel#removeChangeListener
|
||||
*/
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
listenerList.remove(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>ChangeListener</code>s added
|
||||
* to this AbstractSpinnerModel with addChangeListener().
|
||||
*
|
||||
* @return all of the <code>ChangeListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public ChangeListener[] getChangeListeners() {
|
||||
return listenerList.getListeners(ChangeListener.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run each ChangeListeners stateChanged() method.
|
||||
*
|
||||
* @see #setValue
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireStateChanged()
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
for (int i = listeners.length - 2; i >= 0; i -=2 ) {
|
||||
if (listeners[i] == ChangeListener.class) {
|
||||
if (changeEvent == null) {
|
||||
changeEvent = new ChangeEvent(this);
|
||||
}
|
||||
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an array of all the listeners of the given type that
|
||||
* were added to this model. For example to find all of the
|
||||
* ChangeListeners added to this model:
|
||||
* <pre>
|
||||
* myAbstractSpinnerModel.getListeners(ChangeListener.class);
|
||||
* </pre>
|
||||
*
|
||||
* @param listenerType the type of listeners to return, e.g. ChangeListener.class
|
||||
* @return all of the objects receiving <em>listenerType</em> notifications
|
||||
* from this model
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
}
|
||||
390
jdkSrc/jdk8/javax/swing/Action.java
Normal file
390
jdkSrc/jdk8/javax/swing/Action.java
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
|
||||
/**
|
||||
* The <code>Action</code> interface provides a useful extension to the
|
||||
* <code>ActionListener</code>
|
||||
* interface in cases where the same functionality may be accessed by
|
||||
* several controls.
|
||||
* <p>
|
||||
* In addition to the <code>actionPerformed</code> method defined by the
|
||||
* <code>ActionListener</code> interface, this interface allows the
|
||||
* application to define, in a single place:
|
||||
* <ul>
|
||||
* <li>One or more text strings that describe the function. These strings
|
||||
* can be used, for example, to display the flyover text for a button
|
||||
* or to set the text in a menu item.
|
||||
* <li>One or more icons that depict the function. These icons can be used
|
||||
* for the images in a menu control, or for composite entries in a more
|
||||
* sophisticated user interface.
|
||||
* <li>The enabled/disabled state of the functionality. Instead of having
|
||||
* to separately disable the menu item and the toolbar button, the
|
||||
* application can disable the function that implements this interface.
|
||||
* All components which are registered as listeners for the state change
|
||||
* then know to disable event generation for that item and to modify the
|
||||
* display accordingly.
|
||||
* </ul>
|
||||
* <p>
|
||||
* This interface can be added to an existing class or used to create an
|
||||
* adapter (typically, by subclassing <code>AbstractAction</code>).
|
||||
* The <code>Action</code> object
|
||||
* can then be added to multiple <code>Action</code>-aware containers
|
||||
* and connected to <code>Action</code>-capable
|
||||
* components. The GUI controls can then be activated or
|
||||
* deactivated all at once by invoking the <code>Action</code> object's
|
||||
* <code>setEnabled</code> method.
|
||||
* <p>
|
||||
* Note that <code>Action</code> implementations tend to be more expensive
|
||||
* in terms of storage than a typical <code>ActionListener</code>,
|
||||
* which does not offer the benefits of centralized control of
|
||||
* functionality and broadcast of property changes. For this reason,
|
||||
* you should take care to only use <code>Action</code>s where their benefits
|
||||
* are desired, and use simple <code>ActionListener</code>s elsewhere.
|
||||
* <br>
|
||||
*
|
||||
* <h3><a name="buttonActions"></a>Swing Components Supporting <code>Action</code></h3>
|
||||
* <p>
|
||||
* Many of Swing's components have an <code>Action</code> property. When
|
||||
* an <code>Action</code> is set on a component, the following things
|
||||
* happen:
|
||||
* <ul>
|
||||
* <li>The <code>Action</code> is added as an <code>ActionListener</code> to
|
||||
* the component.
|
||||
* <li>The component configures some of its properties to match the
|
||||
* <code>Action</code>.
|
||||
* <li>The component installs a <code>PropertyChangeListener</code> on the
|
||||
* <code>Action</code> so that the component can change its properties
|
||||
* to reflect changes in the <code>Action</code>'s properties.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The following table describes the properties used by
|
||||
* <code>Swing</code> components that support <code>Actions</code>.
|
||||
* In the table, <em>button</em> refers to any
|
||||
* <code>AbstractButton</code> subclass, which includes not only
|
||||
* <code>JButton</code> but also classes such as
|
||||
* <code>JMenuItem</code>. Unless otherwise stated, a
|
||||
* <code>null</code> property value in an <code>Action</code> (or a
|
||||
* <code>Action</code> that is <code>null</code>) results in the
|
||||
* button's corresponding property being set to <code>null</code>.
|
||||
*
|
||||
* <table border="1" cellpadding="1" cellspacing="0"
|
||||
* summary="Supported Action properties">
|
||||
* <tr valign="top" align="left">
|
||||
* <th style="background-color:#CCCCFF" align="left">Component Property
|
||||
* <th style="background-color:#CCCCFF" align="left">Components
|
||||
* <th style="background-color:#CCCCFF" align="left">Action Key
|
||||
* <th style="background-color:#CCCCFF" align="left">Notes
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>enabled</code></b>
|
||||
* <td>All
|
||||
* <td>The <code>isEnabled</code> method
|
||||
* <td>
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>toolTipText</code></b>
|
||||
* <td>All
|
||||
* <td><code>SHORT_DESCRIPTION</code>
|
||||
* <td>
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>actionCommand</code></b>
|
||||
* <td>All
|
||||
* <td><code>ACTION_COMMAND_KEY</code>
|
||||
* <td>
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>mnemonic</code></b>
|
||||
* <td>All buttons
|
||||
* <td><code>MNEMONIC_KEY</code>
|
||||
* <td>A <code>null</code> value or <code>Action</code> results in the
|
||||
* button's <code>mnemonic</code> property being set to
|
||||
* <code>'\0'</code>.
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>text</code></b>
|
||||
* <td>All buttons
|
||||
* <td><code>NAME</code>
|
||||
* <td>If you do not want the text of the button to mirror that
|
||||
* of the <code>Action</code>, set the property
|
||||
* <code>hideActionText</code> to <code>true</code>. If
|
||||
* <code>hideActionText</code> is <code>true</code>, setting the
|
||||
* <code>Action</code> changes the text of the button to
|
||||
* <code>null</code> and any changes to <code>NAME</code>
|
||||
* are ignored. <code>hideActionText</code> is useful for
|
||||
* tool bar buttons that typically only show an <code>Icon</code>.
|
||||
* <code>JToolBar.add(Action)</code> sets the property to
|
||||
* <code>true</code> if the <code>Action</code> has a
|
||||
* non-<code>null</code> value for <code>LARGE_ICON_KEY</code> or
|
||||
* <code>SMALL_ICON</code>.
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>displayedMnemonicIndex</code></b>
|
||||
* <td>All buttons
|
||||
* <td><code>DISPLAYED_MNEMONIC_INDEX_KEY</code>
|
||||
* <td>If the value of <code>DISPLAYED_MNEMONIC_INDEX_KEY</code> is
|
||||
* beyond the bounds of the text, it is ignored. When
|
||||
* <code>setAction</code> is called, if the value from the
|
||||
* <code>Action</code> is <code>null</code>, the displayed
|
||||
* mnemonic index is not updated. In any subsequent changes to
|
||||
* <code>DISPLAYED_MNEMONIC_INDEX_KEY</code>, <code>null</code>
|
||||
* is treated as -1.
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>icon</code></b>
|
||||
* <td>All buttons except of <code>JCheckBox</code>,
|
||||
* <code>JToggleButton</code> and <code>JRadioButton</code>.
|
||||
* <td>either <code>LARGE_ICON_KEY</code> or
|
||||
* <code>SMALL_ICON</code>
|
||||
* <td>The <code>JMenuItem</code> subclasses only use
|
||||
* <code>SMALL_ICON</code>. All other buttons will use
|
||||
* <code>LARGE_ICON_KEY</code>; if the value is <code>null</code> they
|
||||
* use <code>SMALL_ICON</code>.
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>accelerator</code></b>
|
||||
* <td>All <code>JMenuItem</code> subclasses, with the exception of
|
||||
* <code>JMenu</code>.
|
||||
* <td><code>ACCELERATOR_KEY</code>
|
||||
* <td>
|
||||
* <tr valign="top" align="left">
|
||||
* <td><b><code>selected</code></b>
|
||||
* <td><code>JToggleButton</code>, <code>JCheckBox</code>,
|
||||
* <code>JRadioButton</code>, <code>JCheckBoxMenuItem</code> and
|
||||
* <code>JRadioButtonMenuItem</code>
|
||||
* <td><code>SELECTED_KEY</code>
|
||||
* <td>Components that honor this property only use
|
||||
* the value if it is {@code non-null}. For example, if
|
||||
* you set an {@code Action} that has a {@code null}
|
||||
* value for {@code SELECTED_KEY} on a {@code JToggleButton}, the
|
||||
* {@code JToggleButton} will not update it's selected state in
|
||||
* any way. Similarly, any time the {@code JToggleButton}'s
|
||||
* selected state changes it will only set the value back on
|
||||
* the {@code Action} if the {@code Action} has a {@code non-null}
|
||||
* value for {@code SELECTED_KEY}.
|
||||
* <br>
|
||||
* Components that honor this property keep their selected state
|
||||
* in sync with this property. When the same {@code Action} is used
|
||||
* with multiple components, all the components keep their selected
|
||||
* state in sync with this property. Mutually exclusive
|
||||
* buttons, such as {@code JToggleButton}s in a {@code ButtonGroup},
|
||||
* force only one of the buttons to be selected. As such, do not
|
||||
* use the same {@code Action} that defines a value for the
|
||||
* {@code SELECTED_KEY} property with multiple mutually
|
||||
* exclusive buttons.
|
||||
* </table>
|
||||
* <p>
|
||||
* <code>JPopupMenu</code>, <code>JToolBar</code> and <code>JMenu</code>
|
||||
* all provide convenience methods for creating a component and setting the
|
||||
* <code>Action</code> on the corresponding component. Refer to each of
|
||||
* these classes for more information.
|
||||
* <p>
|
||||
* <code>Action</code> uses <code>PropertyChangeListener</code> to
|
||||
* inform listeners the <code>Action</code> has changed. The beans
|
||||
* specification indicates that a <code>null</code> property name can
|
||||
* be used to indicate multiple values have changed. By default Swing
|
||||
* components that take an <code>Action</code> do not handle such a
|
||||
* change. To indicate that Swing should treat <code>null</code>
|
||||
* according to the beans specification set the system property
|
||||
* <code>swing.actions.reconfigureOnNull</code> to the <code>String</code>
|
||||
* value <code>true</code>.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @see AbstractAction
|
||||
*/
|
||||
public interface Action extends ActionListener {
|
||||
/**
|
||||
* Useful constants that can be used as the storage-retrieval key
|
||||
* when setting or getting one of this object's properties (text
|
||||
* or icon).
|
||||
*/
|
||||
/**
|
||||
* Not currently used.
|
||||
*/
|
||||
public static final String DEFAULT = "Default";
|
||||
/**
|
||||
* The key used for storing the <code>String</code> name
|
||||
* for the action, used for a menu or button.
|
||||
*/
|
||||
public static final String NAME = "Name";
|
||||
/**
|
||||
* The key used for storing a short <code>String</code>
|
||||
* description for the action, used for tooltip text.
|
||||
*/
|
||||
public static final String SHORT_DESCRIPTION = "ShortDescription";
|
||||
/**
|
||||
* The key used for storing a longer <code>String</code>
|
||||
* description for the action, could be used for context-sensitive help.
|
||||
*/
|
||||
public static final String LONG_DESCRIPTION = "LongDescription";
|
||||
/**
|
||||
* The key used for storing a small <code>Icon</code>, such
|
||||
* as <code>ImageIcon</code>. This is typically used with
|
||||
* menus such as <code>JMenuItem</code>.
|
||||
* <p>
|
||||
* If the same <code>Action</code> is used with menus and buttons you'll
|
||||
* typically specify both a <code>SMALL_ICON</code> and a
|
||||
* <code>LARGE_ICON_KEY</code>. The menu will use the
|
||||
* <code>SMALL_ICON</code> and the button will use the
|
||||
* <code>LARGE_ICON_KEY</code>.
|
||||
*/
|
||||
public static final String SMALL_ICON = "SmallIcon";
|
||||
|
||||
/**
|
||||
* The key used to determine the command <code>String</code> for the
|
||||
* <code>ActionEvent</code> that will be created when an
|
||||
* <code>Action</code> is going to be notified as the result of
|
||||
* residing in a <code>Keymap</code> associated with a
|
||||
* <code>JComponent</code>.
|
||||
*/
|
||||
public static final String ACTION_COMMAND_KEY = "ActionCommandKey";
|
||||
|
||||
/**
|
||||
* The key used for storing a <code>KeyStroke</code> to be used as the
|
||||
* accelerator for the action.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public static final String ACCELERATOR_KEY="AcceleratorKey";
|
||||
|
||||
/**
|
||||
* The key used for storing an <code>Integer</code> that corresponds to
|
||||
* one of the <code>KeyEvent</code> key codes. The value is
|
||||
* commonly used to specify a mnemonic. For example:
|
||||
* <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A)</code>
|
||||
* sets the mnemonic of <code>myAction</code> to 'a', while
|
||||
* <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar('\u0444'))</code>
|
||||
* sets the mnemonic of <code>myAction</code> to Cyrillic letter "Ef".
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public static final String MNEMONIC_KEY="MnemonicKey";
|
||||
|
||||
/**
|
||||
* The key used for storing a <code>Boolean</code> that corresponds
|
||||
* to the selected state. This is typically used only for components
|
||||
* that have a meaningful selection state. For example,
|
||||
* <code>JRadioButton</code> and <code>JCheckBox</code> make use of
|
||||
* this but instances of <code>JMenu</code> don't.
|
||||
* <p>
|
||||
* This property differs from the others in that it is both read
|
||||
* by the component and set by the component. For example,
|
||||
* if an <code>Action</code> is attached to a <code>JCheckBox</code>
|
||||
* the selected state of the <code>JCheckBox</code> will be set from
|
||||
* that of the <code>Action</code>. If the user clicks on the
|
||||
* <code>JCheckBox</code> the selected state of the <code>JCheckBox</code>
|
||||
* <b>and</b> the <code>Action</code> will <b>both</b> be updated.
|
||||
* <p>
|
||||
* Note: the value of this field is prefixed with 'Swing' to
|
||||
* avoid possible collisions with existing <code>Actions</code>.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final String SELECTED_KEY = "SwingSelectedKey";
|
||||
|
||||
/**
|
||||
* The key used for storing an <code>Integer</code> that corresponds
|
||||
* to the index in the text (identified by the <code>NAME</code>
|
||||
* property) that the decoration for a mnemonic should be rendered at. If
|
||||
* the value of this property is greater than or equal to the length of
|
||||
* the text, it will treated as -1.
|
||||
* <p>
|
||||
* Note: the value of this field is prefixed with 'Swing' to
|
||||
* avoid possible collisions with existing <code>Actions</code>.
|
||||
*
|
||||
* @see AbstractButton#setDisplayedMnemonicIndex
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final String DISPLAYED_MNEMONIC_INDEX_KEY =
|
||||
"SwingDisplayedMnemonicIndexKey";
|
||||
|
||||
/**
|
||||
* The key used for storing an <code>Icon</code>. This is typically
|
||||
* used by buttons, such as <code>JButton</code> and
|
||||
* <code>JToggleButton</code>.
|
||||
* <p>
|
||||
* If the same <code>Action</code> is used with menus and buttons you'll
|
||||
* typically specify both a <code>SMALL_ICON</code> and a
|
||||
* <code>LARGE_ICON_KEY</code>. The menu will use the
|
||||
* <code>SMALL_ICON</code> and the button the <code>LARGE_ICON_KEY</code>.
|
||||
* <p>
|
||||
* Note: the value of this field is prefixed with 'Swing' to
|
||||
* avoid possible collisions with existing <code>Actions</code>.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final String LARGE_ICON_KEY = "SwingLargeIconKey";
|
||||
|
||||
/**
|
||||
* Gets one of this object's properties
|
||||
* using the associated key.
|
||||
* @see #putValue
|
||||
*/
|
||||
public Object getValue(String key);
|
||||
/**
|
||||
* Sets one of this object's properties
|
||||
* using the associated key. If the value has
|
||||
* changed, a <code>PropertyChangeEvent</code> is sent
|
||||
* to listeners.
|
||||
*
|
||||
* @param key a <code>String</code> containing the key
|
||||
* @param value an <code>Object</code> value
|
||||
*/
|
||||
public void putValue(String key, Object value);
|
||||
|
||||
/**
|
||||
* Sets the enabled state of the <code>Action</code>. When enabled,
|
||||
* any component associated with this object is active and
|
||||
* able to fire this object's <code>actionPerformed</code> method.
|
||||
* If the value has changed, a <code>PropertyChangeEvent</code> is sent
|
||||
* to listeners.
|
||||
*
|
||||
* @param b true to enable this <code>Action</code>, false to disable it
|
||||
*/
|
||||
public void setEnabled(boolean b);
|
||||
/**
|
||||
* Returns the enabled state of the <code>Action</code>. When enabled,
|
||||
* any component associated with this object is active and
|
||||
* able to fire this object's <code>actionPerformed</code> method.
|
||||
*
|
||||
* @return true if this <code>Action</code> is enabled
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Adds a <code>PropertyChange</code> listener. Containers and attached
|
||||
* components use these methods to register interest in this
|
||||
* <code>Action</code> object. When its enabled state or other property
|
||||
* changes, the registered listeners are informed of the change.
|
||||
*
|
||||
* @param listener a <code>PropertyChangeListener</code> object
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener);
|
||||
/**
|
||||
* Removes a <code>PropertyChange</code> listener.
|
||||
*
|
||||
* @param listener a <code>PropertyChangeListener</code> object
|
||||
* @see #addPropertyChangeListener
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
}
|
||||
226
jdkSrc/jdk8/javax/swing/ActionMap.java
Normal file
226
jdkSrc/jdk8/javax/swing/ActionMap.java
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 javax.swing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <code>ActionMap</code> provides mappings from
|
||||
* <code>Object</code>s
|
||||
* (called <em>keys</em> or <em><code>Action</code> names</em>)
|
||||
* to <code>Action</code>s.
|
||||
* An <code>ActionMap</code> is usually used with an <code>InputMap</code>
|
||||
* to locate a particular action
|
||||
* when a key is pressed. As with <code>InputMap</code>,
|
||||
* an <code>ActionMap</code> can have a parent
|
||||
* that is searched for keys not defined in the <code>ActionMap</code>.
|
||||
* <p>As with <code>InputMap</code> if you create a cycle, eg:
|
||||
* <pre>
|
||||
* ActionMap am = new ActionMap();
|
||||
* ActionMap bm = new ActionMap():
|
||||
* am.setParent(bm);
|
||||
* bm.setParent(am);
|
||||
* </pre>
|
||||
* some of the methods will cause a StackOverflowError to be thrown.
|
||||
*
|
||||
* @see InputMap
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.3
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ActionMap implements Serializable {
|
||||
/** Handles the mapping between Action name and Action. */
|
||||
private transient ArrayTable arrayTable;
|
||||
/** Parent that handles any bindings we don't contain. */
|
||||
private ActionMap parent;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an <code>ActionMap</code> with no parent and no mappings.
|
||||
*/
|
||||
public ActionMap() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this <code>ActionMap</code>'s parent.
|
||||
*
|
||||
* @param map the <code>ActionMap</code> that is the parent of this one
|
||||
*/
|
||||
public void setParent(ActionMap map) {
|
||||
this.parent = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this <code>ActionMap</code>'s parent.
|
||||
*
|
||||
* @return the <code>ActionMap</code> that is the parent of this one,
|
||||
* or null if this <code>ActionMap</code> has no parent
|
||||
*/
|
||||
public ActionMap getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a binding for <code>key</code> to <code>action</code>.
|
||||
* If <code>action</code> is null, this removes the current binding
|
||||
* for <code>key</code>.
|
||||
* <p>In most instances, <code>key</code> will be
|
||||
* <code>action.getValue(NAME)</code>.
|
||||
*/
|
||||
public void put(Object key, Action action) {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
if (action == null) {
|
||||
remove(key);
|
||||
}
|
||||
else {
|
||||
if (arrayTable == null) {
|
||||
arrayTable = new ArrayTable();
|
||||
}
|
||||
arrayTable.put(key, action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binding for <code>key</code>, messaging the
|
||||
* parent <code>ActionMap</code> if the binding is not locally defined.
|
||||
*/
|
||||
public Action get(Object key) {
|
||||
Action value = (arrayTable == null) ? null :
|
||||
(Action)arrayTable.get(key);
|
||||
|
||||
if (value == null) {
|
||||
ActionMap parent = getParent();
|
||||
|
||||
if (parent != null) {
|
||||
return parent.get(key);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the binding for <code>key</code> from this <code>ActionMap</code>.
|
||||
*/
|
||||
public void remove(Object key) {
|
||||
if (arrayTable != null) {
|
||||
arrayTable.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the mappings from this <code>ActionMap</code>.
|
||||
*/
|
||||
public void clear() {
|
||||
if (arrayTable != null) {
|
||||
arrayTable.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Action</code> names that are bound in this <code>ActionMap</code>.
|
||||
*/
|
||||
public Object[] keys() {
|
||||
if (arrayTable == null) {
|
||||
return null;
|
||||
}
|
||||
return arrayTable.getKeys(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bindings in this {@code ActionMap}.
|
||||
*
|
||||
* @return the number of bindings in this {@code ActionMap}
|
||||
*/
|
||||
public int size() {
|
||||
if (arrayTable == null) {
|
||||
return 0;
|
||||
}
|
||||
return arrayTable.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the keys defined in this <code>ActionMap</code> and
|
||||
* its parent. This method differs from <code>keys()</code> in that
|
||||
* this method includes the keys defined in the parent.
|
||||
*/
|
||||
public Object[] allKeys() {
|
||||
int count = size();
|
||||
ActionMap parent = getParent();
|
||||
|
||||
if (count == 0) {
|
||||
if (parent != null) {
|
||||
return parent.allKeys();
|
||||
}
|
||||
return keys();
|
||||
}
|
||||
if (parent == null) {
|
||||
return keys();
|
||||
}
|
||||
Object[] keys = keys();
|
||||
Object[] pKeys = parent.allKeys();
|
||||
|
||||
if (pKeys == null) {
|
||||
return keys;
|
||||
}
|
||||
if (keys == null) {
|
||||
// Should only happen if size() != keys.length, which should only
|
||||
// happen if mutated from multiple threads (or a bogus subclass).
|
||||
return pKeys;
|
||||
}
|
||||
|
||||
HashMap<Object, Object> keyMap = new HashMap<Object, Object>();
|
||||
int counter;
|
||||
|
||||
for (counter = keys.length - 1; counter >= 0; counter--) {
|
||||
keyMap.put(keys[counter], keys[counter]);
|
||||
}
|
||||
for (counter = pKeys.length - 1; counter >= 0; counter--) {
|
||||
keyMap.put(pKeys[counter], pKeys[counter]);
|
||||
}
|
||||
return keyMap.keySet().toArray();
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
|
||||
ArrayTable.writeArrayTable(s, arrayTable);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s) throws ClassNotFoundException,
|
||||
IOException {
|
||||
s.defaultReadObject();
|
||||
for (int counter = s.readInt() - 1; counter >= 0; counter--) {
|
||||
put(s.readObject(), (Action)s.readObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
157
jdkSrc/jdk8/javax/swing/ActionPropertyChangeListener.java
Normal file
157
jdkSrc/jdk8/javax/swing/ActionPropertyChangeListener.java
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 javax.swing;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
/**
|
||||
* A package-private PropertyChangeListener which listens for
|
||||
* property changes on an Action and updates the properties
|
||||
* of an ActionEvent source.
|
||||
* <p>
|
||||
* Subclasses must override the actionPropertyChanged method,
|
||||
* which is invoked from the propertyChange method as long as
|
||||
* the target is still valid.
|
||||
* </p>
|
||||
* <p>
|
||||
* WARNING WARNING WARNING WARNING WARNING WARNING:<br>
|
||||
* Do NOT create an annonymous inner class that extends this! If you do
|
||||
* a strong reference will be held to the containing class, which in most
|
||||
* cases defeats the purpose of this class.
|
||||
*
|
||||
* @param T the type of JComponent the underlying Action is attached to
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @see AbstractButton
|
||||
*/
|
||||
abstract class ActionPropertyChangeListener<T extends JComponent>
|
||||
implements PropertyChangeListener, Serializable {
|
||||
private static ReferenceQueue<JComponent> queue;
|
||||
|
||||
// WeakReference's aren't serializable.
|
||||
private transient OwnedWeakReference<T> target;
|
||||
// The Component's that reference an Action do so through a strong
|
||||
// reference, so that there is no need to check for serialized.
|
||||
private Action action;
|
||||
|
||||
private static ReferenceQueue<JComponent> getQueue() {
|
||||
synchronized(ActionPropertyChangeListener.class) {
|
||||
if (queue == null) {
|
||||
queue = new ReferenceQueue<JComponent>();
|
||||
}
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
public ActionPropertyChangeListener(T c, Action a) {
|
||||
super();
|
||||
setTarget(c);
|
||||
this.action = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* PropertyChangeListener method. If the target has been gc'ed this
|
||||
* will remove the <code>PropertyChangeListener</code> from the Action,
|
||||
* otherwise this will invoke actionPropertyChanged.
|
||||
*/
|
||||
public final void propertyChange(PropertyChangeEvent e) {
|
||||
T target = getTarget();
|
||||
if (target == null) {
|
||||
getAction().removePropertyChangeListener(this);
|
||||
} else {
|
||||
actionPropertyChanged(target, getAction(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a property changes on the Action and the target
|
||||
* still exists.
|
||||
*/
|
||||
protected abstract void actionPropertyChanged(T target, Action action,
|
||||
PropertyChangeEvent e);
|
||||
|
||||
private void setTarget(T c) {
|
||||
ReferenceQueue<JComponent> queue = getQueue();
|
||||
// Check to see whether any old buttons have
|
||||
// been enqueued for GC. If so, look up their
|
||||
// PCL instance and remove it from its Action.
|
||||
OwnedWeakReference<?> r;
|
||||
while ((r = (OwnedWeakReference)queue.poll()) != null) {
|
||||
ActionPropertyChangeListener<?> oldPCL = r.getOwner();
|
||||
Action oldAction = oldPCL.getAction();
|
||||
if (oldAction!=null) {
|
||||
oldAction.removePropertyChangeListener(oldPCL);
|
||||
}
|
||||
}
|
||||
this.target = new OwnedWeakReference<T>(c, queue, this);
|
||||
}
|
||||
|
||||
public T getTarget() {
|
||||
if (target == null) {
|
||||
// Will only happen if serialized and real target was null
|
||||
return null;
|
||||
}
|
||||
return this.target.get();
|
||||
}
|
||||
|
||||
public Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
s.writeObject(getTarget());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
T target = (T)s.readObject();
|
||||
if (target != null) {
|
||||
setTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class OwnedWeakReference<U extends JComponent> extends
|
||||
WeakReference<U> {
|
||||
private ActionPropertyChangeListener<?> owner;
|
||||
|
||||
OwnedWeakReference(U target, ReferenceQueue<? super U> queue,
|
||||
ActionPropertyChangeListener<?> owner) {
|
||||
super(target, queue);
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public ActionPropertyChangeListener<?> getOwner() {
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
240
jdkSrc/jdk8/javax/swing/AncestorNotifier.java
Normal file
240
jdkSrc/jdk8/javax/swing/AncestorNotifier.java
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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 javax.swing;
|
||||
|
||||
|
||||
import javax.swing.event.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Window;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Moore
|
||||
*/
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class AncestorNotifier implements ComponentListener, PropertyChangeListener, Serializable
|
||||
{
|
||||
transient Component firstInvisibleAncestor;
|
||||
EventListenerList listenerList = new EventListenerList();
|
||||
JComponent root;
|
||||
|
||||
AncestorNotifier(JComponent root) {
|
||||
this.root = root;
|
||||
addListeners(root, true);
|
||||
}
|
||||
|
||||
void addAncestorListener(AncestorListener l) {
|
||||
listenerList.add(AncestorListener.class, l);
|
||||
}
|
||||
|
||||
void removeAncestorListener(AncestorListener l) {
|
||||
listenerList.remove(AncestorListener.class, l);
|
||||
}
|
||||
|
||||
AncestorListener[] getAncestorListeners() {
|
||||
return listenerList.getListeners(AncestorListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is lazily created using the parameters passed into
|
||||
* the fire method.
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireAncestorAdded(JComponent source, int id, Container ancestor, Container ancestorParent) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==AncestorListener.class) {
|
||||
// Lazily create the event:
|
||||
AncestorEvent ancestorEvent =
|
||||
new AncestorEvent(source, id, ancestor, ancestorParent);
|
||||
((AncestorListener)listeners[i+1]).ancestorAdded(ancestorEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is lazily created using the parameters passed into
|
||||
* the fire method.
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireAncestorRemoved(JComponent source, int id, Container ancestor, Container ancestorParent) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==AncestorListener.class) {
|
||||
// Lazily create the event:
|
||||
AncestorEvent ancestorEvent =
|
||||
new AncestorEvent(source, id, ancestor, ancestorParent);
|
||||
((AncestorListener)listeners[i+1]).ancestorRemoved(ancestorEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Notify all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is lazily created using the parameters passed into
|
||||
* the fire method.
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireAncestorMoved(JComponent source, int id, Container ancestor, Container ancestorParent) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==AncestorListener.class) {
|
||||
// Lazily create the event:
|
||||
AncestorEvent ancestorEvent =
|
||||
new AncestorEvent(source, id, ancestor, ancestorParent);
|
||||
((AncestorListener)listeners[i+1]).ancestorMoved(ancestorEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeAllListeners() {
|
||||
removeListeners(root);
|
||||
}
|
||||
|
||||
void addListeners(Component ancestor, boolean addToFirst) {
|
||||
Component a;
|
||||
|
||||
firstInvisibleAncestor = null;
|
||||
for (a = ancestor;
|
||||
firstInvisibleAncestor == null;
|
||||
a = a.getParent()) {
|
||||
if (addToFirst || a != ancestor) {
|
||||
a.addComponentListener(this);
|
||||
|
||||
if (a instanceof JComponent) {
|
||||
JComponent jAncestor = (JComponent)a;
|
||||
|
||||
jAncestor.addPropertyChangeListener(this);
|
||||
}
|
||||
}
|
||||
if (!a.isVisible() || a.getParent() == null || a instanceof Window) {
|
||||
firstInvisibleAncestor = a;
|
||||
}
|
||||
}
|
||||
if (firstInvisibleAncestor instanceof Window &&
|
||||
firstInvisibleAncestor.isVisible()) {
|
||||
firstInvisibleAncestor = null;
|
||||
}
|
||||
}
|
||||
|
||||
void removeListeners(Component ancestor) {
|
||||
Component a;
|
||||
for (a = ancestor; a != null; a = a.getParent()) {
|
||||
a.removeComponentListener(this);
|
||||
if (a instanceof JComponent) {
|
||||
JComponent jAncestor = (JComponent)a;
|
||||
jAncestor.removePropertyChangeListener(this);
|
||||
}
|
||||
if (a == firstInvisibleAncestor || a instanceof Window) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void componentResized(ComponentEvent e) {}
|
||||
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
Component source = e.getComponent();
|
||||
|
||||
fireAncestorMoved(root, AncestorEvent.ANCESTOR_MOVED,
|
||||
(Container)source, source.getParent());
|
||||
}
|
||||
|
||||
public void componentShown(ComponentEvent e) {
|
||||
Component ancestor = e.getComponent();
|
||||
|
||||
if (ancestor == firstInvisibleAncestor) {
|
||||
addListeners(ancestor, false);
|
||||
if (firstInvisibleAncestor == null) {
|
||||
fireAncestorAdded(root, AncestorEvent.ANCESTOR_ADDED,
|
||||
(Container)ancestor, ancestor.getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
Component ancestor = e.getComponent();
|
||||
boolean needsNotify = firstInvisibleAncestor == null;
|
||||
|
||||
if ( !(ancestor instanceof Window) ) {
|
||||
removeListeners(ancestor.getParent());
|
||||
}
|
||||
firstInvisibleAncestor = ancestor;
|
||||
if (needsNotify) {
|
||||
fireAncestorRemoved(root, AncestorEvent.ANCESTOR_REMOVED,
|
||||
(Container)ancestor, ancestor.getParent());
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String s = evt.getPropertyName();
|
||||
|
||||
if (s!=null && (s.equals("parent") || s.equals("ancestor"))) {
|
||||
JComponent component = (JComponent)evt.getSource();
|
||||
|
||||
if (evt.getNewValue() != null) {
|
||||
if (component == firstInvisibleAncestor) {
|
||||
addListeners(component, false);
|
||||
if (firstInvisibleAncestor == null) {
|
||||
fireAncestorAdded(root, AncestorEvent.ANCESTOR_ADDED,
|
||||
component, component.getParent());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean needsNotify = firstInvisibleAncestor == null;
|
||||
Container oldParent = (Container)evt.getOldValue();
|
||||
|
||||
removeListeners(oldParent);
|
||||
firstInvisibleAncestor = component;
|
||||
if (needsNotify) {
|
||||
fireAncestorRemoved(root, AncestorEvent.ANCESTOR_REMOVED,
|
||||
component, oldParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
342
jdkSrc/jdk8/javax/swing/ArrayTable.java
Normal file
342
jdkSrc/jdk8/javax/swing/ArrayTable.java
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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 javax.swing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/*
|
||||
* Private storage mechanism for Action key-value pairs.
|
||||
* In most cases this will be an array of alternating
|
||||
* key-value pairs. As it grows larger it is scaled
|
||||
* up to a Hashtable.
|
||||
* <p>
|
||||
* This does no synchronization, if you need thread safety synchronize on
|
||||
* another object before calling this.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class ArrayTable implements Cloneable {
|
||||
// Our field for storage
|
||||
private Object table = null;
|
||||
private static final int ARRAY_BOUNDARY = 8;
|
||||
|
||||
|
||||
/**
|
||||
* Writes the passed in ArrayTable to the passed in ObjectOutputStream.
|
||||
* The data is saved as an integer indicating how many key/value
|
||||
* pairs are being archived, followed by the the key/value pairs. If
|
||||
* <code>table</code> is null, 0 will be written to <code>s</code>.
|
||||
* <p>
|
||||
* This is a convenience method that ActionMap/InputMap and
|
||||
* AbstractAction use to avoid having the same code in each class.
|
||||
*/
|
||||
static void writeArrayTable(ObjectOutputStream s, ArrayTable table) throws IOException {
|
||||
Object keys[];
|
||||
|
||||
if (table == null || (keys = table.getKeys(null)) == null) {
|
||||
s.writeInt(0);
|
||||
}
|
||||
else {
|
||||
// Determine how many keys have Serializable values, when
|
||||
// done all non-null values in keys identify the Serializable
|
||||
// values.
|
||||
int validCount = 0;
|
||||
|
||||
for (int counter = 0; counter < keys.length; counter++) {
|
||||
Object key = keys[counter];
|
||||
|
||||
/* include in Serialization when both keys and values are Serializable */
|
||||
if ( (key instanceof Serializable
|
||||
&& table.get(key) instanceof Serializable)
|
||||
||
|
||||
/* include these only so that we get the appropriate exception below */
|
||||
(key instanceof ClientPropertyKey
|
||||
&& ((ClientPropertyKey)key).getReportValueNotSerializable())) {
|
||||
|
||||
validCount++;
|
||||
} else {
|
||||
keys[counter] = null;
|
||||
}
|
||||
}
|
||||
// Write ou the Serializable key/value pairs.
|
||||
s.writeInt(validCount);
|
||||
if (validCount > 0) {
|
||||
for (Object key : keys) {
|
||||
if (key != null) {
|
||||
s.writeObject(key);
|
||||
s.writeObject(table.get(key));
|
||||
if (--validCount == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Put the key-value pair into storage
|
||||
*/
|
||||
public void put(Object key, Object value){
|
||||
if (table==null) {
|
||||
table = new Object[] {key, value};
|
||||
} else {
|
||||
int size = size();
|
||||
if (size < ARRAY_BOUNDARY) { // We are an array
|
||||
if (containsKey(key)) {
|
||||
Object[] tmp = (Object[])table;
|
||||
for (int i = 0; i<tmp.length-1; i+=2) {
|
||||
if (tmp[i].equals(key)) {
|
||||
tmp[i+1]=value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Object[] array = (Object[])table;
|
||||
int i = array.length;
|
||||
Object[] tmp = new Object[i+2];
|
||||
System.arraycopy(array, 0, tmp, 0, i);
|
||||
|
||||
tmp[i] = key;
|
||||
tmp[i+1] = value;
|
||||
table = tmp;
|
||||
}
|
||||
} else { // We are a hashtable
|
||||
if ((size==ARRAY_BOUNDARY) && isArray()) {
|
||||
grow();
|
||||
}
|
||||
((Hashtable<Object,Object>)table).put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the value for key
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
Object value = null;
|
||||
if (table !=null) {
|
||||
if (isArray()) {
|
||||
Object[] array = (Object[])table;
|
||||
for (int i = 0; i<array.length-1; i+=2) {
|
||||
if (array[i].equals(key)) {
|
||||
value = array[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value = ((Hashtable)table).get(key);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of pairs in storage
|
||||
*/
|
||||
public int size() {
|
||||
int size;
|
||||
if (table==null)
|
||||
return 0;
|
||||
if (isArray()) {
|
||||
size = ((Object[])table).length/2;
|
||||
} else {
|
||||
size = ((Hashtable)table).size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if we have a value for the key
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
boolean contains = false;
|
||||
if (table !=null) {
|
||||
if (isArray()) {
|
||||
Object[] array = (Object[])table;
|
||||
for (int i = 0; i<array.length-1; i+=2) {
|
||||
if (array[i].equals(key)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
contains = ((Hashtable)table).containsKey(key);
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the key and its value
|
||||
* Returns the value for the pair removed
|
||||
*/
|
||||
public Object remove(Object key){
|
||||
Object value = null;
|
||||
if (key==null) {
|
||||
return null;
|
||||
}
|
||||
if (table !=null) {
|
||||
if (isArray()){
|
||||
// Is key on the list?
|
||||
int index = -1;
|
||||
Object[] array = (Object[])table;
|
||||
for (int i = array.length-2; i>=0; i-=2) {
|
||||
if (array[i].equals(key)) {
|
||||
index = i;
|
||||
value = array[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If so, remove it
|
||||
if (index != -1) {
|
||||
Object[] tmp = new Object[array.length-2];
|
||||
// Copy the list up to index
|
||||
System.arraycopy(array, 0, tmp, 0, index);
|
||||
// Copy from two past the index, up to
|
||||
// the end of tmp (which is two elements
|
||||
// shorter than the old list)
|
||||
if (index < tmp.length)
|
||||
System.arraycopy(array, index+2, tmp, index,
|
||||
tmp.length - index);
|
||||
// set the listener array to the new array or null
|
||||
table = (tmp.length == 0) ? null : tmp;
|
||||
}
|
||||
} else {
|
||||
value = ((Hashtable)table).remove(key);
|
||||
}
|
||||
if (size()==ARRAY_BOUNDARY - 1 && !isArray()) {
|
||||
shrink();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the mappings.
|
||||
*/
|
||||
public void clear() {
|
||||
table = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a clone of the <code>ArrayTable</code>.
|
||||
*/
|
||||
public Object clone() {
|
||||
ArrayTable newArrayTable = new ArrayTable();
|
||||
if (isArray()) {
|
||||
Object[] array = (Object[])table;
|
||||
for (int i = 0 ;i < array.length-1 ; i+=2) {
|
||||
newArrayTable.put(array[i], array[i+1]);
|
||||
}
|
||||
} else {
|
||||
Hashtable<?,?> tmp = (Hashtable)table;
|
||||
Enumeration<?> keys = tmp.keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
Object o = keys.nextElement();
|
||||
newArrayTable.put(o,tmp.get(o));
|
||||
}
|
||||
}
|
||||
return newArrayTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keys of the table, or <code>null</code> if there
|
||||
* are currently no bindings.
|
||||
* @param keys array of keys
|
||||
* @return an array of bindings
|
||||
*/
|
||||
public Object[] getKeys(Object[] keys) {
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
if (isArray()) {
|
||||
Object[] array = (Object[])table;
|
||||
if (keys == null) {
|
||||
keys = new Object[array.length / 2];
|
||||
}
|
||||
for (int i = 0, index = 0 ;i < array.length-1 ; i+=2,
|
||||
index++) {
|
||||
keys[index] = array[i];
|
||||
}
|
||||
} else {
|
||||
Hashtable<?,?> tmp = (Hashtable)table;
|
||||
Enumeration<?> enum_ = tmp.keys();
|
||||
int counter = tmp.size();
|
||||
if (keys == null) {
|
||||
keys = new Object[counter];
|
||||
}
|
||||
while (counter > 0) {
|
||||
keys[--counter] = enum_.nextElement();
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the current storage mechanism is
|
||||
* an array of alternating key-value pairs.
|
||||
*/
|
||||
private boolean isArray(){
|
||||
return (table instanceof Object[]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Grows the storage from an array to a hashtable.
|
||||
*/
|
||||
private void grow() {
|
||||
Object[] array = (Object[])table;
|
||||
Hashtable<Object, Object> tmp = new Hashtable<Object, Object>(array.length/2);
|
||||
for (int i = 0; i<array.length; i+=2) {
|
||||
tmp.put(array[i], array[i+1]);
|
||||
}
|
||||
table = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shrinks the storage from a hashtable to an array.
|
||||
*/
|
||||
private void shrink() {
|
||||
Hashtable<?,?> tmp = (Hashtable)table;
|
||||
Object[] array = new Object[tmp.size()*2];
|
||||
Enumeration<?> keys = tmp.keys();
|
||||
int j = 0;
|
||||
|
||||
while (keys.hasMoreElements()) {
|
||||
Object o = keys.nextElement();
|
||||
array[j] = o;
|
||||
array[j+1] = tmp.get(o);
|
||||
j+=2;
|
||||
}
|
||||
table = array;
|
||||
}
|
||||
}
|
||||
188
jdkSrc/jdk8/javax/swing/Autoscroller.java
Normal file
188
jdkSrc/jdk8/javax/swing/Autoscroller.java
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.AWTAccessor.MouseEventAccessor;
|
||||
|
||||
/**
|
||||
* Autoscroller is responsible for generating synthetic mouse dragged
|
||||
* events. It is the responsibility of the Component (or its MouseListeners)
|
||||
* that receive the events to do the actual scrolling in response to the
|
||||
* mouse dragged events.
|
||||
*
|
||||
* @author Dave Moore
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class Autoscroller implements ActionListener {
|
||||
/**
|
||||
* Global Autoscroller.
|
||||
*/
|
||||
private static Autoscroller sharedInstance = new Autoscroller();
|
||||
|
||||
// As there can only ever be one autoscroller active these fields are
|
||||
// static. The Timer is recreated as necessary to target the appropriate
|
||||
// Autoscroller instance.
|
||||
private static MouseEvent event;
|
||||
private static Timer timer;
|
||||
private static JComponent component;
|
||||
|
||||
//
|
||||
// The public API, all methods are cover methods for an instance method
|
||||
//
|
||||
/**
|
||||
* Stops autoscroll events from happening on the specified component.
|
||||
*/
|
||||
public static void stop(JComponent c) {
|
||||
sharedInstance._stop(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops autoscroll events from happening on the specified component.
|
||||
*/
|
||||
public static boolean isRunning(JComponent c) {
|
||||
return sharedInstance._isRunning(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a mouse dragged event occurs, will start the autoscroller
|
||||
* if necessary.
|
||||
*/
|
||||
public static void processMouseDragged(MouseEvent e) {
|
||||
sharedInstance._processMouseDragged(e);
|
||||
}
|
||||
|
||||
|
||||
Autoscroller() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the timer targeting the passed in component.
|
||||
*/
|
||||
private void start(JComponent c, MouseEvent e) {
|
||||
Point screenLocation = c.getLocationOnScreen();
|
||||
|
||||
if (component != c) {
|
||||
_stop(component);
|
||||
}
|
||||
component = c;
|
||||
event = new MouseEvent(component, e.getID(), e.getWhen(),
|
||||
e.getModifiers(), e.getX() + screenLocation.x,
|
||||
e.getY() + screenLocation.y,
|
||||
e.getXOnScreen(),
|
||||
e.getYOnScreen(),
|
||||
e.getClickCount(), e.isPopupTrigger(),
|
||||
MouseEvent.NOBUTTON);
|
||||
MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
|
||||
meAccessor.setCausedByTouchEvent(event,
|
||||
meAccessor.isCausedByTouchEvent(e));
|
||||
|
||||
if (timer == null) {
|
||||
timer = new Timer(100, this);
|
||||
}
|
||||
|
||||
if (!timer.isRunning()) {
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Methods mirror the public static API
|
||||
//
|
||||
|
||||
/**
|
||||
* Stops scrolling for the passed in widget.
|
||||
*/
|
||||
private void _stop(JComponent c) {
|
||||
if (component == c) {
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
}
|
||||
timer = null;
|
||||
event = null;
|
||||
component = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if autoscrolling is currently running for the specified
|
||||
* widget.
|
||||
*/
|
||||
private boolean _isRunning(JComponent c) {
|
||||
return (c == component && timer != null && timer.isRunning());
|
||||
}
|
||||
|
||||
/**
|
||||
* MouseListener method, invokes start/stop as necessary.
|
||||
*/
|
||||
private void _processMouseDragged(MouseEvent e) {
|
||||
JComponent component = (JComponent)e.getComponent();
|
||||
boolean stop = true;
|
||||
if (component.isShowing()) {
|
||||
Rectangle visibleRect = component.getVisibleRect();
|
||||
stop = visibleRect.contains(e.getX(), e.getY());
|
||||
}
|
||||
if (stop) {
|
||||
_stop(component);
|
||||
} else {
|
||||
start(component, e);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ActionListener
|
||||
//
|
||||
/**
|
||||
* ActionListener method. Invoked when the Timer fires. This will scroll
|
||||
* if necessary.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent x) {
|
||||
JComponent component = Autoscroller.component;
|
||||
|
||||
if (component == null || !component.isShowing() || (event == null)) {
|
||||
_stop(component);
|
||||
return;
|
||||
}
|
||||
Point screenLocation = component.getLocationOnScreen();
|
||||
MouseEvent e = new MouseEvent(component, event.getID(),
|
||||
event.getWhen(), event.getModifiers(),
|
||||
event.getX() - screenLocation.x,
|
||||
event.getY() - screenLocation.y,
|
||||
event.getXOnScreen(),
|
||||
event.getYOnScreen(),
|
||||
event.getClickCount(),
|
||||
event.isPopupTrigger(),
|
||||
MouseEvent.NOBUTTON);
|
||||
MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
|
||||
meAccessor.setCausedByTouchEvent(e,
|
||||
meAccessor.isCausedByTouchEvent(event));
|
||||
component.superProcessMouseMotionEvent(e);
|
||||
}
|
||||
|
||||
}
|
||||
762
jdkSrc/jdk8/javax/swing/BorderFactory.java
Normal file
762
jdkSrc/jdk8/javax/swing/BorderFactory.java
Normal file
@@ -0,0 +1,762 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Paint;
|
||||
import javax.swing.border.*;
|
||||
|
||||
/**
|
||||
* Factory class for vending standard <code>Border</code> objects. Wherever
|
||||
* possible, this factory will hand out references to shared
|
||||
* <code>Border</code> instances.
|
||||
* For further information and examples see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
|
||||
to Use Borders</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
public class BorderFactory
|
||||
{
|
||||
|
||||
/** Don't let anyone instantiate this class */
|
||||
private BorderFactory() {
|
||||
}
|
||||
|
||||
|
||||
//// LineBorder ///////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a line border withe the specified color.
|
||||
*
|
||||
* @param color a <code>Color</code> to use for the line
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createLineBorder(Color color) {
|
||||
return new LineBorder(color, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a line border with the specified color
|
||||
* and width. The width applies to all four sides of the
|
||||
* border. To specify widths individually for the top,
|
||||
* bottom, left, and right, use
|
||||
* {@link #createMatteBorder(int,int,int,int,Color)}.
|
||||
*
|
||||
* @param color a <code>Color</code> to use for the line
|
||||
* @param thickness an integer specifying the width in pixels
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createLineBorder(Color color, int thickness) {
|
||||
return new LineBorder(color, thickness);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a line border with the specified color, thickness, and corner shape.
|
||||
*
|
||||
* @param color the color of the border
|
||||
* @param thickness the thickness of the border
|
||||
* @param rounded whether or not border corners should be round
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @see LineBorder#LineBorder(Color, int, boolean)
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createLineBorder(Color color, int thickness, boolean rounded) {
|
||||
return new LineBorder(color, thickness, rounded);
|
||||
}
|
||||
|
||||
//// BevelBorder /////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static final Border sharedRaisedBevel = new BevelBorder(BevelBorder.RAISED);
|
||||
static final Border sharedLoweredBevel = new BevelBorder(BevelBorder.LOWERED);
|
||||
|
||||
/**
|
||||
* Creates a border with a raised beveled edge, using
|
||||
* brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* (In a raised border, highlights are on top and shadows
|
||||
* are underneath.)
|
||||
*
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createRaisedBevelBorder() {
|
||||
return createSharedBevel(BevelBorder.RAISED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a border with a lowered beveled edge, using
|
||||
* brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* (In a lowered border, shadows are on top and highlights
|
||||
* are underneath.)
|
||||
*
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createLoweredBevelBorder() {
|
||||
return createSharedBevel(BevelBorder.LOWERED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type, using
|
||||
* brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* (In a lowered border, shadows are on top and highlights
|
||||
* are underneath.)
|
||||
*
|
||||
* @param type an integer specifying either
|
||||
* <code>BevelBorder.LOWERED</code> or
|
||||
* <code>BevelBorder.RAISED</code>
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createBevelBorder(int type) {
|
||||
return createSharedBevel(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type, using
|
||||
* the specified highlighting and shadowing. The outer
|
||||
* edge of the highlighted area uses a brighter shade of
|
||||
* the highlight color. The inner edge of the shadow area
|
||||
* uses a brighter shade of the shadow color.
|
||||
*
|
||||
* @param type an integer specifying either
|
||||
* <code>BevelBorder.LOWERED</code> or
|
||||
* <code>BevelBorder.RAISED</code>
|
||||
* @param highlight a <code>Color</code> object for highlights
|
||||
* @param shadow a <code>Color</code> object for shadows
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createBevelBorder(int type, Color highlight, Color shadow) {
|
||||
return new BevelBorder(type, highlight, shadow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type, using
|
||||
* the specified colors for the inner and outer highlight
|
||||
* and shadow areas.
|
||||
*
|
||||
* @param type an integer specifying either
|
||||
* <code>BevelBorder.LOWERED</code> or
|
||||
* <code>BevelBorder.RAISED</code>
|
||||
* @param highlightOuter a <code>Color</code> object for the
|
||||
* outer edge of the highlight area
|
||||
* @param highlightInner a <code>Color</code> object for the
|
||||
* inner edge of the highlight area
|
||||
* @param shadowOuter a <code>Color</code> object for the
|
||||
* outer edge of the shadow area
|
||||
* @param shadowInner a <code>Color</code> object for the
|
||||
* inner edge of the shadow area
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createBevelBorder(int type,
|
||||
Color highlightOuter, Color highlightInner,
|
||||
Color shadowOuter, Color shadowInner) {
|
||||
return new BevelBorder(type, highlightOuter, highlightInner,
|
||||
shadowOuter, shadowInner);
|
||||
}
|
||||
|
||||
static Border createSharedBevel(int type) {
|
||||
if(type == BevelBorder.RAISED) {
|
||||
return sharedRaisedBevel;
|
||||
} else if(type == BevelBorder.LOWERED) {
|
||||
return sharedLoweredBevel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//// SoftBevelBorder ///////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static Border sharedSoftRaisedBevel;
|
||||
private static Border sharedSoftLoweredBevel;
|
||||
|
||||
/**
|
||||
* Creates a beveled border with a raised edge and softened corners,
|
||||
* using brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* In a raised border, highlights are on top and shadows are underneath.
|
||||
*
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createRaisedSoftBevelBorder() {
|
||||
if (sharedSoftRaisedBevel == null) {
|
||||
sharedSoftRaisedBevel = new SoftBevelBorder(BevelBorder.RAISED);
|
||||
}
|
||||
return sharedSoftRaisedBevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border with a lowered edge and softened corners,
|
||||
* using brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* In a lowered border, shadows are on top and highlights are underneath.
|
||||
*
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createLoweredSoftBevelBorder() {
|
||||
if (sharedSoftLoweredBevel == null) {
|
||||
sharedSoftLoweredBevel = new SoftBevelBorder(BevelBorder.LOWERED);
|
||||
}
|
||||
return sharedSoftLoweredBevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type with softened corners,
|
||||
* using brighter shades of the component's current background color
|
||||
* for highlighting, and darker shading for shadows.
|
||||
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
|
||||
*
|
||||
* @param type a type of a bevel
|
||||
* @return the {@code Border} object or {@code null}
|
||||
* if the specified type is not valid
|
||||
*
|
||||
* @see BevelBorder#BevelBorder(int)
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createSoftBevelBorder(int type) {
|
||||
if (type == BevelBorder.RAISED) {
|
||||
return createRaisedSoftBevelBorder();
|
||||
}
|
||||
if (type == BevelBorder.LOWERED) {
|
||||
return createLoweredSoftBevelBorder();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type with softened corners,
|
||||
* using the specified highlighting and shadowing.
|
||||
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
|
||||
* The outer edge of the highlight area uses
|
||||
* a brighter shade of the {@code highlight} color.
|
||||
* The inner edge of the shadow area uses
|
||||
* a brighter shade of the {@code shadow} color.
|
||||
*
|
||||
* @param type a type of a bevel
|
||||
* @param highlight a basic color of the highlight area
|
||||
* @param shadow a basic color of the shadow area
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @see BevelBorder#BevelBorder(int, Color, Color)
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createSoftBevelBorder(int type, Color highlight, Color shadow) {
|
||||
return new SoftBevelBorder(type, highlight, shadow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a beveled border of the specified type with softened corners,
|
||||
* using the specified colors for the inner and outer edges
|
||||
* of the highlight and the shadow areas.
|
||||
* The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
|
||||
* Note: The shadow inner and outer colors are switched
|
||||
* for a lowered bevel border.
|
||||
*
|
||||
* @param type a type of a bevel
|
||||
* @param highlightOuter a color of the outer edge of the highlight area
|
||||
* @param highlightInner a color of the inner edge of the highlight area
|
||||
* @param shadowOuter a color of the outer edge of the shadow area
|
||||
* @param shadowInner a color of the inner edge of the shadow area
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @see BevelBorder#BevelBorder(int, Color, Color, Color, Color)
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createSoftBevelBorder(int type, Color highlightOuter, Color highlightInner, Color shadowOuter, Color shadowInner) {
|
||||
return new SoftBevelBorder(type, highlightOuter, highlightInner, shadowOuter, shadowInner);
|
||||
}
|
||||
|
||||
//// EtchedBorder ///////////////////////////////////////////////////////////
|
||||
|
||||
static final Border sharedEtchedBorder = new EtchedBorder();
|
||||
private static Border sharedRaisedEtchedBorder;
|
||||
|
||||
/**
|
||||
* Creates a border with an "etched" look using
|
||||
* the component's current background color for
|
||||
* highlighting and shading.
|
||||
*
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createEtchedBorder() {
|
||||
return sharedEtchedBorder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a border with an "etched" look using
|
||||
* the specified highlighting and shading colors.
|
||||
*
|
||||
* @param highlight a <code>Color</code> object for the border highlights
|
||||
* @param shadow a <code>Color</code> object for the border shadows
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createEtchedBorder(Color highlight, Color shadow) {
|
||||
return new EtchedBorder(highlight, shadow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a border with an "etched" look using
|
||||
* the component's current background color for
|
||||
* highlighting and shading.
|
||||
*
|
||||
* @param type one of <code>EtchedBorder.RAISED</code>, or
|
||||
* <code>EtchedBorder.LOWERED</code>
|
||||
* @return the <code>Border</code> object
|
||||
* @exception IllegalArgumentException if type is not either
|
||||
* <code>EtchedBorder.RAISED</code> or
|
||||
* <code>EtchedBorder.LOWERED</code>
|
||||
* @since 1.3
|
||||
*/
|
||||
public static Border createEtchedBorder(int type) {
|
||||
switch (type) {
|
||||
case EtchedBorder.RAISED:
|
||||
if (sharedRaisedEtchedBorder == null) {
|
||||
sharedRaisedEtchedBorder = new EtchedBorder
|
||||
(EtchedBorder.RAISED);
|
||||
}
|
||||
return sharedRaisedEtchedBorder;
|
||||
case EtchedBorder.LOWERED:
|
||||
return sharedEtchedBorder;
|
||||
default:
|
||||
throw new IllegalArgumentException("type must be one of EtchedBorder.RAISED or EtchedBorder.LOWERED");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a border with an "etched" look using
|
||||
* the specified highlighting and shading colors.
|
||||
*
|
||||
* @param type one of <code>EtchedBorder.RAISED</code>, or
|
||||
* <code>EtchedBorder.LOWERED</code>
|
||||
* @param highlight a <code>Color</code> object for the border highlights
|
||||
* @param shadow a <code>Color</code> object for the border shadows
|
||||
* @return the <code>Border</code> object
|
||||
* @since 1.3
|
||||
*/
|
||||
public static Border createEtchedBorder(int type, Color highlight,
|
||||
Color shadow) {
|
||||
return new EtchedBorder(type, highlight, shadow);
|
||||
}
|
||||
|
||||
//// TitledBorder ////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a new titled border with the specified title,
|
||||
* the default border type (determined by the current look and feel),
|
||||
* the default text position (determined by the current look and feel),
|
||||
* the default justification (leading), and the default
|
||||
* font and text color (determined by the current look and feel).
|
||||
*
|
||||
* @param title a <code>String</code> containing the text of the title
|
||||
* @return the <code>TitledBorder</code> object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(String title) {
|
||||
return new TitledBorder(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new titled border with an empty title,
|
||||
* the specified border object,
|
||||
* the default text position (determined by the current look and feel),
|
||||
* the default justification (leading), and the default
|
||||
* font and text color (determined by the current look and feel).
|
||||
*
|
||||
* @param border the <code>Border</code> object to add the title to; if
|
||||
* <code>null</code> the <code>Border</code> is determined
|
||||
* by the current look and feel.
|
||||
* @return the <code>TitledBorder</code> object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(Border border) {
|
||||
return new TitledBorder(border);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a title to an existing border,
|
||||
* with default positioning (determined by the current look and feel),
|
||||
* default justification (leading) and the default
|
||||
* font and text color (determined by the current look and feel).
|
||||
*
|
||||
* @param border the <code>Border</code> object to add the title to
|
||||
* @param title a <code>String</code> containing the text of the title
|
||||
* @return the <code>TitledBorder</code> object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(Border border,
|
||||
String title) {
|
||||
return new TitledBorder(border, title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a title to an existing border, with the specified
|
||||
* positioning and using the default
|
||||
* font and text color (determined by the current look and feel).
|
||||
*
|
||||
* @param border the <code>Border</code> object to add the title to
|
||||
* @param title a <code>String</code> containing the text of the title
|
||||
* @param titleJustification an integer specifying the justification
|
||||
* of the title -- one of the following:
|
||||
*<ul>
|
||||
*<li><code>TitledBorder.LEFT</code>
|
||||
*<li><code>TitledBorder.CENTER</code>
|
||||
*<li><code>TitledBorder.RIGHT</code>
|
||||
*<li><code>TitledBorder.LEADING</code>
|
||||
*<li><code>TitledBorder.TRAILING</code>
|
||||
*<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
|
||||
*</ul>
|
||||
* @param titlePosition an integer specifying the vertical position of
|
||||
* the text in relation to the border -- one of the following:
|
||||
*<ul>
|
||||
*<li><code> TitledBorder.ABOVE_TOP</code>
|
||||
*<li><code>TitledBorder.TOP</code> (sitting on the top line)
|
||||
*<li><code>TitledBorder.BELOW_TOP</code>
|
||||
*<li><code>TitledBorder.ABOVE_BOTTOM</code>
|
||||
*<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
|
||||
*<li><code>TitledBorder.BELOW_BOTTOM</code>
|
||||
*<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
|
||||
* is determined by the current look and feel)
|
||||
*</ul>
|
||||
* @return the <code>TitledBorder</code> object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(Border border,
|
||||
String title,
|
||||
int titleJustification,
|
||||
int titlePosition) {
|
||||
return new TitledBorder(border, title, titleJustification,
|
||||
titlePosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a title to an existing border, with the specified
|
||||
* positioning and font, and using the default text color
|
||||
* (determined by the current look and feel).
|
||||
*
|
||||
* @param border the <code>Border</code> object to add the title to
|
||||
* @param title a <code>String</code> containing the text of the title
|
||||
* @param titleJustification an integer specifying the justification
|
||||
* of the title -- one of the following:
|
||||
*<ul>
|
||||
*<li><code>TitledBorder.LEFT</code>
|
||||
*<li><code>TitledBorder.CENTER</code>
|
||||
*<li><code>TitledBorder.RIGHT</code>
|
||||
*<li><code>TitledBorder.LEADING</code>
|
||||
*<li><code>TitledBorder.TRAILING</code>
|
||||
*<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
|
||||
*</ul>
|
||||
* @param titlePosition an integer specifying the vertical position of
|
||||
* the text in relation to the border -- one of the following:
|
||||
*<ul>
|
||||
*<li><code> TitledBorder.ABOVE_TOP</code>
|
||||
*<li><code>TitledBorder.TOP</code> (sitting on the top line)
|
||||
*<li><code>TitledBorder.BELOW_TOP</code>
|
||||
*<li><code>TitledBorder.ABOVE_BOTTOM</code>
|
||||
*<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
|
||||
*<li><code>TitledBorder.BELOW_BOTTOM</code>
|
||||
*<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
|
||||
* is determined by the current look and feel)
|
||||
*</ul>
|
||||
* @param titleFont a Font object specifying the title font
|
||||
* @return the TitledBorder object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(Border border,
|
||||
String title,
|
||||
int titleJustification,
|
||||
int titlePosition,
|
||||
Font titleFont) {
|
||||
return new TitledBorder(border, title, titleJustification,
|
||||
titlePosition, titleFont);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a title to an existing border, with the specified
|
||||
* positioning, font and color.
|
||||
*
|
||||
* @param border the <code>Border</code> object to add the title to
|
||||
* @param title a <code>String</code> containing the text of the title
|
||||
* @param titleJustification an integer specifying the justification
|
||||
* of the title -- one of the following:
|
||||
*<ul>
|
||||
*<li><code>TitledBorder.LEFT</code>
|
||||
*<li><code>TitledBorder.CENTER</code>
|
||||
*<li><code>TitledBorder.RIGHT</code>
|
||||
*<li><code>TitledBorder.LEADING</code>
|
||||
*<li><code>TitledBorder.TRAILING</code>
|
||||
*<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
|
||||
*</ul>
|
||||
* @param titlePosition an integer specifying the vertical position of
|
||||
* the text in relation to the border -- one of the following:
|
||||
*<ul>
|
||||
*<li><code> TitledBorder.ABOVE_TOP</code>
|
||||
*<li><code>TitledBorder.TOP</code> (sitting on the top line)
|
||||
*<li><code>TitledBorder.BELOW_TOP</code>
|
||||
*<li><code>TitledBorder.ABOVE_BOTTOM</code>
|
||||
*<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
|
||||
*<li><code>TitledBorder.BELOW_BOTTOM</code>
|
||||
*<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
|
||||
* is determined by the current look and feel)
|
||||
*</ul>
|
||||
* @param titleFont a <code>Font</code> object specifying the title font
|
||||
* @param titleColor a <code>Color</code> object specifying the title color
|
||||
* @return the <code>TitledBorder</code> object
|
||||
*/
|
||||
public static TitledBorder createTitledBorder(Border border,
|
||||
String title,
|
||||
int titleJustification,
|
||||
int titlePosition,
|
||||
Font titleFont,
|
||||
Color titleColor) {
|
||||
return new TitledBorder(border, title, titleJustification,
|
||||
titlePosition, titleFont, titleColor);
|
||||
}
|
||||
//// EmptyBorder ///////////////////////////////////////////////////////////
|
||||
final static Border emptyBorder = new EmptyBorder(0, 0, 0, 0);
|
||||
|
||||
/**
|
||||
* Creates an empty border that takes up no space. (The width
|
||||
* of the top, bottom, left, and right sides are all zero.)
|
||||
*
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createEmptyBorder() {
|
||||
return emptyBorder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty border that takes up space but which does
|
||||
* no drawing, specifying the width of the top, left, bottom, and
|
||||
* right sides.
|
||||
*
|
||||
* @param top an integer specifying the width of the top,
|
||||
* in pixels
|
||||
* @param left an integer specifying the width of the left side,
|
||||
* in pixels
|
||||
* @param bottom an integer specifying the width of the bottom,
|
||||
* in pixels
|
||||
* @param right an integer specifying the width of the right side,
|
||||
* in pixels
|
||||
* @return the <code>Border</code> object
|
||||
*/
|
||||
public static Border createEmptyBorder(int top, int left,
|
||||
int bottom, int right) {
|
||||
return new EmptyBorder(top, left, bottom, right);
|
||||
}
|
||||
|
||||
//// CompoundBorder ////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a compound border with a <code>null</code> inside edge and a
|
||||
* <code>null</code> outside edge.
|
||||
*
|
||||
* @return the <code>CompoundBorder</code> object
|
||||
*/
|
||||
public static CompoundBorder createCompoundBorder() {
|
||||
return new CompoundBorder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a compound border specifying the border objects to use
|
||||
* for the outside and inside edges.
|
||||
*
|
||||
* @param outsideBorder a <code>Border</code> object for the outer
|
||||
* edge of the compound border
|
||||
* @param insideBorder a <code>Border</code> object for the inner
|
||||
* edge of the compound border
|
||||
* @return the <code>CompoundBorder</code> object
|
||||
*/
|
||||
public static CompoundBorder createCompoundBorder(Border outsideBorder,
|
||||
Border insideBorder) {
|
||||
return new CompoundBorder(outsideBorder, insideBorder);
|
||||
}
|
||||
|
||||
//// MatteBorder ////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Creates a matte-look border using a solid color. (The difference between
|
||||
* this border and a line border is that you can specify the individual
|
||||
* border dimensions.)
|
||||
*
|
||||
* @param top an integer specifying the width of the top,
|
||||
* in pixels
|
||||
* @param left an integer specifying the width of the left side,
|
||||
* in pixels
|
||||
* @param bottom an integer specifying the width of the right side,
|
||||
* in pixels
|
||||
* @param right an integer specifying the width of the bottom,
|
||||
* in pixels
|
||||
* @param color a <code>Color</code> to use for the border
|
||||
* @return the <code>MatteBorder</code> object
|
||||
*/
|
||||
public static MatteBorder createMatteBorder(int top, int left, int bottom, int right,
|
||||
Color color) {
|
||||
return new MatteBorder(top, left, bottom, right, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matte-look border that consists of multiple tiles of a
|
||||
* specified icon. Multiple copies of the icon are placed side-by-side
|
||||
* to fill up the border area.
|
||||
* <p>
|
||||
* Note:<br>
|
||||
* If the icon doesn't load, the border area is painted gray.
|
||||
*
|
||||
* @param top an integer specifying the width of the top,
|
||||
* in pixels
|
||||
* @param left an integer specifying the width of the left side,
|
||||
* in pixels
|
||||
* @param bottom an integer specifying the width of the right side,
|
||||
* in pixels
|
||||
* @param right an integer specifying the width of the bottom,
|
||||
* in pixels
|
||||
* @param tileIcon the <code>Icon</code> object used for the border tiles
|
||||
* @return the <code>MatteBorder</code> object
|
||||
*/
|
||||
public static MatteBorder createMatteBorder(int top, int left, int bottom, int right,
|
||||
Icon tileIcon) {
|
||||
return new MatteBorder(top, left, bottom, right, tileIcon);
|
||||
}
|
||||
|
||||
//// StrokeBorder //////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Creates a border of the specified {@code stroke}.
|
||||
* The component's foreground color will be used to render the border.
|
||||
*
|
||||
* @param stroke the {@link BasicStroke} object used to stroke a shape
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @throws NullPointerException if the specified {@code stroke} is {@code null}
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createStrokeBorder(BasicStroke stroke) {
|
||||
return new StrokeBorder(stroke);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a border of the specified {@code stroke} and {@code paint}.
|
||||
* If the specified {@code paint} is {@code null},
|
||||
* the component's foreground color will be used to render the border.
|
||||
*
|
||||
* @param stroke the {@link BasicStroke} object used to stroke a shape
|
||||
* @param paint the {@link Paint} object used to generate a color
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @throws NullPointerException if the specified {@code stroke} is {@code null}
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createStrokeBorder(BasicStroke stroke, Paint paint) {
|
||||
return new StrokeBorder(stroke, paint);
|
||||
}
|
||||
|
||||
//// DashedBorder //////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static Border sharedDashedBorder;
|
||||
|
||||
/**
|
||||
* Creates a dashed border of the specified {@code paint}.
|
||||
* If the specified {@code paint} is {@code null},
|
||||
* the component's foreground color will be used to render the border.
|
||||
* The width of a dash line is equal to {@code 1}.
|
||||
* The relative length of a dash line and
|
||||
* the relative spacing between dash lines are equal to {@code 1}.
|
||||
* A dash line is not rounded.
|
||||
*
|
||||
* @param paint the {@link Paint} object used to generate a color
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createDashedBorder(Paint paint) {
|
||||
return createDashedBorder(paint, 1.0f, 1.0f, 1.0f, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dashed border of the specified {@code paint},
|
||||
* relative {@code length}, and relative {@code spacing}.
|
||||
* If the specified {@code paint} is {@code null},
|
||||
* the component's foreground color will be used to render the border.
|
||||
* The width of a dash line is equal to {@code 1}.
|
||||
* A dash line is not rounded.
|
||||
*
|
||||
* @param paint the {@link Paint} object used to generate a color
|
||||
* @param length the relative length of a dash line
|
||||
* @param spacing the relative spacing between dash lines
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @throws IllegalArgumentException if the specified {@code length} is less than {@code 1}, or
|
||||
* if the specified {@code spacing} is less than {@code 0}
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createDashedBorder(Paint paint, float length, float spacing) {
|
||||
return createDashedBorder(paint, 1.0f, length, spacing, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dashed border of the specified {@code paint}, {@code thickness},
|
||||
* line shape, relative {@code length}, and relative {@code spacing}.
|
||||
* If the specified {@code paint} is {@code null},
|
||||
* the component's foreground color will be used to render the border.
|
||||
*
|
||||
* @param paint the {@link Paint} object used to generate a color
|
||||
* @param thickness the width of a dash line
|
||||
* @param length the relative length of a dash line
|
||||
* @param spacing the relative spacing between dash lines
|
||||
* @param rounded whether or not line ends should be round
|
||||
* @return the {@code Border} object
|
||||
*
|
||||
* @throws IllegalArgumentException if the specified {@code thickness} is less than {@code 1}, or
|
||||
* if the specified {@code length} is less than {@code 1}, or
|
||||
* if the specified {@code spacing} is less than {@code 0}
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Border createDashedBorder(Paint paint, float thickness, float length, float spacing, boolean rounded) {
|
||||
boolean shared = !rounded && (paint == null) && (thickness == 1.0f) && (length == 1.0f) && (spacing == 1.0f);
|
||||
if (shared && (sharedDashedBorder != null)) {
|
||||
return sharedDashedBorder;
|
||||
}
|
||||
if (thickness < 1.0f) {
|
||||
throw new IllegalArgumentException("thickness is less than 1");
|
||||
}
|
||||
if (length < 1.0f) {
|
||||
throw new IllegalArgumentException("length is less than 1");
|
||||
}
|
||||
if (spacing < 0.0f) {
|
||||
throw new IllegalArgumentException("spacing is less than 0");
|
||||
}
|
||||
int cap = rounded ? BasicStroke.CAP_ROUND : BasicStroke.CAP_SQUARE;
|
||||
int join = rounded ? BasicStroke.JOIN_ROUND : BasicStroke.JOIN_MITER;
|
||||
float[] array = { thickness * (length - 1.0f), thickness * (spacing + 1.0f) };
|
||||
Border border = createStrokeBorder(new BasicStroke(thickness, cap, join, thickness * 2.0f, array, 0.0f), paint);
|
||||
if (shared) {
|
||||
sharedDashedBorder = border;
|
||||
}
|
||||
return border;
|
||||
}
|
||||
}
|
||||
268
jdkSrc/jdk8/javax/swing/BoundedRangeModel.java
Normal file
268
jdkSrc/jdk8/javax/swing/BoundedRangeModel.java
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.event.*;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the data model used by components like <code>Slider</code>s
|
||||
* and <code>ProgressBar</code>s.
|
||||
* Defines four interrelated integer properties: minimum, maximum, extent
|
||||
* and value. These four integers define two nested ranges like this:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* The outer range is <code>minimum,maximum</code> and the inner
|
||||
* range is <code>value,value+extent</code>. The inner range
|
||||
* must lie within the outer one, i.e. <code>value</code> must be
|
||||
* less than or equal to <code>maximum</code> and <code>value+extent</code>
|
||||
* must greater than or equal to <code>minimum</code>, and <code>maximum</code>
|
||||
* must be greater than or equal to <code>minimum</code>.
|
||||
* There are a few features of this model that one might find a little
|
||||
* surprising. These quirks exist for the convenience of the
|
||||
* Swing BoundedRangeModel clients, such as <code>Slider</code> and
|
||||
* <code>ScrollBar</code>.
|
||||
* <ul>
|
||||
* <li>
|
||||
* The minimum and maximum set methods "correct" the other
|
||||
* three properties to accommodate their new value argument. For
|
||||
* example setting the model's minimum may change its maximum, value,
|
||||
* and extent properties (in that order), to maintain the constraints
|
||||
* specified above.
|
||||
*
|
||||
* <li>
|
||||
* The value and extent set methods "correct" their argument to
|
||||
* fit within the limits defined by the other three properties.
|
||||
* For example if <code>value == maximum</code>, <code>setExtent(10)</code>
|
||||
* would change the extent (back) to zero.
|
||||
*
|
||||
* <li>
|
||||
* The four BoundedRangeModel values are defined as Java Beans properties
|
||||
* however Swing ChangeEvents are used to notify clients of changes rather
|
||||
* than PropertyChangeEvents. This was done to keep the overhead of monitoring
|
||||
* a BoundedRangeModel low. Changes are often reported at MouseDragged rates.
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* For an example of specifying custom bounded range models used by sliders,
|
||||
* see <a
|
||||
href="http://www.oracle.com/technetwork/java/architecture-142923.html#separable">Separable model architecture</a>
|
||||
* in <em>A Swing Architecture Overview.</em>
|
||||
*
|
||||
* @author Hans Muller
|
||||
* @see DefaultBoundedRangeModel
|
||||
*/
|
||||
public interface BoundedRangeModel
|
||||
{
|
||||
/**
|
||||
* Returns the minimum acceptable value.
|
||||
*
|
||||
* @return the value of the minimum property
|
||||
* @see #setMinimum
|
||||
*/
|
||||
int getMinimum();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's minimum to <I>newMinimum</I>. The
|
||||
* other three properties may be changed as well, to ensure
|
||||
* that:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* <p>
|
||||
* Notifies any listeners if the model changes.
|
||||
*
|
||||
* @param newMinimum the model's new minimum
|
||||
* @see #getMinimum
|
||||
* @see #addChangeListener
|
||||
*/
|
||||
void setMinimum(int newMinimum);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's maximum. Note that the upper
|
||||
* limit on the model's value is (maximum - extent).
|
||||
*
|
||||
* @return the value of the maximum property.
|
||||
* @see #setMaximum
|
||||
* @see #setExtent
|
||||
*/
|
||||
int getMaximum();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's maximum to <I>newMaximum</I>. The other
|
||||
* three properties may be changed as well, to ensure that
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* <p>
|
||||
* Notifies any listeners if the model changes.
|
||||
*
|
||||
* @param newMaximum the model's new maximum
|
||||
* @see #getMaximum
|
||||
* @see #addChangeListener
|
||||
*/
|
||||
void setMaximum(int newMaximum);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's current value. Note that the upper
|
||||
* limit on the model's value is <code>maximum - extent</code>
|
||||
* and the lower limit is <code>minimum</code>.
|
||||
*
|
||||
* @return the model's value
|
||||
* @see #setValue
|
||||
*/
|
||||
int getValue();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's current value to <code>newValue</code> if <code>newValue</code>
|
||||
* satisfies the model's constraints. Those constraints are:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* Otherwise, if <code>newValue</code> is less than <code>minimum</code>
|
||||
* it's set to <code>minimum</code>, if its greater than
|
||||
* <code>maximum</code> then it's set to <code>maximum</code>, and
|
||||
* if it's greater than <code>value+extent</code> then it's set to
|
||||
* <code>value+extent</code>.
|
||||
* <p>
|
||||
* When a BoundedRange model is used with a scrollbar the value
|
||||
* specifies the origin of the scrollbar knob (aka the "thumb" or
|
||||
* "elevator"). The value usually represents the origin of the
|
||||
* visible part of the object being scrolled.
|
||||
* <p>
|
||||
* Notifies any listeners if the model changes.
|
||||
*
|
||||
* @param newValue the model's new value
|
||||
* @see #getValue
|
||||
*/
|
||||
void setValue(int newValue);
|
||||
|
||||
|
||||
/**
|
||||
* This attribute indicates that any upcoming changes to the value
|
||||
* of the model should be considered a single event. This attribute
|
||||
* will be set to true at the start of a series of changes to the value,
|
||||
* and will be set to false when the value has finished changing. Normally
|
||||
* this allows a listener to only take action when the final value change in
|
||||
* committed, instead of having to do updates for all intermediate values.
|
||||
* <p>
|
||||
* Sliders and scrollbars use this property when a drag is underway.
|
||||
*
|
||||
* @param b true if the upcoming changes to the value property are part of a series
|
||||
*/
|
||||
void setValueIsAdjusting(boolean b);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the current changes to the value property are part
|
||||
* of a series of changes.
|
||||
*
|
||||
* @return the valueIsAdjustingProperty.
|
||||
* @see #setValueIsAdjusting
|
||||
*/
|
||||
boolean getValueIsAdjusting();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's extent, the length of the inner range that
|
||||
* begins at the model's value.
|
||||
*
|
||||
* @return the value of the model's extent property
|
||||
* @see #setExtent
|
||||
* @see #setValue
|
||||
*/
|
||||
int getExtent();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's extent. The <I>newExtent</I> is forced to
|
||||
* be greater than or equal to zero and less than or equal to
|
||||
* maximum - value.
|
||||
* <p>
|
||||
* When a BoundedRange model is used with a scrollbar the extent
|
||||
* defines the length of the scrollbar knob (aka the "thumb" or
|
||||
* "elevator"). The extent usually represents how much of the
|
||||
* object being scrolled is visible. When used with a slider,
|
||||
* the extent determines how much the value can "jump", for
|
||||
* example when the user presses PgUp or PgDn.
|
||||
* <p>
|
||||
* Notifies any listeners if the model changes.
|
||||
*
|
||||
* @param newExtent the model's new extent
|
||||
* @see #getExtent
|
||||
* @see #setValue
|
||||
*/
|
||||
void setExtent(int newExtent);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method sets all of the model's data with a single method call.
|
||||
* The method results in a single change event being generated. This is
|
||||
* convenient when you need to adjust all the model data simultaneously and
|
||||
* do not want individual change events to occur.
|
||||
*
|
||||
* @param value an int giving the current value
|
||||
* @param extent an int giving the amount by which the value can "jump"
|
||||
* @param min an int giving the minimum value
|
||||
* @param max an int giving the maximum value
|
||||
* @param adjusting a boolean, true if a series of changes are in
|
||||
* progress
|
||||
*
|
||||
* @see #setValue
|
||||
* @see #setExtent
|
||||
* @see #setMinimum
|
||||
* @see #setMaximum
|
||||
* @see #setValueIsAdjusting
|
||||
*/
|
||||
void setRangeProperties(int value, int extent, int min, int max, boolean adjusting);
|
||||
|
||||
|
||||
/**
|
||||
* Adds a ChangeListener to the model's listener list.
|
||||
*
|
||||
* @param x the ChangeListener to add
|
||||
* @see #removeChangeListener
|
||||
*/
|
||||
void addChangeListener(ChangeListener x);
|
||||
|
||||
|
||||
/**
|
||||
* Removes a ChangeListener from the model's listener list.
|
||||
*
|
||||
* @param x the ChangeListener to remove
|
||||
* @see #addChangeListener
|
||||
*/
|
||||
void removeChangeListener(ChangeListener x);
|
||||
|
||||
}
|
||||
441
jdkSrc/jdk8/javax/swing/Box.java
Normal file
441
jdkSrc/jdk8/javax/swing/Box.java
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.util.Locale;
|
||||
import java.io.Serializable;
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* A lightweight container
|
||||
* that uses a BoxLayout object as its layout manager.
|
||||
* Box provides several class methods
|
||||
* that are useful for containers using BoxLayout --
|
||||
* even non-Box containers.
|
||||
*
|
||||
* <p>
|
||||
* The <code>Box</code> class can create several kinds
|
||||
* of invisible components
|
||||
* that affect layout:
|
||||
* glue, struts, and rigid areas.
|
||||
* If all the components your <code>Box</code> contains
|
||||
* have a fixed size,
|
||||
* you might want to use a glue component
|
||||
* (returned by <code>createGlue</code>)
|
||||
* to control the components' positions.
|
||||
* If you need a fixed amount of space between two components,
|
||||
* try using a strut
|
||||
* (<code>createHorizontalStrut</code> or <code>createVerticalStrut</code>).
|
||||
* If you need an invisible component
|
||||
* that always takes up the same amount of space,
|
||||
* get it by invoking <code>createRigidArea</code>.
|
||||
* <p>
|
||||
* If you are implementing a <code>BoxLayout</code> you
|
||||
* can find further information and examples in
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see BoxLayout
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Box extends JComponent implements Accessible {
|
||||
|
||||
/**
|
||||
* Creates a <code>Box</code> that displays its components
|
||||
* along the the specified axis.
|
||||
*
|
||||
* @param axis can be {@link BoxLayout#X_AXIS},
|
||||
* {@link BoxLayout#Y_AXIS},
|
||||
* {@link BoxLayout#LINE_AXIS} or
|
||||
* {@link BoxLayout#PAGE_AXIS}.
|
||||
* @throws AWTError if the <code>axis</code> is invalid
|
||||
* @see #createHorizontalBox
|
||||
* @see #createVerticalBox
|
||||
*/
|
||||
public Box(int axis) {
|
||||
super();
|
||||
super.setLayout(new BoxLayout(this, axis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Box</code> that displays its components
|
||||
* from left to right. If you want a <code>Box</code> that
|
||||
* respects the component orientation you should create the
|
||||
* <code>Box</code> using the constructor and pass in
|
||||
* <code>BoxLayout.LINE_AXIS</code>, eg:
|
||||
* <pre>
|
||||
* Box lineBox = new Box(BoxLayout.LINE_AXIS);
|
||||
* </pre>
|
||||
*
|
||||
* @return the box
|
||||
*/
|
||||
public static Box createHorizontalBox() {
|
||||
return new Box(BoxLayout.X_AXIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Box</code> that displays its components
|
||||
* from top to bottom. If you want a <code>Box</code> that
|
||||
* respects the component orientation you should create the
|
||||
* <code>Box</code> using the constructor and pass in
|
||||
* <code>BoxLayout.PAGE_AXIS</code>, eg:
|
||||
* <pre>
|
||||
* Box lineBox = new Box(BoxLayout.PAGE_AXIS);
|
||||
* </pre>
|
||||
*
|
||||
* @return the box
|
||||
*/
|
||||
public static Box createVerticalBox() {
|
||||
return new Box(BoxLayout.Y_AXIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invisible component that's always the specified size.
|
||||
* <!-- WHEN WOULD YOU USE THIS AS OPPOSED TO A STRUT? -->
|
||||
*
|
||||
* @param d the dimensions of the invisible component
|
||||
* @return the component
|
||||
* @see #createGlue
|
||||
* @see #createHorizontalStrut
|
||||
* @see #createVerticalStrut
|
||||
*/
|
||||
public static Component createRigidArea(Dimension d) {
|
||||
return new Filler(d, d, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invisible, fixed-width component.
|
||||
* In a horizontal box,
|
||||
* you typically use this method
|
||||
* to force a certain amount of space between two components.
|
||||
* In a vertical box,
|
||||
* you might use this method
|
||||
* to force the box to be at least the specified width.
|
||||
* The invisible component has no height
|
||||
* unless excess space is available,
|
||||
* in which case it takes its share of available space,
|
||||
* just like any other component that has no maximum height.
|
||||
*
|
||||
* @param width the width of the invisible component, in pixels >= 0
|
||||
* @return the component
|
||||
* @see #createVerticalStrut
|
||||
* @see #createGlue
|
||||
* @see #createRigidArea
|
||||
*/
|
||||
public static Component createHorizontalStrut(int width) {
|
||||
return new Filler(new Dimension(width,0), new Dimension(width,0),
|
||||
new Dimension(width, Short.MAX_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invisible, fixed-height component.
|
||||
* In a vertical box,
|
||||
* you typically use this method
|
||||
* to force a certain amount of space between two components.
|
||||
* In a horizontal box,
|
||||
* you might use this method
|
||||
* to force the box to be at least the specified height.
|
||||
* The invisible component has no width
|
||||
* unless excess space is available,
|
||||
* in which case it takes its share of available space,
|
||||
* just like any other component that has no maximum width.
|
||||
*
|
||||
* @param height the height of the invisible component, in pixels >= 0
|
||||
* @return the component
|
||||
* @see #createHorizontalStrut
|
||||
* @see #createGlue
|
||||
* @see #createRigidArea
|
||||
*/
|
||||
public static Component createVerticalStrut(int height) {
|
||||
return new Filler(new Dimension(0,height), new Dimension(0,height),
|
||||
new Dimension(Short.MAX_VALUE, height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invisible "glue" component
|
||||
* that can be useful in a Box
|
||||
* whose visible components have a maximum width
|
||||
* (for a horizontal box)
|
||||
* or height (for a vertical box).
|
||||
* You can think of the glue component
|
||||
* as being a gooey substance
|
||||
* that expands as much as necessary
|
||||
* to fill the space between its neighboring components.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* For example, suppose you have
|
||||
* a horizontal box that contains two fixed-size components.
|
||||
* If the box gets extra space,
|
||||
* the fixed-size components won't become larger,
|
||||
* so where does the extra space go?
|
||||
* Without glue,
|
||||
* the extra space goes to the right of the second component.
|
||||
* If you put glue between the fixed-size components,
|
||||
* then the extra space goes there.
|
||||
* If you put glue before the first fixed-size component,
|
||||
* the extra space goes there,
|
||||
* and the fixed-size components are shoved against the right
|
||||
* edge of the box.
|
||||
* If you put glue before the first fixed-size component
|
||||
* and after the second fixed-size component,
|
||||
* the fixed-size components are centered in the box.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* To use glue,
|
||||
* call <code>Box.createGlue</code>
|
||||
* and add the returned component to a container.
|
||||
* The glue component has no minimum or preferred size,
|
||||
* so it takes no space unless excess space is available.
|
||||
* If excess space is available,
|
||||
* then the glue component takes its share of available
|
||||
* horizontal or vertical space,
|
||||
* just like any other component that has no maximum width or height.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
public static Component createGlue() {
|
||||
return new Filler(new Dimension(0,0), new Dimension(0,0),
|
||||
new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a horizontal glue component.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
public static Component createHorizontalGlue() {
|
||||
return new Filler(new Dimension(0,0), new Dimension(0,0),
|
||||
new Dimension(Short.MAX_VALUE, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vertical glue component.
|
||||
*
|
||||
* @return the component
|
||||
*/
|
||||
public static Component createVerticalGlue() {
|
||||
return new Filler(new Dimension(0,0), new Dimension(0,0),
|
||||
new Dimension(0, Short.MAX_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an AWTError, since a Box can use only a BoxLayout.
|
||||
*
|
||||
* @param l the layout manager to use
|
||||
*/
|
||||
public void setLayout(LayoutManager l) {
|
||||
throw new AWTError("Illegal request");
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints this <code>Box</code>. If this <code>Box</code> has a UI this
|
||||
* method invokes super's implementation, otherwise if this
|
||||
* <code>Box</code> is opaque the <code>Graphics</code> is filled
|
||||
* using the background.
|
||||
*
|
||||
* @param g the <code>Graphics</code> to paint to
|
||||
* @throws NullPointerException if <code>g</code> is null
|
||||
* @since 1.6
|
||||
*/
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (ui != null) {
|
||||
// On the off chance some one created a UI, honor it
|
||||
super.paintComponent(g);
|
||||
} else if (isOpaque()) {
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a lightweight component that participates in
|
||||
* layout but has no view.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class Filler extends JComponent implements Accessible {
|
||||
|
||||
/**
|
||||
* Constructor to create shape with the given size ranges.
|
||||
*
|
||||
* @param min Minimum size
|
||||
* @param pref Preferred size
|
||||
* @param max Maximum size
|
||||
*/
|
||||
@ConstructorProperties({"minimumSize", "preferredSize", "maximumSize"})
|
||||
public Filler(Dimension min, Dimension pref, Dimension max) {
|
||||
setMinimumSize(min);
|
||||
setPreferredSize(pref);
|
||||
setMaximumSize(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the size requests for this shape. An invalidate() is
|
||||
* propagated upward as a result so that layout will eventually
|
||||
* happen with using the new sizes.
|
||||
*
|
||||
* @param min Value to return for getMinimumSize
|
||||
* @param pref Value to return for getPreferredSize
|
||||
* @param max Value to return for getMaximumSize
|
||||
*/
|
||||
public void changeShape(Dimension min, Dimension pref, Dimension max) {
|
||||
setMinimumSize(min);
|
||||
setPreferredSize(pref);
|
||||
setMaximumSize(max);
|
||||
revalidate();
|
||||
}
|
||||
|
||||
// ---- Component methods ------------------------------------------
|
||||
|
||||
/**
|
||||
* Paints this <code>Filler</code>. If this
|
||||
* <code>Filler</code> has a UI this method invokes super's
|
||||
* implementation, otherwise if this <code>Filler</code> is
|
||||
* opaque the <code>Graphics</code> is filled using the
|
||||
* background.
|
||||
*
|
||||
* @param g the <code>Graphics</code> to paint to
|
||||
* @throws NullPointerException if <code>g</code> is null
|
||||
* @since 1.6
|
||||
*/
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (ui != null) {
|
||||
// On the off chance some one created a UI, honor it
|
||||
super.paintComponent(g);
|
||||
} else if (isOpaque()) {
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support for Box$Filler
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this Box.Filler.
|
||||
* For box fillers, the AccessibleContext takes the form of an
|
||||
* AccessibleBoxFiller.
|
||||
* A new AccessibleAWTBoxFiller instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleBoxFiller that serves as the
|
||||
* AccessibleContext of this Box.Filler.
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleBoxFiller();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>Box.Filler</code> class.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleBoxFiller extends AccessibleAWTComponent {
|
||||
// AccessibleContext methods
|
||||
//
|
||||
/**
|
||||
* Gets the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of
|
||||
* the object (AccessibleRole.FILLER)
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.FILLER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support for Box
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this Box.
|
||||
* For boxes, the AccessibleContext takes the form of an
|
||||
* AccessibleBox.
|
||||
* A new AccessibleAWTBox instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleBox that serves as the
|
||||
* AccessibleContext of this Box
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleBox();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>Box</code> class.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleBox extends AccessibleAWTContainer {
|
||||
// AccessibleContext methods
|
||||
//
|
||||
/**
|
||||
* Gets the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object (AccessibleRole.FILLER)
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.FILLER;
|
||||
}
|
||||
} // inner class AccessibleBox
|
||||
}
|
||||
539
jdkSrc/jdk8/javax/swing/BoxLayout.java
Normal file
539
jdkSrc/jdk8/javax/swing/BoxLayout.java
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.io.Serializable;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* A layout manager that allows multiple components to be laid out either
|
||||
* vertically or horizontally. The components will not wrap so, for
|
||||
* example, a vertical arrangement of components will stay vertically
|
||||
* arranged when the frame is resized.
|
||||
* <TABLE STYLE="FLOAT:RIGHT" BORDER="0" SUMMARY="layout">
|
||||
* <TR>
|
||||
* <TD ALIGN="CENTER">
|
||||
* <P STYLE="TEXT-ALIGN:CENTER"><IMG SRC="doc-files/BoxLayout-1.gif"
|
||||
* alt="The following text describes this graphic."
|
||||
* WIDTH="191" HEIGHT="201" STYLE="FLOAT:BOTTOM; BORDER:0">
|
||||
* </TD>
|
||||
* </TR>
|
||||
* </TABLE>
|
||||
* <p>
|
||||
* Nesting multiple panels with different combinations of horizontal and
|
||||
* vertical gives an effect similar to GridBagLayout, without the
|
||||
* complexity. The diagram shows two panels arranged horizontally, each
|
||||
* of which contains 3 components arranged vertically.
|
||||
*
|
||||
* <p> The BoxLayout manager is constructed with an axis parameter that
|
||||
* specifies the type of layout that will be done. There are four choices:
|
||||
*
|
||||
* <blockquote><b><tt>X_AXIS</tt></b> - Components are laid out horizontally
|
||||
* from left to right.</blockquote>
|
||||
*
|
||||
* <blockquote><b><tt>Y_AXIS</tt></b> - Components are laid out vertically
|
||||
* from top to bottom.</blockquote>
|
||||
*
|
||||
* <blockquote><b><tt>LINE_AXIS</tt></b> - Components are laid out the way
|
||||
* words are laid out in a line, based on the container's
|
||||
* <tt>ComponentOrientation</tt> property. If the container's
|
||||
* <tt>ComponentOrientation</tt> is horizontal then components are laid out
|
||||
* horizontally, otherwise they are laid out vertically. For horizontal
|
||||
* orientations, if the container's <tt>ComponentOrientation</tt> is left to
|
||||
* right then components are laid out left to right, otherwise they are laid
|
||||
* out right to left. For vertical orientations components are always laid out
|
||||
* from top to bottom.</blockquote>
|
||||
*
|
||||
* <blockquote><b><tt>PAGE_AXIS</tt></b> - Components are laid out the way
|
||||
* text lines are laid out on a page, based on the container's
|
||||
* <tt>ComponentOrientation</tt> property. If the container's
|
||||
* <tt>ComponentOrientation</tt> is horizontal then components are laid out
|
||||
* vertically, otherwise they are laid out horizontally. For horizontal
|
||||
* orientations, if the container's <tt>ComponentOrientation</tt> is left to
|
||||
* right then components are laid out left to right, otherwise they are laid
|
||||
* out right to left. For vertical orientations components are always
|
||||
* laid out from top to bottom.</blockquote>
|
||||
* <p>
|
||||
* For all directions, components are arranged in the same order as they were
|
||||
* added to the container.
|
||||
* <p>
|
||||
* BoxLayout attempts to arrange components
|
||||
* at their preferred widths (for horizontal layout)
|
||||
* or heights (for vertical layout).
|
||||
* For a horizontal layout,
|
||||
* if not all the components are the same height,
|
||||
* BoxLayout attempts to make all the components
|
||||
* as high as the highest component.
|
||||
* If that's not possible for a particular component,
|
||||
* then BoxLayout aligns that component vertically,
|
||||
* according to the component's Y alignment.
|
||||
* By default, a component has a Y alignment of 0.5,
|
||||
* which means that the vertical center of the component
|
||||
* should have the same Y coordinate as
|
||||
* the vertical centers of other components with 0.5 Y alignment.
|
||||
* <p>
|
||||
* Similarly, for a vertical layout,
|
||||
* BoxLayout attempts to make all components in the column
|
||||
* as wide as the widest component.
|
||||
* If that fails, it aligns them horizontally
|
||||
* according to their X alignments. For <code>PAGE_AXIS</code> layout,
|
||||
* horizontal alignment is done based on the leading edge of the component.
|
||||
* In other words, an X alignment value of 0.0 means the left edge of a
|
||||
* component if the container's <code>ComponentOrientation</code> is left to
|
||||
* right and it means the right edge of the component otherwise.
|
||||
* <p>
|
||||
* Instead of using BoxLayout directly, many programs use the Box class.
|
||||
* The Box class is a lightweight container that uses a BoxLayout.
|
||||
* It also provides handy methods to help you use BoxLayout well.
|
||||
* Adding components to multiple nested boxes is a powerful way to get
|
||||
* the arrangement you want.
|
||||
* <p>
|
||||
* For further information and examples see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see Box
|
||||
* @see java.awt.ComponentOrientation
|
||||
* @see JComponent#getAlignmentX
|
||||
* @see JComponent#getAlignmentY
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class BoxLayout implements LayoutManager2, Serializable {
|
||||
|
||||
/**
|
||||
* Specifies that components should be laid out left to right.
|
||||
*/
|
||||
public static final int X_AXIS = 0;
|
||||
|
||||
/**
|
||||
* Specifies that components should be laid out top to bottom.
|
||||
*/
|
||||
public static final int Y_AXIS = 1;
|
||||
|
||||
/**
|
||||
* Specifies that components should be laid out in the direction of
|
||||
* a line of text as determined by the target container's
|
||||
* <code>ComponentOrientation</code> property.
|
||||
*/
|
||||
public static final int LINE_AXIS = 2;
|
||||
|
||||
/**
|
||||
* Specifies that components should be laid out in the direction that
|
||||
* lines flow across a page as determined by the target container's
|
||||
* <code>ComponentOrientation</code> property.
|
||||
*/
|
||||
public static final int PAGE_AXIS = 3;
|
||||
|
||||
/**
|
||||
* Creates a layout manager that will lay out components along the
|
||||
* given axis.
|
||||
*
|
||||
* @param target the container that needs to be laid out
|
||||
* @param axis the axis to lay out components along. Can be one of:
|
||||
* <code>BoxLayout.X_AXIS</code>,
|
||||
* <code>BoxLayout.Y_AXIS</code>,
|
||||
* <code>BoxLayout.LINE_AXIS</code> or
|
||||
* <code>BoxLayout.PAGE_AXIS</code>
|
||||
*
|
||||
* @exception AWTError if the value of <code>axis</code> is invalid
|
||||
*/
|
||||
@ConstructorProperties({"target", "axis"})
|
||||
public BoxLayout(Container target, int axis) {
|
||||
if (axis != X_AXIS && axis != Y_AXIS &&
|
||||
axis != LINE_AXIS && axis != PAGE_AXIS) {
|
||||
throw new AWTError("Invalid axis");
|
||||
}
|
||||
this.axis = axis;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BoxLayout that
|
||||
* produces debugging messages.
|
||||
*
|
||||
* @param target the container that needs to be laid out
|
||||
* @param axis the axis to lay out components along. Can be one of:
|
||||
* <code>BoxLayout.X_AXIS</code>,
|
||||
* <code>BoxLayout.Y_AXIS</code>,
|
||||
* <code>BoxLayout.LINE_AXIS</code> or
|
||||
* <code>BoxLayout.PAGE_AXIS</code>
|
||||
*
|
||||
* @param dbg the stream to which debugging messages should be sent,
|
||||
* null if none
|
||||
*/
|
||||
BoxLayout(Container target, int axis, PrintStream dbg) {
|
||||
this(target, axis);
|
||||
this.dbg = dbg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the container that uses this layout manager.
|
||||
*
|
||||
* @return the container that uses this layout manager
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public final Container getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the axis that was used to lay out components.
|
||||
* Returns one of:
|
||||
* <code>BoxLayout.X_AXIS</code>,
|
||||
* <code>BoxLayout.Y_AXIS</code>,
|
||||
* <code>BoxLayout.LINE_AXIS</code> or
|
||||
* <code>BoxLayout.PAGE_AXIS</code>
|
||||
*
|
||||
* @return the axis that was used to lay out components
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public final int getAxis() {
|
||||
return this.axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that a child has changed its layout related information,
|
||||
* and thus any cached calculations should be flushed.
|
||||
* <p>
|
||||
* This method is called by AWT when the invalidate method is called
|
||||
* on the Container. Since the invalidate method may be called
|
||||
* asynchronously to the event thread, this method may be called
|
||||
* asynchronously.
|
||||
*
|
||||
* @param target the affected container
|
||||
*
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
*/
|
||||
public synchronized void invalidateLayout(Container target) {
|
||||
checkContainer(target);
|
||||
xChildren = null;
|
||||
yChildren = null;
|
||||
xTotal = null;
|
||||
yTotal = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this class.
|
||||
*
|
||||
* @param name the name of the component
|
||||
* @param comp the component
|
||||
*/
|
||||
public void addLayoutComponent(String name, Component comp) {
|
||||
invalidateLayout(comp.getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this class.
|
||||
*
|
||||
* @param comp the component
|
||||
*/
|
||||
public void removeLayoutComponent(Component comp) {
|
||||
invalidateLayout(comp.getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used by this class.
|
||||
*
|
||||
* @param comp the component
|
||||
* @param constraints constraints
|
||||
*/
|
||||
public void addLayoutComponent(Component comp, Object constraints) {
|
||||
invalidateLayout(comp.getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred dimensions for this layout, given the components
|
||||
* in the specified target container.
|
||||
*
|
||||
* @param target the container that needs to be laid out
|
||||
* @return the dimensions >= 0 && <= Integer.MAX_VALUE
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
* @see Container
|
||||
* @see #minimumLayoutSize
|
||||
* @see #maximumLayoutSize
|
||||
*/
|
||||
public Dimension preferredLayoutSize(Container target) {
|
||||
Dimension size;
|
||||
synchronized(this) {
|
||||
checkContainer(target);
|
||||
checkRequests();
|
||||
size = new Dimension(xTotal.preferred, yTotal.preferred);
|
||||
}
|
||||
|
||||
Insets insets = target.getInsets();
|
||||
size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
|
||||
size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum dimensions needed to lay out the components
|
||||
* contained in the specified target container.
|
||||
*
|
||||
* @param target the container that needs to be laid out
|
||||
* @return the dimensions >= 0 && <= Integer.MAX_VALUE
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
* @see #preferredLayoutSize
|
||||
* @see #maximumLayoutSize
|
||||
*/
|
||||
public Dimension minimumLayoutSize(Container target) {
|
||||
Dimension size;
|
||||
synchronized(this) {
|
||||
checkContainer(target);
|
||||
checkRequests();
|
||||
size = new Dimension(xTotal.minimum, yTotal.minimum);
|
||||
}
|
||||
|
||||
Insets insets = target.getInsets();
|
||||
size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
|
||||
size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum dimensions the target container can use
|
||||
* to lay out the components it contains.
|
||||
*
|
||||
* @param target the container that needs to be laid out
|
||||
* @return the dimensions >= 0 && <= Integer.MAX_VALUE
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
* @see #preferredLayoutSize
|
||||
* @see #minimumLayoutSize
|
||||
*/
|
||||
public Dimension maximumLayoutSize(Container target) {
|
||||
Dimension size;
|
||||
synchronized(this) {
|
||||
checkContainer(target);
|
||||
checkRequests();
|
||||
size = new Dimension(xTotal.maximum, yTotal.maximum);
|
||||
}
|
||||
|
||||
Insets insets = target.getInsets();
|
||||
size.width = (int) Math.min((long) size.width + (long) insets.left + (long) insets.right, Integer.MAX_VALUE);
|
||||
size.height = (int) Math.min((long) size.height + (long) insets.top + (long) insets.bottom, Integer.MAX_VALUE);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alignment along the X axis for the container.
|
||||
* If the box is horizontal, the default
|
||||
* alignment will be returned. Otherwise, the alignment needed
|
||||
* to place the children along the X axis will be returned.
|
||||
*
|
||||
* @param target the container
|
||||
* @return the alignment >= 0.0f && <= 1.0f
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
*/
|
||||
public synchronized float getLayoutAlignmentX(Container target) {
|
||||
checkContainer(target);
|
||||
checkRequests();
|
||||
return xTotal.alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alignment along the Y axis for the container.
|
||||
* If the box is vertical, the default
|
||||
* alignment will be returned. Otherwise, the alignment needed
|
||||
* to place the children along the Y axis will be returned.
|
||||
*
|
||||
* @param target the container
|
||||
* @return the alignment >= 0.0f && <= 1.0f
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
*/
|
||||
public synchronized float getLayoutAlignmentY(Container target) {
|
||||
checkContainer(target);
|
||||
checkRequests();
|
||||
return yTotal.alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the AWT <!-- XXX CHECK! --> when the specified container
|
||||
* needs to be laid out.
|
||||
*
|
||||
* @param target the container to lay out
|
||||
*
|
||||
* @exception AWTError if the target isn't the container specified to the
|
||||
* BoxLayout constructor
|
||||
*/
|
||||
public void layoutContainer(Container target) {
|
||||
checkContainer(target);
|
||||
int nChildren = target.getComponentCount();
|
||||
int[] xOffsets = new int[nChildren];
|
||||
int[] xSpans = new int[nChildren];
|
||||
int[] yOffsets = new int[nChildren];
|
||||
int[] ySpans = new int[nChildren];
|
||||
|
||||
Dimension alloc = target.getSize();
|
||||
Insets in = target.getInsets();
|
||||
alloc.width -= in.left + in.right;
|
||||
alloc.height -= in.top + in.bottom;
|
||||
|
||||
// Resolve axis to an absolute value (either X_AXIS or Y_AXIS)
|
||||
ComponentOrientation o = target.getComponentOrientation();
|
||||
int absoluteAxis = resolveAxis( axis, o );
|
||||
boolean ltr = (absoluteAxis != axis) ? o.isLeftToRight() : true;
|
||||
|
||||
|
||||
// determine the child placements
|
||||
synchronized(this) {
|
||||
checkRequests();
|
||||
|
||||
if (absoluteAxis == X_AXIS) {
|
||||
SizeRequirements.calculateTiledPositions(alloc.width, xTotal,
|
||||
xChildren, xOffsets,
|
||||
xSpans, ltr);
|
||||
SizeRequirements.calculateAlignedPositions(alloc.height, yTotal,
|
||||
yChildren, yOffsets,
|
||||
ySpans);
|
||||
} else {
|
||||
SizeRequirements.calculateAlignedPositions(alloc.width, xTotal,
|
||||
xChildren, xOffsets,
|
||||
xSpans, ltr);
|
||||
SizeRequirements.calculateTiledPositions(alloc.height, yTotal,
|
||||
yChildren, yOffsets,
|
||||
ySpans);
|
||||
}
|
||||
}
|
||||
|
||||
// flush changes to the container
|
||||
for (int i = 0; i < nChildren; i++) {
|
||||
Component c = target.getComponent(i);
|
||||
c.setBounds((int) Math.min((long) in.left + (long) xOffsets[i], Integer.MAX_VALUE),
|
||||
(int) Math.min((long) in.top + (long) yOffsets[i], Integer.MAX_VALUE),
|
||||
xSpans[i], ySpans[i]);
|
||||
|
||||
}
|
||||
if (dbg != null) {
|
||||
for (int i = 0; i < nChildren; i++) {
|
||||
Component c = target.getComponent(i);
|
||||
dbg.println(c.toString());
|
||||
dbg.println("X: " + xChildren[i]);
|
||||
dbg.println("Y: " + yChildren[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void checkContainer(Container target) {
|
||||
if (this.target != target) {
|
||||
throw new AWTError("BoxLayout can't be shared");
|
||||
}
|
||||
}
|
||||
|
||||
void checkRequests() {
|
||||
if (xChildren == null || yChildren == null) {
|
||||
// The requests have been invalidated... recalculate
|
||||
// the request information.
|
||||
int n = target.getComponentCount();
|
||||
xChildren = new SizeRequirements[n];
|
||||
yChildren = new SizeRequirements[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
Component c = target.getComponent(i);
|
||||
if (!c.isVisible()) {
|
||||
xChildren[i] = new SizeRequirements(0,0,0, c.getAlignmentX());
|
||||
yChildren[i] = new SizeRequirements(0,0,0, c.getAlignmentY());
|
||||
continue;
|
||||
}
|
||||
Dimension min = c.getMinimumSize();
|
||||
Dimension typ = c.getPreferredSize();
|
||||
Dimension max = c.getMaximumSize();
|
||||
xChildren[i] = new SizeRequirements(min.width, typ.width,
|
||||
max.width,
|
||||
c.getAlignmentX());
|
||||
yChildren[i] = new SizeRequirements(min.height, typ.height,
|
||||
max.height,
|
||||
c.getAlignmentY());
|
||||
}
|
||||
|
||||
// Resolve axis to an absolute value (either X_AXIS or Y_AXIS)
|
||||
int absoluteAxis = resolveAxis(axis,target.getComponentOrientation());
|
||||
|
||||
if (absoluteAxis == X_AXIS) {
|
||||
xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
|
||||
yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
|
||||
} else {
|
||||
xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
|
||||
yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one of the 4 axis values, resolve it to an absolute axis.
|
||||
* The relative axis values, PAGE_AXIS and LINE_AXIS are converted
|
||||
* to their absolute couterpart given the target's ComponentOrientation
|
||||
* value. The absolute axes, X_AXIS and Y_AXIS are returned unmodified.
|
||||
*
|
||||
* @param axis the axis to resolve
|
||||
* @param o the ComponentOrientation to resolve against
|
||||
* @return the resolved axis
|
||||
*/
|
||||
private int resolveAxis( int axis, ComponentOrientation o ) {
|
||||
int absoluteAxis;
|
||||
if( axis == LINE_AXIS ) {
|
||||
absoluteAxis = o.isHorizontal() ? X_AXIS : Y_AXIS;
|
||||
} else if( axis == PAGE_AXIS ) {
|
||||
absoluteAxis = o.isHorizontal() ? Y_AXIS : X_AXIS;
|
||||
} else {
|
||||
absoluteAxis = axis;
|
||||
}
|
||||
return absoluteAxis;
|
||||
}
|
||||
|
||||
|
||||
private int axis;
|
||||
private Container target;
|
||||
|
||||
private transient SizeRequirements[] xChildren;
|
||||
private transient SizeRequirements[] yChildren;
|
||||
private transient SizeRequirements xTotal;
|
||||
private transient SizeRequirements yTotal;
|
||||
|
||||
private transient PrintStream dbg;
|
||||
}
|
||||
952
jdkSrc/jdk8/javax/swing/BufferStrategyPaintManager.java
Normal file
952
jdkSrc/jdk8/javax/swing/BufferStrategyPaintManager.java
Normal file
@@ -0,0 +1,952 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
|
||||
import com.sun.java.swing.SwingUtilities3;
|
||||
|
||||
import sun.awt.SubRegionShowable;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/**
|
||||
* A PaintManager implementation that uses a BufferStrategy for
|
||||
* rendering.
|
||||
*
|
||||
* @author Scott Violet
|
||||
*/
|
||||
class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
||||
//
|
||||
// All drawing is done to a BufferStrategy. At the end of painting
|
||||
// (endPaint) the region that was painted is flushed to the screen
|
||||
// (using BufferStrategy.show).
|
||||
//
|
||||
// PaintManager.show is overriden to show directly from the
|
||||
// BufferStrategy (when using blit), if successful true is
|
||||
// returned and a paint event will not be generated. To avoid
|
||||
// showing from the buffer while painting a locking scheme is
|
||||
// implemented. When beginPaint is invoked the field painting is
|
||||
// set to true. If painting is true and show is invoked we
|
||||
// immediately return false. This is done to avoid blocking the
|
||||
// toolkit thread while painting happens. In a similar way when
|
||||
// show is invoked the field showing is set to true, beginPaint
|
||||
// will then block until showing is true. This scheme ensures we
|
||||
// only ever have one thread using the BufferStrategy and it also
|
||||
// ensures the toolkit thread remains as responsive as possible.
|
||||
//
|
||||
// If we're using a flip strategy the contents of the backbuffer may
|
||||
// have changed and so show only attempts to show from the backbuffer
|
||||
// if we get a blit strategy.
|
||||
//
|
||||
|
||||
//
|
||||
// Methods used to create BufferStrategy for Applets.
|
||||
//
|
||||
private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
|
||||
private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
|
||||
|
||||
private static final PlatformLogger LOGGER = PlatformLogger.getLogger(
|
||||
"javax.swing.BufferStrategyPaintManager");
|
||||
|
||||
/**
|
||||
* List of BufferInfos. We don't use a Map primarily because
|
||||
* there are typically only a handful of top level components making
|
||||
* a Map overkill.
|
||||
*/
|
||||
private ArrayList<BufferInfo> bufferInfos;
|
||||
|
||||
/**
|
||||
* Indicates <code>beginPaint</code> has been invoked. This is
|
||||
* set to true for the life of beginPaint/endPaint pair.
|
||||
*/
|
||||
private boolean painting;
|
||||
/**
|
||||
* Indicates we're in the process of showing. All painting, on the EDT,
|
||||
* is blocked while this is true.
|
||||
*/
|
||||
private boolean showing;
|
||||
|
||||
//
|
||||
// Region that we need to flush. When beginPaint is called these are
|
||||
// reset and any subsequent calls to paint/copyArea then update these
|
||||
// fields accordingly. When endPaint is called we then try and show
|
||||
// the accumulated region.
|
||||
// These fields are in the coordinate system of the root.
|
||||
//
|
||||
private int accumulatedX;
|
||||
private int accumulatedY;
|
||||
private int accumulatedMaxX;
|
||||
private int accumulatedMaxY;
|
||||
|
||||
//
|
||||
// The following fields are set by prepare
|
||||
//
|
||||
|
||||
/**
|
||||
* Farthest JComponent ancestor for the current paint/copyArea.
|
||||
*/
|
||||
private JComponent rootJ;
|
||||
/**
|
||||
* Location of component being painted relative to root.
|
||||
*/
|
||||
private int xOffset;
|
||||
/**
|
||||
* Location of component being painted relative to root.
|
||||
*/
|
||||
private int yOffset;
|
||||
/**
|
||||
* Graphics from the BufferStrategy.
|
||||
*/
|
||||
private Graphics bsg;
|
||||
/**
|
||||
* BufferStrategy currently being used.
|
||||
*/
|
||||
private BufferStrategy bufferStrategy;
|
||||
/**
|
||||
* BufferInfo corresponding to root.
|
||||
*/
|
||||
private BufferInfo bufferInfo;
|
||||
|
||||
/**
|
||||
* Set to true if the bufferInfo needs to be disposed when current
|
||||
* paint loop is done.
|
||||
*/
|
||||
private boolean disposeBufferOnEnd;
|
||||
|
||||
private static Method getGetBufferStrategyMethod() {
|
||||
if (COMPONENT_GET_BUFFER_STRATEGY_METHOD == null) {
|
||||
getMethods();
|
||||
}
|
||||
return COMPONENT_GET_BUFFER_STRATEGY_METHOD;
|
||||
}
|
||||
|
||||
private static Method getCreateBufferStrategyMethod() {
|
||||
if (COMPONENT_CREATE_BUFFER_STRATEGY_METHOD == null) {
|
||||
getMethods();
|
||||
}
|
||||
return COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
|
||||
}
|
||||
|
||||
private static void getMethods() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
try {
|
||||
COMPONENT_CREATE_BUFFER_STRATEGY_METHOD = Component.class.
|
||||
getDeclaredMethod("createBufferStrategy",
|
||||
new Class[] { int.class,
|
||||
BufferCapabilities.class });
|
||||
COMPONENT_CREATE_BUFFER_STRATEGY_METHOD.
|
||||
setAccessible(true);
|
||||
COMPONENT_GET_BUFFER_STRATEGY_METHOD = Component.class.
|
||||
getDeclaredMethod("getBufferStrategy");
|
||||
COMPONENT_GET_BUFFER_STRATEGY_METHOD.setAccessible(true);
|
||||
} catch (SecurityException e) {
|
||||
assert false;
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
assert false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BufferStrategyPaintManager() {
|
||||
bufferInfos = new ArrayList<BufferInfo>(1);
|
||||
}
|
||||
|
||||
//
|
||||
// PaintManager methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Cleans up any created BufferStrategies.
|
||||
*/
|
||||
protected void dispose() {
|
||||
// dipose can be invoked at any random time. To avoid
|
||||
// threading dependancies we do the actual diposing via an
|
||||
// invokeLater.
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
java.util.List<BufferInfo> bufferInfos;
|
||||
synchronized(BufferStrategyPaintManager.this) {
|
||||
while (showing) {
|
||||
try {
|
||||
BufferStrategyPaintManager.this.wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
bufferInfos = BufferStrategyPaintManager.this.bufferInfos;
|
||||
BufferStrategyPaintManager.this.bufferInfos = null;
|
||||
}
|
||||
dispose(bufferInfos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dispose(java.util.List<BufferInfo> bufferInfos) {
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("BufferStrategyPaintManager disposed",
|
||||
new RuntimeException());
|
||||
}
|
||||
if (bufferInfos != null) {
|
||||
for (BufferInfo bufferInfo : bufferInfos) {
|
||||
bufferInfo.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the specified region of the back buffer. This will return
|
||||
* true if successful, false otherwise. This is invoked on the
|
||||
* toolkit thread in response to an expose event.
|
||||
*/
|
||||
public boolean show(Container c, int x, int y, int w, int h) {
|
||||
synchronized(this) {
|
||||
if (painting) {
|
||||
// Don't show from backbuffer while in the process of
|
||||
// painting.
|
||||
return false;
|
||||
}
|
||||
showing = true;
|
||||
}
|
||||
try {
|
||||
BufferInfo info = getBufferInfo(c);
|
||||
BufferStrategy bufferStrategy;
|
||||
if (info != null && info.isInSync() &&
|
||||
(bufferStrategy = info.getBufferStrategy(false)) != null) {
|
||||
SubRegionShowable bsSubRegion =
|
||||
(SubRegionShowable)bufferStrategy;
|
||||
boolean paintAllOnExpose = info.getPaintAllOnExpose();
|
||||
info.setPaintAllOnExpose(false);
|
||||
if (bsSubRegion.showIfNotLost(x, y, (x + w), (y + h))) {
|
||||
return !paintAllOnExpose;
|
||||
}
|
||||
// Mark the buffer as needing to be repainted. We don't
|
||||
// immediately do a repaint as this method will return false
|
||||
// indicating a PaintEvent should be generated which will
|
||||
// trigger a complete repaint.
|
||||
bufferInfo.setContentsLostDuringExpose(true);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
synchronized(this) {
|
||||
showing = false;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean paint(JComponent paintingComponent,
|
||||
JComponent bufferComponent, Graphics g,
|
||||
int x, int y, int w, int h) {
|
||||
Container root = fetchRoot(paintingComponent);
|
||||
|
||||
if (prepare(paintingComponent, root, true, x, y, w, h)) {
|
||||
if ((g instanceof SunGraphics2D) &&
|
||||
((SunGraphics2D)g).getDestination() == root) {
|
||||
// BufferStrategy may have already constrained the Graphics. To
|
||||
// account for that we revert the constrain, then apply a
|
||||
// constrain for Swing on top of that.
|
||||
int cx = ((SunGraphics2D)bsg).constrainX;
|
||||
int cy = ((SunGraphics2D)bsg).constrainY;
|
||||
if (cx != 0 || cy != 0) {
|
||||
bsg.translate(-cx, -cy);
|
||||
}
|
||||
((SunGraphics2D)bsg).constrain(xOffset + cx, yOffset + cy,
|
||||
x + w, y + h);
|
||||
bsg.setClip(x, y, w, h);
|
||||
paintingComponent.paintToOffscreen(bsg, x, y, w, h,
|
||||
x + w, y + h);
|
||||
accumulate(xOffset + x, yOffset + y, w, h);
|
||||
return true;
|
||||
} else {
|
||||
// Assume they are going to eventually render to the screen.
|
||||
// This disables showing from backbuffer until a complete
|
||||
// repaint occurs.
|
||||
bufferInfo.setInSync(false);
|
||||
// Fall through to old rendering.
|
||||
}
|
||||
}
|
||||
// Invalid root, do what Swing has always done.
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("prepare failed");
|
||||
}
|
||||
return super.paint(paintingComponent, bufferComponent, g, x, y, w, h);
|
||||
}
|
||||
|
||||
public void copyArea(JComponent c, Graphics g, int x, int y, int w, int h,
|
||||
int deltaX, int deltaY, boolean clip) {
|
||||
// Note: this method is only called internally and we know that
|
||||
// g is from a heavyweight Component, so no check is necessary as
|
||||
// it is in paint() above.
|
||||
//
|
||||
// If the buffer isn't in sync there is no point in doing a copyArea,
|
||||
// it has garbage.
|
||||
Container root = fetchRoot(c);
|
||||
|
||||
if (prepare(c, root, false, 0, 0, 0, 0) && bufferInfo.isInSync()) {
|
||||
if (clip) {
|
||||
Rectangle cBounds = c.getVisibleRect();
|
||||
int relX = xOffset + x;
|
||||
int relY = yOffset + y;
|
||||
bsg.clipRect(xOffset + cBounds.x,
|
||||
yOffset + cBounds.y,
|
||||
cBounds.width, cBounds.height);
|
||||
bsg.copyArea(relX, relY, w, h, deltaX, deltaY);
|
||||
}
|
||||
else {
|
||||
bsg.copyArea(xOffset + x, yOffset + y, w, h, deltaX,
|
||||
deltaY);
|
||||
}
|
||||
accumulate(x + xOffset + deltaX, y + yOffset + deltaY, w, h);
|
||||
} else {
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("copyArea: prepare failed or not in sync");
|
||||
}
|
||||
// Prepare failed, or not in sync. By calling super.copyArea
|
||||
// we'll copy on screen. We need to flush any pending paint to
|
||||
// the screen otherwise we'll do a copyArea on the wrong thing.
|
||||
if (!flushAccumulatedRegion()) {
|
||||
// Flush failed, copyArea will be copying garbage,
|
||||
// force repaint of all.
|
||||
rootJ.repaint();
|
||||
} else {
|
||||
super.copyArea(c, g, x, y, w, h, deltaX, deltaY, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beginPaint() {
|
||||
synchronized(this) {
|
||||
painting = true;
|
||||
// Make sure another thread isn't attempting to show from
|
||||
// the back buffer.
|
||||
while(showing) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
LOGGER.finest("beginPaint");
|
||||
}
|
||||
// Reset the area that needs to be painted.
|
||||
resetAccumulated();
|
||||
}
|
||||
|
||||
public void endPaint() {
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
LOGGER.finest("endPaint: region " + accumulatedX + " " +
|
||||
accumulatedY + " " + accumulatedMaxX + " " +
|
||||
accumulatedMaxY);
|
||||
}
|
||||
if (painting) {
|
||||
if (!flushAccumulatedRegion()) {
|
||||
if (!isRepaintingRoot()) {
|
||||
repaintRoot(rootJ);
|
||||
}
|
||||
else {
|
||||
// Contents lost twice in a row, punt.
|
||||
resetDoubleBufferPerWindow();
|
||||
// In case we've left junk on the screen, force a repaint.
|
||||
rootJ.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferInfo toDispose = null;
|
||||
synchronized(this) {
|
||||
painting = false;
|
||||
if (disposeBufferOnEnd) {
|
||||
disposeBufferOnEnd = false;
|
||||
toDispose = bufferInfo;
|
||||
bufferInfos.remove(toDispose);
|
||||
}
|
||||
}
|
||||
if (toDispose != null) {
|
||||
toDispose.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the BufferStrategy to the screen.
|
||||
*
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
private boolean flushAccumulatedRegion() {
|
||||
boolean success = true;
|
||||
if (accumulatedX != Integer.MAX_VALUE) {
|
||||
SubRegionShowable bsSubRegion = (SubRegionShowable)bufferStrategy;
|
||||
boolean contentsLost = bufferStrategy.contentsLost();
|
||||
if (!contentsLost) {
|
||||
bsSubRegion.show(accumulatedX, accumulatedY,
|
||||
accumulatedMaxX, accumulatedMaxY);
|
||||
contentsLost = bufferStrategy.contentsLost();
|
||||
}
|
||||
if (contentsLost) {
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("endPaint: contents lost");
|
||||
}
|
||||
// Shown region was bogus, mark buffer as out of sync.
|
||||
bufferInfo.setInSync(false);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
resetAccumulated();
|
||||
return success;
|
||||
}
|
||||
|
||||
private void resetAccumulated() {
|
||||
accumulatedX = Integer.MAX_VALUE;
|
||||
accumulatedY = Integer.MAX_VALUE;
|
||||
accumulatedMaxX = 0;
|
||||
accumulatedMaxY = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the double buffering or useTrueDoubleBuffering
|
||||
* changes for a JRootPane. If the rootpane is not double
|
||||
* buffered, or true double buffering changes we throw out any
|
||||
* cache we may have.
|
||||
*/
|
||||
public void doubleBufferingChanged(final JRootPane rootPane) {
|
||||
if ((!rootPane.isDoubleBuffered() ||
|
||||
!rootPane.getUseTrueDoubleBuffering()) &&
|
||||
rootPane.getParent() != null) {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
Runnable updater = new Runnable() {
|
||||
public void run() {
|
||||
doubleBufferingChanged0(rootPane);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(updater);
|
||||
}
|
||||
else {
|
||||
doubleBufferingChanged0(rootPane);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the work for doubleBufferingChanged.
|
||||
*/
|
||||
private void doubleBufferingChanged0(JRootPane rootPane) {
|
||||
// This will only happen on the EDT.
|
||||
BufferInfo info;
|
||||
synchronized(this) {
|
||||
// Make sure another thread isn't attempting to show from
|
||||
// the back buffer.
|
||||
while(showing) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
info = getBufferInfo(rootPane.getParent());
|
||||
if (painting && bufferInfo == info) {
|
||||
// We're in the process of painting and the user grabbed
|
||||
// the Graphics. If we dispose now, endPaint will attempt
|
||||
// to show a bogus BufferStrategy. Set a flag so that
|
||||
// endPaint knows it needs to dispose this buffer.
|
||||
disposeBufferOnEnd = true;
|
||||
info = null;
|
||||
} else if (info != null) {
|
||||
bufferInfos.remove(info);
|
||||
}
|
||||
}
|
||||
if (info != null) {
|
||||
info.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates information common to paint/copyArea.
|
||||
*
|
||||
* @return true if should use buffering per window in painting.
|
||||
*/
|
||||
private boolean prepare(JComponent c, Container root, boolean isPaint, int x, int y,
|
||||
int w, int h) {
|
||||
if (bsg != null) {
|
||||
bsg.dispose();
|
||||
bsg = null;
|
||||
}
|
||||
bufferStrategy = null;
|
||||
if (root != null) {
|
||||
boolean contentsLost = false;
|
||||
BufferInfo bufferInfo = getBufferInfo(root);
|
||||
if (bufferInfo == null) {
|
||||
contentsLost = true;
|
||||
bufferInfo = new BufferInfo(root);
|
||||
bufferInfos.add(bufferInfo);
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("prepare: new BufferInfo: " + root);
|
||||
}
|
||||
}
|
||||
this.bufferInfo = bufferInfo;
|
||||
if (!bufferInfo.hasBufferStrategyChanged()) {
|
||||
bufferStrategy = bufferInfo.getBufferStrategy(true);
|
||||
if (bufferStrategy != null) {
|
||||
bsg = bufferStrategy.getDrawGraphics();
|
||||
if (bufferStrategy.contentsRestored()) {
|
||||
contentsLost = true;
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("prepare: contents restored in prepare");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Couldn't create BufferStrategy, fallback to normal
|
||||
// painting.
|
||||
return false;
|
||||
}
|
||||
if (bufferInfo.getContentsLostDuringExpose()) {
|
||||
contentsLost = true;
|
||||
bufferInfo.setContentsLostDuringExpose(false);
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("prepare: contents lost on expose");
|
||||
}
|
||||
}
|
||||
if (isPaint && c == rootJ && x == 0 && y == 0 &&
|
||||
c.getWidth() == w && c.getHeight() == h) {
|
||||
bufferInfo.setInSync(true);
|
||||
}
|
||||
else if (contentsLost) {
|
||||
// We either recreated the BufferStrategy, or the contents
|
||||
// of the buffer strategy were restored. We need to
|
||||
// repaint the root pane so that the back buffer is in sync
|
||||
// again.
|
||||
bufferInfo.setInSync(false);
|
||||
if (!isRepaintingRoot()) {
|
||||
repaintRoot(rootJ);
|
||||
}
|
||||
else {
|
||||
// Contents lost twice in a row, punt
|
||||
resetDoubleBufferPerWindow();
|
||||
}
|
||||
}
|
||||
return (bufferInfos != null);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Container fetchRoot(JComponent c) {
|
||||
boolean encounteredHW = false;
|
||||
rootJ = c;
|
||||
Container root = c;
|
||||
xOffset = yOffset = 0;
|
||||
while (root != null &&
|
||||
(!(root instanceof Window) &&
|
||||
!SunToolkit.isInstanceOf(root, "java.applet.Applet"))) {
|
||||
xOffset += root.getX();
|
||||
yOffset += root.getY();
|
||||
root = root.getParent();
|
||||
if (root != null) {
|
||||
if (root instanceof JComponent) {
|
||||
rootJ = (JComponent)root;
|
||||
}
|
||||
else if (!root.isLightweight()) {
|
||||
if (!encounteredHW) {
|
||||
encounteredHW = true;
|
||||
}
|
||||
else {
|
||||
// We've encountered two hws now and may have
|
||||
// a containment hierarchy with lightweights containing
|
||||
// heavyweights containing other lightweights.
|
||||
// Heavyweights poke holes in lightweight
|
||||
// rendering so that if we call show on the BS
|
||||
// (which is associated with the Window) you will
|
||||
// not see the contents over any child
|
||||
// heavyweights. If we didn't do this when we
|
||||
// went to show the descendants of the nested hw
|
||||
// you would see nothing, so, we bail out here.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((root instanceof RootPaneContainer) &&
|
||||
(rootJ instanceof JRootPane)) {
|
||||
// We're in a Swing heavyeight (JFrame/JWindow...), use double
|
||||
// buffering if double buffering enabled on the JRootPane and
|
||||
// the JRootPane wants true double buffering.
|
||||
if (rootJ.isDoubleBuffered() &&
|
||||
((JRootPane)rootJ).getUseTrueDoubleBuffering()) {
|
||||
// Whether or not a component is double buffered is a
|
||||
// bit tricky with Swing. This gives a good approximation
|
||||
// of the various ways to turn on double buffering for
|
||||
// components.
|
||||
return root;
|
||||
}
|
||||
}
|
||||
// Don't do true double buffering.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off double buffering per window.
|
||||
*/
|
||||
private void resetDoubleBufferPerWindow() {
|
||||
if (bufferInfos != null) {
|
||||
dispose(bufferInfos);
|
||||
bufferInfos = null;
|
||||
repaintManager.setPaintManager(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BufferInfo for the specified root or null if one
|
||||
* hasn't been created yet.
|
||||
*/
|
||||
private BufferInfo getBufferInfo(Container root) {
|
||||
for (int counter = bufferInfos.size() - 1; counter >= 0; counter--) {
|
||||
BufferInfo bufferInfo = bufferInfos.get(counter);
|
||||
Container biRoot = bufferInfo.getRoot();
|
||||
if (biRoot == null) {
|
||||
// Window gc'ed
|
||||
bufferInfos.remove(counter);
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("BufferInfo pruned, root null");
|
||||
}
|
||||
}
|
||||
else if (biRoot == root) {
|
||||
return bufferInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void accumulate(int x, int y, int w, int h) {
|
||||
accumulatedX = Math.min(x, accumulatedX);
|
||||
accumulatedY = Math.min(y, accumulatedY);
|
||||
accumulatedMaxX = Math.max(accumulatedMaxX, x + w);
|
||||
accumulatedMaxY = Math.max(accumulatedMaxY, y + h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* BufferInfo is used to track the BufferStrategy being used for
|
||||
* a particular Component. In addition to tracking the BufferStrategy
|
||||
* it will install a WindowListener and ComponentListener. When the
|
||||
* component is hidden/iconified the buffer is marked as needing to be
|
||||
* completely repainted.
|
||||
*/
|
||||
private class BufferInfo extends ComponentAdapter implements
|
||||
WindowListener {
|
||||
// NOTE: This class does NOT hold a direct reference to the root, if it
|
||||
// did there would be a cycle between the BufferPerWindowPaintManager
|
||||
// and the Window so that it could never be GC'ed
|
||||
//
|
||||
// Reference to BufferStrategy is referenced via WeakReference for
|
||||
// same reason.
|
||||
private WeakReference<BufferStrategy> weakBS;
|
||||
private WeakReference<Container> root;
|
||||
// Indicates whether or not the backbuffer and display are in sync.
|
||||
// This is set to true when a full repaint on the rootpane is done.
|
||||
private boolean inSync;
|
||||
// Indicates the contents were lost during and expose event.
|
||||
private boolean contentsLostDuringExpose;
|
||||
// Indicates we need to generate a paint event on expose.
|
||||
private boolean paintAllOnExpose;
|
||||
|
||||
|
||||
public BufferInfo(Container root) {
|
||||
this.root = new WeakReference<Container>(root);
|
||||
root.addComponentListener(this);
|
||||
if (root instanceof Window) {
|
||||
((Window)root).addWindowListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPaintAllOnExpose(boolean paintAllOnExpose) {
|
||||
this.paintAllOnExpose = paintAllOnExpose;
|
||||
}
|
||||
|
||||
public boolean getPaintAllOnExpose() {
|
||||
return paintAllOnExpose;
|
||||
}
|
||||
|
||||
public void setContentsLostDuringExpose(boolean value) {
|
||||
contentsLostDuringExpose = value;
|
||||
}
|
||||
|
||||
public boolean getContentsLostDuringExpose() {
|
||||
return contentsLostDuringExpose;
|
||||
}
|
||||
|
||||
public void setInSync(boolean inSync) {
|
||||
this.inSync = inSync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the contents of the buffer strategy
|
||||
* is in sync with the window. This is set to true when the root
|
||||
* pane paints all, and false when contents are lost/restored.
|
||||
*/
|
||||
public boolean isInSync() {
|
||||
return inSync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Root (Window or Applet) that this BufferInfo references.
|
||||
*/
|
||||
public Container getRoot() {
|
||||
return (root == null) ? null : root.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BufferStartegy. This will return null if
|
||||
* the BufferStartegy hasn't been created and <code>create</code> is
|
||||
* false, or if there is a problem in creating the
|
||||
* <code>BufferStartegy</code>.
|
||||
*
|
||||
* @param create If true, and the BufferStartegy is currently null,
|
||||
* one will be created.
|
||||
*/
|
||||
public BufferStrategy getBufferStrategy(boolean create) {
|
||||
BufferStrategy bs = (weakBS == null) ? null : weakBS.get();
|
||||
if (bs == null && create) {
|
||||
bs = createBufferStrategy();
|
||||
if (bs != null) {
|
||||
weakBS = new WeakReference<BufferStrategy>(bs);
|
||||
}
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("getBufferStrategy: created bs: " + bs);
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the buffer strategy of the component differs
|
||||
* from current buffer strategy.
|
||||
*/
|
||||
public boolean hasBufferStrategyChanged() {
|
||||
Container root = getRoot();
|
||||
if (root != null) {
|
||||
BufferStrategy ourBS = null;
|
||||
BufferStrategy componentBS = null;
|
||||
|
||||
ourBS = getBufferStrategy(false);
|
||||
if (root instanceof Window) {
|
||||
componentBS = ((Window)root).getBufferStrategy();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
componentBS = (BufferStrategy)
|
||||
getGetBufferStrategyMethod().invoke(root);
|
||||
} catch (InvocationTargetException ite) {
|
||||
assert false;
|
||||
} catch (IllegalArgumentException iae) {
|
||||
assert false;
|
||||
} catch (IllegalAccessException iae2) {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
if (componentBS != ourBS) {
|
||||
// Component has a different BS, dispose ours.
|
||||
if (ourBS != null) {
|
||||
ourBS.dispose();
|
||||
}
|
||||
weakBS = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the BufferStrategy. If the appropriate system property
|
||||
* has been set we'll try for flip first and then we'll try for
|
||||
* blit.
|
||||
*/
|
||||
private BufferStrategy createBufferStrategy() {
|
||||
Container root = getRoot();
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
BufferStrategy bs = null;
|
||||
if (SwingUtilities3.isVsyncRequested(root)) {
|
||||
bs = createBufferStrategy(root, true);
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("createBufferStrategy: using vsynced strategy");
|
||||
}
|
||||
}
|
||||
if (bs == null) {
|
||||
bs = createBufferStrategy(root, false);
|
||||
}
|
||||
if (!(bs instanceof SubRegionShowable)) {
|
||||
// We do this for two reasons:
|
||||
// 1. So that we know we can cast to SubRegionShowable and
|
||||
// invoke show with the minimal region to update
|
||||
// 2. To avoid the possibility of invoking client code
|
||||
// on the toolkit thread.
|
||||
bs = null;
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
// Creates and returns a buffer strategy. If
|
||||
// there is a problem creating the buffer strategy this will
|
||||
// eat the exception and return null.
|
||||
private BufferStrategy createBufferStrategy(Container root,
|
||||
boolean isVsynced) {
|
||||
BufferCapabilities caps;
|
||||
if (isVsynced) {
|
||||
caps = new ExtendedBufferCapabilities(
|
||||
new ImageCapabilities(true), new ImageCapabilities(true),
|
||||
BufferCapabilities.FlipContents.COPIED,
|
||||
ExtendedBufferCapabilities.VSyncType.VSYNC_ON);
|
||||
} else {
|
||||
caps = new BufferCapabilities(
|
||||
new ImageCapabilities(true), new ImageCapabilities(true),
|
||||
null);
|
||||
}
|
||||
BufferStrategy bs = null;
|
||||
if (SunToolkit.isInstanceOf(root, "java.applet.Applet")) {
|
||||
try {
|
||||
getCreateBufferStrategyMethod().invoke(root, 2, caps);
|
||||
bs = (BufferStrategy)getGetBufferStrategyMethod().
|
||||
invoke(root);
|
||||
} catch (InvocationTargetException ite) {
|
||||
// Type is not supported
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("createBufferStratety failed",
|
||||
ite);
|
||||
}
|
||||
} catch (IllegalArgumentException iae) {
|
||||
assert false;
|
||||
} catch (IllegalAccessException iae2) {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
((Window)root).createBufferStrategy(2, caps);
|
||||
bs = ((Window)root).getBufferStrategy();
|
||||
} catch (AWTException e) {
|
||||
// Type not supported
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("createBufferStratety failed",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up and removes any references.
|
||||
*/
|
||||
public void dispose() {
|
||||
Container root = getRoot();
|
||||
if (LOGGER.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
LOGGER.finer("disposed BufferInfo for: " + root);
|
||||
}
|
||||
if (root != null) {
|
||||
root.removeComponentListener(this);
|
||||
if (root instanceof Window) {
|
||||
((Window)root).removeWindowListener(this);
|
||||
}
|
||||
BufferStrategy bs = getBufferStrategy(false);
|
||||
if (bs != null) {
|
||||
bs.dispose();
|
||||
}
|
||||
}
|
||||
this.root = null;
|
||||
weakBS = null;
|
||||
}
|
||||
|
||||
// We mark the buffer as needing to be painted on a hide/iconify
|
||||
// because the developer may have conditionalized painting based on
|
||||
// visibility.
|
||||
// Ideally we would also move to having the BufferStrategy being
|
||||
// a SoftReference in Component here, but that requires changes to
|
||||
// Component and the like.
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
Container root = getRoot();
|
||||
if (root != null && root.isVisible()) {
|
||||
// This case will only happen if a developer calls
|
||||
// hide immediately followed by show. In this case
|
||||
// the event is delivered after show and the window
|
||||
// will still be visible. If a developer altered the
|
||||
// contents of the window between the hide/show
|
||||
// invocations we won't recognize we need to paint and
|
||||
// the contents would be bogus. Calling repaint here
|
||||
// fixs everything up.
|
||||
root.repaint();
|
||||
}
|
||||
else {
|
||||
setPaintAllOnExpose(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void windowIconified(WindowEvent e) {
|
||||
setPaintAllOnExpose(true);
|
||||
}
|
||||
|
||||
// On a dispose we chuck everything.
|
||||
public void windowClosed(WindowEvent e) {
|
||||
// Make sure we're not showing.
|
||||
synchronized(BufferStrategyPaintManager.this) {
|
||||
while (showing) {
|
||||
try {
|
||||
BufferStrategyPaintManager.this.wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
bufferInfos.remove(this);
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
|
||||
public void windowOpened(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowClosing(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowActivated(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
191
jdkSrc/jdk8/javax/swing/ButtonGroup.java
Normal file
191
jdkSrc/jdk8/javax/swing/ButtonGroup.java
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* This class is used to create a multiple-exclusion scope for
|
||||
* a set of buttons. Creating a set of buttons with the
|
||||
* same <code>ButtonGroup</code> object means that
|
||||
* turning "on" one of those buttons
|
||||
* turns off all other buttons in the group.
|
||||
* <p>
|
||||
* A <code>ButtonGroup</code> can be used with
|
||||
* any set of objects that inherit from <code>AbstractButton</code>.
|
||||
* Typically a button group contains instances of
|
||||
* <code>JRadioButton</code>,
|
||||
* <code>JRadioButtonMenuItem</code>,
|
||||
* or <code>JToggleButton</code>.
|
||||
* It wouldn't make sense to put an instance of
|
||||
* <code>JButton</code> or <code>JMenuItem</code>
|
||||
* in a button group
|
||||
* because <code>JButton</code> and <code>JMenuItem</code>
|
||||
* don't implement the selected state.
|
||||
* <p>
|
||||
* Initially, all buttons in the group are unselected.
|
||||
* <p>
|
||||
* For examples and further information on using button groups see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html#radiobutton">How to Use Radio Buttons</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ButtonGroup implements Serializable {
|
||||
|
||||
// the list of buttons participating in this group
|
||||
protected Vector<AbstractButton> buttons = new Vector<AbstractButton>();
|
||||
|
||||
/**
|
||||
* The current selection.
|
||||
*/
|
||||
ButtonModel selection = null;
|
||||
|
||||
/**
|
||||
* Creates a new <code>ButtonGroup</code>.
|
||||
*/
|
||||
public ButtonGroup() {}
|
||||
|
||||
/**
|
||||
* Adds the button to the group.
|
||||
* @param b the button to be added
|
||||
*/
|
||||
public void add(AbstractButton b) {
|
||||
if(b == null) {
|
||||
return;
|
||||
}
|
||||
buttons.addElement(b);
|
||||
|
||||
if (b.isSelected()) {
|
||||
if (selection == null) {
|
||||
selection = b.getModel();
|
||||
} else {
|
||||
b.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
b.getModel().setGroup(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the button from the group.
|
||||
* @param b the button to be removed
|
||||
*/
|
||||
public void remove(AbstractButton b) {
|
||||
if(b == null) {
|
||||
return;
|
||||
}
|
||||
buttons.removeElement(b);
|
||||
if(b.getModel() == selection) {
|
||||
selection = null;
|
||||
}
|
||||
b.getModel().setGroup(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the selection such that none of the buttons
|
||||
* in the <code>ButtonGroup</code> are selected.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public void clearSelection() {
|
||||
if (selection != null) {
|
||||
ButtonModel oldSelection = selection;
|
||||
selection = null;
|
||||
oldSelection.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the buttons that are participating in
|
||||
* this group.
|
||||
* @return an <code>Enumeration</code> of the buttons in this group
|
||||
*/
|
||||
public Enumeration<AbstractButton> getElements() {
|
||||
return buttons.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the model of the selected button.
|
||||
* @return the selected button model
|
||||
*/
|
||||
public ButtonModel getSelection() {
|
||||
return selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected value for the <code>ButtonModel</code>.
|
||||
* Only one button in the group may be selected at a time.
|
||||
* @param m the <code>ButtonModel</code>
|
||||
* @param b <code>true</code> if this button is to be
|
||||
* selected, otherwise <code>false</code>
|
||||
*/
|
||||
public void setSelected(ButtonModel m, boolean b) {
|
||||
if (b && m != null && m != selection) {
|
||||
ButtonModel oldSelection = selection;
|
||||
selection = m;
|
||||
if (oldSelection != null) {
|
||||
oldSelection.setSelected(false);
|
||||
}
|
||||
m.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a <code>ButtonModel</code> is selected.
|
||||
* @return <code>true</code> if the button is selected,
|
||||
* otherwise returns <code>false</code>
|
||||
*/
|
||||
public boolean isSelected(ButtonModel m) {
|
||||
return (m == selection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of buttons in the group.
|
||||
* @return the button count
|
||||
* @since 1.3
|
||||
*/
|
||||
public int getButtonCount() {
|
||||
if (buttons == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return buttons.size();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
242
jdkSrc/jdk8/javax/swing/ButtonModel.java
Normal file
242
jdkSrc/jdk8/javax/swing/ButtonModel.java
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, 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 javax.swing;
|
||||
|
||||
|
||||
import java.awt.event.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
* State model for buttons.
|
||||
* <p>
|
||||
* This model is used for regular buttons, as well as check boxes
|
||||
* and radio buttons, which are special kinds of buttons. In practice,
|
||||
* a button's UI takes the responsibility of calling methods on its
|
||||
* model to manage the state, as detailed below:
|
||||
* <p>
|
||||
* In simple terms, pressing and releasing the mouse over a regular
|
||||
* button triggers the button and causes and <code>ActionEvent</code>
|
||||
* to be fired. The same behavior can be produced via a keyboard key
|
||||
* defined by the look and feel of the button (typically the SPACE BAR).
|
||||
* Pressing and releasing this key while the button has
|
||||
* focus will give the same results. For check boxes and radio buttons, the
|
||||
* mouse or keyboard equivalent sequence just described causes the button
|
||||
* to become selected.
|
||||
* <p>
|
||||
* In details, the state model for buttons works as follows
|
||||
* when used with the mouse:
|
||||
* <br>
|
||||
* Pressing the mouse on top of a button makes the model both
|
||||
* armed and pressed. As long as the mouse remains down,
|
||||
* the model remains pressed, even if the mouse moves
|
||||
* outside the button. On the contrary, the model is only
|
||||
* armed while the mouse remains pressed within the bounds of
|
||||
* the button (it can move in or out of the button, but the model
|
||||
* is only armed during the portion of time spent within the button).
|
||||
* A button is triggered, and an <code>ActionEvent</code> is fired,
|
||||
* when the mouse is released while the model is armed
|
||||
* - meaning when it is released over top of the button after the mouse
|
||||
* has previously been pressed on that button (and not already released).
|
||||
* Upon mouse release, the model becomes unarmed and unpressed.
|
||||
* <p>
|
||||
* In details, the state model for buttons works as follows
|
||||
* when used with the keyboard:
|
||||
* <br>
|
||||
* Pressing the look and feel defined keyboard key while the button
|
||||
* has focus makes the model both armed and pressed. As long as this key
|
||||
* remains down, the model remains in this state. Releasing the key sets
|
||||
* the model to unarmed and unpressed, triggers the button, and causes an
|
||||
* <code>ActionEvent</code> to be fired.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
public interface ButtonModel extends ItemSelectable {
|
||||
|
||||
/**
|
||||
* Indicates partial commitment towards triggering the
|
||||
* button.
|
||||
*
|
||||
* @return <code>true</code> if the button is armed,
|
||||
* and ready to be triggered
|
||||
* @see #setArmed
|
||||
*/
|
||||
boolean isArmed();
|
||||
|
||||
/**
|
||||
* Indicates if the button has been selected. Only needed for
|
||||
* certain types of buttons - such as radio buttons and check boxes.
|
||||
*
|
||||
* @return <code>true</code> if the button is selected
|
||||
*/
|
||||
boolean isSelected();
|
||||
|
||||
/**
|
||||
* Indicates if the button can be selected or triggered by
|
||||
* an input device, such as a mouse pointer.
|
||||
*
|
||||
* @return <code>true</code> if the button is enabled
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Indicates if the button is pressed.
|
||||
*
|
||||
* @return <code>true</code> if the button is pressed
|
||||
*/
|
||||
boolean isPressed();
|
||||
|
||||
/**
|
||||
* Indicates that the mouse is over the button.
|
||||
*
|
||||
* @return <code>true</code> if the mouse is over the button
|
||||
*/
|
||||
boolean isRollover();
|
||||
|
||||
/**
|
||||
* Marks the button as armed or unarmed.
|
||||
*
|
||||
* @param b whether or not the button should be armed
|
||||
*/
|
||||
public void setArmed(boolean b);
|
||||
|
||||
/**
|
||||
* Selects or deselects the button.
|
||||
*
|
||||
* @param b <code>true</code> selects the button,
|
||||
* <code>false</code> deselects the button
|
||||
*/
|
||||
public void setSelected(boolean b);
|
||||
|
||||
/**
|
||||
* Enables or disables the button.
|
||||
*
|
||||
* @param b whether or not the button should be enabled
|
||||
* @see #isEnabled
|
||||
*/
|
||||
public void setEnabled(boolean b);
|
||||
|
||||
/**
|
||||
* Sets the button to pressed or unpressed.
|
||||
*
|
||||
* @param b whether or not the button should be pressed
|
||||
* @see #isPressed
|
||||
*/
|
||||
public void setPressed(boolean b);
|
||||
|
||||
/**
|
||||
* Sets or clears the button's rollover state
|
||||
*
|
||||
* @param b whether or not the button is in the rollover state
|
||||
* @see #isRollover
|
||||
*/
|
||||
public void setRollover(boolean b);
|
||||
|
||||
/**
|
||||
* Sets the keyboard mnemonic (shortcut key or
|
||||
* accelerator key) for the button.
|
||||
*
|
||||
* @param key an int specifying the accelerator key
|
||||
*/
|
||||
public void setMnemonic(int key);
|
||||
|
||||
/**
|
||||
* Gets the keyboard mnemonic for the button.
|
||||
*
|
||||
* @return an int specifying the accelerator key
|
||||
* @see #setMnemonic
|
||||
*/
|
||||
public int getMnemonic();
|
||||
|
||||
/**
|
||||
* Sets the action command string that gets sent as part of the
|
||||
* <code>ActionEvent</code> when the button is triggered.
|
||||
*
|
||||
* @param s the <code>String</code> that identifies the generated event
|
||||
* @see #getActionCommand
|
||||
* @see java.awt.event.ActionEvent#getActionCommand
|
||||
*/
|
||||
public void setActionCommand(String s);
|
||||
|
||||
/**
|
||||
* Returns the action command string for the button.
|
||||
*
|
||||
* @return the <code>String</code> that identifies the generated event
|
||||
* @see #setActionCommand
|
||||
*/
|
||||
public String getActionCommand();
|
||||
|
||||
/**
|
||||
* Identifies the group the button belongs to --
|
||||
* needed for radio buttons, which are mutually
|
||||
* exclusive within their group.
|
||||
*
|
||||
* @param group the <code>ButtonGroup</code> the button belongs to
|
||||
*/
|
||||
public void setGroup(ButtonGroup group);
|
||||
|
||||
/**
|
||||
* Adds an <code>ActionListener</code> to the model.
|
||||
*
|
||||
* @param l the listener to add
|
||||
*/
|
||||
void addActionListener(ActionListener l);
|
||||
|
||||
/**
|
||||
* Removes an <code>ActionListener</code> from the model.
|
||||
*
|
||||
* @param l the listener to remove
|
||||
*/
|
||||
void removeActionListener(ActionListener l);
|
||||
|
||||
/**
|
||||
* Adds an <code>ItemListener</code> to the model.
|
||||
*
|
||||
* @param l the listener to add
|
||||
*/
|
||||
void addItemListener(ItemListener l);
|
||||
|
||||
/**
|
||||
* Removes an <code>ItemListener</code> from the model.
|
||||
*
|
||||
* @param l the listener to remove
|
||||
*/
|
||||
void removeItemListener(ItemListener l);
|
||||
|
||||
/**
|
||||
* Adds a <code>ChangeListener</code> to the model.
|
||||
*
|
||||
* @param l the listener to add
|
||||
*/
|
||||
void addChangeListener(ChangeListener l);
|
||||
|
||||
/**
|
||||
* Removes a <code>ChangeListener</code> from the model.
|
||||
*
|
||||
* @param l the listener to remove
|
||||
*/
|
||||
void removeChangeListener(ChangeListener l);
|
||||
|
||||
}
|
||||
134
jdkSrc/jdk8/javax/swing/CellEditor.java
Normal file
134
jdkSrc/jdk8/javax/swing/CellEditor.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, 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 javax.swing;
|
||||
|
||||
import java.util.EventObject;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
* This interface defines the methods any general editor should be able
|
||||
* to implement. <p>
|
||||
*
|
||||
* Having this interface enables complex components (the client of the
|
||||
* editor) such as <code>JTree</code> and
|
||||
* <code>JTable</code> to allow any generic editor to
|
||||
* edit values in a table cell, or tree cell, etc. Without this generic
|
||||
* editor interface, <code>JTable</code> would have to know about specific editors,
|
||||
* such as <code>JTextField</code>, <code>JCheckBox</code>, <code>JComboBox</code>,
|
||||
* etc. In addition, without this interface, clients of editors such as
|
||||
* <code>JTable</code> would not be able
|
||||
* to work with any editors developed in the future by the user
|
||||
* or a 3rd party ISV. <p>
|
||||
*
|
||||
* To use this interface, a developer creating a new editor can have the
|
||||
* new component implement the interface. Or the developer can
|
||||
* choose a wrapper based approach and provide a companion object which
|
||||
* implements the <code>CellEditor</code> interface (See
|
||||
* <code>DefaultCellEditor</code> for example). The wrapper approach
|
||||
* is particularly useful if the user want to use a 3rd party ISV
|
||||
* editor with <code>JTable</code>, but the ISV didn't implement the
|
||||
* <code>CellEditor</code> interface. The user can simply create an object
|
||||
* that contains an instance of the 3rd party editor object and "translate"
|
||||
* the <code>CellEditor</code> API into the 3rd party editor's API.
|
||||
*
|
||||
* @see javax.swing.event.CellEditorListener
|
||||
*
|
||||
* @author Alan Chung
|
||||
*/
|
||||
public interface CellEditor {
|
||||
|
||||
/**
|
||||
* Returns the value contained in the editor.
|
||||
* @return the value contained in the editor
|
||||
*/
|
||||
public Object getCellEditorValue();
|
||||
|
||||
/**
|
||||
* Asks the editor if it can start editing using <code>anEvent</code>.
|
||||
* <code>anEvent</code> is in the invoking component coordinate system.
|
||||
* The editor can not assume the Component returned by
|
||||
* <code>getCellEditorComponent</code> is installed. This method
|
||||
* is intended for the use of client to avoid the cost of setting up
|
||||
* and installing the editor component if editing is not possible.
|
||||
* If editing can be started this method returns true.
|
||||
*
|
||||
* @param anEvent the event the editor should use to consider
|
||||
* whether to begin editing or not
|
||||
* @return true if editing can be started
|
||||
* @see #shouldSelectCell
|
||||
*/
|
||||
public boolean isCellEditable(EventObject anEvent);
|
||||
|
||||
/**
|
||||
* Returns true if the editing cell should be selected, false otherwise.
|
||||
* Typically, the return value is true, because is most cases the editing
|
||||
* cell should be selected. However, it is useful to return false to
|
||||
* keep the selection from changing for some types of edits.
|
||||
* eg. A table that contains a column of check boxes, the user might
|
||||
* want to be able to change those checkboxes without altering the
|
||||
* selection. (See Netscape Communicator for just such an example)
|
||||
* Of course, it is up to the client of the editor to use the return
|
||||
* value, but it doesn't need to if it doesn't want to.
|
||||
*
|
||||
* @param anEvent the event the editor should use to start
|
||||
* editing
|
||||
* @return true if the editor would like the editing cell to be selected;
|
||||
* otherwise returns false
|
||||
* @see #isCellEditable
|
||||
*/
|
||||
public boolean shouldSelectCell(EventObject anEvent);
|
||||
|
||||
/**
|
||||
* Tells the editor to stop editing and accept any partially edited
|
||||
* value as the value of the editor. The editor returns false if
|
||||
* editing was not stopped; this is useful for editors that validate
|
||||
* and can not accept invalid entries.
|
||||
*
|
||||
* @return true if editing was stopped; false otherwise
|
||||
*/
|
||||
public boolean stopCellEditing();
|
||||
|
||||
/**
|
||||
* Tells the editor to cancel editing and not accept any partially
|
||||
* edited value.
|
||||
*/
|
||||
public void cancelCellEditing();
|
||||
|
||||
/**
|
||||
* Adds a listener to the list that's notified when the editor
|
||||
* stops, or cancels editing.
|
||||
*
|
||||
* @param l the CellEditorListener
|
||||
*/
|
||||
public void addCellEditorListener(CellEditorListener l);
|
||||
|
||||
/**
|
||||
* Removes a listener from the list that's notified
|
||||
*
|
||||
* @param l the CellEditorListener
|
||||
*/
|
||||
public void removeCellEditorListener(CellEditorListener l);
|
||||
}
|
||||
227
jdkSrc/jdk8/javax/swing/CellRendererPane.java
Normal file
227
jdkSrc/jdk8/javax/swing/CellRendererPane.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* This class is inserted in between cell renderers and the components that
|
||||
* use them. It just exists to thwart the repaint() and invalidate() methods
|
||||
* which would otherwise propagate up the tree when the renderer was configured.
|
||||
* It's used by the implementations of JTable, JTree, and JList. For example,
|
||||
* here's how CellRendererPane is used in the code the paints each row
|
||||
* in a JList:
|
||||
* <pre>
|
||||
* cellRendererPane = new CellRendererPane();
|
||||
* ...
|
||||
* Component rendererComponent = renderer.getListCellRendererComponent();
|
||||
* renderer.configureListCellRenderer(dataModel.getElementAt(row), row);
|
||||
* cellRendererPane.paintComponent(g, rendererComponent, this, x, y, w, h);
|
||||
* </pre>
|
||||
* <p>
|
||||
* A renderer component must override isShowing() and unconditionally return
|
||||
* true to work correctly because the Swing paint does nothing for components
|
||||
* with isShowing false.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Hans Muller
|
||||
*/
|
||||
public class CellRendererPane extends Container implements Accessible
|
||||
{
|
||||
/**
|
||||
* Construct a CellRendererPane object.
|
||||
*/
|
||||
public CellRendererPane() {
|
||||
super();
|
||||
setLayout(null);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to avoid propagating a invalidate up the tree when the
|
||||
* cell renderer child is configured.
|
||||
*/
|
||||
public void invalidate() { }
|
||||
|
||||
|
||||
/**
|
||||
* Shouldn't be called.
|
||||
*/
|
||||
public void paint(Graphics g) { }
|
||||
|
||||
|
||||
/**
|
||||
* Shouldn't be called.
|
||||
*/
|
||||
public void update(Graphics g) { }
|
||||
|
||||
|
||||
/**
|
||||
* If the specified component is already a child of this then we don't
|
||||
* bother doing anything - stacking order doesn't matter for cell
|
||||
* renderer components (CellRendererPane doesn't paint anyway).
|
||||
*/
|
||||
protected void addImpl(Component x, Object constraints, int index) {
|
||||
if (x.getParent() == this) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
super.addImpl(x, constraints, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paint a cell renderer component c on graphics object g. Before the component
|
||||
* is drawn it's reparented to this (if that's necessary), it's bounds
|
||||
* are set to w,h and the graphics object is (effectively) translated to x,y.
|
||||
* If it's a JComponent, double buffering is temporarily turned off. After
|
||||
* the component is painted it's bounds are reset to -w, -h, 0, 0 so that, if
|
||||
* it's the last renderer component painted, it will not start consuming input.
|
||||
* The Container p is the component we're actually drawing on, typically it's
|
||||
* equal to this.getParent(). If shouldValidate is true the component c will be
|
||||
* validated before painted.
|
||||
*/
|
||||
public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) {
|
||||
if (c == null) {
|
||||
if (p != null) {
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor(p.getBackground());
|
||||
g.fillRect(x, y, w, h);
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.getParent() != this) {
|
||||
this.add(c);
|
||||
}
|
||||
|
||||
c.setBounds(x, y, w, h);
|
||||
|
||||
if(shouldValidate) {
|
||||
c.validate();
|
||||
}
|
||||
|
||||
boolean wasDoubleBuffered = false;
|
||||
if ((c instanceof JComponent) && ((JComponent)c).isDoubleBuffered()) {
|
||||
wasDoubleBuffered = true;
|
||||
((JComponent)c).setDoubleBuffered(false);
|
||||
}
|
||||
|
||||
Graphics cg = g.create(x, y, w, h);
|
||||
try {
|
||||
c.paint(cg);
|
||||
}
|
||||
finally {
|
||||
cg.dispose();
|
||||
}
|
||||
|
||||
if (wasDoubleBuffered && (c instanceof JComponent)) {
|
||||
((JComponent)c).setDoubleBuffered(true);
|
||||
}
|
||||
|
||||
c.setBounds(-w, -h, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls this.paintComponent(g, c, p, x, y, w, h, false).
|
||||
*/
|
||||
public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) {
|
||||
paintComponent(g, c, p, x, y, w, h, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls this.paintComponent() with the rectangles x,y,width,height fields.
|
||||
*/
|
||||
public void paintComponent(Graphics g, Component c, Container p, Rectangle r) {
|
||||
paintComponent(g, c, p, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
removeAll();
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
protected AccessibleContext accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this CellRendererPane.
|
||||
* For CellRendererPanes, the AccessibleContext takes the form of an
|
||||
* AccessibleCellRendererPane.
|
||||
* A new AccessibleCellRendererPane instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleCellRendererPane that serves as the
|
||||
* AccessibleContext of this CellRendererPane
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleCellRendererPane();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>CellRendererPane</code> class.
|
||||
*/
|
||||
protected class AccessibleCellRendererPane extends AccessibleAWTContainer {
|
||||
// AccessibleContext methods
|
||||
//
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.PANEL;
|
||||
}
|
||||
} // inner class AccessibleCellRendererPane
|
||||
}
|
||||
124
jdkSrc/jdk8/javax/swing/ClientPropertyKey.java
Normal file
124
jdkSrc/jdk8/javax/swing/ClientPropertyKey.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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 javax.swing;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
/**
|
||||
* An enumeration for keys used as client properties within the Swing
|
||||
* implementation.
|
||||
* <p>
|
||||
* This enum holds only a small subset of the keys currently used within Swing,
|
||||
* but we may move more of them here in the future.
|
||||
* <p>
|
||||
* Adding an item to, and using, this class instead of {@code String} for
|
||||
* client properties protects against conflicts with developer-set client
|
||||
* properties. Using this class also avoids a problem with {@code StringBuilder}
|
||||
* and {@code StringBuffer} keys, whereby the keys are not recognized upon
|
||||
* deserialization.
|
||||
* <p>
|
||||
* When a client property value associated with one of these keys does not
|
||||
* implement {@code Serializable}, the result during serialization depends
|
||||
* on how the key is defined here. Historically, client properties with values
|
||||
* not implementing {@code Serializable} have simply been dropped and left out
|
||||
* of the serialized representation. To define keys with such behavior in this
|
||||
* enum, provide a value of {@code false} for the {@code reportValueNotSerializable}
|
||||
* property. When migrating existing properties to this enum, one may wish to
|
||||
* consider using this by default, to preserve backward compatibility.
|
||||
* <p>
|
||||
* To instead have a {@code NotSerializableException} thrown when a
|
||||
* {@code non-Serializable} property is encountered, provide the value of
|
||||
* {@code true} for the {@code reportValueNotSerializable} property. This
|
||||
* is useful when the property represents something that the developer
|
||||
* needs to know about when it cannot be serialized.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
*/
|
||||
enum ClientPropertyKey {
|
||||
|
||||
/**
|
||||
* Key used by JComponent for storing InputVerifier.
|
||||
*/
|
||||
JComponent_INPUT_VERIFIER(true),
|
||||
|
||||
/**
|
||||
* Key used by JComponent for storing TransferHandler.
|
||||
*/
|
||||
JComponent_TRANSFER_HANDLER(true),
|
||||
|
||||
/**
|
||||
* Key used by JComponent for storing AncestorNotifier.
|
||||
*/
|
||||
JComponent_ANCESTOR_NOTIFIER(true),
|
||||
|
||||
/**
|
||||
* Key used by PopupFactory to force heavy weight popups for a
|
||||
* component.
|
||||
*/
|
||||
PopupFactory_FORCE_HEAVYWEIGHT_POPUP(true);
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not a {@code NotSerializableException} should be thrown
|
||||
* during serialization, when the value associated with this key does
|
||||
* not implement {@code Serializable}.
|
||||
*/
|
||||
private final boolean reportValueNotSerializable;
|
||||
|
||||
static {
|
||||
AWTAccessor.setClientPropertyKeyAccessor(
|
||||
new AWTAccessor.ClientPropertyKeyAccessor() {
|
||||
public Object getJComponent_TRANSFER_HANDLER() {
|
||||
return JComponent_TRANSFER_HANDLER;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a key with the {@code reportValueNotSerializable} property
|
||||
* set to {@code false}.
|
||||
*/
|
||||
private ClientPropertyKey() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a key with the {@code reportValueNotSerializable} property
|
||||
* set to the given value.
|
||||
*/
|
||||
private ClientPropertyKey(boolean reportValueNotSerializable) {
|
||||
this.reportValueNotSerializable = reportValueNotSerializable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not a {@code NotSerializableException} should be thrown
|
||||
* during serialization, when the value associated with this key does
|
||||
* not implement {@code Serializable}.
|
||||
*/
|
||||
public boolean getReportValueNotSerializable() {
|
||||
return reportValueNotSerializable;
|
||||
}
|
||||
}
|
||||
56
jdkSrc/jdk8/javax/swing/ComboBoxEditor.java
Normal file
56
jdkSrc/jdk8/javax/swing/ComboBoxEditor.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* The editor component used for JComboBox components.
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
*/
|
||||
public interface ComboBoxEditor {
|
||||
|
||||
/** Return the component that should be added to the tree hierarchy for
|
||||
* this editor
|
||||
*/
|
||||
public Component getEditorComponent();
|
||||
|
||||
/** Set the item that should be edited. Cancel any editing if necessary **/
|
||||
public void setItem(Object anObject);
|
||||
|
||||
/** Return the edited item **/
|
||||
public Object getItem();
|
||||
|
||||
/** Ask the editor to start editing and to select everything **/
|
||||
public void selectAll();
|
||||
|
||||
/** Add an ActionListener. An action event is generated when the edited item changes **/
|
||||
public void addActionListener(ActionListener l);
|
||||
|
||||
/** Remove an ActionListener **/
|
||||
public void removeActionListener(ActionListener l);
|
||||
}
|
||||
57
jdkSrc/jdk8/javax/swing/ComboBoxModel.java
Normal file
57
jdkSrc/jdk8/javax/swing/ComboBoxModel.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 javax.swing;
|
||||
|
||||
/**
|
||||
* A data model for a combo box. This interface extends <code>ListDataModel</code>
|
||||
* and adds the concept of a <i>selected item</i>. The selected item is generally
|
||||
* the item which is visible in the combo box display area.
|
||||
* <p>
|
||||
* The selected item may not necessarily be managed by the underlying
|
||||
* <code>ListModel</code>. This disjoint behavior allows for the temporary
|
||||
* storage and retrieval of a selected item in the model.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
*/
|
||||
public interface ComboBoxModel<E> extends ListModel<E> {
|
||||
|
||||
/**
|
||||
* Set the selected item. The implementation of this method should notify
|
||||
* all registered <code>ListDataListener</code>s that the contents
|
||||
* have changed.
|
||||
*
|
||||
* @param anItem the list object to select or <code>null</code>
|
||||
* to clear the selection
|
||||
*/
|
||||
void setSelectedItem(Object anItem);
|
||||
|
||||
/**
|
||||
* Returns the selected item
|
||||
* @return The selected item or <code>null</code> if there is no selection
|
||||
*/
|
||||
Object getSelectedItem();
|
||||
}
|
||||
119
jdkSrc/jdk8/javax/swing/ComponentInputMap.java
Normal file
119
jdkSrc/jdk8/javax/swing/ComponentInputMap.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 javax.swing;
|
||||
|
||||
/**
|
||||
* A <code>ComponentInputMap</code> is an <code>InputMap</code>
|
||||
* associated with a particular <code>JComponent</code>.
|
||||
* The component is automatically notified whenever
|
||||
* the <code>ComponentInputMap</code> changes.
|
||||
* <code>ComponentInputMap</code>s are used for
|
||||
* <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.3
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ComponentInputMap extends InputMap {
|
||||
/** Component binding is created for. */
|
||||
private JComponent component;
|
||||
|
||||
/**
|
||||
* Creates a <code>ComponentInputMap</code> associated with the
|
||||
* specified component.
|
||||
*
|
||||
* @param component a non-null <code>JComponent</code>
|
||||
* @throws IllegalArgumentException if <code>component</code> is null
|
||||
*/
|
||||
public ComponentInputMap(JComponent component) {
|
||||
this.component = component;
|
||||
if (component == null) {
|
||||
throw new IllegalArgumentException("ComponentInputMaps must be associated with a non-null JComponent");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent, which must be a <code>ComponentInputMap</code>
|
||||
* associated with the same component as this
|
||||
* <code>ComponentInputMap</code>.
|
||||
*
|
||||
* @param map a <code>ComponentInputMap</code>
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>map</code>
|
||||
* is not a <code>ComponentInputMap</code>
|
||||
* or is not associated with the same component
|
||||
*/
|
||||
public void setParent(InputMap map) {
|
||||
if (getParent() == map) {
|
||||
return;
|
||||
}
|
||||
if (map != null && (!(map instanceof ComponentInputMap) ||
|
||||
((ComponentInputMap)map).getComponent() != getComponent())) {
|
||||
throw new IllegalArgumentException("ComponentInputMaps must have a parent ComponentInputMap associated with the same component");
|
||||
}
|
||||
super.setParent(map);
|
||||
getComponent().componentInputMapChanged(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component the <code>InputMap</code> was created for.
|
||||
*/
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a binding for <code>keyStroke</code> to <code>actionMapKey</code>.
|
||||
* If <code>actionMapKey</code> is null, this removes the current binding
|
||||
* for <code>keyStroke</code>.
|
||||
*/
|
||||
public void put(KeyStroke keyStroke, Object actionMapKey) {
|
||||
super.put(keyStroke, actionMapKey);
|
||||
if (getComponent() != null) {
|
||||
getComponent().componentInputMapChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the binding for <code>key</code> from this object.
|
||||
*/
|
||||
public void remove(KeyStroke key) {
|
||||
super.remove(key);
|
||||
if (getComponent() != null) {
|
||||
getComponent().componentInputMapChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the mappings from this object.
|
||||
*/
|
||||
public void clear() {
|
||||
int oldSize = size();
|
||||
super.clear();
|
||||
if (oldSize > 0 && getComponent() != null) {
|
||||
getComponent().componentInputMapChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
1468
jdkSrc/jdk8/javax/swing/DebugGraphics.java
Normal file
1468
jdkSrc/jdk8/javax/swing/DebugGraphics.java
Normal file
File diff suppressed because it is too large
Load Diff
46
jdkSrc/jdk8/javax/swing/DebugGraphicsFilter.java
Normal file
46
jdkSrc/jdk8/javax/swing/DebugGraphicsFilter.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/** Color filter for DebugGraphics, used for images only.
|
||||
*
|
||||
* @author Dave Karlton
|
||||
*/
|
||||
class DebugGraphicsFilter extends RGBImageFilter {
|
||||
Color color;
|
||||
|
||||
DebugGraphicsFilter(Color c) {
|
||||
canFilterIndexColorModel = true;
|
||||
color = c;
|
||||
}
|
||||
|
||||
public int filterRGB(int x, int y, int rgb) {
|
||||
return color.getRGB() | (rgb & 0xFF000000);
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/javax/swing/DebugGraphicsInfo.java
Normal file
71
jdkSrc/jdk8/javax/swing/DebugGraphicsInfo.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
/** Class used by DebugGraphics for maintaining information about how
|
||||
* to render graphics calls.
|
||||
*
|
||||
* @author Dave Karlton
|
||||
*/
|
||||
class DebugGraphicsInfo {
|
||||
Color flashColor = Color.red;
|
||||
int flashTime = 100;
|
||||
int flashCount = 2;
|
||||
Hashtable<JComponent, Integer> componentToDebug;
|
||||
JFrame debugFrame = null;
|
||||
java.io.PrintStream stream = System.out;
|
||||
|
||||
void setDebugOptions(JComponent component, int debug) {
|
||||
if (debug == 0) {
|
||||
return;
|
||||
}
|
||||
if (componentToDebug == null) {
|
||||
componentToDebug = new Hashtable<JComponent, Integer>();
|
||||
}
|
||||
if (debug > 0) {
|
||||
componentToDebug.put(component, Integer.valueOf(debug));
|
||||
} else {
|
||||
componentToDebug.remove(component);
|
||||
}
|
||||
}
|
||||
|
||||
int getDebugOptions(JComponent component) {
|
||||
if (componentToDebug == null) {
|
||||
return 0;
|
||||
} else {
|
||||
Integer integer = componentToDebug.get(component);
|
||||
|
||||
return integer == null ? 0 : integer.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
void log(String string) {
|
||||
stream.println(string);
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/javax/swing/DebugGraphicsObserver.java
Normal file
53
jdkSrc/jdk8/javax/swing/DebugGraphicsObserver.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/** ImageObserver for DebugGraphics, used for images only.
|
||||
*
|
||||
* @author Dave Karlton
|
||||
*/
|
||||
class DebugGraphicsObserver implements ImageObserver {
|
||||
int lastInfo;
|
||||
|
||||
synchronized boolean allBitsPresent() {
|
||||
return (lastInfo & ImageObserver.ALLBITS) != 0;
|
||||
}
|
||||
|
||||
synchronized boolean imageHasProblem() {
|
||||
return ((lastInfo & ImageObserver.ERROR) != 0 ||
|
||||
(lastInfo & ImageObserver.ABORT) != 0);
|
||||
}
|
||||
|
||||
public synchronized boolean imageUpdate(Image img, int infoflags,
|
||||
int x, int y,
|
||||
int width, int height) {
|
||||
lastInfo = infoflags;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
423
jdkSrc/jdk8/javax/swing/DefaultBoundedRangeModel.java
Normal file
423
jdkSrc/jdk8/javax/swing/DefaultBoundedRangeModel.java
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* A generic implementation of BoundedRangeModel.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author David Kloba
|
||||
* @author Hans Muller
|
||||
* @see BoundedRangeModel
|
||||
*/
|
||||
public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable
|
||||
{
|
||||
/**
|
||||
* Only one <code>ChangeEvent</code> is needed per model instance since the
|
||||
* event's only (read-only) state is the source property. The source
|
||||
* of events generated here is always "this".
|
||||
*/
|
||||
protected transient ChangeEvent changeEvent = null;
|
||||
|
||||
/** The listeners waiting for model changes. */
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private int value = 0;
|
||||
private int extent = 0;
|
||||
private int min = 0;
|
||||
private int max = 100;
|
||||
private boolean isAdjusting = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes all of the properties with default values.
|
||||
* Those values are:
|
||||
* <ul>
|
||||
* <li><code>value</code> = 0
|
||||
* <li><code>extent</code> = 0
|
||||
* <li><code>minimum</code> = 0
|
||||
* <li><code>maximum</code> = 100
|
||||
* <li><code>adjusting</code> = false
|
||||
* </ul>
|
||||
*/
|
||||
public DefaultBoundedRangeModel() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes value, extent, minimum and maximum. Adjusting is false.
|
||||
* Throws an <code>IllegalArgumentException</code> if the following
|
||||
* constraints aren't satisfied:
|
||||
* <pre>
|
||||
* min <= value <= value+extent <= max
|
||||
* </pre>
|
||||
*/
|
||||
public DefaultBoundedRangeModel(int value, int extent, int min, int max)
|
||||
{
|
||||
if ((max >= min) &&
|
||||
(value >= min) &&
|
||||
((value + extent) >= value) &&
|
||||
((value + extent) <= max)) {
|
||||
this.value = value;
|
||||
this.extent = extent;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("invalid range properties");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's current value.
|
||||
* @return the model's current value
|
||||
* @see #setValue
|
||||
* @see BoundedRangeModel#getValue
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's extent.
|
||||
* @return the model's extent
|
||||
* @see #setExtent
|
||||
* @see BoundedRangeModel#getExtent
|
||||
*/
|
||||
public int getExtent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's minimum.
|
||||
* @return the model's minimum
|
||||
* @see #setMinimum
|
||||
* @see BoundedRangeModel#getMinimum
|
||||
*/
|
||||
public int getMinimum() {
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model's maximum.
|
||||
* @return the model's maximum
|
||||
* @see #setMaximum
|
||||
* @see BoundedRangeModel#getMaximum
|
||||
*/
|
||||
public int getMaximum() {
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current value of the model. For a slider, that
|
||||
* determines where the knob appears. Ensures that the new
|
||||
* value, <I>n</I> falls within the model's constraints:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
*
|
||||
* @see BoundedRangeModel#setValue
|
||||
*/
|
||||
public void setValue(int n) {
|
||||
n = Math.min(n, Integer.MAX_VALUE - extent);
|
||||
|
||||
int newValue = Math.max(n, min);
|
||||
if (newValue + extent > max) {
|
||||
newValue = max - extent;
|
||||
}
|
||||
setRangeProperties(newValue, extent, min, max, isAdjusting);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the extent to <I>n</I> after ensuring that <I>n</I>
|
||||
* is greater than or equal to zero and falls within the model's
|
||||
* constraints:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* @see BoundedRangeModel#setExtent
|
||||
*/
|
||||
public void setExtent(int n) {
|
||||
int newExtent = Math.max(0, n);
|
||||
if(value + newExtent > max) {
|
||||
newExtent = max - value;
|
||||
}
|
||||
setRangeProperties(value, newExtent, min, max, isAdjusting);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum to <I>n</I> after ensuring that <I>n</I>
|
||||
* that the other three properties obey the model's constraints:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* @see #getMinimum
|
||||
* @see BoundedRangeModel#setMinimum
|
||||
*/
|
||||
public void setMinimum(int n) {
|
||||
int newMax = Math.max(n, max);
|
||||
int newValue = Math.max(n, value);
|
||||
int newExtent = Math.min(newMax - newValue, extent);
|
||||
setRangeProperties(newValue, newExtent, n, newMax, isAdjusting);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the maximum to <I>n</I> after ensuring that <I>n</I>
|
||||
* that the other three properties obey the model's constraints:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* @see BoundedRangeModel#setMaximum
|
||||
*/
|
||||
public void setMaximum(int n) {
|
||||
int newMin = Math.min(n, min);
|
||||
int newExtent = Math.min(n - newMin, extent);
|
||||
int newValue = Math.min(n - newExtent, value);
|
||||
setRangeProperties(newValue, newExtent, newMin, n, isAdjusting);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>valueIsAdjusting</code> property.
|
||||
*
|
||||
* @see #getValueIsAdjusting
|
||||
* @see #setValue
|
||||
* @see BoundedRangeModel#setValueIsAdjusting
|
||||
*/
|
||||
public void setValueIsAdjusting(boolean b) {
|
||||
setRangeProperties(value, extent, min, max, b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the value is in the process of changing
|
||||
* as a result of actions being taken by the user.
|
||||
*
|
||||
* @return the value of the <code>valueIsAdjusting</code> property
|
||||
* @see #setValue
|
||||
* @see BoundedRangeModel#getValueIsAdjusting
|
||||
*/
|
||||
public boolean getValueIsAdjusting() {
|
||||
return isAdjusting;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets all of the <code>BoundedRangeModel</code> properties after forcing
|
||||
* the arguments to obey the usual constraints:
|
||||
* <pre>
|
||||
* minimum <= value <= value+extent <= maximum
|
||||
* </pre>
|
||||
* <p>
|
||||
* At most, one <code>ChangeEvent</code> is generated.
|
||||
*
|
||||
* @see BoundedRangeModel#setRangeProperties
|
||||
* @see #setValue
|
||||
* @see #setExtent
|
||||
* @see #setMinimum
|
||||
* @see #setMaximum
|
||||
* @see #setValueIsAdjusting
|
||||
*/
|
||||
public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting)
|
||||
{
|
||||
if (newMin > newMax) {
|
||||
newMin = newMax;
|
||||
}
|
||||
if (newValue > newMax) {
|
||||
newMax = newValue;
|
||||
}
|
||||
if (newValue < newMin) {
|
||||
newMin = newValue;
|
||||
}
|
||||
|
||||
/* Convert the addends to long so that extent can be
|
||||
* Integer.MAX_VALUE without rolling over the sum.
|
||||
* A JCK test covers this, see bug 4097718.
|
||||
*/
|
||||
if (((long)newExtent + (long)newValue) > newMax) {
|
||||
newExtent = newMax - newValue;
|
||||
}
|
||||
|
||||
if (newExtent < 0) {
|
||||
newExtent = 0;
|
||||
}
|
||||
|
||||
boolean isChange =
|
||||
(newValue != value) ||
|
||||
(newExtent != extent) ||
|
||||
(newMin != min) ||
|
||||
(newMax != max) ||
|
||||
(adjusting != isAdjusting);
|
||||
|
||||
if (isChange) {
|
||||
value = newValue;
|
||||
extent = newExtent;
|
||||
min = newMin;
|
||||
max = newMax;
|
||||
isAdjusting = adjusting;
|
||||
|
||||
fireStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a <code>ChangeListener</code>. The change listeners are run each
|
||||
* time any one of the Bounded Range model properties changes.
|
||||
*
|
||||
* @param l the ChangeListener to add
|
||||
* @see #removeChangeListener
|
||||
* @see BoundedRangeModel#addChangeListener
|
||||
*/
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
listenerList.add(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a <code>ChangeListener</code>.
|
||||
*
|
||||
* @param l the <code>ChangeListener</code> to remove
|
||||
* @see #addChangeListener
|
||||
* @see BoundedRangeModel#removeChangeListener
|
||||
*/
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
listenerList.remove(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the change listeners
|
||||
* registered on this <code>DefaultBoundedRangeModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ChangeListener</code>s
|
||||
* or an empty
|
||||
* array if no change listeners are currently registered
|
||||
*
|
||||
* @see #addChangeListener
|
||||
* @see #removeChangeListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ChangeListener[] getChangeListeners() {
|
||||
return listenerList.getListeners(ChangeListener.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs each <code>ChangeListener</code>'s <code>stateChanged</code> method.
|
||||
*
|
||||
* @see #setRangeProperties
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireStateChanged()
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
for (int i = listeners.length - 2; i >= 0; i -=2 ) {
|
||||
if (listeners[i] == ChangeListener.class) {
|
||||
if (changeEvent == null) {
|
||||
changeEvent = new ChangeEvent(this);
|
||||
}
|
||||
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that displays all of the
|
||||
* <code>BoundedRangeModel</code> properties.
|
||||
*/
|
||||
public String toString() {
|
||||
String modelString =
|
||||
"value=" + getValue() + ", " +
|
||||
"extent=" + getExtent() + ", " +
|
||||
"min=" + getMinimum() + ", " +
|
||||
"max=" + getMaximum() + ", " +
|
||||
"adj=" + getValueIsAdjusting();
|
||||
|
||||
return getClass().getName() + "[" + modelString + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a <code>DefaultBoundedRangeModel</code>
|
||||
* instance <code>m</code>
|
||||
* for its change listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre>
|
||||
*
|
||||
* 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</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getChangeListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
}
|
||||
533
jdkSrc/jdk8/javax/swing/DefaultButtonModel.java
Normal file
533
jdkSrc/jdk8/javax/swing/DefaultButtonModel.java
Normal file
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.EventListener;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
* The default implementation of a <code>Button</code> component's data model.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
public class DefaultButtonModel implements ButtonModel, Serializable {
|
||||
|
||||
/** The bitmask used to store the state of the button. */
|
||||
protected int stateMask = 0;
|
||||
|
||||
/** The action command string fired by the button. */
|
||||
protected String actionCommand = null;
|
||||
|
||||
/** The button group that the button belongs to. */
|
||||
protected ButtonGroup group = null;
|
||||
|
||||
/** The button's mnemonic. */
|
||||
protected int mnemonic = 0;
|
||||
|
||||
/**
|
||||
* Only one <code>ChangeEvent</code> is needed per button model
|
||||
* instance since the event's only state is the source property.
|
||||
* The source of events generated is always "this".
|
||||
*/
|
||||
protected transient ChangeEvent changeEvent = null;
|
||||
|
||||
/** Stores the listeners on this model. */
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
// controls the usage of the MenuItem.disabledAreNavigable UIDefaults
|
||||
// property in the setArmed() method
|
||||
private boolean menuItem = false;
|
||||
|
||||
/**
|
||||
* Constructs a <code>DefaultButtonModel</code>.
|
||||
*
|
||||
*/
|
||||
public DefaultButtonModel() {
|
||||
stateMask = 0;
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the "armed" bit in the bitmask, which
|
||||
* indicates partial commitment towards choosing/triggering
|
||||
* the button.
|
||||
*/
|
||||
public final static int ARMED = 1 << 0;
|
||||
|
||||
/**
|
||||
* Identifies the "selected" bit in the bitmask, which
|
||||
* indicates that the button has been selected. Only needed for
|
||||
* certain types of buttons - such as radio button or check box.
|
||||
*/
|
||||
public final static int SELECTED = 1 << 1;
|
||||
|
||||
/**
|
||||
* Identifies the "pressed" bit in the bitmask, which
|
||||
* indicates that the button is pressed.
|
||||
*/
|
||||
public final static int PRESSED = 1 << 2;
|
||||
|
||||
/**
|
||||
* Identifies the "enabled" bit in the bitmask, which
|
||||
* indicates that the button can be selected by
|
||||
* an input device (such as a mouse pointer).
|
||||
*/
|
||||
public final static int ENABLED = 1 << 3;
|
||||
|
||||
/**
|
||||
* Identifies the "rollover" bit in the bitmask, which
|
||||
* indicates that the mouse is over the button.
|
||||
*/
|
||||
public final static int ROLLOVER = 1 << 4;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setActionCommand(String actionCommand) {
|
||||
this.actionCommand = actionCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getActionCommand() {
|
||||
return actionCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isArmed() {
|
||||
return (stateMask & ARMED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isSelected() {
|
||||
return (stateMask & SELECTED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return (stateMask & ENABLED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isPressed() {
|
||||
return (stateMask & PRESSED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isRollover() {
|
||||
return (stateMask & ROLLOVER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setArmed(boolean b) {
|
||||
if(isMenuItem() &&
|
||||
UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
|
||||
if ((isArmed() == b)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ((isArmed() == b) || !isEnabled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= ARMED;
|
||||
} else {
|
||||
stateMask &= ~ARMED;
|
||||
}
|
||||
|
||||
fireStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setEnabled(boolean b) {
|
||||
if(isEnabled() == b) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= ENABLED;
|
||||
} else {
|
||||
stateMask &= ~ENABLED;
|
||||
// unarm and unpress, just in case
|
||||
stateMask &= ~ARMED;
|
||||
stateMask &= ~PRESSED;
|
||||
}
|
||||
|
||||
|
||||
fireStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setSelected(boolean b) {
|
||||
if (this.isSelected() == b) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= SELECTED;
|
||||
} else {
|
||||
stateMask &= ~SELECTED;
|
||||
}
|
||||
|
||||
fireItemStateChanged(
|
||||
new ItemEvent(this,
|
||||
ItemEvent.ITEM_STATE_CHANGED,
|
||||
this,
|
||||
b ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
|
||||
|
||||
fireStateChanged();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setPressed(boolean b) {
|
||||
if((isPressed() == b) || !isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= PRESSED;
|
||||
} else {
|
||||
stateMask &= ~PRESSED;
|
||||
}
|
||||
|
||||
if(!isPressed() && isArmed()) {
|
||||
int modifiers = 0;
|
||||
AWTEvent currentEvent = EventQueue.getCurrentEvent();
|
||||
if (currentEvent instanceof InputEvent) {
|
||||
modifiers = ((InputEvent)currentEvent).getModifiers();
|
||||
} else if (currentEvent instanceof ActionEvent) {
|
||||
modifiers = ((ActionEvent)currentEvent).getModifiers();
|
||||
}
|
||||
fireActionPerformed(
|
||||
new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
|
||||
getActionCommand(),
|
||||
EventQueue.getMostRecentEventTime(),
|
||||
modifiers));
|
||||
}
|
||||
|
||||
fireStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setRollover(boolean b) {
|
||||
if((isRollover() == b) || !isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= ROLLOVER;
|
||||
} else {
|
||||
stateMask &= ~ROLLOVER;
|
||||
}
|
||||
|
||||
fireStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setMnemonic(int key) {
|
||||
mnemonic = key;
|
||||
fireStateChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int getMnemonic() {
|
||||
return mnemonic;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
listenerList.add(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
listenerList.remove(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the change listeners
|
||||
* registered on this <code>DefaultButtonModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ChangeListener</code>s
|
||||
* or an empty
|
||||
* array if no change listeners are currently registered
|
||||
*
|
||||
* @see #addChangeListener
|
||||
* @see #removeChangeListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ChangeListener[] getChangeListeners() {
|
||||
return listenerList.getListeners(ChangeListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is created lazily.
|
||||
*
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireStateChanged() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ChangeListener.class) {
|
||||
// Lazily create the event:
|
||||
if (changeEvent == null)
|
||||
changeEvent = new ChangeEvent(this);
|
||||
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addActionListener(ActionListener l) {
|
||||
listenerList.add(ActionListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeActionListener(ActionListener l) {
|
||||
listenerList.remove(ActionListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the action listeners
|
||||
* registered on this <code>DefaultButtonModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ActionListener</code>s
|
||||
* or an empty
|
||||
* array if no action listeners are currently registered
|
||||
*
|
||||
* @see #addActionListener
|
||||
* @see #removeActionListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ActionListener[] getActionListeners() {
|
||||
return listenerList.getListeners(ActionListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param e the <code>ActionEvent</code> to deliver to listeners
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireActionPerformed(ActionEvent e) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ActionListener.class) {
|
||||
// Lazily create the event:
|
||||
// if (changeEvent == null)
|
||||
// changeEvent = new ChangeEvent(this);
|
||||
((ActionListener)listeners[i+1]).actionPerformed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addItemListener(ItemListener l) {
|
||||
listenerList.add(ItemListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeItemListener(ItemListener l) {
|
||||
listenerList.remove(ItemListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the item listeners
|
||||
* registered on this <code>DefaultButtonModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ItemListener</code>s
|
||||
* or an empty
|
||||
* array if no item listeners are currently registered
|
||||
*
|
||||
* @see #addItemListener
|
||||
* @see #removeItemListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ItemListener[] getItemListeners() {
|
||||
return listenerList.getListeners(ItemListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param e the <code>ItemEvent</code> to deliver to listeners
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireItemStateChanged(ItemEvent e) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ItemListener.class) {
|
||||
// Lazily create the event:
|
||||
// if (changeEvent == null)
|
||||
// changeEvent = new ChangeEvent(this);
|
||||
((ItemListener)listeners[i+1]).itemStateChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a <code>DefaultButtonModel</code>
|
||||
* instance <code>m</code>
|
||||
* for its action listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>
|
||||
*
|
||||
* 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</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getActionListeners
|
||||
* @see #getChangeListeners
|
||||
* @see #getItemListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
|
||||
/** Overridden to return <code>null</code>. */
|
||||
public Object[] getSelectedObjects() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setGroup(ButtonGroup group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group that the button belongs to.
|
||||
* Normally used with radio buttons, which are mutually
|
||||
* exclusive within their group.
|
||||
*
|
||||
* @return the <code>ButtonGroup</code> that the button belongs to
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public ButtonGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
boolean isMenuItem() {
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
void setMenuItem(boolean menuItem) {
|
||||
this.menuItem = menuItem;
|
||||
}
|
||||
}
|
||||
398
jdkSrc/jdk8/javax/swing/DefaultCellEditor.java
Normal file
398
jdkSrc/jdk8/javax/swing/DefaultCellEditor.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.lang.Boolean;
|
||||
import javax.swing.table.*;
|
||||
import javax.swing.event.*;
|
||||
import java.util.EventObject;
|
||||
import javax.swing.tree.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The default editor for table and tree cells.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Alan Chung
|
||||
* @author Philip Milne
|
||||
*/
|
||||
|
||||
public class DefaultCellEditor extends AbstractCellEditor
|
||||
implements TableCellEditor, TreeCellEditor {
|
||||
|
||||
//
|
||||
// Instance Variables
|
||||
//
|
||||
|
||||
/** The Swing component being edited. */
|
||||
protected JComponent editorComponent;
|
||||
/**
|
||||
* The delegate class which handles all methods sent from the
|
||||
* <code>CellEditor</code>.
|
||||
*/
|
||||
protected EditorDelegate delegate;
|
||||
/**
|
||||
* An integer specifying the number of clicks needed to start editing.
|
||||
* Even if <code>clickCountToStart</code> is defined as zero, it
|
||||
* will not initiate until a click occurs.
|
||||
*/
|
||||
protected int clickCountToStart = 1;
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
/**
|
||||
* Constructs a <code>DefaultCellEditor</code> that uses a text field.
|
||||
*
|
||||
* @param textField a <code>JTextField</code> object
|
||||
*/
|
||||
@ConstructorProperties({"component"})
|
||||
public DefaultCellEditor(final JTextField textField) {
|
||||
editorComponent = textField;
|
||||
this.clickCountToStart = 2;
|
||||
delegate = new EditorDelegate() {
|
||||
public void setValue(Object value) {
|
||||
textField.setText((value != null) ? value.toString() : "");
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
return textField.getText();
|
||||
}
|
||||
};
|
||||
textField.addActionListener(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>DefaultCellEditor</code> object that uses a check box.
|
||||
*
|
||||
* @param checkBox a <code>JCheckBox</code> object
|
||||
*/
|
||||
public DefaultCellEditor(final JCheckBox checkBox) {
|
||||
editorComponent = checkBox;
|
||||
delegate = new EditorDelegate() {
|
||||
public void setValue(Object value) {
|
||||
boolean selected = false;
|
||||
if (value instanceof Boolean) {
|
||||
selected = ((Boolean)value).booleanValue();
|
||||
}
|
||||
else if (value instanceof String) {
|
||||
selected = value.equals("true");
|
||||
}
|
||||
checkBox.setSelected(selected);
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
return Boolean.valueOf(checkBox.isSelected());
|
||||
}
|
||||
};
|
||||
checkBox.addActionListener(delegate);
|
||||
checkBox.setRequestFocusEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>DefaultCellEditor</code> object that uses a
|
||||
* combo box.
|
||||
*
|
||||
* @param comboBox a <code>JComboBox</code> object
|
||||
*/
|
||||
public DefaultCellEditor(final JComboBox comboBox) {
|
||||
editorComponent = comboBox;
|
||||
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
|
||||
delegate = new EditorDelegate() {
|
||||
public void setValue(Object value) {
|
||||
comboBox.setSelectedItem(value);
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
return comboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
public boolean shouldSelectCell(EventObject anEvent) {
|
||||
if (anEvent instanceof MouseEvent) {
|
||||
MouseEvent e = (MouseEvent)anEvent;
|
||||
return e.getID() != MouseEvent.MOUSE_DRAGGED;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean stopCellEditing() {
|
||||
if (comboBox.isEditable()) {
|
||||
// Commit edited value.
|
||||
comboBox.actionPerformed(new ActionEvent(
|
||||
DefaultCellEditor.this, 0, ""));
|
||||
}
|
||||
return super.stopCellEditing();
|
||||
}
|
||||
};
|
||||
comboBox.addActionListener(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the editor component.
|
||||
*
|
||||
* @return the editor <code>Component</code>
|
||||
*/
|
||||
public Component getComponent() {
|
||||
return editorComponent;
|
||||
}
|
||||
|
||||
//
|
||||
// Modifying
|
||||
//
|
||||
|
||||
/**
|
||||
* Specifies the number of clicks needed to start editing.
|
||||
*
|
||||
* @param count an int specifying the number of clicks needed to start editing
|
||||
* @see #getClickCountToStart
|
||||
*/
|
||||
public void setClickCountToStart(int count) {
|
||||
clickCountToStart = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of clicks needed to start editing.
|
||||
* @return the number of clicks needed to start editing
|
||||
*/
|
||||
public int getClickCountToStart() {
|
||||
return clickCountToStart;
|
||||
}
|
||||
|
||||
//
|
||||
// Override the implementations of the superclass, forwarding all methods
|
||||
// from the CellEditor interface to our delegate.
|
||||
//
|
||||
|
||||
/**
|
||||
* Forwards the message from the <code>CellEditor</code> to
|
||||
* the <code>delegate</code>.
|
||||
* @see EditorDelegate#getCellEditorValue
|
||||
*/
|
||||
public Object getCellEditorValue() {
|
||||
return delegate.getCellEditorValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the message from the <code>CellEditor</code> to
|
||||
* the <code>delegate</code>.
|
||||
* @see EditorDelegate#isCellEditable(EventObject)
|
||||
*/
|
||||
public boolean isCellEditable(EventObject anEvent) {
|
||||
return delegate.isCellEditable(anEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the message from the <code>CellEditor</code> to
|
||||
* the <code>delegate</code>.
|
||||
* @see EditorDelegate#shouldSelectCell(EventObject)
|
||||
*/
|
||||
public boolean shouldSelectCell(EventObject anEvent) {
|
||||
return delegate.shouldSelectCell(anEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the message from the <code>CellEditor</code> to
|
||||
* the <code>delegate</code>.
|
||||
* @see EditorDelegate#stopCellEditing
|
||||
*/
|
||||
public boolean stopCellEditing() {
|
||||
return delegate.stopCellEditing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the message from the <code>CellEditor</code> to
|
||||
* the <code>delegate</code>.
|
||||
* @see EditorDelegate#cancelCellEditing
|
||||
*/
|
||||
public void cancelCellEditing() {
|
||||
delegate.cancelCellEditing();
|
||||
}
|
||||
|
||||
//
|
||||
// Implementing the TreeCellEditor Interface
|
||||
//
|
||||
|
||||
/** Implements the <code>TreeCellEditor</code> interface. */
|
||||
public Component getTreeCellEditorComponent(JTree tree, Object value,
|
||||
boolean isSelected,
|
||||
boolean expanded,
|
||||
boolean leaf, int row) {
|
||||
String stringValue = tree.convertValueToText(value, isSelected,
|
||||
expanded, leaf, row, false);
|
||||
|
||||
delegate.setValue(stringValue);
|
||||
return editorComponent;
|
||||
}
|
||||
|
||||
//
|
||||
// Implementing the CellEditor Interface
|
||||
//
|
||||
/** Implements the <code>TableCellEditor</code> interface. */
|
||||
public Component getTableCellEditorComponent(JTable table, Object value,
|
||||
boolean isSelected,
|
||||
int row, int column) {
|
||||
delegate.setValue(value);
|
||||
if (editorComponent instanceof JCheckBox) {
|
||||
//in order to avoid a "flashing" effect when clicking a checkbox
|
||||
//in a table, it is important for the editor to have as a border
|
||||
//the same border that the renderer has, and have as the background
|
||||
//the same color as the renderer has. This is primarily only
|
||||
//needed for JCheckBox since this editor doesn't fill all the
|
||||
//visual space of the table cell, unlike a text field.
|
||||
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
||||
Component c = renderer.getTableCellRendererComponent(table, value,
|
||||
isSelected, true, row, column);
|
||||
if (c != null) {
|
||||
editorComponent.setOpaque(true);
|
||||
editorComponent.setBackground(c.getBackground());
|
||||
if (c instanceof JComponent) {
|
||||
editorComponent.setBorder(((JComponent)c).getBorder());
|
||||
}
|
||||
} else {
|
||||
editorComponent.setOpaque(false);
|
||||
}
|
||||
}
|
||||
return editorComponent;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Protected EditorDelegate class
|
||||
//
|
||||
|
||||
/**
|
||||
* The protected <code>EditorDelegate</code> class.
|
||||
*/
|
||||
protected class EditorDelegate implements ActionListener, ItemListener, Serializable {
|
||||
|
||||
/** The value of this cell. */
|
||||
protected Object value;
|
||||
|
||||
/**
|
||||
* Returns the value of this cell.
|
||||
* @return the value of this cell
|
||||
*/
|
||||
public Object getCellEditorValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this cell.
|
||||
* @param value the new value of this cell
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if <code>anEvent</code> is <b>not</b> a
|
||||
* <code>MouseEvent</code>. Otherwise, it returns true
|
||||
* if the necessary number of clicks have occurred, and
|
||||
* returns false otherwise.
|
||||
*
|
||||
* @param anEvent the event
|
||||
* @return true if cell is ready for editing, false otherwise
|
||||
* @see #setClickCountToStart
|
||||
* @see #shouldSelectCell
|
||||
*/
|
||||
public boolean isCellEditable(EventObject anEvent) {
|
||||
if (anEvent instanceof MouseEvent) {
|
||||
return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true to indicate that the editing cell may
|
||||
* be selected.
|
||||
*
|
||||
* @param anEvent the event
|
||||
* @return true
|
||||
* @see #isCellEditable
|
||||
*/
|
||||
public boolean shouldSelectCell(EventObject anEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true to indicate that editing has begun.
|
||||
*
|
||||
* @param anEvent the event
|
||||
*/
|
||||
public boolean startCellEditing(EventObject anEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops editing and
|
||||
* returns true to indicate that editing has stopped.
|
||||
* This method calls <code>fireEditingStopped</code>.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public boolean stopCellEditing() {
|
||||
fireEditingStopped();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels editing. This method calls <code>fireEditingCanceled</code>.
|
||||
*/
|
||||
public void cancelCellEditing() {
|
||||
fireEditingCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
* When an action is performed, editing is ended.
|
||||
* @param e the action event
|
||||
* @see #stopCellEditing
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DefaultCellEditor.this.stopCellEditing();
|
||||
}
|
||||
|
||||
/**
|
||||
* When an item's state changes, editing is ended.
|
||||
* @param e the action event
|
||||
* @see #stopCellEditing
|
||||
*/
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
DefaultCellEditor.this.stopCellEditing();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of class JCellEditor
|
||||
179
jdkSrc/jdk8/javax/swing/DefaultComboBoxModel.java
Normal file
179
jdkSrc/jdk8/javax/swing/DefaultComboBoxModel.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 javax.swing;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The default model for combo boxes.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
* @author Tom Santos
|
||||
*/
|
||||
|
||||
public class DefaultComboBoxModel<E> extends AbstractListModel<E> implements MutableComboBoxModel<E>, Serializable {
|
||||
Vector<E> objects;
|
||||
Object selectedObject;
|
||||
|
||||
/**
|
||||
* Constructs an empty DefaultComboBoxModel object.
|
||||
*/
|
||||
public DefaultComboBoxModel() {
|
||||
objects = new Vector<E>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DefaultComboBoxModel object initialized with
|
||||
* an array of objects.
|
||||
*
|
||||
* @param items an array of Object objects
|
||||
*/
|
||||
public DefaultComboBoxModel(final E items[]) {
|
||||
objects = new Vector<E>(items.length);
|
||||
|
||||
int i,c;
|
||||
for ( i=0,c=items.length;i<c;i++ )
|
||||
objects.addElement(items[i]);
|
||||
|
||||
if ( getSize() > 0 ) {
|
||||
selectedObject = getElementAt( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DefaultComboBoxModel object initialized with
|
||||
* a vector.
|
||||
*
|
||||
* @param v a Vector object ...
|
||||
*/
|
||||
public DefaultComboBoxModel(Vector<E> v) {
|
||||
objects = v;
|
||||
|
||||
if ( getSize() > 0 ) {
|
||||
selectedObject = getElementAt( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.ComboBoxModel
|
||||
/**
|
||||
* Set the value of the selected item. The selected item may be null.
|
||||
*
|
||||
* @param anObject The combo box value or null for no selection.
|
||||
*/
|
||||
public void setSelectedItem(Object anObject) {
|
||||
if ((selectedObject != null && !selectedObject.equals( anObject )) ||
|
||||
selectedObject == null && anObject != null) {
|
||||
selectedObject = anObject;
|
||||
fireContentsChanged(this, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.ComboBoxModel
|
||||
public Object getSelectedItem() {
|
||||
return selectedObject;
|
||||
}
|
||||
|
||||
// implements javax.swing.ListModel
|
||||
public int getSize() {
|
||||
return objects.size();
|
||||
}
|
||||
|
||||
// implements javax.swing.ListModel
|
||||
public E getElementAt(int index) {
|
||||
if ( index >= 0 && index < objects.size() )
|
||||
return objects.elementAt(index);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index-position of the specified object in the list.
|
||||
*
|
||||
* @param anObject
|
||||
* @return an int representing the index position, where 0 is
|
||||
* the first position
|
||||
*/
|
||||
public int getIndexOf(Object anObject) {
|
||||
return objects.indexOf(anObject);
|
||||
}
|
||||
|
||||
// implements javax.swing.MutableComboBoxModel
|
||||
public void addElement(E anObject) {
|
||||
objects.addElement(anObject);
|
||||
fireIntervalAdded(this,objects.size()-1, objects.size()-1);
|
||||
if ( objects.size() == 1 && selectedObject == null && anObject != null ) {
|
||||
setSelectedItem( anObject );
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.MutableComboBoxModel
|
||||
public void insertElementAt(E anObject,int index) {
|
||||
objects.insertElementAt(anObject,index);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
// implements javax.swing.MutableComboBoxModel
|
||||
public void removeElementAt(int index) {
|
||||
if ( getElementAt( index ) == selectedObject ) {
|
||||
if ( index == 0 ) {
|
||||
setSelectedItem( getSize() == 1 ? null : getElementAt( index + 1 ) );
|
||||
}
|
||||
else {
|
||||
setSelectedItem( getElementAt( index - 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
objects.removeElementAt(index);
|
||||
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
|
||||
// implements javax.swing.MutableComboBoxModel
|
||||
public void removeElement(Object anObject) {
|
||||
int index = objects.indexOf(anObject);
|
||||
if ( index != -1 ) {
|
||||
removeElementAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the list.
|
||||
*/
|
||||
public void removeAllElements() {
|
||||
if ( objects.size() > 0 ) {
|
||||
int firstIndex = 0;
|
||||
int lastIndex = objects.size() - 1;
|
||||
objects.removeAllElements();
|
||||
selectedObject = null;
|
||||
fireIntervalRemoved(this, firstIndex, lastIndex);
|
||||
} else {
|
||||
selectedObject = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
815
jdkSrc/jdk8/javax/swing/DefaultDesktopManager.java
Normal file
815
jdkSrc/jdk8/javax/swing/DefaultDesktopManager.java
Normal file
@@ -0,0 +1,815 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 javax.swing;
|
||||
|
||||
import com.sun.awt.AWTUtilities;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyVetoException;
|
||||
|
||||
/** This is an implementation of the <code>DesktopManager</code>.
|
||||
* It currently implements the basic behaviors for managing
|
||||
* <code>JInternalFrame</code>s in an arbitrary parent.
|
||||
* <code>JInternalFrame</code>s that are not children of a
|
||||
* <code>JDesktop</code> will use this component
|
||||
* to handle their desktop-like actions.
|
||||
* <p>This class provides a policy for the various JInternalFrame methods,
|
||||
* it is not meant to be called directly rather the various JInternalFrame
|
||||
* methods will call into the DesktopManager.</p>
|
||||
* @see JDesktopPane
|
||||
* @see JInternalFrame
|
||||
* @author David Kloba
|
||||
* @author Steve Wilson
|
||||
*/
|
||||
public class DefaultDesktopManager implements DesktopManager, java.io.Serializable {
|
||||
final static String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce";
|
||||
|
||||
final static int DEFAULT_DRAG_MODE = 0;
|
||||
final static int OUTLINE_DRAG_MODE = 1;
|
||||
final static int FASTER_DRAG_MODE = 2;
|
||||
|
||||
int dragMode = DEFAULT_DRAG_MODE;
|
||||
|
||||
private transient Rectangle currentBounds = null;
|
||||
private transient Graphics desktopGraphics = null;
|
||||
private transient Rectangle desktopBounds = null;
|
||||
private transient Rectangle[] floatingItems = {};
|
||||
|
||||
/**
|
||||
* Set to true when the user actually drags a frame vs clicks on it
|
||||
* to start the drag operation. This is only used when dragging with
|
||||
* FASTER_DRAG_MODE.
|
||||
*/
|
||||
private transient boolean didDrag;
|
||||
|
||||
/** Normally this method will not be called. If it is, it
|
||||
* try to determine the appropriate parent from the desktopIcon of the frame.
|
||||
* Will remove the desktopIcon from its parent if it successfully adds the frame.
|
||||
*/
|
||||
public void openFrame(JInternalFrame f) {
|
||||
if(f.getDesktopIcon().getParent() != null) {
|
||||
f.getDesktopIcon().getParent().add(f);
|
||||
removeIconFor(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the frame, and, if necessary, the
|
||||
* <code>desktopIcon</code>, from its parent.
|
||||
* @param f the <code>JInternalFrame</code> to be removed
|
||||
*/
|
||||
public void closeFrame(JInternalFrame f) {
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
if (d == null) {
|
||||
return;
|
||||
}
|
||||
boolean findNext = f.isSelected();
|
||||
Container c = f.getParent();
|
||||
JInternalFrame nextFrame = null;
|
||||
if (findNext) {
|
||||
nextFrame = d.getNextFrame(f);
|
||||
try { f.setSelected(false); } catch (PropertyVetoException e2) { }
|
||||
}
|
||||
if(c != null) {
|
||||
c.remove(f); // Removes the focus.
|
||||
c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
|
||||
}
|
||||
removeIconFor(f);
|
||||
if(f.getNormalBounds() != null)
|
||||
f.setNormalBounds(null);
|
||||
if(wasIcon(f))
|
||||
setWasIcon(f, null);
|
||||
if (nextFrame != null) {
|
||||
try { nextFrame.setSelected(true); }
|
||||
catch (PropertyVetoException e2) { }
|
||||
} else if (findNext && d.getComponentCount() == 0) {
|
||||
// It was selected and was the last component on the desktop.
|
||||
d.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes the frame to fill its parents bounds.
|
||||
* @param f the frame to be resized
|
||||
*/
|
||||
public void maximizeFrame(JInternalFrame f) {
|
||||
if (f.isIcon()) {
|
||||
try {
|
||||
// In turn calls deiconifyFrame in the desktop manager.
|
||||
// That method will handle the maximization of the frame.
|
||||
f.setIcon(false);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
} else {
|
||||
f.setNormalBounds(f.getBounds());
|
||||
Rectangle desktopBounds = f.getParent().getBounds();
|
||||
setBoundsForFrame(f, 0, 0,
|
||||
desktopBounds.width, desktopBounds.height);
|
||||
}
|
||||
|
||||
// Set the maximized frame as selected.
|
||||
try {
|
||||
f.setSelected(true);
|
||||
} catch (PropertyVetoException e2) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the frame back to its size and position prior
|
||||
* to a <code>maximizeFrame</code> call.
|
||||
* @param f the <code>JInternalFrame</code> to be restored
|
||||
*/
|
||||
public void minimizeFrame(JInternalFrame f) {
|
||||
// If the frame was an icon restore it back to an icon.
|
||||
if (f.isIcon()) {
|
||||
iconifyFrame(f);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((f.getNormalBounds()) != null) {
|
||||
Rectangle r = f.getNormalBounds();
|
||||
f.setNormalBounds(null);
|
||||
try { f.setSelected(true); } catch (PropertyVetoException e2) { }
|
||||
setBoundsForFrame(f, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the frame from its parent and adds its
|
||||
* <code>desktopIcon</code> to the parent.
|
||||
* @param f the <code>JInternalFrame</code> to be iconified
|
||||
*/
|
||||
public void iconifyFrame(JInternalFrame f) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon;
|
||||
Container c = f.getParent();
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
boolean findNext = f.isSelected();
|
||||
desktopIcon = f.getDesktopIcon();
|
||||
if(!wasIcon(f)) {
|
||||
Rectangle r = getBoundsForIconOf(f);
|
||||
desktopIcon.setBounds(r.x, r.y, r.width, r.height);
|
||||
// we must validate the hierarchy to not break the hw/lw mixing
|
||||
desktopIcon.revalidate();
|
||||
setWasIcon(f, Boolean.TRUE);
|
||||
}
|
||||
|
||||
if (c == null || d == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (c instanceof JLayeredPane) {
|
||||
JLayeredPane lp = (JLayeredPane)c;
|
||||
int layer = lp.getLayer(f);
|
||||
lp.putLayer(desktopIcon, layer);
|
||||
}
|
||||
|
||||
// If we are maximized we already have the normal bounds recorded
|
||||
// don't try to re-record them, otherwise we incorrectly set the
|
||||
// normal bounds to maximized state.
|
||||
if (!f.isMaximum()) {
|
||||
f.setNormalBounds(f.getBounds());
|
||||
}
|
||||
d.setComponentOrderCheckingEnabled(false);
|
||||
c.remove(f);
|
||||
c.add(desktopIcon);
|
||||
d.setComponentOrderCheckingEnabled(true);
|
||||
c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
|
||||
if (findNext) {
|
||||
if (d.selectFrame(true) == null) {
|
||||
// The icon is the last frame.
|
||||
f.restoreSubcomponentFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the desktopIcon from its parent and adds its frame
|
||||
* to the parent.
|
||||
* @param f the <code>JInternalFrame</code> to be de-iconified
|
||||
*/
|
||||
public void deiconifyFrame(JInternalFrame f) {
|
||||
JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
|
||||
Container c = desktopIcon.getParent();
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
if (c != null && d != null) {
|
||||
c.add(f);
|
||||
// If the frame is to be restored to a maximized state make
|
||||
// sure it still fills the whole desktop.
|
||||
if (f.isMaximum()) {
|
||||
Rectangle desktopBounds = c.getBounds();
|
||||
if (f.getWidth() != desktopBounds.width ||
|
||||
f.getHeight() != desktopBounds.height) {
|
||||
setBoundsForFrame(f, 0, 0,
|
||||
desktopBounds.width, desktopBounds.height);
|
||||
}
|
||||
}
|
||||
removeIconFor(f);
|
||||
if (f.isSelected()) {
|
||||
f.moveToFront();
|
||||
f.restoreSubcomponentFocus();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
f.setSelected(true);
|
||||
} catch (PropertyVetoException e2) {}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This will activate <b>f</b> moving it to the front. It will
|
||||
* set the current active frame's (if any)
|
||||
* <code>IS_SELECTED_PROPERTY</code> to <code>false</code>.
|
||||
* There can be only one active frame across all Layers.
|
||||
* @param f the <code>JInternalFrame</code> to be activated
|
||||
*/
|
||||
public void activateFrame(JInternalFrame f) {
|
||||
Container p = f.getParent();
|
||||
Component[] c;
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
JInternalFrame currentlyActiveFrame =
|
||||
(d == null) ? null : d.getSelectedFrame();
|
||||
// fix for bug: 4162443
|
||||
if(p == null) {
|
||||
// If the frame is not in parent, its icon maybe, check it
|
||||
p = f.getDesktopIcon().getParent();
|
||||
if(p == null)
|
||||
return;
|
||||
}
|
||||
// we only need to keep track of the currentActive InternalFrame, if any
|
||||
if (currentlyActiveFrame == null){
|
||||
if (d != null) { d.setSelectedFrame(f);}
|
||||
} else if (currentlyActiveFrame != f) {
|
||||
// if not the same frame as the current active
|
||||
// we deactivate the current
|
||||
if (currentlyActiveFrame.isSelected()) {
|
||||
try {
|
||||
currentlyActiveFrame.setSelected(false);
|
||||
}
|
||||
catch(PropertyVetoException e2) {}
|
||||
}
|
||||
if (d != null) { d.setSelectedFrame(f);}
|
||||
}
|
||||
f.moveToFront();
|
||||
}
|
||||
|
||||
// implements javax.swing.DesktopManager
|
||||
public void deactivateFrame(JInternalFrame f) {
|
||||
JDesktopPane d = f.getDesktopPane();
|
||||
JInternalFrame currentlyActiveFrame =
|
||||
(d == null) ? null : d.getSelectedFrame();
|
||||
if (currentlyActiveFrame == f)
|
||||
d.setSelectedFrame(null);
|
||||
}
|
||||
|
||||
// implements javax.swing.DesktopManager
|
||||
public void beginDraggingFrame(JComponent f) {
|
||||
setupDragMode(f);
|
||||
|
||||
if (dragMode == FASTER_DRAG_MODE) {
|
||||
Component desktop = f.getParent();
|
||||
floatingItems = findFloatingItems(f);
|
||||
currentBounds = f.getBounds();
|
||||
if (desktop instanceof JComponent) {
|
||||
desktopBounds = ((JComponent)desktop).getVisibleRect();
|
||||
}
|
||||
else {
|
||||
desktopBounds = desktop.getBounds();
|
||||
desktopBounds.x = desktopBounds.y = 0;
|
||||
}
|
||||
desktopGraphics = JComponent.safelyGetGraphics(desktop);
|
||||
((JInternalFrame)f).isDragging = true;
|
||||
didDrag = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setupDragMode(JComponent f) {
|
||||
JDesktopPane p = getDesktopPane(f);
|
||||
Container parent = f.getParent();
|
||||
dragMode = DEFAULT_DRAG_MODE;
|
||||
if (p != null) {
|
||||
String mode = (String)p.getClientProperty("JDesktopPane.dragMode");
|
||||
Window window = SwingUtilities.getWindowAncestor(f);
|
||||
if (window != null && !AWTUtilities.isWindowOpaque(window)) {
|
||||
dragMode = DEFAULT_DRAG_MODE;
|
||||
} else if (mode != null && mode.equals("outline")) {
|
||||
dragMode = OUTLINE_DRAG_MODE;
|
||||
} else if (mode != null && mode.equals("faster")
|
||||
&& f instanceof JInternalFrame
|
||||
&& ((JInternalFrame)f).isOpaque() &&
|
||||
(parent == null || parent.isOpaque())) {
|
||||
dragMode = FASTER_DRAG_MODE;
|
||||
} else {
|
||||
if (p.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE ) {
|
||||
dragMode = OUTLINE_DRAG_MODE;
|
||||
} else if ( p.getDragMode() == JDesktopPane.LIVE_DRAG_MODE
|
||||
&& f instanceof JInternalFrame
|
||||
&& ((JInternalFrame)f).isOpaque()) {
|
||||
dragMode = FASTER_DRAG_MODE;
|
||||
} else {
|
||||
dragMode = DEFAULT_DRAG_MODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private transient Point currentLoc = null;
|
||||
|
||||
/**
|
||||
* Moves the visible location of the frame being dragged
|
||||
* to the location specified. The means by which this occurs can vary depending
|
||||
* on the dragging algorithm being used. The actual logical location of the frame
|
||||
* might not change until <code>endDraggingFrame</code> is called.
|
||||
*/
|
||||
public void dragFrame(JComponent f, int newX, int newY) {
|
||||
|
||||
if (dragMode == OUTLINE_DRAG_MODE) {
|
||||
JDesktopPane desktopPane = getDesktopPane(f);
|
||||
if (desktopPane != null){
|
||||
Graphics g = JComponent.safelyGetGraphics(desktopPane);
|
||||
|
||||
g.setXORMode(Color.white);
|
||||
if (currentLoc != null) {
|
||||
g.drawRect(currentLoc.x, currentLoc.y,
|
||||
f.getWidth()-1, f.getHeight()-1);
|
||||
}
|
||||
g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
|
||||
/* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
|
||||
* Swing doesn't expect that its XOR drawRect did
|
||||
* not complete, so believes that on re-entering at
|
||||
* the next update location, that there is an XOR rect
|
||||
* to draw out at "currentLoc". But in fact
|
||||
* its now got a new clean surface without that rect,
|
||||
* so drawing it "out" in fact draws it on, leaving garbage.
|
||||
* So only update/set currentLoc if the draw completed.
|
||||
*/
|
||||
sun.java2d.SurfaceData sData =
|
||||
((sun.java2d.SunGraphics2D)g).getSurfaceData();
|
||||
|
||||
if (!sData.isSurfaceLost()) {
|
||||
currentLoc = new Point (newX, newY);
|
||||
}
|
||||
;
|
||||
g.dispose();
|
||||
}
|
||||
} else if (dragMode == FASTER_DRAG_MODE) {
|
||||
dragFrameFaster(f, newX, newY);
|
||||
} else {
|
||||
setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.DesktopManager
|
||||
public void endDraggingFrame(JComponent f) {
|
||||
if ( dragMode == OUTLINE_DRAG_MODE && currentLoc != null) {
|
||||
setBoundsForFrame(f, currentLoc.x, currentLoc.y, f.getWidth(), f.getHeight() );
|
||||
currentLoc = null;
|
||||
} else if (dragMode == FASTER_DRAG_MODE) {
|
||||
currentBounds = null;
|
||||
if (desktopGraphics != null) {
|
||||
desktopGraphics.dispose();
|
||||
desktopGraphics = null;
|
||||
}
|
||||
desktopBounds = null;
|
||||
((JInternalFrame)f).isDragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.DesktopManager
|
||||
public void beginResizingFrame(JComponent f, int direction) {
|
||||
setupDragMode(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>setBoundsForFrame</code> with the new values.
|
||||
* @param f the component to be resized
|
||||
* @param newX the new x-coordinate
|
||||
* @param newY the new y-coordinate
|
||||
* @param newWidth the new width
|
||||
* @param newHeight the new height
|
||||
*/
|
||||
public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
|
||||
|
||||
if ( dragMode == DEFAULT_DRAG_MODE || dragMode == FASTER_DRAG_MODE ) {
|
||||
setBoundsForFrame(f, newX, newY, newWidth, newHeight);
|
||||
} else {
|
||||
JDesktopPane desktopPane = getDesktopPane(f);
|
||||
if (desktopPane != null){
|
||||
Graphics g = JComponent.safelyGetGraphics(desktopPane);
|
||||
|
||||
g.setXORMode(Color.white);
|
||||
if (currentBounds != null) {
|
||||
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
|
||||
}
|
||||
g.drawRect( newX, newY, newWidth-1, newHeight-1);
|
||||
|
||||
// Work around for 6635462, see comment in dragFrame()
|
||||
sun.java2d.SurfaceData sData =
|
||||
((sun.java2d.SunGraphics2D)g).getSurfaceData();
|
||||
if (!sData.isSurfaceLost()) {
|
||||
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
|
||||
}
|
||||
|
||||
g.setPaintMode();
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// implements javax.swing.DesktopManager
|
||||
public void endResizingFrame(JComponent f) {
|
||||
if ( dragMode == OUTLINE_DRAG_MODE && currentBounds != null) {
|
||||
setBoundsForFrame(f, currentBounds.x, currentBounds.y, currentBounds.width, currentBounds.height );
|
||||
currentBounds = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** This moves the <code>JComponent</code> and repaints the damaged areas. */
|
||||
public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
|
||||
f.setBounds(newX, newY, newWidth, newHeight);
|
||||
// we must validate the hierarchy to not break the hw/lw mixing
|
||||
f.revalidate();
|
||||
}
|
||||
|
||||
/** Convenience method to remove the desktopIcon of <b>f</b> is necessary. */
|
||||
protected void removeIconFor(JInternalFrame f) {
|
||||
JInternalFrame.JDesktopIcon di = f.getDesktopIcon();
|
||||
Container c = di.getParent();
|
||||
if(c != null) {
|
||||
c.remove(di);
|
||||
c.repaint(di.getX(), di.getY(), di.getWidth(), di.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
/** The iconifyFrame() code calls this to determine the proper bounds
|
||||
* for the desktopIcon.
|
||||
*/
|
||||
|
||||
protected Rectangle getBoundsForIconOf(JInternalFrame f) {
|
||||
//
|
||||
// Get the icon for this internal frame and its preferred size
|
||||
//
|
||||
|
||||
JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
|
||||
Dimension prefSize = icon.getPreferredSize();
|
||||
//
|
||||
// Get the parent bounds and child components.
|
||||
//
|
||||
|
||||
Container c = f.getParent();
|
||||
if (c == null) {
|
||||
c = f.getDesktopIcon().getParent();
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
/* the frame has not yet been added to the parent; how about (0,0) ?*/
|
||||
return new Rectangle(0, 0, prefSize.width, prefSize.height);
|
||||
}
|
||||
|
||||
Rectangle parentBounds = c.getBounds();
|
||||
Component [] components = c.getComponents();
|
||||
|
||||
|
||||
//
|
||||
// Iterate through valid default icon locations and return the
|
||||
// first one that does not intersect any other icons.
|
||||
//
|
||||
|
||||
Rectangle availableRectangle = null;
|
||||
JInternalFrame.JDesktopIcon currentIcon = null;
|
||||
|
||||
int x = 0;
|
||||
int y = parentBounds.height - prefSize.height;
|
||||
int w = prefSize.width;
|
||||
int h = prefSize.height;
|
||||
|
||||
boolean found = false;
|
||||
|
||||
while (!found) {
|
||||
|
||||
availableRectangle = new Rectangle(x,y,w,h);
|
||||
|
||||
found = true;
|
||||
|
||||
for ( int i=0; i<components.length; i++ ) {
|
||||
|
||||
//
|
||||
// Get the icon for this component
|
||||
//
|
||||
|
||||
if ( components[i] instanceof JInternalFrame ) {
|
||||
currentIcon = ((JInternalFrame)components[i]).getDesktopIcon();
|
||||
}
|
||||
else if ( components[i] instanceof JInternalFrame.JDesktopIcon ){
|
||||
currentIcon = (JInternalFrame.JDesktopIcon)components[i];
|
||||
} else
|
||||
/* found a child that's neither an internal frame nor
|
||||
an icon. I don't believe this should happen, but at
|
||||
present it does and causes a null pointer exception.
|
||||
Even when that gets fixed, this code protects against
|
||||
the npe. hania */
|
||||
continue;
|
||||
|
||||
//
|
||||
// If this icon intersects the current location, get next location.
|
||||
//
|
||||
|
||||
if ( !currentIcon.equals(icon) ) {
|
||||
if ( availableRectangle.intersects(currentIcon.getBounds()) ) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentIcon == null)
|
||||
/* didn't find any useful children above. This probably shouldn't
|
||||
happen, but this check protects against an npe if it ever does
|
||||
(and it's happening now) */
|
||||
return availableRectangle;
|
||||
|
||||
x += currentIcon.getBounds().width;
|
||||
|
||||
if ( x + w > parentBounds.width ) {
|
||||
x = 0;
|
||||
y -= h;
|
||||
}
|
||||
}
|
||||
|
||||
return(availableRectangle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the bounds of the component just before a maximize call.
|
||||
* @param f the component about to be resized
|
||||
* @param r the normal bounds to be saved away
|
||||
*/
|
||||
protected void setPreviousBounds(JInternalFrame f, Rectangle r) {
|
||||
f.setNormalBounds(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the normal bounds of the component prior to the component
|
||||
* being maximized.
|
||||
* @param f the <code>JInternalFrame</code> of interest
|
||||
* @return the normal bounds of the component
|
||||
*/
|
||||
protected Rectangle getPreviousBounds(JInternalFrame f) {
|
||||
return f.getNormalBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets that the component has been iconized and the bounds of the
|
||||
* <code>desktopIcon</code> are valid.
|
||||
*/
|
||||
protected void setWasIcon(JInternalFrame f, Boolean value) {
|
||||
if (value != null) {
|
||||
f.putClientProperty(HAS_BEEN_ICONIFIED_PROPERTY, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the component has been iconized
|
||||
* and the bounds of the <code>desktopIcon</code> are valid,
|
||||
* otherwise returns <code>false</code>.
|
||||
*
|
||||
* @param f the <code>JInternalFrame</code> of interest
|
||||
* @return <code>true</code> if the component has been iconized;
|
||||
* otherwise returns <code>false</code>
|
||||
*/
|
||||
protected boolean wasIcon(JInternalFrame f) {
|
||||
return (f.getClientProperty(HAS_BEEN_ICONIFIED_PROPERTY) == Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
JDesktopPane getDesktopPane( JComponent frame ) {
|
||||
JDesktopPane pane = null;
|
||||
Component c = frame.getParent();
|
||||
|
||||
// Find the JDesktopPane
|
||||
while ( pane == null ) {
|
||||
if ( c instanceof JDesktopPane ) {
|
||||
pane = (JDesktopPane)c;
|
||||
}
|
||||
else if ( c == null ) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
c = c.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
// =========== stuff for faster frame dragging ===================
|
||||
|
||||
private void dragFrameFaster(JComponent f, int newX, int newY) {
|
||||
|
||||
Rectangle previousBounds = new Rectangle(currentBounds.x,
|
||||
currentBounds.y,
|
||||
currentBounds.width,
|
||||
currentBounds.height);
|
||||
|
||||
// move the frame
|
||||
currentBounds.x = newX;
|
||||
currentBounds.y = newY;
|
||||
|
||||
if (didDrag) {
|
||||
// Only initiate cleanup if we have actually done a drag.
|
||||
emergencyCleanup(f);
|
||||
}
|
||||
else {
|
||||
didDrag = true;
|
||||
// We reset the danger field as until now we haven't actually
|
||||
// moved the internal frame so we don't need to initiate repaint.
|
||||
((JInternalFrame)f).danger = false;
|
||||
}
|
||||
|
||||
boolean floaterCollision = isFloaterCollision(previousBounds, currentBounds);
|
||||
|
||||
JComponent parent = (JComponent)f.getParent();
|
||||
Rectangle visBounds = previousBounds.intersection(desktopBounds);
|
||||
|
||||
RepaintManager currentManager = RepaintManager.currentManager(f);
|
||||
|
||||
currentManager.beginPaint();
|
||||
try {
|
||||
if(!floaterCollision) {
|
||||
currentManager.copyArea(parent, desktopGraphics, visBounds.x,
|
||||
visBounds.y,
|
||||
visBounds.width,
|
||||
visBounds.height,
|
||||
newX - previousBounds.x,
|
||||
newY - previousBounds.y,
|
||||
true);
|
||||
}
|
||||
|
||||
f.setBounds(currentBounds);
|
||||
|
||||
if (!floaterCollision) {
|
||||
Rectangle r = currentBounds;
|
||||
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
if(floaterCollision) {
|
||||
// since we couldn't blit we just redraw as fast as possible
|
||||
// the isDragging mucking is to avoid activating emergency
|
||||
// cleanup
|
||||
((JInternalFrame)f).isDragging = false;
|
||||
parent.paintImmediately(currentBounds);
|
||||
((JInternalFrame)f).isDragging = true;
|
||||
}
|
||||
|
||||
// fake out the repaint manager. We'll take care of everything
|
||||
|
||||
currentManager.markCompletelyClean(parent);
|
||||
currentManager.markCompletelyClean(f);
|
||||
|
||||
// compute the minimal newly exposed area
|
||||
// if the rects intersect then we use computeDifference. Otherwise
|
||||
// we'll repaint the entire previous bounds
|
||||
Rectangle[] dirtyRects = null;
|
||||
if ( previousBounds.intersects(currentBounds) ) {
|
||||
dirtyRects = SwingUtilities.computeDifference(previousBounds,
|
||||
currentBounds);
|
||||
} else {
|
||||
dirtyRects = new Rectangle[1];
|
||||
dirtyRects[0] = previousBounds;
|
||||
};
|
||||
|
||||
// Fix the damage
|
||||
for (int i = 0; i < dirtyRects.length; i++) {
|
||||
parent.paintImmediately(dirtyRects[i]);
|
||||
Rectangle r = dirtyRects[i];
|
||||
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
// new areas of blit were exposed
|
||||
if ( !(visBounds.equals(previousBounds)) ) {
|
||||
dirtyRects = SwingUtilities.computeDifference(previousBounds,
|
||||
desktopBounds);
|
||||
for (int i = 0; i < dirtyRects.length; i++) {
|
||||
dirtyRects[i].x += newX - previousBounds.x;
|
||||
dirtyRects[i].y += newY - previousBounds.y;
|
||||
((JInternalFrame)f).isDragging = false;
|
||||
parent.paintImmediately(dirtyRects[i]);
|
||||
((JInternalFrame)f).isDragging = true;
|
||||
Rectangle r = dirtyRects[i];
|
||||
currentManager.notifyRepaintPerformed(parent, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
currentManager.endPaint();
|
||||
}
|
||||
|
||||
// update window if it's non-opaque
|
||||
Window topLevel = SwingUtilities.getWindowAncestor(f);
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
if (!topLevel.isOpaque() &&
|
||||
(tk instanceof SunToolkit) &&
|
||||
((SunToolkit)tk).needUpdateWindow())
|
||||
{
|
||||
AWTAccessor.getWindowAccessor().updateWindow(topLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFloaterCollision(Rectangle moveFrom, Rectangle moveTo) {
|
||||
if (floatingItems.length == 0) {
|
||||
// System.out.println("no floaters");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < floatingItems.length; i++) {
|
||||
boolean intersectsFrom = moveFrom.intersects(floatingItems[i]);
|
||||
if (intersectsFrom) {
|
||||
return true;
|
||||
}
|
||||
boolean intersectsTo = moveTo.intersects(floatingItems[i]);
|
||||
if (intersectsTo) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Rectangle[] findFloatingItems(JComponent f) {
|
||||
Container desktop = f.getParent();
|
||||
Component[] children = desktop.getComponents();
|
||||
int i = 0;
|
||||
for (i = 0; i < children.length; i++) {
|
||||
if (children[i] == f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// System.out.println(i);
|
||||
Rectangle[] floaters = new Rectangle[i];
|
||||
for (i = 0; i < floaters.length; i++) {
|
||||
floaters[i] = children[i].getBounds();
|
||||
}
|
||||
|
||||
return floaters;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is here to clean up problems associated
|
||||
* with a race condition which can occur when the full contents
|
||||
* of a copyArea's source argument is not available onscreen.
|
||||
* This uses brute force to clean up in case of possible damage
|
||||
*/
|
||||
private void emergencyCleanup(final JComponent f) {
|
||||
|
||||
if ( ((JInternalFrame)f).danger ) {
|
||||
|
||||
SwingUtilities.invokeLater( new Runnable(){
|
||||
public void run(){
|
||||
|
||||
((JInternalFrame)f).isDragging = false;
|
||||
f.paintImmediately(0,0,
|
||||
f.getWidth(),
|
||||
f.getHeight());
|
||||
|
||||
//finalFrame.repaint();
|
||||
((JInternalFrame)f).isDragging = true;
|
||||
// System.out.println("repair complete");
|
||||
}});
|
||||
|
||||
((JInternalFrame)f).danger = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
172
jdkSrc/jdk8/javax/swing/DefaultFocusManager.java
Normal file
172
jdkSrc/jdk8/javax/swing/DefaultFocusManager.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
import java.util.Comparator;
|
||||
|
||||
|
||||
/**
|
||||
* This class has been obsoleted by the 1.4 focus APIs. While client code may
|
||||
* still use this class, developers are strongly encouraged to use
|
||||
* <code>java.awt.KeyboardFocusManager</code> and
|
||||
* <code>java.awt.DefaultKeyboardFocusManager</code> instead.
|
||||
* <p>
|
||||
* Please see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
|
||||
* How to Use the Focus Subsystem</a>,
|
||||
* a section in <em>The Java Tutorial</em>, and the
|
||||
* <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
|
||||
* for more information.
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
* @author David Mendenhall
|
||||
*/
|
||||
public class DefaultFocusManager extends FocusManager {
|
||||
|
||||
final FocusTraversalPolicy gluePolicy =
|
||||
new LegacyGlueFocusTraversalPolicy(this);
|
||||
private final FocusTraversalPolicy layoutPolicy =
|
||||
new LegacyLayoutFocusTraversalPolicy(this);
|
||||
private final LayoutComparator comparator =
|
||||
new LayoutComparator();
|
||||
|
||||
public DefaultFocusManager() {
|
||||
setDefaultFocusTraversalPolicy(gluePolicy);
|
||||
}
|
||||
|
||||
public Component getComponentAfter(Container aContainer,
|
||||
Component aComponent)
|
||||
{
|
||||
Container root = (aContainer.isFocusCycleRoot())
|
||||
? aContainer
|
||||
: aContainer.getFocusCycleRootAncestor();
|
||||
|
||||
// Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
|
||||
// traversal policy is non-legacy, then honor it.
|
||||
if (root != null) {
|
||||
FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
|
||||
if (policy != gluePolicy) {
|
||||
return policy.getComponentAfter(root, aComponent);
|
||||
}
|
||||
|
||||
comparator.setComponentOrientation(root.getComponentOrientation());
|
||||
return layoutPolicy.getComponentAfter(root, aComponent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Component getComponentBefore(Container aContainer,
|
||||
Component aComponent)
|
||||
{
|
||||
Container root = (aContainer.isFocusCycleRoot())
|
||||
? aContainer
|
||||
: aContainer.getFocusCycleRootAncestor();
|
||||
|
||||
// Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
|
||||
// traversal policy is non-legacy, then honor it.
|
||||
if (root != null) {
|
||||
FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
|
||||
if (policy != gluePolicy) {
|
||||
return policy.getComponentBefore(root, aComponent);
|
||||
}
|
||||
|
||||
comparator.setComponentOrientation(root.getComponentOrientation());
|
||||
return layoutPolicy.getComponentBefore(root, aComponent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Component getFirstComponent(Container aContainer) {
|
||||
Container root = (aContainer.isFocusCycleRoot())
|
||||
? aContainer
|
||||
: aContainer.getFocusCycleRootAncestor();
|
||||
|
||||
// Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
|
||||
// traversal policy is non-legacy, then honor it.
|
||||
if (root != null) {
|
||||
FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
|
||||
if (policy != gluePolicy) {
|
||||
return policy.getFirstComponent(root);
|
||||
}
|
||||
|
||||
comparator.setComponentOrientation(root.getComponentOrientation());
|
||||
return layoutPolicy.getFirstComponent(root);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Component getLastComponent(Container aContainer) {
|
||||
Container root = (aContainer.isFocusCycleRoot())
|
||||
? aContainer
|
||||
: aContainer.getFocusCycleRootAncestor();
|
||||
|
||||
// Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
|
||||
// traversal policy is non-legacy, then honor it.
|
||||
if (root != null) {
|
||||
FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
|
||||
if (policy != gluePolicy) {
|
||||
return policy.getLastComponent(root);
|
||||
}
|
||||
|
||||
comparator.setComponentOrientation(root.getComponentOrientation());
|
||||
return layoutPolicy.getLastComponent(root);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean compareTabOrder(Component a, Component b) {
|
||||
return (comparator.compare(a, b) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
final class LegacyLayoutFocusTraversalPolicy
|
||||
extends LayoutFocusTraversalPolicy
|
||||
{
|
||||
LegacyLayoutFocusTraversalPolicy(DefaultFocusManager defaultFocusManager) {
|
||||
super(new CompareTabOrderComparator(defaultFocusManager));
|
||||
}
|
||||
}
|
||||
|
||||
final class CompareTabOrderComparator implements Comparator<Component> {
|
||||
private final DefaultFocusManager defaultFocusManager;
|
||||
|
||||
CompareTabOrderComparator(DefaultFocusManager defaultFocusManager) {
|
||||
this.defaultFocusManager = defaultFocusManager;
|
||||
}
|
||||
|
||||
public int compare(Component o1, Component o2) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
}
|
||||
return (defaultFocusManager.compareTabOrder(o1, o2)) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
348
jdkSrc/jdk8/javax/swing/DefaultListCellRenderer.java
Normal file
348
jdkSrc/jdk8/javax/swing/DefaultListCellRenderer.java
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 javax.swing;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import java.io.Serializable;
|
||||
import sun.swing.DefaultLookup;
|
||||
|
||||
|
||||
/**
|
||||
* Renders an item in a list.
|
||||
* <p>
|
||||
* <strong><a name="override">Implementation Note:</a></strong>
|
||||
* This class overrides
|
||||
* <code>invalidate</code>,
|
||||
* <code>validate</code>,
|
||||
* <code>revalidate</code>,
|
||||
* <code>repaint</code>,
|
||||
* <code>isOpaque</code>,
|
||||
* and
|
||||
* <code>firePropertyChange</code>
|
||||
* solely to improve performance.
|
||||
* If not overridden, these frequently called methods would execute code paths
|
||||
* that are unnecessary for the default list cell renderer.
|
||||
* If you write your own renderer,
|
||||
* take care to weigh the benefits and
|
||||
* drawbacks of overriding these methods.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Philip Milne
|
||||
* @author Hans Muller
|
||||
*/
|
||||
public class DefaultListCellRenderer extends JLabel
|
||||
implements ListCellRenderer<Object>, Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* An empty <code>Border</code>. This field might not be used. To change the
|
||||
* <code>Border</code> used by this renderer override the
|
||||
* <code>getListCellRendererComponent</code> method and set the border
|
||||
* of the returned component directly.
|
||||
*/
|
||||
private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
|
||||
private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
|
||||
protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
|
||||
|
||||
/**
|
||||
* Constructs a default renderer object for an item
|
||||
* in a list.
|
||||
*/
|
||||
public DefaultListCellRenderer() {
|
||||
super();
|
||||
setOpaque(true);
|
||||
setBorder(getNoFocusBorder());
|
||||
setName("List.cellRenderer");
|
||||
}
|
||||
|
||||
private Border getNoFocusBorder() {
|
||||
Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder");
|
||||
if (System.getSecurityManager() != null) {
|
||||
if (border != null) return border;
|
||||
return SAFE_NO_FOCUS_BORDER;
|
||||
} else {
|
||||
if (border != null &&
|
||||
(noFocusBorder == null ||
|
||||
noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) {
|
||||
return border;
|
||||
}
|
||||
return noFocusBorder;
|
||||
}
|
||||
}
|
||||
|
||||
public Component getListCellRendererComponent(
|
||||
JList<?> list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus)
|
||||
{
|
||||
setComponentOrientation(list.getComponentOrientation());
|
||||
|
||||
Color bg = null;
|
||||
Color fg = null;
|
||||
|
||||
JList.DropLocation dropLocation = list.getDropLocation();
|
||||
if (dropLocation != null
|
||||
&& !dropLocation.isInsert()
|
||||
&& dropLocation.getIndex() == index) {
|
||||
|
||||
bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground");
|
||||
fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground");
|
||||
|
||||
isSelected = true;
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
setBackground(bg == null ? list.getSelectionBackground() : bg);
|
||||
setForeground(fg == null ? list.getSelectionForeground() : fg);
|
||||
}
|
||||
else {
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
|
||||
if (value instanceof Icon) {
|
||||
setIcon((Icon)value);
|
||||
setText("");
|
||||
}
|
||||
else {
|
||||
setIcon(null);
|
||||
setText((value == null) ? "" : value.toString());
|
||||
}
|
||||
|
||||
setEnabled(list.isEnabled());
|
||||
setFont(list.getFont());
|
||||
|
||||
Border border = null;
|
||||
if (cellHasFocus) {
|
||||
if (isSelected) {
|
||||
border = DefaultLookup.getBorder(this, ui, "List.focusSelectedCellHighlightBorder");
|
||||
}
|
||||
if (border == null) {
|
||||
border = DefaultLookup.getBorder(this, ui, "List.focusCellHighlightBorder");
|
||||
}
|
||||
} else {
|
||||
border = getNoFocusBorder();
|
||||
}
|
||||
setBorder(border);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*
|
||||
* @since 1.5
|
||||
* @return <code>true</code> if the background is completely opaque
|
||||
* and differs from the JList's background;
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
Color back = getBackground();
|
||||
Component p = getParent();
|
||||
if (p != null) {
|
||||
p = p.getParent();
|
||||
}
|
||||
// p should now be the JList.
|
||||
boolean colorMatch = (back != null) && (p != null) &&
|
||||
back.equals(p.getBackground()) &&
|
||||
p.isOpaque();
|
||||
return !colorMatch && super.isOpaque();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void validate() {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public void invalidate() {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public void repaint() {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void revalidate() {}
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(long tm, int x, int y, int width, int height) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(Rectangle r) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
// Strings get interned...
|
||||
if (propertyName == "text"
|
||||
|| ((propertyName == "font" || propertyName == "foreground")
|
||||
&& oldValue != newValue
|
||||
&& getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
|
||||
|
||||
super.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, char oldValue, char newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, short oldValue, short newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, int oldValue, int newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, long oldValue, long newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, float oldValue, float newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, double oldValue, double newValue) {}
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
* See the <a href="#override">Implementation Note</a>
|
||||
* for more information.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
|
||||
|
||||
/**
|
||||
* A subclass of DefaultListCellRenderer that implements UIResource.
|
||||
* DefaultListCellRenderer doesn't implement UIResource
|
||||
* directly so that applications can safely override the
|
||||
* cellRenderer property with DefaultListCellRenderer subclasses.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
public static class UIResource extends DefaultListCellRenderer
|
||||
implements javax.swing.plaf.UIResource
|
||||
{
|
||||
}
|
||||
}
|
||||
546
jdkSrc/jdk8/javax/swing/DefaultListModel.java
Normal file
546
jdkSrc/jdk8/javax/swing/DefaultListModel.java
Normal file
@@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.swing.event.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class loosely implements the <code>java.util.Vector</code>
|
||||
* API, in that it implements the 1.1.x version of
|
||||
* <code>java.util.Vector</code>, has no collection class support,
|
||||
* and notifies the <code>ListDataListener</code>s when changes occur.
|
||||
* Presently it delegates to a <code>Vector</code>,
|
||||
* in a future release it will be a real Collection implementation.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @param <E> the type of the elements of this model
|
||||
*
|
||||
* @author Hans Muller
|
||||
*/
|
||||
public class DefaultListModel<E> extends AbstractListModel<E>
|
||||
{
|
||||
private Vector<E> delegate = new Vector<E>();
|
||||
|
||||
/**
|
||||
* Returns the number of components in this list.
|
||||
* <p>
|
||||
* This method is identical to <code>size</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* This method exists in conjunction with <code>setSize</code> so that
|
||||
* <code>size</code> is identifiable as a JavaBean property.
|
||||
*
|
||||
* @return the number of components in this list
|
||||
* @see #size()
|
||||
*/
|
||||
public int getSize() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>get(int)</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
* @param index an index into this list
|
||||
* @return the component at the specified index
|
||||
* @exception ArrayIndexOutOfBoundsException if the <code>index</code>
|
||||
* is negative or greater than the current size of this
|
||||
* list
|
||||
* @see #get(int)
|
||||
*/
|
||||
public E getElementAt(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the components of this list into the specified array.
|
||||
* The array must be big enough to hold all the objects in this list,
|
||||
* else an <code>IndexOutOfBoundsException</code> is thrown.
|
||||
*
|
||||
* @param anArray the array into which the components get copied
|
||||
* @see Vector#copyInto(Object[])
|
||||
*/
|
||||
public void copyInto(Object anArray[]) {
|
||||
delegate.copyInto(anArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the capacity of this list to be the list's current size.
|
||||
*
|
||||
* @see Vector#trimToSize()
|
||||
*/
|
||||
public void trimToSize() {
|
||||
delegate.trimToSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the capacity of this list, if necessary, to ensure
|
||||
* that it can hold at least the number of components specified by
|
||||
* the minimum capacity argument.
|
||||
*
|
||||
* @param minCapacity the desired minimum capacity
|
||||
* @see Vector#ensureCapacity(int)
|
||||
*/
|
||||
public void ensureCapacity(int minCapacity) {
|
||||
delegate.ensureCapacity(minCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of this list.
|
||||
*
|
||||
* @param newSize the new size of this list
|
||||
* @see Vector#setSize(int)
|
||||
*/
|
||||
public void setSize(int newSize) {
|
||||
int oldSize = delegate.size();
|
||||
delegate.setSize(newSize);
|
||||
if (oldSize > newSize) {
|
||||
fireIntervalRemoved(this, newSize, oldSize-1);
|
||||
}
|
||||
else if (oldSize < newSize) {
|
||||
fireIntervalAdded(this, oldSize, newSize-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current capacity of this list.
|
||||
*
|
||||
* @return the current capacity
|
||||
* @see Vector#capacity()
|
||||
*/
|
||||
public int capacity() {
|
||||
return delegate.capacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of components in this list.
|
||||
*
|
||||
* @return the number of components in this list
|
||||
* @see Vector#size()
|
||||
*/
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this list has any components.
|
||||
*
|
||||
* @return <code>true</code> if and only if this list has
|
||||
* no components, that is, its size is zero;
|
||||
* <code>false</code> otherwise
|
||||
* @see Vector#isEmpty()
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return delegate.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the components of this list.
|
||||
*
|
||||
* @return an enumeration of the components of this list
|
||||
* @see Vector#elements()
|
||||
*/
|
||||
public Enumeration<E> elements() {
|
||||
return delegate.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the specified object is a component in this list.
|
||||
*
|
||||
* @param elem an object
|
||||
* @return <code>true</code> if the specified object
|
||||
* is the same as a component in this list
|
||||
* @see Vector#contains(Object)
|
||||
*/
|
||||
public boolean contains(Object elem) {
|
||||
return delegate.contains(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the first occurrence of <code>elem</code>.
|
||||
*
|
||||
* @param elem an object
|
||||
* @return the index of the first occurrence of the argument in this
|
||||
* list; returns <code>-1</code> if the object is not found
|
||||
* @see Vector#indexOf(Object)
|
||||
*/
|
||||
public int indexOf(Object elem) {
|
||||
return delegate.indexOf(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the first occurrence of <code>elem</code>, beginning
|
||||
* the search at <code>index</code>.
|
||||
*
|
||||
* @param elem an desired component
|
||||
* @param index the index from which to begin searching
|
||||
* @return the index where the first occurrence of <code>elem</code>
|
||||
* is found after <code>index</code>; returns <code>-1</code>
|
||||
* if the <code>elem</code> is not found in the list
|
||||
* @see Vector#indexOf(Object,int)
|
||||
*/
|
||||
public int indexOf(Object elem, int index) {
|
||||
return delegate.indexOf(elem, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of <code>elem</code>.
|
||||
*
|
||||
* @param elem the desired component
|
||||
* @return the index of the last occurrence of <code>elem</code>
|
||||
* in the list; returns <code>-1</code> if the object is not found
|
||||
* @see Vector#lastIndexOf(Object)
|
||||
*/
|
||||
public int lastIndexOf(Object elem) {
|
||||
return delegate.lastIndexOf(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches backwards for <code>elem</code>, starting from the
|
||||
* specified index, and returns an index to it.
|
||||
*
|
||||
* @param elem the desired component
|
||||
* @param index the index to start searching from
|
||||
* @return the index of the last occurrence of the <code>elem</code>
|
||||
* in this list at position less than <code>index</code>;
|
||||
* returns <code>-1</code> if the object is not found
|
||||
* @see Vector#lastIndexOf(Object,int)
|
||||
*/
|
||||
public int lastIndexOf(Object elem, int index) {
|
||||
return delegate.lastIndexOf(elem, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
|
||||
* is negative or not less than the size of the list.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>get(int)</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param index an index into this list
|
||||
* @return the component at the specified index
|
||||
* @see #get(int)
|
||||
* @see Vector#elementAt(int)
|
||||
*/
|
||||
public E elementAt(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first component of this list.
|
||||
* Throws a <code>NoSuchElementException</code> if this
|
||||
* vector has no components.
|
||||
* @return the first component of this list
|
||||
* @see Vector#firstElement()
|
||||
*/
|
||||
public E firstElement() {
|
||||
return delegate.firstElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last component of the list.
|
||||
* Throws a <code>NoSuchElementException</code> if this vector
|
||||
* has no components.
|
||||
*
|
||||
* @return the last component of the list
|
||||
* @see Vector#lastElement()
|
||||
*/
|
||||
public E lastElement() {
|
||||
return delegate.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the component at the specified <code>index</code> of this
|
||||
* list to be the specified element. The previous component at that
|
||||
* position is discarded.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
|
||||
* is invalid.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>set(int,Object)</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param element what the component is to be set to
|
||||
* @param index the specified index
|
||||
* @see #set(int,Object)
|
||||
* @see Vector#setElementAt(Object,int)
|
||||
*/
|
||||
public void setElementAt(E element, int index) {
|
||||
delegate.setElementAt(element, index);
|
||||
fireContentsChanged(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the component at the specified index.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
|
||||
* is invalid.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>remove(int)</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param index the index of the object to remove
|
||||
* @see #remove(int)
|
||||
* @see Vector#removeElementAt(int)
|
||||
*/
|
||||
public void removeElementAt(int index) {
|
||||
delegate.removeElementAt(index);
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element as a component in this list at the
|
||||
* specified <code>index</code>.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
|
||||
* is invalid.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>add(int,Object)</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param element the component to insert
|
||||
* @param index where to insert the new component
|
||||
* @exception ArrayIndexOutOfBoundsException if the index was invalid
|
||||
* @see #add(int,Object)
|
||||
* @see Vector#insertElementAt(Object,int)
|
||||
*/
|
||||
public void insertElementAt(E element, int index) {
|
||||
delegate.insertElementAt(element, index);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified component to the end of this list.
|
||||
*
|
||||
* @param element the component to be added
|
||||
* @see Vector#addElement(Object)
|
||||
*/
|
||||
public void addElement(E element) {
|
||||
int index = delegate.size();
|
||||
delegate.addElement(element);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first (lowest-indexed) occurrence of the argument
|
||||
* from this list.
|
||||
*
|
||||
* @param obj the component to be removed
|
||||
* @return <code>true</code> if the argument was a component of this
|
||||
* list; <code>false</code> otherwise
|
||||
* @see Vector#removeElement(Object)
|
||||
*/
|
||||
public boolean removeElement(Object obj) {
|
||||
int index = indexOf(obj);
|
||||
boolean rv = delegate.removeElement(obj);
|
||||
if (index >= 0) {
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all components from this list and sets its size to zero.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> Although this method is not deprecated, the preferred
|
||||
* method to use is <code>clear</code>, which implements the
|
||||
* <code>List</code> interface defined in the 1.2 Collections framework.
|
||||
* </blockquote>
|
||||
*
|
||||
* @see #clear()
|
||||
* @see Vector#removeAllElements()
|
||||
*/
|
||||
public void removeAllElements() {
|
||||
int index1 = delegate.size()-1;
|
||||
delegate.removeAllElements();
|
||||
if (index1 >= 0) {
|
||||
fireIntervalRemoved(this, 0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that displays and identifies this
|
||||
* object's properties.
|
||||
*
|
||||
* @return a String representation of this object
|
||||
*/
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
|
||||
/* The remaining methods are included for compatibility with the
|
||||
* Java 2 platform Vector class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in the
|
||||
* correct order.
|
||||
*
|
||||
* @return an array containing the elements of the list
|
||||
* @see Vector#toArray()
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
Object[] rv = new Object[delegate.size()];
|
||||
delegate.copyInto(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element at the specified position in this list.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code>
|
||||
* if the index is out of range
|
||||
* (<code>index < 0 || index >= size()</code>).
|
||||
*
|
||||
* @param index index of element to return
|
||||
*/
|
||||
public E get(int index) {
|
||||
return delegate.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the
|
||||
* specified element.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code>
|
||||
* if the index is out of range
|
||||
* (<code>index < 0 || index >= size()</code>).
|
||||
*
|
||||
* @param index index of element to replace
|
||||
* @param element element to be stored at the specified position
|
||||
* @return the element previously at the specified position
|
||||
*/
|
||||
public E set(int index, E element) {
|
||||
E rv = delegate.elementAt(index);
|
||||
delegate.setElementAt(element, index);
|
||||
fireContentsChanged(this, index, index);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the specified position in this list.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the
|
||||
* index is out of range
|
||||
* (<code>index < 0 || index > size()</code>).
|
||||
*
|
||||
* @param index index at which the specified element is to be inserted
|
||||
* @param element element to be inserted
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
delegate.insertElementAt(element, index);
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list.
|
||||
* Returns the element that was removed from the list.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code>
|
||||
* if the index is out of range
|
||||
* (<code>index < 0 || index >= size()</code>).
|
||||
*
|
||||
* @param index the index of the element to removed
|
||||
* @return the element previously at the specified position
|
||||
*/
|
||||
public E remove(int index) {
|
||||
E rv = delegate.elementAt(index);
|
||||
delegate.removeElementAt(index);
|
||||
fireIntervalRemoved(this, index, index);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this list. The list will
|
||||
* be empty after this call returns (unless it throws an exception).
|
||||
*/
|
||||
public void clear() {
|
||||
int index1 = delegate.size()-1;
|
||||
delegate.removeAllElements();
|
||||
if (index1 >= 0) {
|
||||
fireIntervalRemoved(this, 0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the components at the specified range of indexes.
|
||||
* The removal is inclusive, so specifying a range of (1,5)
|
||||
* removes the component at index 1 and the component at index 5,
|
||||
* as well as all components in between.
|
||||
* <p>
|
||||
* Throws an <code>ArrayIndexOutOfBoundsException</code>
|
||||
* if the index was invalid.
|
||||
* Throws an <code>IllegalArgumentException</code> if
|
||||
* <code>fromIndex > toIndex</code>.
|
||||
*
|
||||
* @param fromIndex the index of the lower end of the range
|
||||
* @param toIndex the index of the upper end of the range
|
||||
* @see #remove(int)
|
||||
*/
|
||||
public void removeRange(int fromIndex, int toIndex) {
|
||||
if (fromIndex > toIndex) {
|
||||
throw new IllegalArgumentException("fromIndex must be <= toIndex");
|
||||
}
|
||||
for(int i = toIndex; i >= fromIndex; i--) {
|
||||
delegate.removeElementAt(i);
|
||||
}
|
||||
fireIntervalRemoved(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
public void addAll(Collection c) {
|
||||
}
|
||||
|
||||
public void addAll(int index, Collection c) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
849
jdkSrc/jdk8/javax/swing/DefaultListSelectionModel.java
Normal file
849
jdkSrc/jdk8/javax/swing/DefaultListSelectionModel.java
Normal file
@@ -0,0 +1,849 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.util.BitSet;
|
||||
import java.io.Serializable;
|
||||
import java.beans.Transient;
|
||||
|
||||
import javax.swing.event.*;
|
||||
|
||||
|
||||
/**
|
||||
* Default data model for list selections.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Philip Milne
|
||||
* @author Hans Muller
|
||||
* @see ListSelectionModel
|
||||
*/
|
||||
|
||||
public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, Serializable
|
||||
{
|
||||
private static final int MIN = -1;
|
||||
private static final int MAX = Integer.MAX_VALUE;
|
||||
private int selectionMode = MULTIPLE_INTERVAL_SELECTION;
|
||||
private int minIndex = MAX;
|
||||
private int maxIndex = MIN;
|
||||
private int anchorIndex = -1;
|
||||
private int leadIndex = -1;
|
||||
private int firstAdjustedIndex = MAX;
|
||||
private int lastAdjustedIndex = MIN;
|
||||
private boolean isAdjusting = false;
|
||||
|
||||
private int firstChangedIndex = MAX;
|
||||
private int lastChangedIndex = MIN;
|
||||
|
||||
private BitSet value = new BitSet(32);
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
protected boolean leadAnchorNotificationEnabled = true;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getMinSelectionIndex() { return isSelectionEmpty() ? -1 : minIndex; }
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getMaxSelectionIndex() { return maxIndex; }
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean getValueIsAdjusting() { return isAdjusting; }
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getSelectionMode() { return selectionMode; }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public void setSelectionMode(int selectionMode) {
|
||||
switch (selectionMode) {
|
||||
case SINGLE_SELECTION:
|
||||
case SINGLE_INTERVAL_SELECTION:
|
||||
case MULTIPLE_INTERVAL_SELECTION:
|
||||
this.selectionMode = selectionMode;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid selectionMode");
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isSelectedIndex(int index) {
|
||||
return ((index < minIndex) || (index > maxIndex)) ? false : value.get(index);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isSelectionEmpty() {
|
||||
return (minIndex > maxIndex);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void addListSelectionListener(ListSelectionListener l) {
|
||||
listenerList.add(ListSelectionListener.class, l);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void removeListSelectionListener(ListSelectionListener l) {
|
||||
listenerList.remove(ListSelectionListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the list selection listeners
|
||||
* registered on this <code>DefaultListSelectionModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ListSelectionListener</code>s
|
||||
* or an empty
|
||||
* array if no list selection listeners are currently registered
|
||||
*
|
||||
* @see #addListSelectionListener
|
||||
* @see #removeListSelectionListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ListSelectionListener[] getListSelectionListeners() {
|
||||
return listenerList.getListeners(ListSelectionListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners that we have ended a series of adjustments.
|
||||
*/
|
||||
protected void fireValueChanged(boolean isAdjusting) {
|
||||
if (lastChangedIndex == MIN) {
|
||||
return;
|
||||
}
|
||||
/* Change the values before sending the event to the
|
||||
* listeners in case the event causes a listener to make
|
||||
* another change to the selection.
|
||||
*/
|
||||
int oldFirstChangedIndex = firstChangedIndex;
|
||||
int oldLastChangedIndex = lastChangedIndex;
|
||||
firstChangedIndex = MAX;
|
||||
lastChangedIndex = MIN;
|
||||
fireValueChanged(oldFirstChangedIndex, oldLastChangedIndex, isAdjusting);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notifies <code>ListSelectionListeners</code> that the value
|
||||
* of the selection, in the closed interval <code>firstIndex</code>,
|
||||
* <code>lastIndex</code>, has changed.
|
||||
*/
|
||||
protected void fireValueChanged(int firstIndex, int lastIndex) {
|
||||
fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param firstIndex the first index in the interval
|
||||
* @param lastIndex the last index in the interval
|
||||
* @param isAdjusting true if this is the final change in a series of
|
||||
* adjustments
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting)
|
||||
{
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
ListSelectionEvent e = null;
|
||||
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i] == ListSelectionListener.class) {
|
||||
if (e == null) {
|
||||
e = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting);
|
||||
}
|
||||
((ListSelectionListener)listeners[i+1]).valueChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fireValueChanged() {
|
||||
if (lastAdjustedIndex == MIN) {
|
||||
return;
|
||||
}
|
||||
/* If getValueAdjusting() is true, (eg. during a drag opereration)
|
||||
* record the bounds of the changes so that, when the drag finishes (and
|
||||
* setValueAdjusting(false) is called) we can post a single event
|
||||
* with bounds covering all of these individual adjustments.
|
||||
*/
|
||||
if (getValueIsAdjusting()) {
|
||||
firstChangedIndex = Math.min(firstChangedIndex, firstAdjustedIndex);
|
||||
lastChangedIndex = Math.max(lastChangedIndex, lastAdjustedIndex);
|
||||
}
|
||||
/* Change the values before sending the event to the
|
||||
* listeners in case the event causes a listener to make
|
||||
* another change to the selection.
|
||||
*/
|
||||
int oldFirstAdjustedIndex = firstAdjustedIndex;
|
||||
int oldLastAdjustedIndex = lastAdjustedIndex;
|
||||
firstAdjustedIndex = MAX;
|
||||
lastAdjustedIndex = MIN;
|
||||
|
||||
fireValueChanged(oldFirstAdjustedIndex, oldLastAdjustedIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a <code>DefaultListSelectionModel</code>
|
||||
* instance <code>m</code>
|
||||
* for its list selection listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ListSelectionListener[] lsls = (ListSelectionListener[])(m.getListeners(ListSelectionListener.class));</pre>
|
||||
*
|
||||
* 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</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getListSelectionListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
|
||||
// Updates first and last change indices
|
||||
private void markAsDirty(int r) {
|
||||
if (r == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
firstAdjustedIndex = Math.min(firstAdjustedIndex, r);
|
||||
lastAdjustedIndex = Math.max(lastAdjustedIndex, r);
|
||||
}
|
||||
|
||||
// Sets the state at this index and update all relevant state.
|
||||
private void set(int r) {
|
||||
if (value.get(r)) {
|
||||
return;
|
||||
}
|
||||
value.set(r);
|
||||
markAsDirty(r);
|
||||
|
||||
// Update minimum and maximum indices
|
||||
minIndex = Math.min(minIndex, r);
|
||||
maxIndex = Math.max(maxIndex, r);
|
||||
}
|
||||
|
||||
// Clears the state at this index and update all relevant state.
|
||||
private void clear(int r) {
|
||||
if (!value.get(r)) {
|
||||
return;
|
||||
}
|
||||
value.clear(r);
|
||||
markAsDirty(r);
|
||||
|
||||
// Update minimum and maximum indices
|
||||
/*
|
||||
If (r > minIndex) the minimum has not changed.
|
||||
The case (r < minIndex) is not possible because r'th value was set.
|
||||
We only need to check for the case when lowest entry has been cleared,
|
||||
and in this case we need to search for the first value set above it.
|
||||
*/
|
||||
if (r == minIndex) {
|
||||
for(minIndex = minIndex + 1; minIndex <= maxIndex; minIndex++) {
|
||||
if (value.get(minIndex)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
If (r < maxIndex) the maximum has not changed.
|
||||
The case (r > maxIndex) is not possible because r'th value was set.
|
||||
We only need to check for the case when highest entry has been cleared,
|
||||
and in this case we need to search for the first value set below it.
|
||||
*/
|
||||
if (r == maxIndex) {
|
||||
for(maxIndex = maxIndex - 1; minIndex <= maxIndex; maxIndex--) {
|
||||
if (value.get(maxIndex)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Performance note: This method is called from inside a loop in
|
||||
changeSelection() but we will only iterate in the loops
|
||||
above on the basis of one iteration per deselected cell - in total.
|
||||
Ie. the next time this method is called the work of the previous
|
||||
deselection will not be repeated.
|
||||
|
||||
We also don't need to worry about the case when the min and max
|
||||
values are in their unassigned states. This cannot happen because
|
||||
this method's initial check ensures that the selection was not empty
|
||||
and therefore that the minIndex and maxIndex had 'real' values.
|
||||
|
||||
If we have cleared the whole selection, set the minIndex and maxIndex
|
||||
to their cannonical values so that the next set command always works
|
||||
just by using Math.min and Math.max.
|
||||
*/
|
||||
if (isSelectionEmpty()) {
|
||||
minIndex = MAX;
|
||||
maxIndex = MIN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the leadAnchorNotificationEnabled flag.
|
||||
* @see #isLeadAnchorNotificationEnabled()
|
||||
*/
|
||||
public void setLeadAnchorNotificationEnabled(boolean flag) {
|
||||
leadAnchorNotificationEnabled = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the <code>leadAnchorNotificationEnabled</code> flag.
|
||||
* When <code>leadAnchorNotificationEnabled</code> is true the model
|
||||
* generates notification events with bounds that cover all the changes to
|
||||
* the selection plus the changes to the lead and anchor indices.
|
||||
* Setting the flag to false causes a narrowing of the event's bounds to
|
||||
* include only the elements that have been selected or deselected since
|
||||
* the last change. Either way, the model continues to maintain the lead
|
||||
* and anchor variables internally. The default is true.
|
||||
* <p>
|
||||
* Note: It is possible for the lead or anchor to be changed without a
|
||||
* change to the selection. Notification of these changes is often
|
||||
* important, such as when the new lead or anchor needs to be updated in
|
||||
* the view. Therefore, caution is urged when changing the default value.
|
||||
*
|
||||
* @return the value of the <code>leadAnchorNotificationEnabled</code> flag
|
||||
* @see #setLeadAnchorNotificationEnabled(boolean)
|
||||
*/
|
||||
public boolean isLeadAnchorNotificationEnabled() {
|
||||
return leadAnchorNotificationEnabled;
|
||||
}
|
||||
|
||||
private void updateLeadAnchorIndices(int anchorIndex, int leadIndex) {
|
||||
if (leadAnchorNotificationEnabled) {
|
||||
if (this.anchorIndex != anchorIndex) {
|
||||
markAsDirty(this.anchorIndex);
|
||||
markAsDirty(anchorIndex);
|
||||
}
|
||||
|
||||
if (this.leadIndex != leadIndex) {
|
||||
markAsDirty(this.leadIndex);
|
||||
markAsDirty(leadIndex);
|
||||
}
|
||||
}
|
||||
this.anchorIndex = anchorIndex;
|
||||
this.leadIndex = leadIndex;
|
||||
}
|
||||
|
||||
private boolean contains(int a, int b, int i) {
|
||||
return (i >= a) && (i <= b);
|
||||
}
|
||||
|
||||
private void changeSelection(int clearMin, int clearMax,
|
||||
int setMin, int setMax, boolean clearFirst) {
|
||||
for(int i = Math.min(setMin, clearMin); i <= Math.max(setMax, clearMax); i++) {
|
||||
|
||||
boolean shouldClear = contains(clearMin, clearMax, i);
|
||||
boolean shouldSet = contains(setMin, setMax, i);
|
||||
|
||||
if (shouldSet && shouldClear) {
|
||||
if (clearFirst) {
|
||||
shouldClear = false;
|
||||
}
|
||||
else {
|
||||
shouldSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSet) {
|
||||
set(i);
|
||||
}
|
||||
if (shouldClear) {
|
||||
clear(i);
|
||||
}
|
||||
}
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the selection with the effect of first clearing the values
|
||||
* in the inclusive range [clearMin, clearMax] then setting the values
|
||||
* in the inclusive range [setMin, setMax]. Do this in one pass so
|
||||
* that no values are cleared if they would later be set.
|
||||
*/
|
||||
private void changeSelection(int clearMin, int clearMax, int setMin, int setMax) {
|
||||
changeSelection(clearMin, clearMax, setMin, setMax, true);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void clearSelection() {
|
||||
removeSelectionIntervalImpl(minIndex, maxIndex, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the selection to be between {@code index0} and {@code index1}
|
||||
* inclusive. {@code index0} doesn't have to be less than or equal to
|
||||
* {@code index1}.
|
||||
* <p>
|
||||
* In {@code SINGLE_SELECTION} selection mode, only the second index
|
||||
* is used.
|
||||
* <p>
|
||||
* If this represents a change to the current selection, then each
|
||||
* {@code ListSelectionListener} is notified of the change.
|
||||
* <p>
|
||||
* If either index is {@code -1}, this method does nothing and returns
|
||||
* without exception. Otherwise, if either index is less than {@code -1},
|
||||
* an {@code IndexOutOfBoundsException} is thrown.
|
||||
*
|
||||
* @param index0 one end of the interval.
|
||||
* @param index1 other end of the interval
|
||||
* @throws IndexOutOfBoundsException if either index is less than {@code -1}
|
||||
* (and neither index is {@code -1})
|
||||
* @see #addListSelectionListener
|
||||
*/
|
||||
public void setSelectionInterval(int index0, int index1) {
|
||||
if (index0 == -1 || index1 == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSelectionMode() == SINGLE_SELECTION) {
|
||||
index0 = index1;
|
||||
}
|
||||
|
||||
updateLeadAnchorIndices(index0, index1);
|
||||
|
||||
int clearMin = minIndex;
|
||||
int clearMax = maxIndex;
|
||||
int setMin = Math.min(index0, index1);
|
||||
int setMax = Math.max(index0, index1);
|
||||
changeSelection(clearMin, clearMax, setMin, setMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the selection to be the set union of the current selection
|
||||
* and the indices between {@code index0} and {@code index1} inclusive.
|
||||
* <p>
|
||||
* In {@code SINGLE_SELECTION} selection mode, this is equivalent
|
||||
* to calling {@code setSelectionInterval}, and only the second index
|
||||
* is used. In {@code SINGLE_INTERVAL_SELECTION} selection mode, this
|
||||
* method behaves like {@code setSelectionInterval}, unless the given
|
||||
* interval is immediately adjacent to or overlaps the existing selection,
|
||||
* and can therefore be used to grow it.
|
||||
* <p>
|
||||
* If this represents a change to the current selection, then each
|
||||
* {@code ListSelectionListener} is notified of the change. Note that
|
||||
* {@code index0} doesn't have to be less than or equal to {@code index1}.
|
||||
* <p>
|
||||
* If either index is {@code -1}, this method does nothing and returns
|
||||
* without exception. Otherwise, if either index is less than {@code -1},
|
||||
* an {@code IndexOutOfBoundsException} is thrown.
|
||||
*
|
||||
* @param index0 one end of the interval.
|
||||
* @param index1 other end of the interval
|
||||
* @throws IndexOutOfBoundsException if either index is less than {@code -1}
|
||||
* (and neither index is {@code -1})
|
||||
* @see #addListSelectionListener
|
||||
* @see #setSelectionInterval
|
||||
*/
|
||||
public void addSelectionInterval(int index0, int index1)
|
||||
{
|
||||
if (index0 == -1 || index1 == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we only allow a single selection, channel through
|
||||
// setSelectionInterval() to enforce the rule.
|
||||
if (getSelectionMode() == SINGLE_SELECTION) {
|
||||
setSelectionInterval(index0, index1);
|
||||
return;
|
||||
}
|
||||
|
||||
updateLeadAnchorIndices(index0, index1);
|
||||
|
||||
int clearMin = MAX;
|
||||
int clearMax = MIN;
|
||||
int setMin = Math.min(index0, index1);
|
||||
int setMax = Math.max(index0, index1);
|
||||
|
||||
// If we only allow a single interval and this would result
|
||||
// in multiple intervals, then set the selection to be just
|
||||
// the new range.
|
||||
if (getSelectionMode() == SINGLE_INTERVAL_SELECTION &&
|
||||
(setMax < minIndex - 1 || setMin > maxIndex + 1)) {
|
||||
|
||||
setSelectionInterval(index0, index1);
|
||||
return;
|
||||
}
|
||||
|
||||
changeSelection(clearMin, clearMax, setMin, setMax);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the selection to be the set difference of the current selection
|
||||
* and the indices between {@code index0} and {@code index1} inclusive.
|
||||
* {@code index0} doesn't have to be less than or equal to {@code index1}.
|
||||
* <p>
|
||||
* In {@code SINGLE_INTERVAL_SELECTION} selection mode, if the removal
|
||||
* would produce two disjoint selections, the removal is extended through
|
||||
* the greater end of the selection. For example, if the selection is
|
||||
* {@code 0-10} and you supply indices {@code 5,6} (in any order) the
|
||||
* resulting selection is {@code 0-4}.
|
||||
* <p>
|
||||
* If this represents a change to the current selection, then each
|
||||
* {@code ListSelectionListener} is notified of the change.
|
||||
* <p>
|
||||
* If either index is {@code -1}, this method does nothing and returns
|
||||
* without exception. Otherwise, if either index is less than {@code -1},
|
||||
* an {@code IndexOutOfBoundsException} is thrown.
|
||||
*
|
||||
* @param index0 one end of the interval
|
||||
* @param index1 other end of the interval
|
||||
* @throws IndexOutOfBoundsException if either index is less than {@code -1}
|
||||
* (and neither index is {@code -1})
|
||||
* @see #addListSelectionListener
|
||||
*/
|
||||
public void removeSelectionInterval(int index0, int index1)
|
||||
{
|
||||
removeSelectionIntervalImpl(index0, index1, true);
|
||||
}
|
||||
|
||||
// private implementation allowing the selection interval
|
||||
// to be removed without affecting the lead and anchor
|
||||
private void removeSelectionIntervalImpl(int index0, int index1,
|
||||
boolean changeLeadAnchor) {
|
||||
|
||||
if (index0 == -1 || index1 == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (changeLeadAnchor) {
|
||||
updateLeadAnchorIndices(index0, index1);
|
||||
}
|
||||
|
||||
int clearMin = Math.min(index0, index1);
|
||||
int clearMax = Math.max(index0, index1);
|
||||
int setMin = MAX;
|
||||
int setMax = MIN;
|
||||
|
||||
// If the removal would produce to two disjoint selections in a mode
|
||||
// that only allows one, extend the removal to the end of the selection.
|
||||
if (getSelectionMode() != MULTIPLE_INTERVAL_SELECTION &&
|
||||
clearMin > minIndex && clearMax < maxIndex) {
|
||||
clearMax = maxIndex;
|
||||
}
|
||||
|
||||
changeSelection(clearMin, clearMax, setMin, setMax);
|
||||
}
|
||||
|
||||
private void setState(int index, boolean state) {
|
||||
if (state) {
|
||||
set(index);
|
||||
}
|
||||
else {
|
||||
clear(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert length indices beginning before/after index. If the value
|
||||
* at index is itself selected and the selection mode is not
|
||||
* SINGLE_SELECTION, set all of the newly inserted items as selected.
|
||||
* Otherwise leave them unselected. This method is typically
|
||||
* called to sync the selection model with a corresponding change
|
||||
* in the data model.
|
||||
*/
|
||||
public void insertIndexInterval(int index, int length, boolean before)
|
||||
{
|
||||
/* The first new index will appear at insMinIndex and the last
|
||||
* one will appear at insMaxIndex
|
||||
*/
|
||||
int insMinIndex = (before) ? index : index + 1;
|
||||
int insMaxIndex = (insMinIndex + length) - 1;
|
||||
|
||||
/* Right shift the entire bitset by length, beginning with
|
||||
* index-1 if before is true, index+1 if it's false (i.e. with
|
||||
* insMinIndex).
|
||||
*/
|
||||
for(int i = maxIndex; i >= insMinIndex; i--) {
|
||||
setState(i + length, value.get(i));
|
||||
}
|
||||
|
||||
/* Initialize the newly inserted indices.
|
||||
*/
|
||||
boolean setInsertedValues = ((getSelectionMode() == SINGLE_SELECTION) ?
|
||||
false : value.get(index));
|
||||
for(int i = insMinIndex; i <= insMaxIndex; i++) {
|
||||
setState(i, setInsertedValues);
|
||||
}
|
||||
|
||||
int leadIndex = this.leadIndex;
|
||||
if (leadIndex > index || (before && leadIndex == index)) {
|
||||
leadIndex = this.leadIndex + length;
|
||||
}
|
||||
int anchorIndex = this.anchorIndex;
|
||||
if (anchorIndex > index || (before && anchorIndex == index)) {
|
||||
anchorIndex = this.anchorIndex + length;
|
||||
}
|
||||
if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) {
|
||||
updateLeadAnchorIndices(anchorIndex, leadIndex);
|
||||
}
|
||||
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the indices in the interval index0,index1 (inclusive) from
|
||||
* the selection model. This is typically called to sync the selection
|
||||
* model width a corresponding change in the data model. Note
|
||||
* that (as always) index0 need not be <= index1.
|
||||
*/
|
||||
public void removeIndexInterval(int index0, int index1)
|
||||
{
|
||||
int rmMinIndex = Math.min(index0, index1);
|
||||
int rmMaxIndex = Math.max(index0, index1);
|
||||
int gapLength = (rmMaxIndex - rmMinIndex) + 1;
|
||||
|
||||
/* Shift the entire bitset to the left to close the index0, index1
|
||||
* gap.
|
||||
*/
|
||||
for(int i = rmMinIndex; i <= maxIndex; i++) {
|
||||
setState(i, value.get(i + gapLength));
|
||||
}
|
||||
|
||||
int leadIndex = this.leadIndex;
|
||||
if (leadIndex == 0 && rmMinIndex == 0) {
|
||||
// do nothing
|
||||
} else if (leadIndex > rmMaxIndex) {
|
||||
leadIndex = this.leadIndex - gapLength;
|
||||
} else if (leadIndex >= rmMinIndex) {
|
||||
leadIndex = rmMinIndex - 1;
|
||||
}
|
||||
|
||||
int anchorIndex = this.anchorIndex;
|
||||
if (anchorIndex == 0 && rmMinIndex == 0) {
|
||||
// do nothing
|
||||
} else if (anchorIndex > rmMaxIndex) {
|
||||
anchorIndex = this.anchorIndex - gapLength;
|
||||
} else if (anchorIndex >= rmMinIndex) {
|
||||
anchorIndex = rmMinIndex - 1;
|
||||
}
|
||||
|
||||
if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) {
|
||||
updateLeadAnchorIndices(anchorIndex, leadIndex);
|
||||
}
|
||||
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setValueIsAdjusting(boolean isAdjusting) {
|
||||
if (isAdjusting != this.isAdjusting) {
|
||||
this.isAdjusting = isAdjusting;
|
||||
this.fireValueChanged(isAdjusting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that displays and identifies this
|
||||
* object's properties.
|
||||
*
|
||||
* @return a <code>String</code> representation of this object
|
||||
*/
|
||||
public String toString() {
|
||||
String s = ((getValueIsAdjusting()) ? "~" : "=") + value.toString();
|
||||
return getClass().getName() + " " + Integer.toString(hashCode()) + " " + s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this selection model with the same selection.
|
||||
* <code>listenerLists</code> are not duplicated.
|
||||
*
|
||||
* @exception CloneNotSupportedException if the selection model does not
|
||||
* both (a) implement the Cloneable interface and (b) define a
|
||||
* <code>clone</code> method.
|
||||
*/
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
DefaultListSelectionModel clone = (DefaultListSelectionModel)super.clone();
|
||||
clone.value = (BitSet)value.clone();
|
||||
clone.listenerList = new EventListenerList();
|
||||
return clone;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Transient
|
||||
public int getAnchorSelectionIndex() {
|
||||
return anchorIndex;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Transient
|
||||
public int getLeadSelectionIndex() {
|
||||
return leadIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the anchor selection index, leaving all selection values unchanged.
|
||||
* If leadAnchorNotificationEnabled is true, send a notification covering
|
||||
* the old and new anchor cells.
|
||||
*
|
||||
* @see #getAnchorSelectionIndex
|
||||
* @see #setLeadSelectionIndex
|
||||
*/
|
||||
public void setAnchorSelectionIndex(int anchorIndex) {
|
||||
updateLeadAnchorIndices(anchorIndex, this.leadIndex);
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the lead selection index, leaving all selection values unchanged.
|
||||
* If leadAnchorNotificationEnabled is true, send a notification covering
|
||||
* the old and new lead cells.
|
||||
*
|
||||
* @param leadIndex the new lead selection index
|
||||
*
|
||||
* @see #setAnchorSelectionIndex
|
||||
* @see #setLeadSelectionIndex
|
||||
* @see #getLeadSelectionIndex
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public void moveLeadSelectionIndex(int leadIndex) {
|
||||
// disallow a -1 lead unless the anchor is already -1
|
||||
if (leadIndex == -1) {
|
||||
if (this.anchorIndex != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* PENDING(shannonh) - The following check is nice, to be consistent with
|
||||
setLeadSelectionIndex. However, it is not absolutely
|
||||
necessary: One could work around it by setting the anchor
|
||||
to something valid, modifying the lead, and then moving
|
||||
the anchor back to -1. For this reason, there's no sense
|
||||
in adding it at this time, as that would require
|
||||
updating the spec and officially committing to it.
|
||||
|
||||
// otherwise, don't do anything if the anchor is -1
|
||||
} else if (this.anchorIndex == -1) {
|
||||
return;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
updateLeadAnchorIndices(this.anchorIndex, leadIndex);
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lead selection index, ensuring that values between the
|
||||
* anchor and the new lead are either all selected or all deselected.
|
||||
* If the value at the anchor index is selected, first clear all the
|
||||
* values in the range [anchor, oldLeadIndex], then select all the values
|
||||
* values in the range [anchor, newLeadIndex], where oldLeadIndex is the old
|
||||
* leadIndex and newLeadIndex is the new one.
|
||||
* <p>
|
||||
* If the value at the anchor index is not selected, do the same thing in
|
||||
* reverse selecting values in the old range and deselecting values in the
|
||||
* new one.
|
||||
* <p>
|
||||
* Generate a single event for this change and notify all listeners.
|
||||
* For the purposes of generating minimal bounds in this event, do the
|
||||
* operation in a single pass; that way the first and last index inside the
|
||||
* ListSelectionEvent that is broadcast will refer to cells that actually
|
||||
* changed value because of this method. If, instead, this operation were
|
||||
* done in two steps the effect on the selection state would be the same
|
||||
* but two events would be generated and the bounds around the changed
|
||||
* values would be wider, including cells that had been first cleared only
|
||||
* to later be set.
|
||||
* <p>
|
||||
* This method can be used in the <code>mouseDragged</code> method
|
||||
* of a UI class to extend a selection.
|
||||
*
|
||||
* @see #getLeadSelectionIndex
|
||||
* @see #setAnchorSelectionIndex
|
||||
*/
|
||||
public void setLeadSelectionIndex(int leadIndex) {
|
||||
int anchorIndex = this.anchorIndex;
|
||||
|
||||
// only allow a -1 lead if the anchor is already -1
|
||||
if (leadIndex == -1) {
|
||||
if (anchorIndex == -1) {
|
||||
updateLeadAnchorIndices(anchorIndex, leadIndex);
|
||||
fireValueChanged();
|
||||
}
|
||||
|
||||
return;
|
||||
// otherwise, don't do anything if the anchor is -1
|
||||
} else if (anchorIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.leadIndex == -1) {
|
||||
this.leadIndex = leadIndex;
|
||||
}
|
||||
|
||||
boolean shouldSelect = value.get(this.anchorIndex);
|
||||
|
||||
if (getSelectionMode() == SINGLE_SELECTION) {
|
||||
anchorIndex = leadIndex;
|
||||
shouldSelect = true;
|
||||
}
|
||||
|
||||
int oldMin = Math.min(this.anchorIndex, this.leadIndex);
|
||||
int oldMax = Math.max(this.anchorIndex, this.leadIndex);
|
||||
int newMin = Math.min(anchorIndex, leadIndex);
|
||||
int newMax = Math.max(anchorIndex, leadIndex);
|
||||
|
||||
updateLeadAnchorIndices(anchorIndex, leadIndex);
|
||||
|
||||
if (shouldSelect) {
|
||||
changeSelection(oldMin, oldMax, newMin, newMax);
|
||||
}
|
||||
else {
|
||||
changeSelection(newMin, newMax, oldMin, oldMax, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
1379
jdkSrc/jdk8/javax/swing/DefaultRowSorter.java
Normal file
1379
jdkSrc/jdk8/javax/swing/DefaultRowSorter.java
Normal file
File diff suppressed because it is too large
Load Diff
175
jdkSrc/jdk8/javax/swing/DefaultSingleSelectionModel.java
Normal file
175
jdkSrc/jdk8/javax/swing/DefaultSingleSelectionModel.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* A generic implementation of SingleSelectionModel.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Dave Moore
|
||||
*/
|
||||
public class DefaultSingleSelectionModel implements SingleSelectionModel,
|
||||
Serializable {
|
||||
/* Only one ModelChangeEvent is needed per model instance since the
|
||||
* event's only (read-only) state is the source property. The source
|
||||
* of events generated here is always "this".
|
||||
*/
|
||||
protected transient ChangeEvent changeEvent = null;
|
||||
/** The collection of registered listeners */
|
||||
protected EventListenerList listenerList = new EventListenerList();
|
||||
|
||||
private int index = -1;
|
||||
|
||||
// implements javax.swing.SingleSelectionModel
|
||||
public int getSelectedIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
// implements javax.swing.SingleSelectionModel
|
||||
public void setSelectedIndex(int index) {
|
||||
if (this.index != index) {
|
||||
this.index = index;
|
||||
fireStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// implements javax.swing.SingleSelectionModel
|
||||
public void clearSelection() {
|
||||
setSelectedIndex(-1);
|
||||
}
|
||||
|
||||
// implements javax.swing.SingleSelectionModel
|
||||
public boolean isSelected() {
|
||||
boolean ret = false;
|
||||
if (getSelectedIndex() != -1) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>ChangeListener</code> to the button.
|
||||
*/
|
||||
public void addChangeListener(ChangeListener l) {
|
||||
listenerList.add(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a <code>ChangeListener</code> from the button.
|
||||
*/
|
||||
public void removeChangeListener(ChangeListener l) {
|
||||
listenerList.remove(ChangeListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the change listeners
|
||||
* registered on this <code>DefaultSingleSelectionModel</code>.
|
||||
*
|
||||
* @return all of this model's <code>ChangeListener</code>s
|
||||
* or an empty
|
||||
* array if no change listeners are currently registered
|
||||
*
|
||||
* @see #addChangeListener
|
||||
* @see #removeChangeListener
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public ChangeListener[] getChangeListeners() {
|
||||
return listenerList.getListeners(ChangeListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is created lazily.
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireStateChanged() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ChangeListener.class) {
|
||||
// Lazily create the event:
|
||||
if (changeEvent == null)
|
||||
changeEvent = new ChangeEvent(this);
|
||||
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* upon this model.
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* are registered using the <code>add<em>Foo</em>Listener</code> method.
|
||||
* <p>
|
||||
* You can specify the <code>listenerType</code> argument
|
||||
* with a class literal, such as <code><em>Foo</em>Listener.class</code>.
|
||||
* For example, you can query a <code>DefaultSingleSelectionModel</code>
|
||||
* instance <code>m</code>
|
||||
* for its change listeners
|
||||
* with the following code:
|
||||
*
|
||||
* <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre>
|
||||
*
|
||||
* 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</code>
|
||||
* @return an array of all objects registered as
|
||||
* <code><em>Foo</em>Listener</code>s
|
||||
* on this model,
|
||||
* or an empty array if no such
|
||||
* listeners have been added
|
||||
* @exception ClassCastException if <code>listenerType</code> doesn't
|
||||
* specify a class or interface that implements
|
||||
* <code>java.util.EventListener</code>
|
||||
*
|
||||
* @see #getChangeListeners
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
|
||||
return listenerList.getListeners(listenerType);
|
||||
}
|
||||
}
|
||||
162
jdkSrc/jdk8/javax/swing/DelegatingDefaultFocusManager.java
Normal file
162
jdkSrc/jdk8/javax/swing/DelegatingDefaultFocusManager.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2004, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Provides a javax.swing.DefaultFocusManager view onto an arbitrary
|
||||
* java.awt.KeyboardFocusManager. We subclass DefaultFocusManager instead of
|
||||
* FocusManager because it seems more backward-compatible. It is likely that
|
||||
* some pre-1.4 code assumes that the object returned by
|
||||
* FocusManager.getCurrentManager is an instance of DefaultFocusManager unless
|
||||
* set explicitly.
|
||||
*/
|
||||
final class DelegatingDefaultFocusManager extends DefaultFocusManager {
|
||||
private final KeyboardFocusManager delegate;
|
||||
|
||||
DelegatingDefaultFocusManager(KeyboardFocusManager delegate) {
|
||||
this.delegate = delegate;
|
||||
setDefaultFocusTraversalPolicy(gluePolicy);
|
||||
}
|
||||
|
||||
KeyboardFocusManager getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
// Legacy methods which first appeared in javax.swing.FocusManager.
|
||||
// Client code is most likely to invoke these methods.
|
||||
|
||||
public void processKeyEvent(Component focusedComponent, KeyEvent e) {
|
||||
delegate.processKeyEvent(focusedComponent, e);
|
||||
}
|
||||
public void focusNextComponent(Component aComponent) {
|
||||
delegate.focusNextComponent(aComponent);
|
||||
}
|
||||
public void focusPreviousComponent(Component aComponent) {
|
||||
delegate.focusPreviousComponent(aComponent);
|
||||
}
|
||||
|
||||
// Make sure that we delegate all new methods in KeyboardFocusManager
|
||||
// as well as the legacy methods from Swing. It is theoretically possible,
|
||||
// although unlikely, that a client app will treat this instance as a
|
||||
// new-style KeyboardFocusManager. We might as well be safe.
|
||||
//
|
||||
// The JLS won't let us override the protected methods in
|
||||
// KeyboardFocusManager such that they invoke the corresponding methods on
|
||||
// the delegate. However, since client code would never be able to call
|
||||
// those methods anyways, we don't have to worry about that problem.
|
||||
|
||||
public Component getFocusOwner() {
|
||||
return delegate.getFocusOwner();
|
||||
}
|
||||
public void clearGlobalFocusOwner() {
|
||||
delegate.clearGlobalFocusOwner();
|
||||
}
|
||||
public Component getPermanentFocusOwner() {
|
||||
return delegate.getPermanentFocusOwner();
|
||||
}
|
||||
public Window getFocusedWindow() {
|
||||
return delegate.getFocusedWindow();
|
||||
}
|
||||
public Window getActiveWindow() {
|
||||
return delegate.getActiveWindow();
|
||||
}
|
||||
public FocusTraversalPolicy getDefaultFocusTraversalPolicy() {
|
||||
return delegate.getDefaultFocusTraversalPolicy();
|
||||
}
|
||||
public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy
|
||||
defaultPolicy) {
|
||||
if (delegate != null) {
|
||||
// Will be null when invoked from supers constructor.
|
||||
delegate.setDefaultFocusTraversalPolicy(defaultPolicy);
|
||||
}
|
||||
}
|
||||
public void
|
||||
setDefaultFocusTraversalKeys(int id,
|
||||
Set<? extends AWTKeyStroke> keystrokes)
|
||||
{
|
||||
delegate.setDefaultFocusTraversalKeys(id, keystrokes);
|
||||
}
|
||||
public Set<AWTKeyStroke> getDefaultFocusTraversalKeys(int id) {
|
||||
return delegate.getDefaultFocusTraversalKeys(id);
|
||||
}
|
||||
public Container getCurrentFocusCycleRoot() {
|
||||
return delegate.getCurrentFocusCycleRoot();
|
||||
}
|
||||
public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) {
|
||||
delegate.setGlobalCurrentFocusCycleRoot(newFocusCycleRoot);
|
||||
}
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
delegate.addPropertyChangeListener(listener);
|
||||
}
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
delegate.removePropertyChangeListener(listener);
|
||||
}
|
||||
public void addPropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
delegate.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
public void removePropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
delegate.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
public void addVetoableChangeListener(VetoableChangeListener listener) {
|
||||
delegate.addVetoableChangeListener(listener);
|
||||
}
|
||||
public void removeVetoableChangeListener(VetoableChangeListener listener) {
|
||||
delegate.removeVetoableChangeListener(listener);
|
||||
}
|
||||
public void addVetoableChangeListener(String propertyName,
|
||||
VetoableChangeListener listener) {
|
||||
delegate.addVetoableChangeListener(propertyName, listener);
|
||||
}
|
||||
public void removeVetoableChangeListener(String propertyName,
|
||||
VetoableChangeListener listener) {
|
||||
delegate.removeVetoableChangeListener(propertyName, listener);
|
||||
}
|
||||
public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) {
|
||||
delegate.addKeyEventDispatcher(dispatcher);
|
||||
}
|
||||
public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher) {
|
||||
delegate.removeKeyEventDispatcher(dispatcher);
|
||||
}
|
||||
public boolean dispatchEvent(AWTEvent e) {
|
||||
return delegate.dispatchEvent(e);
|
||||
}
|
||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||
return delegate.dispatchKeyEvent(e);
|
||||
}
|
||||
public void upFocusCycle(Component aComponent) {
|
||||
delegate.upFocusCycle(aComponent);
|
||||
}
|
||||
public void downFocusCycle(Container aContainer) {
|
||||
delegate.downFocusCycle(aContainer);
|
||||
}
|
||||
}
|
||||
118
jdkSrc/jdk8/javax/swing/DesktopManager.java
Normal file
118
jdkSrc/jdk8/javax/swing/DesktopManager.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
/** DesktopManager objects are owned by a JDesktopPane object. They are responsible
|
||||
* for implementing L&F specific behaviors for the JDesktopPane. JInternalFrame
|
||||
* implementations should delegate specific behaviors to the DesktopManager. For
|
||||
* instance, if a JInternalFrame was asked to iconify, it should try:
|
||||
* <PRE>
|
||||
* getDesktopPane().getDesktopManager().iconifyFrame(frame);
|
||||
* </PRE>
|
||||
* This delegation allows each L&F to provide custom behaviors for desktop-specific
|
||||
* actions. (For example, how and where the internal frame's icon would appear.)
|
||||
* <p>This class provides a policy for the various JInternalFrame methods, it is not
|
||||
* meant to be called directly rather the various JInternalFrame methods will call
|
||||
* into the DesktopManager.</p>
|
||||
*
|
||||
* @see JDesktopPane
|
||||
* @see JInternalFrame
|
||||
* @see JInternalFrame.JDesktopIcon
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
public interface DesktopManager
|
||||
{
|
||||
/** If possible, display this frame in an appropriate location.
|
||||
* Normally, this is not called, as the creator of the JInternalFrame
|
||||
* will add the frame to the appropriate parent.
|
||||
*/
|
||||
void openFrame(JInternalFrame f);
|
||||
|
||||
/** Generally, this call should remove the frame from it's parent. */
|
||||
void closeFrame(JInternalFrame f);
|
||||
|
||||
/** Generally, the frame should be resized to match it's parents bounds. */
|
||||
void maximizeFrame(JInternalFrame f);
|
||||
/** Generally, this indicates that the frame should be restored to it's
|
||||
* size and position prior to a maximizeFrame() call.
|
||||
*/
|
||||
void minimizeFrame(JInternalFrame f);
|
||||
/** Generally, remove this frame from it's parent and add an iconic representation. */
|
||||
void iconifyFrame(JInternalFrame f);
|
||||
/** Generally, remove any iconic representation that is present and restore the
|
||||
* frame to it's original size and location.
|
||||
*/
|
||||
void deiconifyFrame(JInternalFrame f);
|
||||
|
||||
/**
|
||||
* Generally, indicate that this frame has focus. This is usually called after
|
||||
* the JInternalFrame's IS_SELECTED_PROPERTY has been set to true.
|
||||
*/
|
||||
void activateFrame(JInternalFrame f);
|
||||
|
||||
/**
|
||||
* Generally, indicate that this frame has lost focus. This is usually called
|
||||
* after the JInternalFrame's IS_SELECTED_PROPERTY has been set to false.
|
||||
*/
|
||||
void deactivateFrame(JInternalFrame f);
|
||||
|
||||
/** This method is normally called when the user has indicated that
|
||||
* they will begin dragging a component around. This method should be called
|
||||
* prior to any dragFrame() calls to allow the DesktopManager to prepare any
|
||||
* necessary state. Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void beginDraggingFrame(JComponent f);
|
||||
|
||||
/** The user has moved the frame. Calls to this method will be preceded by calls
|
||||
* to beginDraggingFrame().
|
||||
* Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void dragFrame(JComponent f, int newX, int newY);
|
||||
/** This method signals the end of the dragging session. Any state maintained by
|
||||
* the DesktopManager can be removed here. Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void endDraggingFrame(JComponent f);
|
||||
|
||||
/** This methods is normally called when the user has indicated that
|
||||
* they will begin resizing the frame. This method should be called
|
||||
* prior to any resizeFrame() calls to allow the DesktopManager to prepare any
|
||||
* necessary state. Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void beginResizingFrame(JComponent f, int direction);
|
||||
/** The user has resized the component. Calls to this method will be preceded by calls
|
||||
* to beginResizingFrame().
|
||||
* Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight);
|
||||
/** This method signals the end of the resize session. Any state maintained by
|
||||
* the DesktopManager can be removed here. Normally <b>f</b> will be a JInternalFrame.
|
||||
*/
|
||||
void endResizingFrame(JComponent f);
|
||||
|
||||
/** This is a primitive reshape method.*/
|
||||
void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight);
|
||||
}
|
||||
103
jdkSrc/jdk8/javax/swing/DropMode.java
Normal file
103
jdkSrc/jdk8/javax/swing/DropMode.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 javax.swing;
|
||||
|
||||
/**
|
||||
* Drop modes, used to determine the method by which a component
|
||||
* tracks and indicates a drop location during drag and drop.
|
||||
*
|
||||
* @author Shannon Hickey
|
||||
* @see JTable#setDropMode
|
||||
* @see JList#setDropMode
|
||||
* @see JTree#setDropMode
|
||||
* @see javax.swing.text.JTextComponent#setDropMode
|
||||
* @since 1.6
|
||||
*/
|
||||
public enum DropMode {
|
||||
|
||||
/**
|
||||
* A component's own internal selection mechanism (or caret for text
|
||||
* components) should be used to track the drop location.
|
||||
*/
|
||||
USE_SELECTION,
|
||||
|
||||
/**
|
||||
* The drop location should be tracked in terms of the index of
|
||||
* existing items. Useful for dropping on items in tables, lists,
|
||||
* and trees.
|
||||
*/
|
||||
ON,
|
||||
|
||||
/**
|
||||
* The drop location should be tracked in terms of the position
|
||||
* where new data should be inserted. For components that manage
|
||||
* a list of items (list and tree for example), the drop location
|
||||
* should indicate the index where new data should be inserted.
|
||||
* For text components the location should represent a position
|
||||
* between characters. For components that manage tabular data
|
||||
* (table for example), the drop location should indicate
|
||||
* where to insert new rows, columns, or both, to accommodate
|
||||
* the dropped data.
|
||||
*/
|
||||
INSERT,
|
||||
|
||||
/**
|
||||
* The drop location should be tracked in terms of the row index
|
||||
* where new rows should be inserted to accommodate the dropped
|
||||
* data. This is useful for components that manage tabular data.
|
||||
*/
|
||||
INSERT_ROWS,
|
||||
|
||||
/**
|
||||
* The drop location should be tracked in terms of the column index
|
||||
* where new columns should be inserted to accommodate the dropped
|
||||
* data. This is useful for components that manage tabular data.
|
||||
*/
|
||||
INSERT_COLS,
|
||||
|
||||
/**
|
||||
* This mode is a combination of <code>ON</code>
|
||||
* and <code>INSERT</code>, specifying that data can be
|
||||
* dropped on existing items, or in insert locations
|
||||
* as specified by <code>INSERT</code>.
|
||||
*/
|
||||
ON_OR_INSERT,
|
||||
|
||||
/**
|
||||
* This mode is a combination of <code>ON</code>
|
||||
* and <code>INSERT_ROWS</code>, specifying that data can be
|
||||
* dropped on existing items, or as insert rows
|
||||
* as specified by <code>INSERT_ROWS</code>.
|
||||
*/
|
||||
ON_OR_INSERT_ROWS,
|
||||
|
||||
/**
|
||||
* This mode is a combination of <code>ON</code>
|
||||
* and <code>INSERT_COLS</code>, specifying that data can be
|
||||
* dropped on existing items, or as insert columns
|
||||
* as specified by <code>INSERT_COLS</code>.
|
||||
*/
|
||||
ON_OR_INSERT_COLS
|
||||
}
|
||||
151
jdkSrc/jdk8/javax/swing/FocusManager.java
Normal file
151
jdkSrc/jdk8/javax/swing/FocusManager.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class has been obsoleted by the 1.4 focus APIs. While client code may
|
||||
* still use this class, developers are strongly encouraged to use
|
||||
* <code>java.awt.KeyboardFocusManager</code> and
|
||||
* <code>java.awt.DefaultKeyboardFocusManager</code> instead.
|
||||
* <p>
|
||||
* Please see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
|
||||
* How to Use the Focus Subsystem</a>,
|
||||
* a section in <em>The Java Tutorial</em>, and the
|
||||
* <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
|
||||
* for more information.
|
||||
*
|
||||
* @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
* @author David Mendenhall
|
||||
*/
|
||||
public abstract class FocusManager extends DefaultKeyboardFocusManager {
|
||||
|
||||
/**
|
||||
* This field is obsolete, and its use is discouraged since its
|
||||
* specification is incompatible with the 1.4 focus APIs.
|
||||
* The current FocusManager is no longer a property of the UI.
|
||||
* Client code must query for the current FocusManager using
|
||||
* <code>KeyboardFocusManager.getCurrentKeyboardFocusManager()</code>.
|
||||
* See the Focus Specification for more information.
|
||||
*
|
||||
* @see java.awt.KeyboardFocusManager#getCurrentKeyboardFocusManager
|
||||
* @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
|
||||
*/
|
||||
public static final String FOCUS_MANAGER_CLASS_PROPERTY =
|
||||
"FocusManagerClassName";
|
||||
|
||||
private static boolean enabled = true;
|
||||
|
||||
/**
|
||||
* Returns the current <code>KeyboardFocusManager</code> instance
|
||||
* for the calling thread's context.
|
||||
*
|
||||
* @return this thread's context's <code>KeyboardFocusManager</code>
|
||||
* @see #setCurrentManager
|
||||
*/
|
||||
public static FocusManager getCurrentManager() {
|
||||
KeyboardFocusManager manager =
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
if (manager instanceof FocusManager) {
|
||||
return (FocusManager)manager;
|
||||
} else {
|
||||
return new DelegatingDefaultFocusManager(manager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current <code>KeyboardFocusManager</code> instance
|
||||
* for the calling thread's context. If <code>null</code> is
|
||||
* specified, then the current <code>KeyboardFocusManager</code>
|
||||
* is replaced with a new instance of
|
||||
* <code>DefaultKeyboardFocusManager</code>.
|
||||
* <p>
|
||||
* If a <code>SecurityManager</code> is installed,
|
||||
* the calling thread must be granted the <code>AWTPermission</code>
|
||||
* "replaceKeyboardFocusManager" in order to replace the
|
||||
* the current <code>KeyboardFocusManager</code>.
|
||||
* If this permission is not granted,
|
||||
* this method will throw a <code>SecurityException</code>,
|
||||
* and the current <code>KeyboardFocusManager</code> will be unchanged.
|
||||
*
|
||||
* @param aFocusManager the new <code>KeyboardFocusManager</code>
|
||||
* for this thread's context
|
||||
* @see #getCurrentManager
|
||||
* @see java.awt.DefaultKeyboardFocusManager
|
||||
* @throws SecurityException if the calling thread does not have permission
|
||||
* to replace the current <code>KeyboardFocusManager</code>
|
||||
*/
|
||||
public static void setCurrentManager(FocusManager aFocusManager)
|
||||
throws SecurityException
|
||||
{
|
||||
// Note: This method is not backward-compatible with 1.3 and earlier
|
||||
// releases. It now throws a SecurityException in an applet, whereas
|
||||
// in previous releases, it did not. This issue was discussed at
|
||||
// length, and ultimately approved by Hans.
|
||||
KeyboardFocusManager toSet =
|
||||
(aFocusManager instanceof DelegatingDefaultFocusManager)
|
||||
? ((DelegatingDefaultFocusManager)aFocusManager).getDelegate()
|
||||
: aFocusManager;
|
||||
KeyboardFocusManager.setCurrentKeyboardFocusManager(toSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current <code>KeyboardFocusManager</code>'s default
|
||||
* <code>FocusTraversalPolicy</code> to
|
||||
* <code>DefaultFocusTraversalPolicy</code>.
|
||||
*
|
||||
* @see java.awt.DefaultFocusTraversalPolicy
|
||||
* @see java.awt.KeyboardFocusManager#setDefaultFocusTraversalPolicy
|
||||
* @deprecated as of 1.4, replaced by
|
||||
* <code>KeyboardFocusManager.setDefaultFocusTraversalPolicy(FocusTraversalPolicy)</code>
|
||||
*/
|
||||
@Deprecated
|
||||
public static void disableSwingFocusManager() {
|
||||
if (enabled) {
|
||||
enabled = false;
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().
|
||||
setDefaultFocusTraversalPolicy(
|
||||
new DefaultFocusTraversalPolicy());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the application has invoked
|
||||
* <code>disableSwingFocusManager()</code>.
|
||||
*
|
||||
* @see #disableSwingFocusManager
|
||||
* @deprecated As of 1.4, replaced by
|
||||
* <code>KeyboardFocusManager.getDefaultFocusTraversalPolicy()</code>
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isFocusManagerEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
47
jdkSrc/jdk8/javax/swing/GraphicsWrapper.java
Normal file
47
jdkSrc/jdk8/javax/swing/GraphicsWrapper.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 javax.swing;
|
||||
|
||||
/**
|
||||
* A private interface to access clip bounds in wrapped Graphics objects.
|
||||
*
|
||||
* @author Thomas Ball
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
interface GraphicsWrapper {
|
||||
Graphics subGraphics();
|
||||
|
||||
boolean isClipIntersecting(Rectangle r);
|
||||
|
||||
int getClipX();
|
||||
|
||||
int getClipY();
|
||||
|
||||
int getClipWidth();
|
||||
|
||||
int getClipHeight();
|
||||
}
|
||||
93
jdkSrc/jdk8/javax/swing/GrayFilter.java
Normal file
93
jdkSrc/jdk8/javax/swing/GrayFilter.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* An image filter that "disables" an image by turning
|
||||
* it into a grayscale image, and brightening the pixels
|
||||
* in the image. Used by buttons to create an image for
|
||||
* a disabled button.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @author Tom Ball
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class GrayFilter extends RGBImageFilter {
|
||||
private boolean brighter;
|
||||
private int percent;
|
||||
|
||||
/**
|
||||
* Creates a disabled image
|
||||
*/
|
||||
public static Image createDisabledImage (Image i) {
|
||||
GrayFilter filter = new GrayFilter(true, 50);
|
||||
ImageProducer prod = new FilteredImageSource(i.getSource(), filter);
|
||||
Image grayImage = Toolkit.getDefaultToolkit().createImage(prod);
|
||||
return grayImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a GrayFilter object that filters a color image to a
|
||||
* grayscale image. Used by buttons to create disabled ("grayed out")
|
||||
* button images.
|
||||
*
|
||||
* @param b a boolean -- true if the pixels should be brightened
|
||||
* @param p an int in the range 0..100 that determines the percentage
|
||||
* of gray, where 100 is the darkest gray, and 0 is the lightest
|
||||
*/
|
||||
public GrayFilter(boolean b, int p) {
|
||||
brighter = b;
|
||||
percent = p;
|
||||
|
||||
// canFilterIndexColorModel indicates whether or not it is acceptable
|
||||
// to apply the color filtering of the filterRGB method to the color
|
||||
// table entries of an IndexColorModel object in lieu of pixel by pixel
|
||||
// filtering.
|
||||
canFilterIndexColorModel = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides <code>RGBImageFilter.filterRGB</code>.
|
||||
*/
|
||||
public int filterRGB(int x, int y, int rgb) {
|
||||
// Use NTSC conversion formula.
|
||||
int gray = (int)((0.30 * ((rgb >> 16) & 0xff) +
|
||||
0.59 * ((rgb >> 8) & 0xff) +
|
||||
0.11 * (rgb & 0xff)) / 3);
|
||||
|
||||
if (brighter) {
|
||||
gray = (255 - ((255 - gray) * (100 - percent) / 100));
|
||||
} else {
|
||||
gray = (gray * (100 - percent) / 100);
|
||||
}
|
||||
|
||||
if (gray < 0) gray = 0;
|
||||
if (gray > 255) gray = 255;
|
||||
return (rgb & 0xff000000) | (gray << 16) | (gray << 8) | (gray << 0);
|
||||
}
|
||||
}
|
||||
3745
jdkSrc/jdk8/javax/swing/GroupLayout.java
Normal file
3745
jdkSrc/jdk8/javax/swing/GroupLayout.java
Normal file
File diff suppressed because it is too large
Load Diff
59
jdkSrc/jdk8/javax/swing/Icon.java
Normal file
59
jdkSrc/jdk8/javax/swing/Icon.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Component;
|
||||
|
||||
|
||||
/**
|
||||
* A small fixed size picture, typically used to decorate components.
|
||||
*
|
||||
* @see ImageIcon
|
||||
*/
|
||||
|
||||
public interface Icon
|
||||
{
|
||||
/**
|
||||
* Draw the icon at the specified location. Icon implementations
|
||||
* may use the Component argument to get properties useful for
|
||||
* painting, e.g. the foreground or background color.
|
||||
*/
|
||||
void paintIcon(Component c, Graphics g, int x, int y);
|
||||
|
||||
/**
|
||||
* Returns the icon's width.
|
||||
*
|
||||
* @return an int specifying the fixed width of the icon.
|
||||
*/
|
||||
int getIconWidth();
|
||||
|
||||
/**
|
||||
* Returns the icon's height.
|
||||
*
|
||||
* @return an int specifying the fixed height of the icon.
|
||||
*/
|
||||
int getIconHeight();
|
||||
}
|
||||
715
jdkSrc/jdk8/javax/swing/ImageIcon.java
Normal file
715
jdkSrc/jdk8/javax/swing/ImageIcon.java
Normal file
@@ -0,0 +1,715 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.beans.Transient;
|
||||
import java.net.URL;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.*;
|
||||
|
||||
/**
|
||||
* An implementation of the Icon interface that paints Icons
|
||||
* from Images. Images that are created from a URL, filename or byte array
|
||||
* are preloaded using MediaTracker to monitor the loaded state
|
||||
* of the image.
|
||||
*
|
||||
* <p>
|
||||
* For further information and examples of using image icons, see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/icon.html">How to Use Icons</a>
|
||||
* in <em>The Java Tutorial.</em>
|
||||
*
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @author Lynn Monsanto
|
||||
*/
|
||||
public class ImageIcon implements Icon, Serializable, Accessible {
|
||||
/* Keep references to the filename and location so that
|
||||
* alternate persistence schemes have the option to archive
|
||||
* images symbolically rather than including the image data
|
||||
* in the archive.
|
||||
*/
|
||||
transient private String filename;
|
||||
transient private URL location;
|
||||
|
||||
transient Image image;
|
||||
transient int loadStatus = 0;
|
||||
ImageObserver imageObserver;
|
||||
String description = null;
|
||||
|
||||
/**
|
||||
* Do not use this shared component, which is used to track image loading.
|
||||
* It is left for backward compatibility only.
|
||||
* @deprecated since 1.8
|
||||
*/
|
||||
@Deprecated
|
||||
protected final static Component component;
|
||||
|
||||
/**
|
||||
* Do not use this shared media tracker, which is used to load images.
|
||||
* It is left for backward compatibility only.
|
||||
* @deprecated since 1.8
|
||||
*/
|
||||
@Deprecated
|
||||
protected final static MediaTracker tracker;
|
||||
|
||||
static {
|
||||
component = AccessController.doPrivileged(new PrivilegedAction<Component>() {
|
||||
public Component run() {
|
||||
try {
|
||||
final Component component = createNoPermsComponent();
|
||||
|
||||
// 6482575 - clear the appContext field so as not to leak it
|
||||
Field appContextField =
|
||||
|
||||
Component.class.getDeclaredField("appContext");
|
||||
appContextField.setAccessible(true);
|
||||
appContextField.set(component, null);
|
||||
|
||||
return component;
|
||||
} catch (Throwable e) {
|
||||
// We don't care about component.
|
||||
// So don't prevent class initialisation.
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
tracker = new MediaTracker(component);
|
||||
}
|
||||
|
||||
private static Component createNoPermsComponent() {
|
||||
// 7020198 - set acc field to no permissions and no subject
|
||||
// Note, will have appContext set.
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<Component>() {
|
||||
public Component run() {
|
||||
return new Component() {
|
||||
};
|
||||
}
|
||||
},
|
||||
new AccessControlContext(new ProtectionDomain[]{
|
||||
new ProtectionDomain(null, null)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Id used in loading images from MediaTracker.
|
||||
*/
|
||||
private static int mediaTrackerID;
|
||||
|
||||
private final static Object TRACKER_KEY = new StringBuilder("TRACKER_KEY");
|
||||
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from the specified file. The image will
|
||||
* be preloaded by using MediaTracker to monitor the loading state
|
||||
* of the image.
|
||||
* @param filename the name of the file containing the image
|
||||
* @param description a brief textual description of the image
|
||||
* @see #ImageIcon(String)
|
||||
*/
|
||||
public ImageIcon(String filename, String description) {
|
||||
image = Toolkit.getDefaultToolkit().getImage(filename);
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
this.filename = filename;
|
||||
this.description = description;
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from the specified file. The image will
|
||||
* be preloaded by using MediaTracker to monitor the loading state
|
||||
* of the image. The specified String can be a file name or a
|
||||
* file path. When specifying a path, use the Internet-standard
|
||||
* forward-slash ("/") as a separator.
|
||||
* (The string is converted to an URL, so the forward-slash works
|
||||
* on all systems.)
|
||||
* For example, specify:
|
||||
* <pre>
|
||||
* new ImageIcon("images/myImage.gif") </pre>
|
||||
* The description is initialized to the <code>filename</code> string.
|
||||
*
|
||||
* @param filename a String specifying a filename or path
|
||||
* @see #getDescription
|
||||
*/
|
||||
@ConstructorProperties({"description"})
|
||||
public ImageIcon (String filename) {
|
||||
this(filename, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from the specified URL. The image will
|
||||
* be preloaded by using MediaTracker to monitor the loaded state
|
||||
* of the image.
|
||||
* @param location the URL for the image
|
||||
* @param description a brief textual description of the image
|
||||
* @see #ImageIcon(String)
|
||||
*/
|
||||
public ImageIcon(URL location, String description) {
|
||||
image = Toolkit.getDefaultToolkit().getImage(location);
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
this.location = location;
|
||||
this.description = description;
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from the specified URL. The image will
|
||||
* be preloaded by using MediaTracker to monitor the loaded state
|
||||
* of the image.
|
||||
* The icon's description is initialized to be
|
||||
* a string representation of the URL.
|
||||
* @param location the URL for the image
|
||||
* @see #getDescription
|
||||
*/
|
||||
public ImageIcon (URL location) {
|
||||
this(location, location.toExternalForm());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from the image.
|
||||
* @param image the image
|
||||
* @param description a brief textual description of the image
|
||||
*/
|
||||
public ImageIcon(Image image, String description) {
|
||||
this(image);
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from an image object.
|
||||
* If the image has a "comment" property that is a string,
|
||||
* then the string is used as the description of this icon.
|
||||
* @param image the image
|
||||
* @see #getDescription
|
||||
* @see java.awt.Image#getProperty
|
||||
*/
|
||||
public ImageIcon (Image image) {
|
||||
this.image = image;
|
||||
Object o = image.getProperty("comment", imageObserver);
|
||||
if (o instanceof String) {
|
||||
description = (String) o;
|
||||
}
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from an array of bytes which were
|
||||
* read from an image file containing a supported image format,
|
||||
* such as GIF, JPEG, or (as of 1.3) PNG.
|
||||
* Normally this array is created
|
||||
* by reading an image using Class.getResourceAsStream(), but
|
||||
* the byte array may also be statically stored in a class.
|
||||
*
|
||||
* @param imageData an array of pixels in an image format supported
|
||||
* by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
|
||||
* @param description a brief textual description of the image
|
||||
* @see java.awt.Toolkit#createImage
|
||||
*/
|
||||
public ImageIcon (byte[] imageData, String description) {
|
||||
this.image = Toolkit.getDefaultToolkit().createImage(imageData);
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
this.description = description;
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ImageIcon from an array of bytes which were
|
||||
* read from an image file containing a supported image format,
|
||||
* such as GIF, JPEG, or (as of 1.3) PNG.
|
||||
* Normally this array is created
|
||||
* by reading an image using Class.getResourceAsStream(), but
|
||||
* the byte array may also be statically stored in a class.
|
||||
* If the resulting image has a "comment" property that is a string,
|
||||
* then the string is used as the description of this icon.
|
||||
*
|
||||
* @param imageData an array of pixels in an image format supported by
|
||||
* the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
|
||||
* @see java.awt.Toolkit#createImage
|
||||
* @see #getDescription
|
||||
* @see java.awt.Image#getProperty
|
||||
*/
|
||||
public ImageIcon (byte[] imageData) {
|
||||
this.image = Toolkit.getDefaultToolkit().createImage(imageData);
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
Object o = image.getProperty("comment", imageObserver);
|
||||
if (o instanceof String) {
|
||||
description = (String) o;
|
||||
}
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an uninitialized image icon.
|
||||
*/
|
||||
public ImageIcon() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image, returning only when the image is loaded.
|
||||
* @param image the image
|
||||
*/
|
||||
protected void loadImage(Image image) {
|
||||
MediaTracker mTracker = getTracker();
|
||||
synchronized(mTracker) {
|
||||
int id = getNextID();
|
||||
|
||||
mTracker.addImage(image, id);
|
||||
try {
|
||||
mTracker.waitForID(id, 0);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("INTERRUPTED while loading Image");
|
||||
}
|
||||
loadStatus = mTracker.statusID(id, false);
|
||||
mTracker.removeImage(image, id);
|
||||
|
||||
width = image.getWidth(imageObserver);
|
||||
height = image.getHeight(imageObserver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID to use with the MediaTracker in loading an image.
|
||||
*/
|
||||
private int getNextID() {
|
||||
synchronized(getTracker()) {
|
||||
return ++mediaTrackerID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MediaTracker for the current AppContext, creating a new
|
||||
* MediaTracker if necessary.
|
||||
*/
|
||||
private MediaTracker getTracker() {
|
||||
Object trackerObj;
|
||||
AppContext ac = AppContext.getAppContext();
|
||||
// Opt: Only synchronize if trackerObj comes back null?
|
||||
// If null, synchronize, re-check for null, and put new tracker
|
||||
synchronized(ac) {
|
||||
trackerObj = ac.get(TRACKER_KEY);
|
||||
if (trackerObj == null) {
|
||||
Component comp = new Component() {};
|
||||
trackerObj = new MediaTracker(comp);
|
||||
ac.put(TRACKER_KEY, trackerObj);
|
||||
}
|
||||
}
|
||||
return (MediaTracker) trackerObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the image loading operation.
|
||||
* @return the loading status as defined by java.awt.MediaTracker
|
||||
* @see java.awt.MediaTracker#ABORTED
|
||||
* @see java.awt.MediaTracker#ERRORED
|
||||
* @see java.awt.MediaTracker#COMPLETE
|
||||
*/
|
||||
public int getImageLoadStatus() {
|
||||
return loadStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this icon's <code>Image</code>.
|
||||
* @return the <code>Image</code> object for this <code>ImageIcon</code>
|
||||
*/
|
||||
@Transient
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image displayed by this icon.
|
||||
* @param image the image
|
||||
*/
|
||||
public void setImage(Image image) {
|
||||
this.image = image;
|
||||
loadImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description of the image. This is meant to be a brief
|
||||
* textual description of the object. For example, it might be
|
||||
* presented to a blind user to give an indication of the purpose
|
||||
* of the image.
|
||||
* The description may be null.
|
||||
*
|
||||
* @return a brief textual description of the image
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of the image. This is meant to be a brief
|
||||
* textual description of the object. For example, it might be
|
||||
* presented to a blind user to give an indication of the purpose
|
||||
* of the image.
|
||||
* @param description a brief textual description of the image
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the icon.
|
||||
* The top-left corner of the icon is drawn at
|
||||
* the point (<code>x</code>, <code>y</code>)
|
||||
* in the coordinate space of the graphics context <code>g</code>.
|
||||
* If this icon has no image observer,
|
||||
* this method uses the <code>c</code> component
|
||||
* as the observer.
|
||||
*
|
||||
* @param c the component to be used as the observer
|
||||
* if this icon has no image observer
|
||||
* @param g the graphics context
|
||||
* @param x the X coordinate of the icon's top-left corner
|
||||
* @param y the Y coordinate of the icon's top-left corner
|
||||
*/
|
||||
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if(imageObserver == null) {
|
||||
g.drawImage(image, x, y, c);
|
||||
} else {
|
||||
g.drawImage(image, x, y, imageObserver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the icon.
|
||||
*
|
||||
* @return the width in pixels of this icon
|
||||
*/
|
||||
public int getIconWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the icon.
|
||||
*
|
||||
* @return the height in pixels of this icon
|
||||
*/
|
||||
public int getIconHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image observer for the image. Set this
|
||||
* property if the ImageIcon contains an animated GIF, so
|
||||
* the observer is notified to update its display.
|
||||
* For example:
|
||||
* <pre>
|
||||
* icon = new ImageIcon(...)
|
||||
* button.setIcon(icon);
|
||||
* icon.setImageObserver(button);
|
||||
* </pre>
|
||||
*
|
||||
* @param observer the image observer
|
||||
*/
|
||||
public void setImageObserver(ImageObserver observer) {
|
||||
imageObserver = observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image observer for the image.
|
||||
*
|
||||
* @return the image observer, which may be null
|
||||
*/
|
||||
@Transient
|
||||
public ImageObserver getImageObserver() {
|
||||
return imageObserver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this image.
|
||||
*
|
||||
* @return a string representing this image
|
||||
*/
|
||||
public String toString() {
|
||||
if (description != null) {
|
||||
return description;
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws ClassNotFoundException, IOException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
|
||||
int w = s.readInt();
|
||||
int h = s.readInt();
|
||||
int[] pixels = (int[])(s.readObject());
|
||||
|
||||
if (pixels != null) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
ColorModel cm = ColorModel.getRGBdefault();
|
||||
image = tk.createImage(new MemoryImageSource(w, h, cm, pixels, 0, w));
|
||||
loadImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
|
||||
int w = getIconWidth();
|
||||
int h = getIconHeight();
|
||||
int[] pixels = image != null? new int[w * h] : null;
|
||||
|
||||
if (image != null) {
|
||||
try {
|
||||
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
|
||||
pg.grabPixels();
|
||||
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
throw new IOException("failed to load image contents");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new IOException("image load interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
s.writeInt(w);
|
||||
s.writeInt(h);
|
||||
s.writeObject(pixels);
|
||||
}
|
||||
|
||||
/**
|
||||
* --- Accessibility Support ---
|
||||
*/
|
||||
|
||||
private AccessibleImageIcon accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this ImageIcon.
|
||||
* For image icons, the AccessibleContext takes the form of an
|
||||
* AccessibleImageIcon.
|
||||
* A new AccessibleImageIcon instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleImageIcon that serves as the
|
||||
* AccessibleContext of this ImageIcon
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: The AccessibleContext associated with this ImageIcon.
|
||||
* @since 1.3
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleImageIcon();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>ImageIcon</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to image icon user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected class AccessibleImageIcon extends AccessibleContext
|
||||
implements AccessibleIcon, Serializable {
|
||||
|
||||
/*
|
||||
* AccessibleContest implementation -----------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.ICON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of this object.
|
||||
*
|
||||
* @return an instance of AccessibleStateSet containing the current
|
||||
* state set of the object
|
||||
* @see AccessibleState
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Accessible parent of this object. If the parent of this
|
||||
* object implements Accessible, this method should simply return
|
||||
* getParent().
|
||||
*
|
||||
* @return the Accessible parent of this object -- can be null if this
|
||||
* object does not have an Accessible parent
|
||||
*/
|
||||
public Accessible getAccessibleParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of this object in its accessible parent.
|
||||
*
|
||||
* @return the index of this object in its parent; -1 if this
|
||||
* object does not have an accessible parent.
|
||||
* @see #getAccessibleParent
|
||||
*/
|
||||
public int getAccessibleIndexInParent() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of accessible children in the object. If all
|
||||
* of the children of this object implement Accessible, than 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth Accessible child of the object.
|
||||
*
|
||||
* @param i zero-based index of child
|
||||
* @return the nth Accessible child of the object
|
||||
*/
|
||||
public Accessible getAccessibleChild(int i) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale of this object.
|
||||
*
|
||||
* @return the locale of this object
|
||||
*/
|
||||
public Locale getLocale() throws IllegalComponentStateException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* AccessibleIcon implementation -----------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the description of the icon. This is meant to be a brief
|
||||
* textual description of the object. For example, it might be
|
||||
* presented to a blind user to give an indication of the purpose
|
||||
* of the icon.
|
||||
*
|
||||
* @return the description of the icon
|
||||
*/
|
||||
public String getAccessibleIconDescription() {
|
||||
return ImageIcon.this.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of the icon. This is meant to be a brief
|
||||
* textual description of the object. For example, it might be
|
||||
* presented to a blind user to give an indication of the purpose
|
||||
* of the icon.
|
||||
*
|
||||
* @param description the description of the icon
|
||||
*/
|
||||
public void setAccessibleIconDescription(String description) {
|
||||
ImageIcon.this.setDescription(description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the icon.
|
||||
*
|
||||
* @return the height of the icon
|
||||
*/
|
||||
public int getAccessibleIconHeight() {
|
||||
return ImageIcon.this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the icon.
|
||||
*
|
||||
* @return the width of the icon
|
||||
*/
|
||||
public int getAccessibleIconWidth() {
|
||||
return ImageIcon.this.width;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws ClassNotFoundException, IOException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
} // AccessibleImageIcon
|
||||
}
|
||||
232
jdkSrc/jdk8/javax/swing/InputMap.java
Normal file
232
jdkSrc/jdk8/javax/swing/InputMap.java
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 javax.swing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <code>InputMap</code> provides a binding between an input event
|
||||
* (currently only <code>KeyStroke</code>s are used)
|
||||
* and an <code>Object</code>. <code>InputMap</code>s
|
||||
* are usually used with an <code>ActionMap</code>,
|
||||
* to determine an <code>Action</code> to perform
|
||||
* when a key is pressed.
|
||||
* An <code>InputMap</code> can have a parent
|
||||
* that is searched for bindings not defined in the <code>InputMap</code>.
|
||||
* <p>As with <code>ActionMap</code> if you create a cycle, eg:
|
||||
* <pre>
|
||||
* InputMap am = new InputMap();
|
||||
* InputMap bm = new InputMap():
|
||||
* am.setParent(bm);
|
||||
* bm.setParent(am);
|
||||
* </pre>
|
||||
* some of the methods will cause a StackOverflowError to be thrown.
|
||||
*
|
||||
* @author Scott Violet
|
||||
* @since 1.3
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InputMap implements Serializable {
|
||||
/** Handles the mapping between KeyStroke and Action name. */
|
||||
private transient ArrayTable arrayTable;
|
||||
/** Parent that handles any bindings we don't contain. */
|
||||
private InputMap parent;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an <code>InputMap</code> with no parent and no mappings.
|
||||
*/
|
||||
public InputMap() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this <code>InputMap</code>'s parent.
|
||||
*
|
||||
* @param map the <code>InputMap</code> that is the parent of this one
|
||||
*/
|
||||
public void setParent(InputMap map) {
|
||||
this.parent = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this <code>InputMap</code>'s parent.
|
||||
*
|
||||
* @return map the <code>InputMap</code> that is the parent of this one,
|
||||
* or null if this <code>InputMap</code> has no parent
|
||||
*/
|
||||
public InputMap getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a binding for <code>keyStroke</code> to <code>actionMapKey</code>.
|
||||
* If <code>actionMapKey</code> is null, this removes the current binding
|
||||
* for <code>keyStroke</code>.
|
||||
*/
|
||||
public void put(KeyStroke keyStroke, Object actionMapKey) {
|
||||
if (keyStroke == null) {
|
||||
return;
|
||||
}
|
||||
if (actionMapKey == null) {
|
||||
remove(keyStroke);
|
||||
}
|
||||
else {
|
||||
if (arrayTable == null) {
|
||||
arrayTable = new ArrayTable();
|
||||
}
|
||||
arrayTable.put(keyStroke, actionMapKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binding for <code>keyStroke</code>, messaging the
|
||||
* parent <code>InputMap</code> if the binding is not locally defined.
|
||||
*/
|
||||
public Object get(KeyStroke keyStroke) {
|
||||
if (arrayTable == null) {
|
||||
InputMap parent = getParent();
|
||||
|
||||
if (parent != null) {
|
||||
return parent.get(keyStroke);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Object value = arrayTable.get(keyStroke);
|
||||
|
||||
if (value == null) {
|
||||
InputMap parent = getParent();
|
||||
|
||||
if (parent != null) {
|
||||
return parent.get(keyStroke);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the binding for <code>key</code> from this
|
||||
* <code>InputMap</code>.
|
||||
*/
|
||||
public void remove(KeyStroke key) {
|
||||
if (arrayTable != null) {
|
||||
arrayTable.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the mappings from this <code>InputMap</code>.
|
||||
*/
|
||||
public void clear() {
|
||||
if (arrayTable != null) {
|
||||
arrayTable.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>KeyStroke</code>s that are bound in this <code>InputMap</code>.
|
||||
*/
|
||||
public KeyStroke[] keys() {
|
||||
if (arrayTable == null) {
|
||||
return null;
|
||||
}
|
||||
KeyStroke[] keys = new KeyStroke[arrayTable.size()];
|
||||
arrayTable.getKeys(keys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of <code>KeyStroke</code> bindings.
|
||||
*/
|
||||
public int size() {
|
||||
if (arrayTable == null) {
|
||||
return 0;
|
||||
}
|
||||
return arrayTable.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the <code>KeyStroke</code>s defined in this
|
||||
* <code>InputMap</code> and its parent. This differs from <code>keys()</code> in that
|
||||
* this method includes the keys defined in the parent.
|
||||
*/
|
||||
public KeyStroke[] allKeys() {
|
||||
int count = size();
|
||||
InputMap parent = getParent();
|
||||
|
||||
if (count == 0) {
|
||||
if (parent != null) {
|
||||
return parent.allKeys();
|
||||
}
|
||||
return keys();
|
||||
}
|
||||
if (parent == null) {
|
||||
return keys();
|
||||
}
|
||||
KeyStroke[] keys = keys();
|
||||
KeyStroke[] pKeys = parent.allKeys();
|
||||
|
||||
if (pKeys == null) {
|
||||
return keys;
|
||||
}
|
||||
if (keys == null) {
|
||||
// Should only happen if size() != keys.length, which should only
|
||||
// happen if mutated from multiple threads (or a bogus subclass).
|
||||
return pKeys;
|
||||
}
|
||||
|
||||
HashMap<KeyStroke, KeyStroke> keyMap = new HashMap<KeyStroke, KeyStroke>();
|
||||
int counter;
|
||||
|
||||
for (counter = keys.length - 1; counter >= 0; counter--) {
|
||||
keyMap.put(keys[counter], keys[counter]);
|
||||
}
|
||||
for (counter = pKeys.length - 1; counter >= 0; counter--) {
|
||||
keyMap.put(pKeys[counter], pKeys[counter]);
|
||||
}
|
||||
|
||||
KeyStroke[] allKeys = new KeyStroke[keyMap.size()];
|
||||
|
||||
return keyMap.keySet().toArray(allKeys);
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
|
||||
ArrayTable.writeArrayTable(s, arrayTable);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s) throws ClassNotFoundException,
|
||||
IOException {
|
||||
s.defaultReadObject();
|
||||
for (int counter = s.readInt() - 1; counter >= 0; counter--) {
|
||||
put((KeyStroke)s.readObject(), s.readObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
135
jdkSrc/jdk8/javax/swing/InputVerifier.java
Normal file
135
jdkSrc/jdk8/javax/swing/InputVerifier.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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 javax.swing;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to help clients support smooth focus
|
||||
* navigation through GUIs with text fields. Such GUIs often need
|
||||
* to ensure that the text entered by the user is valid (for example,
|
||||
* that it's in
|
||||
* the proper format) before allowing the user to navigate out of
|
||||
* the text field. To do this, clients create a subclass of
|
||||
* <code>InputVerifier</code> and, using <code>JComponent</code>'s
|
||||
* <code>setInputVerifier</code> method,
|
||||
* attach an instance of their subclass to the <code>JComponent</code> whose input they
|
||||
* want to validate. Before focus is transfered to another Swing component
|
||||
* that requests it, the input verifier's <code>shouldYieldFocus</code> method is
|
||||
* called. Focus is transfered only if that method returns <code>true</code>.
|
||||
* <p>
|
||||
* The following example has two text fields, with the first one expecting
|
||||
* the string "pass" to be entered by the user. If that string is entered in
|
||||
* the first text field, then the user can advance to the second text field
|
||||
* either by clicking in it or by pressing TAB. However, if another string
|
||||
* is entered in the first text field, then the user will be unable to
|
||||
* transfer focus to the second text field.
|
||||
*
|
||||
* <pre>
|
||||
* import java.awt.*;
|
||||
* import java.util.*;
|
||||
* import java.awt.event.*;
|
||||
* import javax.swing.*;
|
||||
*
|
||||
* // This program demonstrates the use of the Swing InputVerifier class.
|
||||
* // It creates two text fields; the first of the text fields expects the
|
||||
* // string "pass" as input, and will allow focus to advance out of it
|
||||
* // only after that string is typed in by the user.
|
||||
*
|
||||
* public class VerifierTest extends JFrame {
|
||||
* public VerifierTest() {
|
||||
* JTextField tf1 = new JTextField ("Type \"pass\" here");
|
||||
* getContentPane().add (tf1, BorderLayout.NORTH);
|
||||
* tf1.setInputVerifier(new PassVerifier());
|
||||
*
|
||||
* JTextField tf2 = new JTextField ("TextField2");
|
||||
* getContentPane().add (tf2, BorderLayout.SOUTH);
|
||||
*
|
||||
* WindowListener l = new WindowAdapter() {
|
||||
* public void windowClosing(WindowEvent e) {
|
||||
* System.exit(0);
|
||||
* }
|
||||
* };
|
||||
* addWindowListener(l);
|
||||
* }
|
||||
*
|
||||
* class PassVerifier extends InputVerifier {
|
||||
* public boolean verify(JComponent input) {
|
||||
* JTextField tf = (JTextField) input;
|
||||
* return "pass".equals(tf.getText());
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public static void main(String[] args) {
|
||||
* Frame f = new VerifierTest();
|
||||
* f.pack();
|
||||
* f.setVisible(true);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
|
||||
public abstract class InputVerifier {
|
||||
|
||||
/**
|
||||
* Checks whether the JComponent's input is valid. This method should
|
||||
* have no side effects. It returns a boolean indicating the status
|
||||
* of the argument's input.
|
||||
*
|
||||
* @param input the JComponent to verify
|
||||
* @return <code>true</code> when valid, <code>false</code> when invalid
|
||||
* @see JComponent#setInputVerifier
|
||||
* @see JComponent#getInputVerifier
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract boolean verify(JComponent input);
|
||||
|
||||
|
||||
/**
|
||||
* Calls <code>verify(input)</code> to ensure that the input is valid.
|
||||
* This method can have side effects. In particular, this method
|
||||
* is called when the user attempts to advance focus out of the
|
||||
* argument component into another Swing component in this window.
|
||||
* If this method returns <code>true</code>, then the focus is transfered
|
||||
* normally; if it returns <code>false</code>, then the focus remains in
|
||||
* the argument component.
|
||||
*
|
||||
* @param input the JComponent to verify
|
||||
* @return <code>true</code> when valid, <code>false</code> when invalid
|
||||
* @see JComponent#setInputVerifier
|
||||
* @see JComponent#getInputVerifier
|
||||
*
|
||||
*/
|
||||
|
||||
public boolean shouldYieldFocus(JComponent input) {
|
||||
return verify(input);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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 javax.swing;
|
||||
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
|
||||
/**
|
||||
* A FocusTraversalPolicy which can optionally provide an algorithm for
|
||||
* determining a JInternalFrame's initial Component. The initial Component is
|
||||
* the first to receive focus when the JInternalFrame is first selected. By
|
||||
* default, this is the same as the JInternalFrame's default Component to
|
||||
* focus.
|
||||
*
|
||||
* @author David Mendenhall
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class InternalFrameFocusTraversalPolicy
|
||||
extends FocusTraversalPolicy
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the Component that should receive the focus when a
|
||||
* JInternalFrame is selected for the first time. Once the JInternalFrame
|
||||
* has been selected by a call to <code>setSelected(true)</code>, the
|
||||
* initial Component will not be used again. Instead, if the JInternalFrame
|
||||
* loses and subsequently regains selection, or is made invisible or
|
||||
* undisplayable and subsequently made visible and displayable, the
|
||||
* JInternalFrame's most recently focused Component will become the focus
|
||||
* owner. The default implementation of this method returns the
|
||||
* JInternalFrame's default Component to focus.
|
||||
*
|
||||
* @param frame the JInternalFrame whose initial Component is to be
|
||||
* returned
|
||||
* @return the Component that should receive the focus when frame is
|
||||
* selected for the first time, or null if no suitable Component
|
||||
* can be found
|
||||
* @see JInternalFrame#getMostRecentFocusOwner
|
||||
* @throws IllegalArgumentException if window is null
|
||||
*/
|
||||
public Component getInitialComponent(JInternalFrame frame) {
|
||||
return getDefaultComponent(frame);
|
||||
}
|
||||
}
|
||||
568
jdkSrc/jdk8/javax/swing/JApplet.java
Normal file
568
jdkSrc/jdk8/javax/swing/JApplet.java
Normal file
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.applet.Applet;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
import java.io.Serializable;
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* An extended version of <code>java.applet.Applet</code> that adds support for
|
||||
* the JFC/Swing component architecture.
|
||||
* You can find task-oriented documentation about using <code>JApplet</code>
|
||||
* in <em>The Java Tutorial</em>,
|
||||
* in the section
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/applet.html">How to Make Applets</a>.
|
||||
* <p>
|
||||
* The <code>JApplet</code> class is slightly incompatible with
|
||||
* <code>java.applet.Applet</code>. <code>JApplet</code> contains a
|
||||
* <code>JRootPane</code> as its only child. The <code>contentPane</code>
|
||||
* should be the parent of any children of the <code>JApplet</code>.
|
||||
* As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
|
||||
* methods of this class are overridden, so that they delegate calls
|
||||
* to the corresponding methods of the {@code ContentPane}.
|
||||
* For example, you can add a child component to an applet as follows:
|
||||
* <pre>
|
||||
* applet.add(child);
|
||||
* </pre>
|
||||
*
|
||||
* And the child will be added to the <code>contentPane</code>.
|
||||
* The <code>contentPane</code> will always be non-<code>null</code>.
|
||||
* Attempting to set it to <code>null</code> will cause the
|
||||
* <code>JApplet</code> to throw an exception. The default
|
||||
* <code>contentPane</code> will have a <code>BorderLayout</code>
|
||||
* manager set on it.
|
||||
* Refer to {@link javax.swing.RootPaneContainer}
|
||||
* for details on adding, removing and setting the <code>LayoutManager</code>
|
||||
* of a <code>JApplet</code>.
|
||||
* <p>
|
||||
* Please see the <code>JRootPane</code> documentation for a
|
||||
* complete description of the <code>contentPane</code>, <code>glassPane</code>,
|
||||
* and <code>layeredPane</code> properties.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see javax.swing.RootPaneContainer
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* attribute: containerDelegate getContentPane
|
||||
* description: Swing's Applet subclass.
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
*/
|
||||
public class JApplet extends Applet implements Accessible,
|
||||
RootPaneContainer,
|
||||
TransferHandler.HasGetTransferHandler
|
||||
{
|
||||
/**
|
||||
* @see #getRootPane
|
||||
* @see #setRootPane
|
||||
*/
|
||||
protected JRootPane rootPane;
|
||||
|
||||
/**
|
||||
* If true then calls to <code>add</code> and <code>setLayout</code>
|
||||
* will be forwarded to the <code>contentPane</code>. This is initially
|
||||
* false, but is set to true when the <code>JApplet</code> is constructed.
|
||||
*
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean rootPaneCheckingEnabled = false;
|
||||
|
||||
/**
|
||||
* The <code>TransferHandler</code> for this applet.
|
||||
*/
|
||||
private TransferHandler transferHandler;
|
||||
|
||||
/**
|
||||
* Creates a swing applet instance.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JApplet() throws HeadlessException {
|
||||
super();
|
||||
// Check the timerQ and restart if necessary.
|
||||
TimerQueue q = TimerQueue.sharedInstance();
|
||||
if(q != null) {
|
||||
q.startIfNeeded();
|
||||
}
|
||||
|
||||
/* Workaround for bug 4155072. The shared double buffer image
|
||||
* may hang on to a reference to this applet; unfortunately
|
||||
* Image.getGraphics() will continue to call JApplet.getForeground()
|
||||
* and getBackground() even after this applet has been destroyed.
|
||||
* So we ensure that these properties are non-null here.
|
||||
*/
|
||||
setForeground(Color.black);
|
||||
setBackground(Color.white);
|
||||
|
||||
setLocale( JComponent.getDefaultLocale() );
|
||||
setLayout(new BorderLayout());
|
||||
setRootPane(createRootPane());
|
||||
setRootPaneCheckingEnabled(true);
|
||||
|
||||
setFocusTraversalPolicyProvider(true);
|
||||
sun.awt.SunToolkit.checkAndSetPolicy(this);
|
||||
|
||||
enableEvents(AWTEvent.KEY_EVENT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/** Called by the constructor methods to create the default rootPane. */
|
||||
protected JRootPane createRootPane() {
|
||||
JRootPane rp = new JRootPane();
|
||||
// NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
|
||||
// is NO reason for the RootPane not to be opaque. For painting to
|
||||
// work the contentPane must be opaque, therefor the RootPane can
|
||||
// also be opaque.
|
||||
rp.setOpaque(true);
|
||||
return rp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code transferHandler} property, which is a mechanism to
|
||||
* support transfer of data into this component. Use {@code null}
|
||||
* if the component does not support data transfer operations.
|
||||
* <p>
|
||||
* If the system property {@code suppressSwingDropSupport} is {@code false}
|
||||
* (the default) and the current drop target on this component is either
|
||||
* {@code null} or not a user-set drop target, this method will change the
|
||||
* drop target as follows: If {@code newHandler} is {@code null} it will
|
||||
* clear the drop target. If not {@code null} it will install a new
|
||||
* {@code DropTarget}.
|
||||
* <p>
|
||||
* Note: When used with {@code JApplet}, {@code TransferHandler} only
|
||||
* provides data import capability, as the data export related methods
|
||||
* are currently typed to {@code JComponent}.
|
||||
* <p>
|
||||
* Please see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
|
||||
* How to Use Drag and Drop and Data Transfer</a>, a section in
|
||||
* <em>The Java Tutorial</em>, for more information.
|
||||
*
|
||||
* @param newHandler the new {@code TransferHandler}
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #getTransferHandler
|
||||
* @see java.awt.Component#setDropTarget
|
||||
* @since 1.6
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: Mechanism for transfer of data into the component
|
||||
*/
|
||||
public void setTransferHandler(TransferHandler newHandler) {
|
||||
TransferHandler oldHandler = transferHandler;
|
||||
transferHandler = newHandler;
|
||||
SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler);
|
||||
firePropertyChange("transferHandler", oldHandler, newHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>transferHandler</code> property.
|
||||
*
|
||||
* @return the value of the <code>transferHandler</code> property
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #setTransferHandler
|
||||
* @since 1.6
|
||||
*/
|
||||
public TransferHandler getTransferHandler() {
|
||||
return transferHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just calls <code>paint(g)</code>. This method was overridden to
|
||||
* prevent an unnecessary call to clear the background.
|
||||
*/
|
||||
public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the menubar for this applet.
|
||||
* @param menuBar the menubar being placed in the applet
|
||||
*
|
||||
* @see #getJMenuBar
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The menubar for accessing pulldown menus from this applet.
|
||||
*/
|
||||
public void setJMenuBar(JMenuBar menuBar) {
|
||||
getRootPane().setMenuBar(menuBar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menubar set on this applet.
|
||||
*
|
||||
* @see #setJMenuBar
|
||||
*/
|
||||
public JMenuBar getJMenuBar() {
|
||||
return getRootPane().getMenuBar();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @return true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded; false otherwise
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean isRootPaneCheckingEnabled() {
|
||||
return rootPaneCheckingEnabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @param enabled true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded, false if they should operate directly on the
|
||||
* <code>JApplet</code>.
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: Whether the add and setLayout methods are forwarded
|
||||
*/
|
||||
protected void setRootPaneCheckingEnabled(boolean enabled) {
|
||||
rootPaneCheckingEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the specified child <code>Component</code>.
|
||||
* This method is overridden to conditionally forward calls to the
|
||||
* <code>contentPane</code>.
|
||||
* By default, children are added to the <code>contentPane</code> instead
|
||||
* of the frame, refer to {@link javax.swing.RootPaneContainer} for
|
||||
* details.
|
||||
*
|
||||
* @param comp the component to be enhanced
|
||||
* @param constraints the constraints to be respected
|
||||
* @param index the index
|
||||
* @exception IllegalArgumentException if <code>index</code> is invalid
|
||||
* @exception IllegalArgumentException if adding the container's parent
|
||||
* to itself
|
||||
* @exception IllegalArgumentException if adding a window to a container
|
||||
*
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index)
|
||||
{
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().add(comp, constraints, index);
|
||||
}
|
||||
else {
|
||||
super.addImpl(comp, constraints, index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified component from the container. If
|
||||
* <code>comp</code> is not the <code>rootPane</code>, this will forward
|
||||
* the call to the <code>contentPane</code>. This will do nothing if
|
||||
* <code>comp</code> is not a child of the <code>JFrame</code> or
|
||||
* <code>contentPane</code>.
|
||||
*
|
||||
* @param comp the component to be removed
|
||||
* @throws NullPointerException if <code>comp</code> is null
|
||||
* @see #add
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void remove(Component comp) {
|
||||
if (comp == rootPane) {
|
||||
super.remove(comp);
|
||||
} else {
|
||||
getContentPane().remove(comp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>LayoutManager</code>.
|
||||
* Overridden to conditionally forward the call to the
|
||||
* <code>contentPane</code>.
|
||||
* Refer to {@link javax.swing.RootPaneContainer} for
|
||||
* more information.
|
||||
*
|
||||
* @param manager the <code>LayoutManager</code>
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void setLayout(LayoutManager manager) {
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().setLayout(manager);
|
||||
}
|
||||
else {
|
||||
super.setLayout(manager);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the rootPane object for this applet.
|
||||
*
|
||||
* @see #setRootPane
|
||||
* @see RootPaneContainer#getRootPane
|
||||
*/
|
||||
public JRootPane getRootPane() {
|
||||
return rootPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the rootPane property. This method is called by the constructor.
|
||||
* @param root the rootPane object for this applet
|
||||
*
|
||||
* @see #getRootPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: the RootPane object for this applet.
|
||||
*/
|
||||
protected void setRootPane(JRootPane root) {
|
||||
if(rootPane != null) {
|
||||
remove(rootPane);
|
||||
}
|
||||
rootPane = root;
|
||||
if(rootPane != null) {
|
||||
boolean checkingEnabled = isRootPaneCheckingEnabled();
|
||||
try {
|
||||
setRootPaneCheckingEnabled(false);
|
||||
add(rootPane, BorderLayout.CENTER);
|
||||
}
|
||||
finally {
|
||||
setRootPaneCheckingEnabled(checkingEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the contentPane object for this applet.
|
||||
*
|
||||
* @see #setContentPane
|
||||
* @see RootPaneContainer#getContentPane
|
||||
*/
|
||||
public Container getContentPane() {
|
||||
return getRootPane().getContentPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contentPane property. This method is called by the constructor.
|
||||
* @param contentPane the contentPane object for this applet
|
||||
*
|
||||
* @exception java.awt.IllegalComponentStateException (a runtime
|
||||
* exception) if the content pane parameter is null
|
||||
* @see #getContentPane
|
||||
* @see RootPaneContainer#setContentPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The client area of the applet where child
|
||||
* components are normally inserted.
|
||||
*/
|
||||
public void setContentPane(Container contentPane) {
|
||||
getRootPane().setContentPane(contentPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layeredPane object for this applet.
|
||||
*
|
||||
* @exception java.awt.IllegalComponentStateException (a runtime
|
||||
* exception) if the layered pane parameter is null
|
||||
* @see #setLayeredPane
|
||||
* @see RootPaneContainer#getLayeredPane
|
||||
*/
|
||||
public JLayeredPane getLayeredPane() {
|
||||
return getRootPane().getLayeredPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the layeredPane property. This method is called by the constructor.
|
||||
* @param layeredPane the layeredPane object for this applet
|
||||
*
|
||||
* @see #getLayeredPane
|
||||
* @see RootPaneContainer#setLayeredPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The pane which holds the various applet layers.
|
||||
*/
|
||||
public void setLayeredPane(JLayeredPane layeredPane) {
|
||||
getRootPane().setLayeredPane(layeredPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the glassPane object for this applet.
|
||||
*
|
||||
* @see #setGlassPane
|
||||
* @see RootPaneContainer#getGlassPane
|
||||
*/
|
||||
public Component getGlassPane() {
|
||||
return getRootPane().getGlassPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the glassPane property.
|
||||
* This method is called by the constructor.
|
||||
* @param glassPane the glassPane object for this applet
|
||||
*
|
||||
* @see #getGlassPane
|
||||
* @see RootPaneContainer#setGlassPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: A transparent pane used for menu rendering.
|
||||
*/
|
||||
public void setGlassPane(Component glassPane) {
|
||||
getRootPane().setGlassPane(glassPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
JComponent.getGraphicsInvoked(this);
|
||||
return super.getGraphics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaints the specified rectangle of this component within
|
||||
* <code>time</code> milliseconds. Refer to <code>RepaintManager</code>
|
||||
* for details on how the repaint is handled.
|
||||
*
|
||||
* @param time maximum time in milliseconds before update
|
||||
* @param x the <i>x</i> coordinate
|
||||
* @param y the <i>y</i> coordinate
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
* @see RepaintManager
|
||||
* @since 1.6
|
||||
*/
|
||||
public void repaint(long time, int x, int y, int width, int height) {
|
||||
if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
|
||||
RepaintManager.currentManager(this).addDirtyRegion(
|
||||
this, x, y, width, height);
|
||||
}
|
||||
else {
|
||||
super.repaint(time, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JApplet. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JApplet.
|
||||
*/
|
||||
protected String paramString() {
|
||||
String rootPaneString = (rootPane != null ?
|
||||
rootPane.toString() : "");
|
||||
String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
|
||||
"true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",rootPane=" + rootPaneString +
|
||||
",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
protected AccessibleContext accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JApplet.
|
||||
* For JApplets, the AccessibleContext takes the form of an
|
||||
* AccessibleJApplet.
|
||||
* A new AccessibleJApplet instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJApplet that serves as the
|
||||
* AccessibleContext of this JApplet
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJApplet();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JApplet</code> class.
|
||||
*/
|
||||
protected class AccessibleJApplet extends AccessibleApplet {
|
||||
// everything moved to new parent, AccessibleApplet
|
||||
}
|
||||
}
|
||||
325
jdkSrc/jdk8/javax/swing/JButton.java
Normal file
325
jdkSrc/jdk8/javax/swing/JButton.java
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a "push" button.
|
||||
* <p>
|
||||
* Buttons can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a button has many benefits beyond directly
|
||||
* configuring a button. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
|
||||
* in <em>The Java Tutorial</em>
|
||||
* for information and examples of using buttons.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: An implementation of a \"push\" button.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JButton extends AbstractButton implements Accessible {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ButtonUI";
|
||||
|
||||
/**
|
||||
* Creates a button with no set text or icon.
|
||||
*/
|
||||
public JButton() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button with an icon.
|
||||
*
|
||||
* @param icon the Icon image to display on the button
|
||||
*/
|
||||
public JButton(Icon icon) {
|
||||
this(null, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button with text.
|
||||
*
|
||||
* @param text the text of the button
|
||||
*/
|
||||
@ConstructorProperties({"text"})
|
||||
public JButton(String text) {
|
||||
this(text, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button where properties are taken from the
|
||||
* <code>Action</code> supplied.
|
||||
*
|
||||
* @param a the <code>Action</code> used to specify the new button
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JButton(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button with initial text and an icon.
|
||||
*
|
||||
* @param text the text of the button
|
||||
* @param icon the Icon image to display on the button
|
||||
*/
|
||||
public JButton(String text, Icon icon) {
|
||||
// Create the model
|
||||
setModel(new DefaultButtonModel());
|
||||
|
||||
// initialize
|
||||
init(text, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and
|
||||
* feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ButtonUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that specifies the name of the L&F class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return the string "ButtonUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: A string that specifies the name of the L&F class.
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of the <code>defaultButton</code> property,
|
||||
* which if <code>true</code> means that this button is the current
|
||||
* default button for its <code>JRootPane</code>.
|
||||
* Most look and feels render the default button
|
||||
* differently, and may potentially provide bindings
|
||||
* to access the default button.
|
||||
*
|
||||
* @return the value of the <code>defaultButton</code> property
|
||||
* @see JRootPane#setDefaultButton
|
||||
* @see #isDefaultCapable
|
||||
* @beaninfo
|
||||
* description: Whether or not this button is the default button
|
||||
*/
|
||||
public boolean isDefaultButton() {
|
||||
JRootPane root = SwingUtilities.getRootPane(this);
|
||||
if (root != null) {
|
||||
return root.getDefaultButton() == this;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the <code>defaultCapable</code> property.
|
||||
*
|
||||
* @return the value of the <code>defaultCapable</code> property
|
||||
* @see #setDefaultCapable
|
||||
* @see #isDefaultButton
|
||||
* @see JRootPane#setDefaultButton
|
||||
*/
|
||||
public boolean isDefaultCapable() {
|
||||
return defaultCapable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>defaultCapable</code> property,
|
||||
* which determines whether this button can be
|
||||
* made the default button for its root pane.
|
||||
* The default value of the <code>defaultCapable</code>
|
||||
* property is <code>true</code> unless otherwise
|
||||
* specified by the look and feel.
|
||||
*
|
||||
* @param defaultCapable <code>true</code> if this button will be
|
||||
* capable of being the default button on the
|
||||
* <code>RootPane</code>; otherwise <code>false</code>
|
||||
* @see #isDefaultCapable
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: Whether or not this button can be the default button
|
||||
*/
|
||||
public void setDefaultCapable(boolean defaultCapable) {
|
||||
boolean oldDefaultCapable = this.defaultCapable;
|
||||
this.defaultCapable = defaultCapable;
|
||||
firePropertyChange("defaultCapable", oldDefaultCapable, defaultCapable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides <code>JComponent.removeNotify</code> to check if
|
||||
* this button is currently set as the default button on the
|
||||
* <code>RootPane</code>, and if so, sets the <code>RootPane</code>'s
|
||||
* default button to <code>null</code> to ensure the
|
||||
* <code>RootPane</code> doesn't hold onto an invalid button reference.
|
||||
*/
|
||||
public void removeNotify() {
|
||||
JRootPane root = SwingUtilities.getRootPane(this);
|
||||
if (root != null && root.getDefaultButton() == this) {
|
||||
root.setDefaultButton(null);
|
||||
}
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JButton</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JButton</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String defaultCapableString = (defaultCapable ? "true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",defaultCapable=" + defaultCapableString;
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the <code>AccessibleContext</code> associated with this
|
||||
* <code>JButton</code>. For <code>JButton</code>s,
|
||||
* the <code>AccessibleContext</code> takes the form of an
|
||||
* <code>AccessibleJButton</code>.
|
||||
* A new <code>AccessibleJButton</code> instance is created if necessary.
|
||||
*
|
||||
* @return an <code>AccessibleJButton</code> that serves as the
|
||||
* <code>AccessibleContext</code> of this <code>JButton</code>
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: The AccessibleContext associated with this Button.
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJButton();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JButton</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to button user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJButton extends AccessibleAbstractButton {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.PUSH_BUTTON;
|
||||
}
|
||||
} // inner class AccessibleJButton
|
||||
}
|
||||
350
jdkSrc/jdk8/javax/swing/JCheckBox.java
Normal file
350
jdkSrc/jdk8/javax/swing/JCheckBox.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a check box -- an item that can be selected or
|
||||
* deselected, and which displays its state to the user.
|
||||
* By convention, any number of check boxes in a group can be selected.
|
||||
* See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
|
||||
* in <em>The Java Tutorial</em>
|
||||
* for examples and information on using check boxes.
|
||||
* <p>
|
||||
* Buttons can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a button has many benefits beyond directly
|
||||
* configuring a button. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JRadioButton
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component which can be selected or deselected.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
public class JCheckBox extends JToggleButton implements Accessible {
|
||||
|
||||
/** Identifies a change to the flat property. */
|
||||
public static final String BORDER_PAINTED_FLAT_CHANGED_PROPERTY = "borderPaintedFlat";
|
||||
|
||||
private boolean flat = false;
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "CheckBoxUI";
|
||||
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box button with no text, no icon.
|
||||
*/
|
||||
public JCheckBox () {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box with an icon.
|
||||
*
|
||||
* @param icon the Icon image to display
|
||||
*/
|
||||
public JCheckBox(Icon icon) {
|
||||
this(null, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a check box with an icon and specifies whether
|
||||
* or not it is initially selected.
|
||||
*
|
||||
* @param icon the Icon image to display
|
||||
* @param selected a boolean value indicating the initial selection
|
||||
* state. If <code>true</code> the check box is selected
|
||||
*/
|
||||
public JCheckBox(Icon icon, boolean selected) {
|
||||
this(null, icon, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box with text.
|
||||
*
|
||||
* @param text the text of the check box.
|
||||
*/
|
||||
public JCheckBox (String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a check box where properties are taken from the
|
||||
* Action supplied.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JCheckBox(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a check box with text and specifies whether
|
||||
* or not it is initially selected.
|
||||
*
|
||||
* @param text the text of the check box.
|
||||
* @param selected a boolean value indicating the initial selection
|
||||
* state. If <code>true</code> the check box is selected
|
||||
*/
|
||||
public JCheckBox (String text, boolean selected) {
|
||||
this(text, null, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box with
|
||||
* the specified text and icon.
|
||||
*
|
||||
* @param text the text of the check box.
|
||||
* @param icon the Icon image to display
|
||||
*/
|
||||
public JCheckBox(String text, Icon icon) {
|
||||
this(text, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a check box with text and icon,
|
||||
* and specifies whether or not it is initially selected.
|
||||
*
|
||||
* @param text the text of the check box.
|
||||
* @param icon the Icon image to display
|
||||
* @param selected a boolean value indicating the initial selection
|
||||
* state. If <code>true</code> the check box is selected
|
||||
*/
|
||||
public JCheckBox (String text, Icon icon, boolean selected) {
|
||||
super(text, icon, selected);
|
||||
setUIProperty("borderPainted", Boolean.FALSE);
|
||||
setHorizontalAlignment(LEADING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>borderPaintedFlat</code> property,
|
||||
* which gives a hint to the look and feel as to the
|
||||
* appearance of the check box border.
|
||||
* This is usually set to <code>true</code> when a
|
||||
* <code>JCheckBox</code> instance is used as a
|
||||
* renderer in a component such as a <code>JTable</code> or
|
||||
* <code>JTree</code>. The default value for the
|
||||
* <code>borderPaintedFlat</code> property is <code>false</code>.
|
||||
* This method fires a property changed event.
|
||||
* Some look and feels might not implement flat borders;
|
||||
* they will ignore this property.
|
||||
*
|
||||
* @param b <code>true</code> requests that the border be painted flat;
|
||||
* <code>false</code> requests normal borders
|
||||
* @see #isBorderPaintedFlat
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: Whether the border is painted flat.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setBorderPaintedFlat(boolean b) {
|
||||
boolean oldValue = flat;
|
||||
flat = b;
|
||||
firePropertyChange(BORDER_PAINTED_FLAT_CHANGED_PROPERTY, oldValue, flat);
|
||||
if (b != oldValue) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the <code>borderPaintedFlat</code> property.
|
||||
*
|
||||
* @return the value of the <code>borderPaintedFlat</code> property
|
||||
* @see #setBorderPaintedFlat
|
||||
* @since 1.3
|
||||
*/
|
||||
public boolean isBorderPaintedFlat() {
|
||||
return flat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ButtonUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that specifies the name of the L&F class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return the string "CheckBoxUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: A string that specifies the name of the L&F class
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The icon for checkboxs comes from the look and feel,
|
||||
* not the Action; this is overriden to do nothing.
|
||||
*/
|
||||
void setIconFromAction(Action a) {
|
||||
}
|
||||
|
||||
/*
|
||||
* See readObject and writeObject in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See JComponent.readObject() for information about serialization
|
||||
* in Swing.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JCheckBox. 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</code>.
|
||||
* specific new aspects of the JFC components.
|
||||
*
|
||||
* @return a string representation of this JCheckBox.
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JCheckBox.
|
||||
* For JCheckBoxes, the AccessibleContext takes the form of an
|
||||
* AccessibleJCheckBox.
|
||||
* A new AccessibleJCheckBox instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJCheckBox that serves as the
|
||||
* AccessibleContext of this JCheckBox
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: The AccessibleContext associated with this CheckBox.
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJCheckBox();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JCheckBox</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to check box user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJCheckBox extends AccessibleJToggleButton {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.CHECK_BOX;
|
||||
}
|
||||
|
||||
} // inner class AccessibleJCheckBox
|
||||
}
|
||||
307
jdkSrc/jdk8/javax/swing/JCheckBoxMenuItem.java
Normal file
307
jdkSrc/jdk8/javax/swing/JCheckBoxMenuItem.java
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
|
||||
/**
|
||||
* A menu item that can be selected or deselected. If selected, the menu
|
||||
* item typically appears with a checkmark next to it. If unselected or
|
||||
* deselected, the menu item appears without a checkmark. Like a regular
|
||||
* menu item, a check box menu item can have either text or a graphic
|
||||
* icon associated with it, or both.
|
||||
* <p>
|
||||
* Either <code>isSelected</code>/<code>setSelected</code> or
|
||||
* <code>getState</code>/<code>setState</code> can be used
|
||||
* to determine/specify the menu item's selection state. The
|
||||
* preferred methods are <code>isSelected</code> and
|
||||
* <code>setSelected</code>, which work for all menus and buttons.
|
||||
* The <code>getState</code> and <code>setState</code> methods exist for
|
||||
* compatibility with other component sets.
|
||||
* <p>
|
||||
* Menu items can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a menu item has many benefits beyond directly
|
||||
* configuring a menu item. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* For further information and examples of using check box menu items,
|
||||
* see <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A menu item which can be selected or deselected.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
*/
|
||||
public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
|
||||
Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "CheckBoxMenuItemUI";
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box menu item with no set text or icon.
|
||||
*/
|
||||
public JCheckBoxMenuItem() {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box menu item with an icon.
|
||||
*
|
||||
* @param icon the icon of the CheckBoxMenuItem.
|
||||
*/
|
||||
public JCheckBoxMenuItem(Icon icon) {
|
||||
this(null, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box menu item with text.
|
||||
*
|
||||
* @param text the text of the CheckBoxMenuItem
|
||||
*/
|
||||
public JCheckBoxMenuItem(String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a menu item whose properties are taken from the
|
||||
* Action supplied.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JCheckBoxMenuItem(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected check box menu item with the specified text and icon.
|
||||
*
|
||||
* @param text the text of the CheckBoxMenuItem
|
||||
* @param icon the icon of the CheckBoxMenuItem
|
||||
*/
|
||||
public JCheckBoxMenuItem(String text, Icon icon) {
|
||||
this(text, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a check box menu item with the specified text and selection state.
|
||||
*
|
||||
* @param text the text of the check box menu item.
|
||||
* @param b the selected state of the check box menu item
|
||||
*/
|
||||
public JCheckBoxMenuItem(String text, boolean b) {
|
||||
this(text, null, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a check box menu item with the specified text, icon, and selection state.
|
||||
*
|
||||
* @param text the text of the check box menu item
|
||||
* @param icon the icon of the check box menu item
|
||||
* @param b the selected state of the check box menu item
|
||||
*/
|
||||
public JCheckBoxMenuItem(String text, Icon icon, boolean b) {
|
||||
super(text, icon);
|
||||
setModel(new JToggleButton.ToggleButtonModel());
|
||||
setSelected(b);
|
||||
setFocusable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return "CheckBoxMenuItemUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected-state of the item. This method
|
||||
* exists for AWT compatibility only. New code should
|
||||
* use isSelected() instead.
|
||||
*
|
||||
* @return true if the item is selected
|
||||
*/
|
||||
public boolean getState() {
|
||||
return isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected-state of the item. This method
|
||||
* exists for AWT compatibility only. New code should
|
||||
* use setSelected() instead.
|
||||
*
|
||||
* @param b a boolean value indicating the item's
|
||||
* selected-state, where true=selected
|
||||
* @beaninfo
|
||||
* description: The selection state of the check box menu item
|
||||
* hidden: true
|
||||
*/
|
||||
public synchronized void setState(boolean b) {
|
||||
setSelected(b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array (length 1) containing the check box menu item
|
||||
* label or null if the check box is not selected.
|
||||
*
|
||||
* @return an array containing one Object -- the text of the menu item
|
||||
* -- if the item is selected; otherwise null
|
||||
*/
|
||||
public Object[] getSelectedObjects() {
|
||||
if (isSelected() == false)
|
||||
return null;
|
||||
Object[] selectedObjects = new Object[1];
|
||||
selectedObjects[0] = getText();
|
||||
return selectedObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JCheckBoxMenuItem. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JCheckBoxMenuItem.
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriden to return true, JCheckBoxMenuItem supports
|
||||
* the selected state.
|
||||
*/
|
||||
boolean shouldUpdateSelectedStateFromAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JCheckBoxMenuItem.
|
||||
* For JCheckBoxMenuItems, the AccessibleContext takes the form of an
|
||||
* AccessibleJCheckBoxMenuItem.
|
||||
* A new AccessibleJCheckBoxMenuItem instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJCheckBoxMenuItem that serves as the
|
||||
* AccessibleContext of this AccessibleJCheckBoxMenuItem
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJCheckBoxMenuItem();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JCheckBoxMenuItem</code> class. It provides an implementation
|
||||
* of the Java Accessibility API appropriate to checkbox menu item
|
||||
* user-interface elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem {
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.CHECK_BOX;
|
||||
}
|
||||
} // inner class AccessibleJCheckBoxMenuItem
|
||||
}
|
||||
763
jdkSrc/jdk8/javax/swing/JColorChooser.java
Normal file
763
jdkSrc/jdk8/javax/swing/JColorChooser.java
Normal file
@@ -0,0 +1,763 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.colorchooser.*;
|
||||
import javax.swing.plaf.ColorChooserUI;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
|
||||
/**
|
||||
* <code>JColorChooser</code> provides a pane of controls designed to allow
|
||||
* a user to manipulate and select a color.
|
||||
* For information about using color choosers, see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html">How to Use Color Choosers</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* This class provides three levels of API:
|
||||
* <ol>
|
||||
* <li>A static convenience method which shows a modal color-chooser
|
||||
* dialog and returns the color selected by the user.
|
||||
* <li>A static convenience method for creating a color-chooser dialog
|
||||
* where <code>ActionListeners</code> can be specified to be invoked when
|
||||
* the user presses one of the dialog buttons.
|
||||
* <li>The ability to create instances of <code>JColorChooser</code> panes
|
||||
* directly (within any container). <code>PropertyChange</code> listeners
|
||||
* can be added to detect when the current "color" property changes.
|
||||
* </ol>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component that supports selecting a Color.
|
||||
*
|
||||
*
|
||||
* @author James Gosling
|
||||
* @author Amy Fowler
|
||||
* @author Steve Wilson
|
||||
*/
|
||||
public class JColorChooser extends JComponent implements Accessible {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ColorChooserUI";
|
||||
|
||||
private ColorSelectionModel selectionModel;
|
||||
|
||||
private JComponent previewPanel = ColorChooserComponentFactory.getPreviewPanel();
|
||||
|
||||
private AbstractColorChooserPanel[] chooserPanels = new AbstractColorChooserPanel[0];
|
||||
|
||||
private boolean dragEnabled;
|
||||
|
||||
/**
|
||||
* The selection model property name.
|
||||
*/
|
||||
public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
|
||||
|
||||
/**
|
||||
* The preview panel property name.
|
||||
*/
|
||||
public static final String PREVIEW_PANEL_PROPERTY = "previewPanel";
|
||||
|
||||
/**
|
||||
* The chooserPanel array property name.
|
||||
*/
|
||||
public static final String CHOOSER_PANELS_PROPERTY = "chooserPanels";
|
||||
|
||||
|
||||
/**
|
||||
* Shows a modal color-chooser dialog and blocks until the
|
||||
* dialog is hidden. If the user presses the "OK" button, then
|
||||
* this method hides/disposes the dialog and returns the selected color.
|
||||
* If the user presses the "Cancel" button or closes the dialog without
|
||||
* pressing "OK", then this method hides/disposes the dialog and returns
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param component the parent <code>Component</code> for the dialog
|
||||
* @param title the String containing the dialog's title
|
||||
* @param initialColor the initial Color set when the color-chooser is shown
|
||||
* @return the selected color or <code>null</code> if the user opted out
|
||||
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
*/
|
||||
public static Color showDialog(Component component,
|
||||
String title, Color initialColor) throws HeadlessException {
|
||||
|
||||
final JColorChooser pane = new JColorChooser(initialColor != null?
|
||||
initialColor : Color.white);
|
||||
|
||||
ColorTracker ok = new ColorTracker(pane);
|
||||
JDialog dialog = createDialog(component, title, true, pane, ok, null);
|
||||
|
||||
dialog.addComponentListener(new ColorChooserDialog.DisposeOnClose());
|
||||
|
||||
dialog.show(); // blocks until user brings dialog down...
|
||||
|
||||
return ok.getColor();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and returns a new dialog containing the specified
|
||||
* <code>ColorChooser</code> pane along with "OK", "Cancel", and "Reset"
|
||||
* buttons. If the "OK" or "Cancel" buttons are pressed, the dialog is
|
||||
* automatically hidden (but not disposed). If the "Reset"
|
||||
* button is pressed, the color-chooser's color will be reset to the
|
||||
* color which was set the last time <code>show</code> was invoked on the
|
||||
* dialog and the dialog will remain showing.
|
||||
*
|
||||
* @param c the parent component for the dialog
|
||||
* @param title the title for the dialog
|
||||
* @param modal a boolean. When true, the remainder of the program
|
||||
* is inactive until the dialog is closed.
|
||||
* @param chooserPane the color-chooser to be placed inside the dialog
|
||||
* @param okListener the ActionListener invoked when "OK" is pressed
|
||||
* @param cancelListener the ActionListener invoked when "Cancel" is pressed
|
||||
* @return a new dialog containing the color-chooser pane
|
||||
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
*/
|
||||
public static JDialog createDialog(Component c, String title, boolean modal,
|
||||
JColorChooser chooserPane, ActionListener okListener,
|
||||
ActionListener cancelListener) throws HeadlessException {
|
||||
|
||||
Window window = JOptionPane.getWindowForComponent(c);
|
||||
ColorChooserDialog dialog;
|
||||
if (window instanceof Frame) {
|
||||
dialog = new ColorChooserDialog((Frame)window, title, modal, c, chooserPane,
|
||||
okListener, cancelListener);
|
||||
} else {
|
||||
dialog = new ColorChooserDialog((Dialog)window, title, modal, c, chooserPane,
|
||||
okListener, cancelListener);
|
||||
}
|
||||
dialog.getAccessibleContext().setAccessibleDescription(title);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color chooser pane with an initial color of white.
|
||||
*/
|
||||
public JColorChooser() {
|
||||
this(Color.white);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color chooser pane with the specified initial color.
|
||||
*
|
||||
* @param initialColor the initial color set in the chooser
|
||||
*/
|
||||
public JColorChooser(Color initialColor) {
|
||||
this( new DefaultColorSelectionModel(initialColor) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color chooser pane with the specified
|
||||
* <code>ColorSelectionModel</code>.
|
||||
*
|
||||
* @param model the <code>ColorSelectionModel</code> to be used
|
||||
*/
|
||||
public JColorChooser(ColorSelectionModel model) {
|
||||
selectionModel = model;
|
||||
updateUI();
|
||||
dragEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the L&F object that renders this component.
|
||||
*
|
||||
* @return the <code>ColorChooserUI</code> object that renders
|
||||
* this component
|
||||
*/
|
||||
public ColorChooserUI getUI() {
|
||||
return (ColorChooserUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the L&F object that renders this component.
|
||||
*
|
||||
* @param ui the <code>ColorChooserUI</code> L&F object
|
||||
* @see UIDefaults#getUI
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: The UI object that implements the color chooser's LookAndFeel.
|
||||
*/
|
||||
public void setUI(ColorChooserUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification from the <code>UIManager</code> that the L&F has changed.
|
||||
* Replaces the current UI object with the latest version from the
|
||||
* <code>UIManager</code>.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ColorChooserUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "ColorChooserUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current color value from the color chooser.
|
||||
* By default, this delegates to the model.
|
||||
*
|
||||
* @return the current color value of the color chooser
|
||||
*/
|
||||
public Color getColor() {
|
||||
return selectionModel.getSelectedColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current color of the color chooser to the specified color.
|
||||
* The <code>ColorSelectionModel</code> will fire a <code>ChangeEvent</code>
|
||||
* @param color the color to be set in the color chooser
|
||||
* @see JComponent#addPropertyChangeListener
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: false
|
||||
* hidden: false
|
||||
* description: The current color the chooser is to display.
|
||||
*/
|
||||
public void setColor(Color color) {
|
||||
selectionModel.setSelectedColor(color);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current color of the color chooser to the
|
||||
* specified RGB color. Note that the values of red, green,
|
||||
* and blue should be between the numbers 0 and 255, inclusive.
|
||||
*
|
||||
* @param r an int specifying the amount of Red
|
||||
* @param g an int specifying the amount of Green
|
||||
* @param b an int specifying the amount of Blue
|
||||
* @exception IllegalArgumentException if r,g,b values are out of range
|
||||
* @see java.awt.Color
|
||||
*/
|
||||
public void setColor(int r, int g, int b) {
|
||||
setColor(new Color(r,g,b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current color of the color chooser to the
|
||||
* specified color.
|
||||
*
|
||||
* @param c an integer value that sets the current color in the chooser
|
||||
* where the low-order 8 bits specify the Blue value,
|
||||
* the next 8 bits specify the Green value, and the 8 bits
|
||||
* above that specify the Red value.
|
||||
*/
|
||||
public void setColor(int c) {
|
||||
setColor((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>dragEnabled</code> property,
|
||||
* which must be <code>true</code> to enable
|
||||
* automatic drag handling (the first part of drag and drop)
|
||||
* on this component.
|
||||
* The <code>transferHandler</code> property needs to be set
|
||||
* to a non-<code>null</code> value for the drag to do
|
||||
* anything. The default value of the <code>dragEnabled</code>
|
||||
* property
|
||||
* is <code>false</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* When automatic drag handling is enabled,
|
||||
* most look and feels begin a drag-and-drop operation
|
||||
* when the user presses the mouse button over the preview panel.
|
||||
* Some look and feels might not support automatic drag and drop;
|
||||
* they will ignore this property. You can work around such
|
||||
* look and feels by modifying the component
|
||||
* to directly call the <code>exportAsDrag</code> method of a
|
||||
* <code>TransferHandler</code>.
|
||||
*
|
||||
* @param b the value to set the <code>dragEnabled</code> property to
|
||||
* @exception HeadlessException if
|
||||
* <code>b</code> is <code>true</code> and
|
||||
* <code>GraphicsEnvironment.isHeadless()</code>
|
||||
* returns <code>true</code>
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #getDragEnabled
|
||||
* @see #setTransferHandler
|
||||
* @see TransferHandler
|
||||
*
|
||||
* @beaninfo
|
||||
* description: Determines whether automatic drag handling is enabled.
|
||||
* bound: false
|
||||
*/
|
||||
public void setDragEnabled(boolean b) {
|
||||
if (b && GraphicsEnvironment.isHeadless()) {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
dragEnabled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the <code>dragEnabled</code> property.
|
||||
*
|
||||
* @return the value of the <code>dragEnabled</code> property
|
||||
* @see #setDragEnabled
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean getDragEnabled() {
|
||||
return dragEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current preview panel.
|
||||
* This will fire a <code>PropertyChangeEvent</code> for the property
|
||||
* named "previewPanel".
|
||||
*
|
||||
* @param preview the <code>JComponent</code> which displays the current color
|
||||
* @see JComponent#addPropertyChangeListener
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: The UI component which displays the current color.
|
||||
*/
|
||||
public void setPreviewPanel(JComponent preview) {
|
||||
|
||||
if (previewPanel != preview) {
|
||||
JComponent oldPreview = previewPanel;
|
||||
previewPanel = preview;
|
||||
firePropertyChange(JColorChooser.PREVIEW_PANEL_PROPERTY, oldPreview, preview);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preview panel that shows a chosen color.
|
||||
*
|
||||
* @return a <code>JComponent</code> object -- the preview panel
|
||||
*/
|
||||
public JComponent getPreviewPanel() {
|
||||
return previewPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a color chooser panel to the color chooser.
|
||||
*
|
||||
* @param panel the <code>AbstractColorChooserPanel</code> to be added
|
||||
*/
|
||||
public void addChooserPanel( AbstractColorChooserPanel panel ) {
|
||||
AbstractColorChooserPanel[] oldPanels = getChooserPanels();
|
||||
AbstractColorChooserPanel[] newPanels = new AbstractColorChooserPanel[oldPanels.length+1];
|
||||
System.arraycopy(oldPanels, 0, newPanels, 0, oldPanels.length);
|
||||
newPanels[newPanels.length-1] = panel;
|
||||
setChooserPanels(newPanels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the Color Panel specified.
|
||||
*
|
||||
* @param panel a string that specifies the panel to be removed
|
||||
* @return the color panel
|
||||
* @exception IllegalArgumentException if panel is not in list of
|
||||
* known chooser panels
|
||||
*/
|
||||
public AbstractColorChooserPanel removeChooserPanel( AbstractColorChooserPanel panel ) {
|
||||
|
||||
|
||||
int containedAt = -1;
|
||||
|
||||
for (int i = 0; i < chooserPanels.length; i++) {
|
||||
if (chooserPanels[i] == panel) {
|
||||
containedAt = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (containedAt == -1) {
|
||||
throw new IllegalArgumentException("chooser panel not in this chooser");
|
||||
}
|
||||
|
||||
AbstractColorChooserPanel[] newArray = new AbstractColorChooserPanel[chooserPanels.length-1];
|
||||
|
||||
if (containedAt == chooserPanels.length-1) { // at end
|
||||
System.arraycopy(chooserPanels, 0, newArray, 0, newArray.length);
|
||||
}
|
||||
else if (containedAt == 0) { // at start
|
||||
System.arraycopy(chooserPanels, 1, newArray, 0, newArray.length);
|
||||
}
|
||||
else { // in middle
|
||||
System.arraycopy(chooserPanels, 0, newArray, 0, containedAt);
|
||||
System.arraycopy(chooserPanels, containedAt+1,
|
||||
newArray, containedAt, (chooserPanels.length - containedAt - 1));
|
||||
}
|
||||
|
||||
setChooserPanels(newArray);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the Color Panels used to choose a color value.
|
||||
*
|
||||
* @param panels an array of <code>AbstractColorChooserPanel</code>
|
||||
* objects
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: An array of different chooser types.
|
||||
*/
|
||||
public void setChooserPanels( AbstractColorChooserPanel[] panels) {
|
||||
AbstractColorChooserPanel[] oldValue = chooserPanels;
|
||||
chooserPanels = panels;
|
||||
firePropertyChange(CHOOSER_PANELS_PROPERTY, oldValue, panels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified color panels.
|
||||
*
|
||||
* @return an array of <code>AbstractColorChooserPanel</code> objects
|
||||
*/
|
||||
public AbstractColorChooserPanel[] getChooserPanels() {
|
||||
return chooserPanels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data model that handles color selections.
|
||||
*
|
||||
* @return a <code>ColorSelectionModel</code> object
|
||||
*/
|
||||
public ColorSelectionModel getSelectionModel() {
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model containing the selected color.
|
||||
*
|
||||
* @param newModel the new <code>ColorSelectionModel</code> object
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: The model which contains the currently selected color.
|
||||
*/
|
||||
public void setSelectionModel(ColorSelectionModel newModel ) {
|
||||
ColorSelectionModel oldModel = selectionModel;
|
||||
selectionModel = newModel;
|
||||
firePropertyChange(JColorChooser.SELECTION_MODEL_PROPERTY, oldModel, newModel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JColorChooser</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JColorChooser</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
StringBuffer chooserPanelsString = new StringBuffer("");
|
||||
for (int i=0; i<chooserPanels.length; i++) {
|
||||
chooserPanelsString.append("[" + chooserPanels[i].toString()
|
||||
+ "]");
|
||||
}
|
||||
String previewPanelString = (previewPanel != null ?
|
||||
previewPanel.toString() : "");
|
||||
|
||||
return super.paramString() +
|
||||
",chooserPanels=" + chooserPanelsString.toString() +
|
||||
",previewPanel=" + previewPanelString;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
protected AccessibleContext accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JColorChooser.
|
||||
* For color choosers, the AccessibleContext takes the form of an
|
||||
* AccessibleJColorChooser.
|
||||
* A new AccessibleJColorChooser instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJColorChooser that serves as the
|
||||
* AccessibleContext of this JColorChooser
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJColorChooser();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JColorChooser</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to color chooser user-interface
|
||||
* elements.
|
||||
*/
|
||||
protected class AccessibleJColorChooser extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.COLOR_CHOOSER;
|
||||
}
|
||||
|
||||
} // inner class AccessibleJColorChooser
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class which builds a color chooser dialog consisting of
|
||||
* a JColorChooser with "Ok", "Cancel", and "Reset" buttons.
|
||||
*
|
||||
* Note: This needs to be fixed to deal with localization!
|
||||
*/
|
||||
class ColorChooserDialog extends JDialog {
|
||||
private Color initialColor;
|
||||
private JColorChooser chooserPane;
|
||||
private JButton cancelButton;
|
||||
|
||||
public ColorChooserDialog(Dialog owner, String title, boolean modal,
|
||||
Component c, JColorChooser chooserPane,
|
||||
ActionListener okListener, ActionListener cancelListener)
|
||||
throws HeadlessException {
|
||||
super(owner, title, modal);
|
||||
initColorChooserDialog(c, chooserPane, okListener, cancelListener);
|
||||
}
|
||||
|
||||
public ColorChooserDialog(Frame owner, String title, boolean modal,
|
||||
Component c, JColorChooser chooserPane,
|
||||
ActionListener okListener, ActionListener cancelListener)
|
||||
throws HeadlessException {
|
||||
super(owner, title, modal);
|
||||
initColorChooserDialog(c, chooserPane, okListener, cancelListener);
|
||||
}
|
||||
|
||||
protected void initColorChooserDialog(Component c, JColorChooser chooserPane,
|
||||
ActionListener okListener, ActionListener cancelListener) {
|
||||
//setResizable(false);
|
||||
|
||||
this.chooserPane = chooserPane;
|
||||
|
||||
Locale locale = getLocale();
|
||||
String okString = UIManager.getString("ColorChooser.okText", locale);
|
||||
String cancelString = UIManager.getString("ColorChooser.cancelText", locale);
|
||||
String resetString = UIManager.getString("ColorChooser.resetText", locale);
|
||||
|
||||
Container contentPane = getContentPane();
|
||||
contentPane.setLayout(new BorderLayout());
|
||||
contentPane.add(chooserPane, BorderLayout.CENTER);
|
||||
|
||||
/*
|
||||
* Create Lower button panel
|
||||
*/
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||
JButton okButton = new JButton(okString);
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
okButton.getAccessibleContext().setAccessibleDescription(okString);
|
||||
okButton.setActionCommand("OK");
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
if (okListener != null) {
|
||||
okButton.addActionListener(okListener);
|
||||
}
|
||||
buttonPane.add(okButton);
|
||||
|
||||
cancelButton = new JButton(cancelString);
|
||||
cancelButton.getAccessibleContext().setAccessibleDescription(cancelString);
|
||||
|
||||
// The following few lines are used to register esc to close the dialog
|
||||
Action cancelKeyAction = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
((AbstractButton)e.getSource()).fireActionPerformed(e);
|
||||
}
|
||||
};
|
||||
KeyStroke cancelKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
||||
InputMap inputMap = cancelButton.getInputMap(JComponent.
|
||||
WHEN_IN_FOCUSED_WINDOW);
|
||||
ActionMap actionMap = cancelButton.getActionMap();
|
||||
if (inputMap != null && actionMap != null) {
|
||||
inputMap.put(cancelKeyStroke, "cancel");
|
||||
actionMap.put("cancel", cancelKeyAction);
|
||||
}
|
||||
// end esc handling
|
||||
|
||||
cancelButton.setActionCommand("cancel");
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
if (cancelListener != null) {
|
||||
cancelButton.addActionListener(cancelListener);
|
||||
}
|
||||
buttonPane.add(cancelButton);
|
||||
|
||||
JButton resetButton = new JButton(resetString);
|
||||
resetButton.getAccessibleContext().setAccessibleDescription(resetString);
|
||||
resetButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
reset();
|
||||
}
|
||||
});
|
||||
int mnemonic = SwingUtilities2.getUIDefaultsInt("ColorChooser.resetMnemonic", locale, -1);
|
||||
if (mnemonic != -1) {
|
||||
resetButton.setMnemonic(mnemonic);
|
||||
}
|
||||
buttonPane.add(resetButton);
|
||||
contentPane.add(buttonPane, BorderLayout.SOUTH);
|
||||
|
||||
if (JDialog.isDefaultLookAndFeelDecorated()) {
|
||||
boolean supportsWindowDecorations =
|
||||
UIManager.getLookAndFeel().getSupportsWindowDecorations();
|
||||
if (supportsWindowDecorations) {
|
||||
getRootPane().setWindowDecorationStyle(JRootPane.COLOR_CHOOSER_DIALOG);
|
||||
}
|
||||
}
|
||||
applyComponentOrientation(((c == null) ? getRootPane() : c).getComponentOrientation());
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(c);
|
||||
|
||||
this.addWindowListener(new Closer());
|
||||
}
|
||||
|
||||
public void show() {
|
||||
initialColor = chooserPane.getColor();
|
||||
super.show();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
chooserPane.setColor(initialColor);
|
||||
}
|
||||
|
||||
class Closer extends WindowAdapter implements Serializable{
|
||||
public void windowClosing(WindowEvent e) {
|
||||
cancelButton.doClick(0);
|
||||
Window w = e.getWindow();
|
||||
w.hide();
|
||||
}
|
||||
}
|
||||
|
||||
static class DisposeOnClose extends ComponentAdapter implements Serializable{
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
Window w = (Window)e.getComponent();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ColorTracker implements ActionListener, Serializable {
|
||||
JColorChooser chooser;
|
||||
Color color;
|
||||
|
||||
public ColorTracker(JColorChooser c) {
|
||||
chooser = c;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
color = chooser.getColor();
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
2433
jdkSrc/jdk8/javax/swing/JComboBox.java
Normal file
2433
jdkSrc/jdk8/javax/swing/JComboBox.java
Normal file
File diff suppressed because it is too large
Load Diff
5575
jdkSrc/jdk8/javax/swing/JComponent.java
Normal file
5575
jdkSrc/jdk8/javax/swing/JComponent.java
Normal file
File diff suppressed because it is too large
Load Diff
633
jdkSrc/jdk8/javax/swing/JDesktopPane.java
Normal file
633
jdkSrc/jdk8/javax/swing/JDesktopPane.java
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.DefaultFocusTraversalPolicy;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
import java.awt.Window;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.LinkedHashSet;
|
||||
/**
|
||||
* A container used to create a multiple-document interface or a virtual desktop.
|
||||
* You create <code>JInternalFrame</code> objects and add them to the
|
||||
* <code>JDesktopPane</code>. <code>JDesktopPane</code> extends
|
||||
* <code>JLayeredPane</code> to manage the potentially overlapping internal
|
||||
* frames. It also maintains a reference to an instance of
|
||||
* <code>DesktopManager</code> that is set by the UI
|
||||
* class for the current look and feel (L&F). Note that <code>JDesktopPane</code>
|
||||
* does not support borders.
|
||||
* <p>
|
||||
* This class is normally used as the parent of <code>JInternalFrames</code>
|
||||
* to provide a pluggable <code>DesktopManager</code> object to the
|
||||
* <code>JInternalFrames</code>. The <code>installUI</code> of the
|
||||
* L&F specific implementation is responsible for setting the
|
||||
* <code>desktopManager</code> variable appropriately.
|
||||
* When the parent of a <code>JInternalFrame</code> is a <code>JDesktopPane</code>,
|
||||
* it should delegate most of its behavior to the <code>desktopManager</code>
|
||||
* (closing, resizing, etc).
|
||||
* <p>
|
||||
* For further documentation and examples see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html">How to Use Internal Frames</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JInternalFrame
|
||||
* @see JInternalFrame.JDesktopIcon
|
||||
* @see DesktopManager
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
public class JDesktopPane extends JLayeredPane implements Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "DesktopPaneUI";
|
||||
|
||||
transient DesktopManager desktopManager;
|
||||
|
||||
private transient JInternalFrame selectedFrame = null;
|
||||
|
||||
/**
|
||||
* Indicates that the entire contents of the item being dragged
|
||||
* should appear inside the desktop pane.
|
||||
*
|
||||
* @see #OUTLINE_DRAG_MODE
|
||||
* @see #setDragMode
|
||||
*/
|
||||
public static final int LIVE_DRAG_MODE = 0;
|
||||
|
||||
/**
|
||||
* Indicates that an outline only of the item being dragged
|
||||
* should appear inside the desktop pane.
|
||||
*
|
||||
* @see #LIVE_DRAG_MODE
|
||||
* @see #setDragMode
|
||||
*/
|
||||
public static final int OUTLINE_DRAG_MODE = 1;
|
||||
|
||||
private int dragMode = LIVE_DRAG_MODE;
|
||||
private boolean dragModeSet = false;
|
||||
private transient List<JInternalFrame> framesCache;
|
||||
private boolean componentOrderCheckingEnabled = true;
|
||||
private boolean componentOrderChanged = false;
|
||||
|
||||
/**
|
||||
* Creates a new <code>JDesktopPane</code>.
|
||||
*/
|
||||
public JDesktopPane() {
|
||||
setUIProperty("opaque", Boolean.TRUE);
|
||||
setFocusCycleRoot(true);
|
||||
|
||||
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
|
||||
public Component getDefaultComponent(Container c) {
|
||||
JInternalFrame jifArray[] = getAllFrames();
|
||||
Component comp = null;
|
||||
for (JInternalFrame jif : jifArray) {
|
||||
comp = jif.getFocusTraversalPolicy().getDefaultComponent(jif);
|
||||
if (comp != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
});
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the L&F object that renders this component.
|
||||
*
|
||||
* @return the <code>DesktopPaneUI</code> object that
|
||||
* renders this component
|
||||
*/
|
||||
public DesktopPaneUI getUI() {
|
||||
return (DesktopPaneUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the L&F object that renders this component.
|
||||
*
|
||||
* @param ui the DesktopPaneUI L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(DesktopPaneUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "dragging style" used by the desktop pane.
|
||||
* You may want to change to one mode or another for
|
||||
* performance or aesthetic reasons.
|
||||
*
|
||||
* @param dragMode the style of drag to use for items in the Desktop
|
||||
*
|
||||
* @see #LIVE_DRAG_MODE
|
||||
* @see #OUTLINE_DRAG_MODE
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* description: Dragging style for internal frame children.
|
||||
* enum: LIVE_DRAG_MODE JDesktopPane.LIVE_DRAG_MODE
|
||||
* OUTLINE_DRAG_MODE JDesktopPane.OUTLINE_DRAG_MODE
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setDragMode(int dragMode) {
|
||||
int oldDragMode = this.dragMode;
|
||||
this.dragMode = dragMode;
|
||||
firePropertyChange("dragMode", oldDragMode, this.dragMode);
|
||||
dragModeSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current "dragging style" used by the desktop pane.
|
||||
* @return either <code>Live_DRAG_MODE</code> or
|
||||
* <code>OUTLINE_DRAG_MODE</code>
|
||||
* @see #setDragMode
|
||||
* @since 1.3
|
||||
*/
|
||||
public int getDragMode() {
|
||||
return dragMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>DesktopManger</code> that handles
|
||||
* desktop-specific UI actions.
|
||||
*/
|
||||
public DesktopManager getDesktopManager() {
|
||||
return desktopManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>DesktopManger</code> that will handle
|
||||
* desktop-specific UI actions. This may be overridden by
|
||||
* {@code LookAndFeel}.
|
||||
*
|
||||
* @param d the <code>DesktopManager</code> to use
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* description: Desktop manager to handle the internal frames in the
|
||||
* desktop pane.
|
||||
*/
|
||||
public void setDesktopManager(DesktopManager d) {
|
||||
DesktopManager oldValue = desktopManager;
|
||||
desktopManager = d;
|
||||
firePropertyChange("desktopManager", oldValue, desktopManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification from the <code>UIManager</code> that the L&F has changed.
|
||||
* Replaces the current UI object with the latest version from the
|
||||
* <code>UIManager</code>.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((DesktopPaneUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "DesktopPaneUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all <code>JInternalFrames</code> currently displayed in the
|
||||
* desktop. Returns iconified frames as well as expanded frames.
|
||||
*
|
||||
* @return an array of <code>JInternalFrame</code> objects
|
||||
*/
|
||||
public JInternalFrame[] getAllFrames() {
|
||||
return getAllFrames(this).toArray(new JInternalFrame[0]);
|
||||
}
|
||||
|
||||
private static Collection<JInternalFrame> getAllFrames(Container parent) {
|
||||
int i, count;
|
||||
Collection<JInternalFrame> results = new LinkedHashSet<>();
|
||||
count = parent.getComponentCount();
|
||||
for (i = 0; i < count; i++) {
|
||||
Component next = parent.getComponent(i);
|
||||
if (next instanceof JInternalFrame) {
|
||||
results.add((JInternalFrame) next);
|
||||
} else if (next instanceof JInternalFrame.JDesktopIcon) {
|
||||
JInternalFrame tmp = ((JInternalFrame.JDesktopIcon) next).getInternalFrame();
|
||||
if (tmp != null) {
|
||||
results.add(tmp);
|
||||
}
|
||||
} else if (next instanceof Container) {
|
||||
results.addAll(getAllFrames((Container) next));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Returns the currently active <code>JInternalFrame</code>
|
||||
* in this <code>JDesktopPane</code>, or <code>null</code>
|
||||
* if no <code>JInternalFrame</code> is currently active.
|
||||
*
|
||||
* @return the currently active <code>JInternalFrame</code> or
|
||||
* <code>null</code>
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
public JInternalFrame getSelectedFrame() {
|
||||
return selectedFrame;
|
||||
}
|
||||
|
||||
/** Sets the currently active <code>JInternalFrame</code>
|
||||
* in this <code>JDesktopPane</code>. This method is used to bridge
|
||||
* the package gap between JDesktopPane and the platform implementation
|
||||
* code and should not be called directly. To visually select the frame
|
||||
* the client must call JInternalFrame.setSelected(true) to activate
|
||||
* the frame.
|
||||
* @see JInternalFrame#setSelected(boolean)
|
||||
*
|
||||
* @param f the internal frame that's currently selected
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
public void setSelectedFrame(JInternalFrame f) {
|
||||
selectedFrame = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all <code>JInternalFrames</code> currently displayed in the
|
||||
* specified layer of the desktop. Returns iconified frames as well
|
||||
* expanded frames.
|
||||
*
|
||||
* @param layer an int specifying the desktop layer
|
||||
* @return an array of <code>JInternalFrame</code> objects
|
||||
* @see JLayeredPane
|
||||
*/
|
||||
public JInternalFrame[] getAllFramesInLayer(int layer) {
|
||||
Collection<JInternalFrame> allFrames = getAllFrames(this);
|
||||
Iterator<JInternalFrame> iterator = allFrames.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().getLayer() != layer) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return allFrames.toArray(new JInternalFrame[0]);
|
||||
}
|
||||
|
||||
private List<JInternalFrame> getFrames() {
|
||||
Component c;
|
||||
Set<ComponentPosition> set = new TreeSet<ComponentPosition>();
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
c = getComponent(i);
|
||||
if (c instanceof JInternalFrame) {
|
||||
set.add(new ComponentPosition((JInternalFrame)c, getLayer(c),
|
||||
i));
|
||||
}
|
||||
else if (c instanceof JInternalFrame.JDesktopIcon) {
|
||||
c = ((JInternalFrame.JDesktopIcon)c).getInternalFrame();
|
||||
set.add(new ComponentPosition((JInternalFrame)c, getLayer(c),
|
||||
i));
|
||||
}
|
||||
}
|
||||
List<JInternalFrame> frames = new ArrayList<JInternalFrame>(
|
||||
set.size());
|
||||
for (ComponentPosition position : set) {
|
||||
frames.add(position.component);
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
private static class ComponentPosition implements
|
||||
Comparable<ComponentPosition> {
|
||||
private final JInternalFrame component;
|
||||
private final int layer;
|
||||
private final int zOrder;
|
||||
|
||||
ComponentPosition(JInternalFrame component, int layer, int zOrder) {
|
||||
this.component = component;
|
||||
this.layer = layer;
|
||||
this.zOrder = zOrder;
|
||||
}
|
||||
|
||||
public int compareTo(ComponentPosition o) {
|
||||
int delta = o.layer - layer;
|
||||
if (delta == 0) {
|
||||
return zOrder - o.zOrder;
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
private JInternalFrame getNextFrame(JInternalFrame f, boolean forward) {
|
||||
verifyFramesCache();
|
||||
if (f == null) {
|
||||
return getTopInternalFrame();
|
||||
}
|
||||
int i = framesCache.indexOf(f);
|
||||
if (i == -1 || framesCache.size() == 1) {
|
||||
/* error */
|
||||
return null;
|
||||
}
|
||||
if (forward) {
|
||||
// navigate to the next frame
|
||||
if (++i == framesCache.size()) {
|
||||
/* wrap */
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// navigate to the previous frame
|
||||
if (--i == -1) {
|
||||
/* wrap */
|
||||
i = framesCache.size() - 1;
|
||||
}
|
||||
}
|
||||
return framesCache.get(i);
|
||||
}
|
||||
|
||||
JInternalFrame getNextFrame(JInternalFrame f) {
|
||||
return getNextFrame(f, true);
|
||||
}
|
||||
|
||||
private JInternalFrame getTopInternalFrame() {
|
||||
if (framesCache.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return framesCache.get(0);
|
||||
}
|
||||
|
||||
private void updateFramesCache() {
|
||||
framesCache = getFrames();
|
||||
}
|
||||
|
||||
private void verifyFramesCache() {
|
||||
// If framesCache is dirty, then recreate it.
|
||||
if (componentOrderChanged) {
|
||||
componentOrderChanged = false;
|
||||
updateFramesCache();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void remove(Component comp) {
|
||||
super.remove(comp);
|
||||
updateFramesCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the next <code>JInternalFrame</code> in this desktop pane.
|
||||
*
|
||||
* @param forward a boolean indicating which direction to select in;
|
||||
* <code>true</code> for forward, <code>false</code> for
|
||||
* backward
|
||||
* @return the JInternalFrame that was selected or <code>null</code>
|
||||
* if nothing was selected
|
||||
* @since 1.6
|
||||
*/
|
||||
public JInternalFrame selectFrame(boolean forward) {
|
||||
JInternalFrame selectedFrame = getSelectedFrame();
|
||||
JInternalFrame frameToSelect = getNextFrame(selectedFrame, forward);
|
||||
if (frameToSelect == null) {
|
||||
return null;
|
||||
}
|
||||
// Maintain navigation traversal order until an
|
||||
// external stack change, such as a click on a frame.
|
||||
setComponentOrderCheckingEnabled(false);
|
||||
if (forward && selectedFrame != null) {
|
||||
selectedFrame.moveToBack(); // For Windows MDI fidelity.
|
||||
}
|
||||
try { frameToSelect.setSelected(true);
|
||||
} catch (PropertyVetoException pve) {}
|
||||
setComponentOrderCheckingEnabled(true);
|
||||
return frameToSelect;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets whether component order checking is enabled.
|
||||
* @param enable a boolean value, where <code>true</code> means
|
||||
* a change in component order will cause a change in the keyboard
|
||||
* navigation order.
|
||||
* @since 1.6
|
||||
*/
|
||||
void setComponentOrderCheckingEnabled(boolean enable) {
|
||||
componentOrderCheckingEnabled = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index) {
|
||||
super.addImpl(comp, constraints, index);
|
||||
if (componentOrderCheckingEnabled) {
|
||||
if (comp instanceof JInternalFrame ||
|
||||
comp instanceof JInternalFrame.JDesktopIcon) {
|
||||
componentOrderChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
public void remove(int index) {
|
||||
if (componentOrderCheckingEnabled) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp instanceof JInternalFrame ||
|
||||
comp instanceof JInternalFrame.JDesktopIcon) {
|
||||
componentOrderChanged = true;
|
||||
}
|
||||
}
|
||||
super.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
public void removeAll() {
|
||||
if (componentOrderCheckingEnabled) {
|
||||
int count = getComponentCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Component comp = getComponent(i);
|
||||
if (comp instanceof JInternalFrame ||
|
||||
comp instanceof JInternalFrame.JDesktopIcon) {
|
||||
componentOrderChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
public void setComponentZOrder(Component comp, int index) {
|
||||
super.setComponentZOrder(comp, index);
|
||||
if (componentOrderCheckingEnabled) {
|
||||
if (comp instanceof JInternalFrame ||
|
||||
comp instanceof JInternalFrame.JDesktopIcon) {
|
||||
componentOrderChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setUIProperty(String propertyName, Object value) {
|
||||
if (propertyName == "dragMode") {
|
||||
if (!dragModeSet) {
|
||||
setDragMode(((Integer)value).intValue());
|
||||
dragModeSet = false;
|
||||
}
|
||||
} else {
|
||||
super.setUIProperty(propertyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JDesktopPane</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JDesktopPane</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String desktopManagerString = (desktopManager != null ?
|
||||
desktopManager.toString() : "");
|
||||
|
||||
return super.paramString() +
|
||||
",desktopManager=" + desktopManagerString;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the <code>AccessibleContext</code> associated with this
|
||||
* <code>JDesktopPane</code>. For desktop panes, the
|
||||
* <code>AccessibleContext</code> takes the form of an
|
||||
* <code>AccessibleJDesktopPane</code>.
|
||||
* A new <code>AccessibleJDesktopPane</code> instance is created if necessary.
|
||||
*
|
||||
* @return an <code>AccessibleJDesktopPane</code> that serves as the
|
||||
* <code>AccessibleContext</code> of this <code>JDesktopPane</code>
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJDesktopPane();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JDesktopPane</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to desktop pane user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJDesktopPane extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.DESKTOP_PANE;
|
||||
}
|
||||
}
|
||||
}
|
||||
1295
jdkSrc/jdk8/javax/swing/JDialog.java
Normal file
1295
jdkSrc/jdk8/javax/swing/JDialog.java
Normal file
File diff suppressed because it is too large
Load Diff
2411
jdkSrc/jdk8/javax/swing/JEditorPane.java
Normal file
2411
jdkSrc/jdk8/javax/swing/JEditorPane.java
Normal file
File diff suppressed because it is too large
Load Diff
2014
jdkSrc/jdk8/javax/swing/JFileChooser.java
Normal file
2014
jdkSrc/jdk8/javax/swing/JFileChooser.java
Normal file
File diff suppressed because it is too large
Load Diff
1186
jdkSrc/jdk8/javax/swing/JFormattedTextField.java
Normal file
1186
jdkSrc/jdk8/javax/swing/JFormattedTextField.java
Normal file
File diff suppressed because it is too large
Load Diff
945
jdkSrc/jdk8/javax/swing/JFrame.java
Normal file
945
jdkSrc/jdk8/javax/swing/JFrame.java
Normal file
@@ -0,0 +1,945 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.Image;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import javax.accessibility.AccessibleState;
|
||||
import javax.accessibility.AccessibleStateSet;
|
||||
|
||||
|
||||
/**
|
||||
* An extended version of <code>java.awt.Frame</code> that adds support for
|
||||
* the JFC/Swing component architecture.
|
||||
* You can find task-oriented documentation about using <code>JFrame</code>
|
||||
* in <em>The Java Tutorial</em>, in the section
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html">How to Make Frames</a>.
|
||||
*
|
||||
* <p>
|
||||
* The <code>JFrame</code> class is slightly incompatible with <code>Frame</code>.
|
||||
* Like all other JFC/Swing top-level containers,
|
||||
* a <code>JFrame</code> contains a <code>JRootPane</code> as its only child.
|
||||
* The <b>content pane</b> provided by the root pane should,
|
||||
* as a rule, contain
|
||||
* all the non-menu components displayed by the <code>JFrame</code>.
|
||||
* This is different from the AWT <code>Frame</code> case.
|
||||
* As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
|
||||
* methods of this class are overridden, so that they delegate calls
|
||||
* to the corresponding methods of the {@code ContentPane}.
|
||||
* For example, you can add a child component to a frame as follows:
|
||||
* <pre>
|
||||
* frame.add(child);
|
||||
* </pre>
|
||||
* And the child will be added to the contentPane.
|
||||
* The content pane will
|
||||
* always be non-null. Attempting to set it to null will cause the JFrame
|
||||
* to throw an exception. The default content pane will have a BorderLayout
|
||||
* manager set on it.
|
||||
* Refer to {@link javax.swing.RootPaneContainer}
|
||||
* for details on adding, removing and setting the <code>LayoutManager</code>
|
||||
* of a <code>JFrame</code>.
|
||||
* <p>
|
||||
* Unlike a <code>Frame</code>, a <code>JFrame</code> has some notion of how to
|
||||
* respond when the user attempts to close the window. The default behavior
|
||||
* is to simply hide the JFrame when the user closes the window. To change the
|
||||
* default behavior, you invoke the method
|
||||
* {@link #setDefaultCloseOperation}.
|
||||
* To make the <code>JFrame</code> behave the same as a <code>Frame</code>
|
||||
* instance, use
|
||||
* <code>setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)</code>.
|
||||
* <p>
|
||||
* For more information on content panes
|
||||
* and other features that root panes provide,
|
||||
* see <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Using Top-Level Containers</a> in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* In a multi-screen environment, you can create a <code>JFrame</code>
|
||||
* on a different screen device. See {@link java.awt.Frame} for more
|
||||
* information.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JRootPane
|
||||
* @see #setDefaultCloseOperation
|
||||
* @see java.awt.event.WindowListener#windowClosing
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* attribute: containerDelegate getContentPane
|
||||
* description: A toplevel window which can be minimized to an icon.
|
||||
*
|
||||
* @author Jeff Dinkins
|
||||
* @author Georges Saab
|
||||
* @author David Kloba
|
||||
*/
|
||||
public class JFrame extends Frame implements WindowConstants,
|
||||
Accessible,
|
||||
RootPaneContainer,
|
||||
TransferHandler.HasGetTransferHandler
|
||||
{
|
||||
/**
|
||||
* The exit application default window close operation. If a window
|
||||
* has this set as the close operation and is closed in an applet,
|
||||
* a <code>SecurityException</code> may be thrown.
|
||||
* It is recommended you only use this in an application.
|
||||
* <p>
|
||||
* @since 1.3
|
||||
*/
|
||||
public static final int EXIT_ON_CLOSE = 3;
|
||||
|
||||
/**
|
||||
* Key into the AppContext, used to check if should provide decorations
|
||||
* by default.
|
||||
*/
|
||||
private static final Object defaultLookAndFeelDecoratedKey =
|
||||
new StringBuffer("JFrame.defaultLookAndFeelDecorated");
|
||||
|
||||
private int defaultCloseOperation = HIDE_ON_CLOSE;
|
||||
|
||||
/**
|
||||
* The <code>TransferHandler</code> for this frame.
|
||||
*/
|
||||
private TransferHandler transferHandler;
|
||||
|
||||
/**
|
||||
* The <code>JRootPane</code> instance that manages the
|
||||
* <code>contentPane</code>
|
||||
* and optional <code>menuBar</code> for this frame, as well as the
|
||||
* <code>glassPane</code>.
|
||||
*
|
||||
* @see JRootPane
|
||||
* @see RootPaneContainer
|
||||
*/
|
||||
protected JRootPane rootPane;
|
||||
|
||||
/**
|
||||
* If true then calls to <code>add</code> and <code>setLayout</code>
|
||||
* will be forwarded to the <code>contentPane</code>. This is initially
|
||||
* false, but is set to true when the <code>JFrame</code> is constructed.
|
||||
*
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean rootPaneCheckingEnabled = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new frame that is initially invisible.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see Component#setSize
|
||||
* @see Component#setVisible
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JFrame() throws HeadlessException {
|
||||
super();
|
||||
frameInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Frame</code> in the specified
|
||||
* <code>GraphicsConfiguration</code> of
|
||||
* a screen device and a blank title.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param gc the <code>GraphicsConfiguration</code> that is used
|
||||
* to construct the new <code>Frame</code>;
|
||||
* if <code>gc</code> is <code>null</code>, the system
|
||||
* default <code>GraphicsConfiguration</code> is assumed
|
||||
* @exception IllegalArgumentException if <code>gc</code> is not from
|
||||
* a screen device. This exception is always thrown when
|
||||
* GraphicsEnvironment.isHeadless() returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see JComponent#getDefaultLocale
|
||||
* @since 1.3
|
||||
*/
|
||||
public JFrame(GraphicsConfiguration gc) {
|
||||
super(gc);
|
||||
frameInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new, initially invisible <code>Frame</code> with the
|
||||
* specified title.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param title the title for the frame
|
||||
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see Component#setSize
|
||||
* @see Component#setVisible
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JFrame(String title) throws HeadlessException {
|
||||
super(title);
|
||||
frameInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JFrame</code> with the specified title and the
|
||||
* specified <code>GraphicsConfiguration</code> of a screen device.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param title the title to be displayed in the
|
||||
* frame's border. A <code>null</code> value is treated as
|
||||
* an empty string, "".
|
||||
* @param gc the <code>GraphicsConfiguration</code> that is used
|
||||
* to construct the new <code>JFrame</code> with;
|
||||
* if <code>gc</code> is <code>null</code>, the system
|
||||
* default <code>GraphicsConfiguration</code> is assumed
|
||||
* @exception IllegalArgumentException if <code>gc</code> is not from
|
||||
* a screen device. This exception is always thrown when
|
||||
* GraphicsEnvironment.isHeadless() returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see JComponent#getDefaultLocale
|
||||
* @since 1.3
|
||||
*/
|
||||
public JFrame(String title, GraphicsConfiguration gc) {
|
||||
super(title, gc);
|
||||
frameInit();
|
||||
}
|
||||
|
||||
/** Called by the constructors to init the <code>JFrame</code> properly. */
|
||||
protected void frameInit() {
|
||||
enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
|
||||
setLocale( JComponent.getDefaultLocale() );
|
||||
setRootPane(createRootPane());
|
||||
setBackground(UIManager.getColor("control"));
|
||||
setRootPaneCheckingEnabled(true);
|
||||
if (JFrame.isDefaultLookAndFeelDecorated()) {
|
||||
boolean supportsWindowDecorations =
|
||||
UIManager.getLookAndFeel().getSupportsWindowDecorations();
|
||||
if (supportsWindowDecorations) {
|
||||
setUndecorated(true);
|
||||
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||
}
|
||||
}
|
||||
sun.awt.SunToolkit.checkAndSetPolicy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the constructor methods to create the default
|
||||
* <code>rootPane</code>.
|
||||
*/
|
||||
protected JRootPane createRootPane() {
|
||||
JRootPane rp = new JRootPane();
|
||||
// NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
|
||||
// is NO reason for the RootPane not to be opaque. For painting to
|
||||
// work the contentPane must be opaque, therefor the RootPane can
|
||||
// also be opaque.
|
||||
rp.setOpaque(true);
|
||||
return rp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes window events occurring on this component.
|
||||
* Hides the window or disposes of it, as specified by the setting
|
||||
* of the <code>defaultCloseOperation</code> property.
|
||||
*
|
||||
* @param e the window event
|
||||
* @see #setDefaultCloseOperation
|
||||
* @see java.awt.Window#processWindowEvent
|
||||
*/
|
||||
protected void processWindowEvent(final WindowEvent e) {
|
||||
super.processWindowEvent(e);
|
||||
|
||||
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
|
||||
switch (defaultCloseOperation) {
|
||||
case HIDE_ON_CLOSE:
|
||||
setVisible(false);
|
||||
break;
|
||||
case DISPOSE_ON_CLOSE:
|
||||
dispose();
|
||||
break;
|
||||
case EXIT_ON_CLOSE:
|
||||
// This needs to match the checkExit call in
|
||||
// setDefaultCloseOperation
|
||||
System.exit(0);
|
||||
break;
|
||||
case DO_NOTHING_ON_CLOSE:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operation that will happen by default when
|
||||
* the user initiates a "close" on this frame.
|
||||
* You must specify one of the following choices:
|
||||
* <br><br>
|
||||
* <ul>
|
||||
* <li><code>DO_NOTHING_ON_CLOSE</code>
|
||||
* (defined in <code>WindowConstants</code>):
|
||||
* Don't do anything; require the
|
||||
* program to handle the operation in the <code>windowClosing</code>
|
||||
* method of a registered <code>WindowListener</code> object.
|
||||
*
|
||||
* <li><code>HIDE_ON_CLOSE</code>
|
||||
* (defined in <code>WindowConstants</code>):
|
||||
* Automatically hide the frame after
|
||||
* invoking any registered <code>WindowListener</code>
|
||||
* objects.
|
||||
*
|
||||
* <li><code>DISPOSE_ON_CLOSE</code>
|
||||
* (defined in <code>WindowConstants</code>):
|
||||
* Automatically hide and dispose the
|
||||
* frame after invoking any registered <code>WindowListener</code>
|
||||
* objects.
|
||||
*
|
||||
* <li><code>EXIT_ON_CLOSE</code>
|
||||
* (defined in <code>JFrame</code>):
|
||||
* Exit the application using the <code>System</code>
|
||||
* <code>exit</code> method. Use this only in applications.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The value is set to <code>HIDE_ON_CLOSE</code> by default. Changes
|
||||
* to the value of this property cause the firing of a property
|
||||
* change event, with property name "defaultCloseOperation".
|
||||
* <p>
|
||||
* <b>Note</b>: When the last displayable window within the
|
||||
* Java virtual machine (VM) is disposed of, the VM may
|
||||
* terminate. See <a href="../../java/awt/doc-files/AWTThreadIssues.html">
|
||||
* AWT Threading Issues</a> for more information.
|
||||
*
|
||||
* @param operation the operation which should be performed when the
|
||||
* user closes the frame
|
||||
* @exception IllegalArgumentException if defaultCloseOperation value
|
||||
* isn't one of the above valid values
|
||||
* @see #addWindowListener
|
||||
* @see #getDefaultCloseOperation
|
||||
* @see WindowConstants
|
||||
* @throws SecurityException
|
||||
* if <code>EXIT_ON_CLOSE</code> has been specified and the
|
||||
* <code>SecurityManager</code> will
|
||||
* not allow the caller to invoke <code>System.exit</code>
|
||||
* @see java.lang.Runtime#exit(int)
|
||||
*
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* enum: DO_NOTHING_ON_CLOSE WindowConstants.DO_NOTHING_ON_CLOSE
|
||||
* HIDE_ON_CLOSE WindowConstants.HIDE_ON_CLOSE
|
||||
* DISPOSE_ON_CLOSE WindowConstants.DISPOSE_ON_CLOSE
|
||||
* EXIT_ON_CLOSE WindowConstants.EXIT_ON_CLOSE
|
||||
* description: The frame's default close operation.
|
||||
*/
|
||||
public void setDefaultCloseOperation(int operation) {
|
||||
if (operation != DO_NOTHING_ON_CLOSE &&
|
||||
operation != HIDE_ON_CLOSE &&
|
||||
operation != DISPOSE_ON_CLOSE &&
|
||||
operation != EXIT_ON_CLOSE) {
|
||||
throw new IllegalArgumentException("defaultCloseOperation must be one of: DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or EXIT_ON_CLOSE");
|
||||
}
|
||||
|
||||
if (operation == EXIT_ON_CLOSE) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkExit(0);
|
||||
}
|
||||
}
|
||||
if (this.defaultCloseOperation != operation) {
|
||||
int oldValue = this.defaultCloseOperation;
|
||||
this.defaultCloseOperation = operation;
|
||||
firePropertyChange("defaultCloseOperation", oldValue, operation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the operation that occurs when the user
|
||||
* initiates a "close" on this frame.
|
||||
*
|
||||
* @return an integer indicating the window-close operation
|
||||
* @see #setDefaultCloseOperation
|
||||
*/
|
||||
public int getDefaultCloseOperation() {
|
||||
return defaultCloseOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code transferHandler} property, which is a mechanism to
|
||||
* support transfer of data into this component. Use {@code null}
|
||||
* if the component does not support data transfer operations.
|
||||
* <p>
|
||||
* If the system property {@code suppressSwingDropSupport} is {@code false}
|
||||
* (the default) and the current drop target on this component is either
|
||||
* {@code null} or not a user-set drop target, this method will change the
|
||||
* drop target as follows: If {@code newHandler} is {@code null} it will
|
||||
* clear the drop target. If not {@code null} it will install a new
|
||||
* {@code DropTarget}.
|
||||
* <p>
|
||||
* Note: When used with {@code JFrame}, {@code TransferHandler} only
|
||||
* provides data import capability, as the data export related methods
|
||||
* are currently typed to {@code JComponent}.
|
||||
* <p>
|
||||
* Please see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
|
||||
* How to Use Drag and Drop and Data Transfer</a>, a section in
|
||||
* <em>The Java Tutorial</em>, for more information.
|
||||
*
|
||||
* @param newHandler the new {@code TransferHandler}
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #getTransferHandler
|
||||
* @see java.awt.Component#setDropTarget
|
||||
* @since 1.6
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: Mechanism for transfer of data into the component
|
||||
*/
|
||||
public void setTransferHandler(TransferHandler newHandler) {
|
||||
TransferHandler oldHandler = transferHandler;
|
||||
transferHandler = newHandler;
|
||||
SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler);
|
||||
firePropertyChange("transferHandler", oldHandler, newHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>transferHandler</code> property.
|
||||
*
|
||||
* @return the value of the <code>transferHandler</code> property
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #setTransferHandler
|
||||
* @since 1.6
|
||||
*/
|
||||
public TransferHandler getTransferHandler() {
|
||||
return transferHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just calls <code>paint(g)</code>. This method was overridden to
|
||||
* prevent an unnecessary call to clear the background.
|
||||
*
|
||||
* @param g the Graphics context in which to paint
|
||||
*/
|
||||
public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the menubar for this frame.
|
||||
* @param menubar the menubar being placed in the frame
|
||||
*
|
||||
* @see #getJMenuBar
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The menubar for accessing pulldown menus from this frame.
|
||||
*/
|
||||
public void setJMenuBar(JMenuBar menubar) {
|
||||
getRootPane().setMenuBar(menubar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menubar set on this frame.
|
||||
* @return the menubar for this frame
|
||||
*
|
||||
* @see #setJMenuBar
|
||||
*/
|
||||
public JMenuBar getJMenuBar() {
|
||||
return getRootPane().getMenuBar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @return true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded; false otherwise
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean isRootPaneCheckingEnabled() {
|
||||
return rootPaneCheckingEnabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @param enabled true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded, false if they should operate directly on the
|
||||
* <code>JFrame</code>.
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: Whether the add and setLayout methods are forwarded
|
||||
*/
|
||||
protected void setRootPaneCheckingEnabled(boolean enabled) {
|
||||
rootPaneCheckingEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the specified child <code>Component</code>.
|
||||
* This method is overridden to conditionally forward calls to the
|
||||
* <code>contentPane</code>.
|
||||
* By default, children are added to the <code>contentPane</code> instead
|
||||
* of the frame, refer to {@link javax.swing.RootPaneContainer} for
|
||||
* details.
|
||||
*
|
||||
* @param comp the component to be enhanced
|
||||
* @param constraints the constraints to be respected
|
||||
* @param index the index
|
||||
* @exception IllegalArgumentException if <code>index</code> is invalid
|
||||
* @exception IllegalArgumentException if adding the container's parent
|
||||
* to itself
|
||||
* @exception IllegalArgumentException if adding a window to a container
|
||||
*
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index)
|
||||
{
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().add(comp, constraints, index);
|
||||
}
|
||||
else {
|
||||
super.addImpl(comp, constraints, index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified component from the container. If
|
||||
* <code>comp</code> is not the <code>rootPane</code>, this will forward
|
||||
* the call to the <code>contentPane</code>. This will do nothing if
|
||||
* <code>comp</code> is not a child of the <code>JFrame</code> or
|
||||
* <code>contentPane</code>.
|
||||
*
|
||||
* @param comp the component to be removed
|
||||
* @throws NullPointerException if <code>comp</code> is null
|
||||
* @see #add
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void remove(Component comp) {
|
||||
if (comp == rootPane) {
|
||||
super.remove(comp);
|
||||
} else {
|
||||
getContentPane().remove(comp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>LayoutManager</code>.
|
||||
* Overridden to conditionally forward the call to the
|
||||
* <code>contentPane</code>.
|
||||
* Refer to {@link javax.swing.RootPaneContainer} for
|
||||
* more information.
|
||||
*
|
||||
* @param manager the <code>LayoutManager</code>
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void setLayout(LayoutManager manager) {
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().setLayout(manager);
|
||||
}
|
||||
else {
|
||||
super.setLayout(manager);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the <code>rootPane</code> object for this frame.
|
||||
* @return the <code>rootPane</code> property
|
||||
*
|
||||
* @see #setRootPane
|
||||
* @see RootPaneContainer#getRootPane
|
||||
*/
|
||||
public JRootPane getRootPane() {
|
||||
return rootPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>rootPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
* @param root the <code>rootPane</code> object for this frame
|
||||
*
|
||||
* @see #getRootPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: the RootPane object for this frame.
|
||||
*/
|
||||
protected void setRootPane(JRootPane root)
|
||||
{
|
||||
if(rootPane != null) {
|
||||
remove(rootPane);
|
||||
}
|
||||
rootPane = root;
|
||||
if(rootPane != null) {
|
||||
boolean checkingEnabled = isRootPaneCheckingEnabled();
|
||||
try {
|
||||
setRootPaneCheckingEnabled(false);
|
||||
add(rootPane, BorderLayout.CENTER);
|
||||
}
|
||||
finally {
|
||||
setRootPaneCheckingEnabled(checkingEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setIconImage(Image image) {
|
||||
super.setIconImage(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>contentPane</code> object for this frame.
|
||||
* @return the <code>contentPane</code> property
|
||||
*
|
||||
* @see #setContentPane
|
||||
* @see RootPaneContainer#getContentPane
|
||||
*/
|
||||
public Container getContentPane() {
|
||||
return getRootPane().getContentPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>contentPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
* <p>
|
||||
* Swing's painting architecture requires an opaque <code>JComponent</code>
|
||||
* in the containment hierarchy. This is typically provided by the
|
||||
* content pane. If you replace the content pane it is recommended you
|
||||
* replace it with an opaque <code>JComponent</code>.
|
||||
*
|
||||
* @param contentPane the <code>contentPane</code> object for this frame
|
||||
*
|
||||
* @exception java.awt.IllegalComponentStateException (a runtime
|
||||
* exception) if the content pane parameter is <code>null</code>
|
||||
* @see #getContentPane
|
||||
* @see RootPaneContainer#setContentPane
|
||||
* @see JRootPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The client area of the frame where child
|
||||
* components are normally inserted.
|
||||
*/
|
||||
public void setContentPane(Container contentPane) {
|
||||
getRootPane().setContentPane(contentPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>layeredPane</code> object for this frame.
|
||||
* @return the <code>layeredPane</code> property
|
||||
*
|
||||
* @see #setLayeredPane
|
||||
* @see RootPaneContainer#getLayeredPane
|
||||
*/
|
||||
public JLayeredPane getLayeredPane() {
|
||||
return getRootPane().getLayeredPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>layeredPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
* @param layeredPane the <code>layeredPane</code> object for this frame
|
||||
*
|
||||
* @exception java.awt.IllegalComponentStateException (a runtime
|
||||
* exception) if the layered pane parameter is <code>null</code>
|
||||
* @see #getLayeredPane
|
||||
* @see RootPaneContainer#setLayeredPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The pane that holds the various frame layers.
|
||||
*/
|
||||
public void setLayeredPane(JLayeredPane layeredPane) {
|
||||
getRootPane().setLayeredPane(layeredPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>glassPane</code> object for this frame.
|
||||
* @return the <code>glassPane</code> property
|
||||
*
|
||||
* @see #setGlassPane
|
||||
* @see RootPaneContainer#getGlassPane
|
||||
*/
|
||||
public Component getGlassPane() {
|
||||
return getRootPane().getGlassPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>glassPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
* @param glassPane the <code>glassPane</code> object for this frame
|
||||
*
|
||||
* @see #getGlassPane
|
||||
* @see RootPaneContainer#setGlassPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: A transparent pane used for menu rendering.
|
||||
*/
|
||||
public void setGlassPane(Component glassPane) {
|
||||
getRootPane().setGlassPane(glassPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
JComponent.getGraphicsInvoked(this);
|
||||
return super.getGraphics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaints the specified rectangle of this component within
|
||||
* <code>time</code> milliseconds. Refer to <code>RepaintManager</code>
|
||||
* for details on how the repaint is handled.
|
||||
*
|
||||
* @param time maximum time in milliseconds before update
|
||||
* @param x the <i>x</i> coordinate
|
||||
* @param y the <i>y</i> coordinate
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
* @see RepaintManager
|
||||
* @since 1.6
|
||||
*/
|
||||
public void repaint(long time, int x, int y, int width, int height) {
|
||||
if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
|
||||
RepaintManager.currentManager(this).addDirtyRegion(
|
||||
this, x, y, width, height);
|
||||
}
|
||||
else {
|
||||
super.repaint(time, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a hint as to whether or not newly created <code>JFrame</code>s
|
||||
* should have their Window decorations (such as borders, widgets to
|
||||
* close the window, title...) provided by the current look
|
||||
* and feel. If <code>defaultLookAndFeelDecorated</code> is true,
|
||||
* the current <code>LookAndFeel</code> supports providing window
|
||||
* decorations, and the current window manager supports undecorated
|
||||
* windows, then newly created <code>JFrame</code>s will have their
|
||||
* Window decorations provided by the current <code>LookAndFeel</code>.
|
||||
* Otherwise, newly created <code>JFrame</code>s will have their
|
||||
* Window decorations provided by the current window manager.
|
||||
* <p>
|
||||
* You can get the same effect on a single JFrame by doing the following:
|
||||
* <pre>
|
||||
* JFrame frame = new JFrame();
|
||||
* frame.setUndecorated(true);
|
||||
* frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||
* </pre>
|
||||
*
|
||||
* @param defaultLookAndFeelDecorated A hint as to whether or not current
|
||||
* look and feel should provide window decorations
|
||||
* @see javax.swing.LookAndFeel#getSupportsWindowDecorations
|
||||
* @since 1.4
|
||||
*/
|
||||
public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated) {
|
||||
if (defaultLookAndFeelDecorated) {
|
||||
SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.TRUE);
|
||||
} else {
|
||||
SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if newly created <code>JFrame</code>s should have their
|
||||
* Window decorations provided by the current look and feel. This is only
|
||||
* a hint, as certain look and feels may not support this feature.
|
||||
*
|
||||
* @return true if look and feel should provide Window decorations.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static boolean isDefaultLookAndFeelDecorated() {
|
||||
Boolean defaultLookAndFeelDecorated =
|
||||
(Boolean) SwingUtilities.appContextGet(defaultLookAndFeelDecoratedKey);
|
||||
if (defaultLookAndFeelDecorated == null) {
|
||||
defaultLookAndFeelDecorated = Boolean.FALSE;
|
||||
}
|
||||
return defaultLookAndFeelDecorated.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JFrame</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JFrame</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String defaultCloseOperationString;
|
||||
if (defaultCloseOperation == HIDE_ON_CLOSE) {
|
||||
defaultCloseOperationString = "HIDE_ON_CLOSE";
|
||||
} else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
|
||||
defaultCloseOperationString = "DISPOSE_ON_CLOSE";
|
||||
} else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
|
||||
defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
|
||||
} else if (defaultCloseOperation == 3) {
|
||||
defaultCloseOperationString = "EXIT_ON_CLOSE";
|
||||
} else defaultCloseOperationString = "";
|
||||
String rootPaneString = (rootPane != null ?
|
||||
rootPane.toString() : "");
|
||||
String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
|
||||
"true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",defaultCloseOperation=" + defaultCloseOperationString +
|
||||
",rootPane=" + rootPaneString +
|
||||
",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/** The accessible context property. */
|
||||
protected AccessibleContext accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JFrame.
|
||||
* For JFrames, the AccessibleContext takes the form of an
|
||||
* AccessibleJFrame.
|
||||
* A new AccessibleJFrame instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJFrame that serves as the
|
||||
* AccessibleContext of this JFrame
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJFrame();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JFrame</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to frame user-interface
|
||||
* elements.
|
||||
*/
|
||||
protected class AccessibleJFrame extends AccessibleAWTFrame {
|
||||
|
||||
// AccessibleContext methods
|
||||
/**
|
||||
* Get the accessible name of this object.
|
||||
*
|
||||
* @return the localized name of the object -- can be null if this
|
||||
* object does not have a name
|
||||
*/
|
||||
public String getAccessibleName() {
|
||||
if (accessibleName != null) {
|
||||
return accessibleName;
|
||||
} else {
|
||||
if (getTitle() == null) {
|
||||
return super.getAccessibleName();
|
||||
} else {
|
||||
return getTitle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of this object.
|
||||
*
|
||||
* @return an instance of AccessibleStateSet containing the current
|
||||
* state set of the object
|
||||
* @see AccessibleState
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
|
||||
if (isResizable()) {
|
||||
states.add(AccessibleState.RESIZABLE);
|
||||
}
|
||||
if (getFocusOwner() != null) {
|
||||
states.add(AccessibleState.ACTIVE);
|
||||
}
|
||||
// FIXME: [[[WDW - should also return ICONIFIED and ICONIFIABLE
|
||||
// if we can ever figure these out]]]
|
||||
return states;
|
||||
}
|
||||
} // inner class AccessibleJFrame
|
||||
}
|
||||
2422
jdkSrc/jdk8/javax/swing/JInternalFrame.java
Normal file
2422
jdkSrc/jdk8/javax/swing/JInternalFrame.java
Normal file
File diff suppressed because it is too large
Load Diff
1636
jdkSrc/jdk8/javax/swing/JLabel.java
Normal file
1636
jdkSrc/jdk8/javax/swing/JLabel.java
Normal file
File diff suppressed because it is too large
Load Diff
865
jdkSrc/jdk8/javax/swing/JLayer.java
Normal file
865
jdkSrc/jdk8/javax/swing/JLayer.java
Normal file
@@ -0,0 +1,865 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 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 javax.swing;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
import javax.swing.plaf.LayerUI;
|
||||
import javax.swing.border.Border;
|
||||
import javax.accessibility.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* {@code JLayer} is a universal decorator for Swing components
|
||||
* which enables you to implement various advanced painting effects as well as
|
||||
* receive notifications of all {@code AWTEvent}s generated within its borders.
|
||||
* <p>
|
||||
* {@code JLayer} delegates the handling of painting and input events to a
|
||||
* {@link javax.swing.plaf.LayerUI} object, which performs the actual decoration.
|
||||
* <p>
|
||||
* The custom painting implemented in the {@code LayerUI} and events notification
|
||||
* work for the JLayer itself and all its subcomponents.
|
||||
* This combination enables you to enrich existing components
|
||||
* by adding new advanced functionality such as temporary locking of a hierarchy,
|
||||
* data tips for compound components, enhanced mouse scrolling etc and so on.
|
||||
* <p>
|
||||
* {@code JLayer} is a good solution if you only need to do custom painting
|
||||
* over compound component or catch input events from its subcomponents.
|
||||
* <pre>
|
||||
* import javax.swing.*;
|
||||
* import javax.swing.plaf.LayerUI;
|
||||
* import java.awt.*;
|
||||
*
|
||||
* public class JLayerSample {
|
||||
*
|
||||
* private static JLayer<JComponent> createLayer() {
|
||||
* // This custom layerUI will fill the layer with translucent green
|
||||
* // and print out all mouseMotion events generated within its borders
|
||||
* LayerUI<JComponent> layerUI = new LayerUI<JComponent>() {
|
||||
*
|
||||
* public void paint(Graphics g, JComponent c) {
|
||||
* // paint the layer as is
|
||||
* super.paint(g, c);
|
||||
* // fill it with the translucent green
|
||||
* g.setColor(new Color(0, 128, 0, 128));
|
||||
* g.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
* }
|
||||
*
|
||||
* public void installUI(JComponent c) {
|
||||
* super.installUI(c);
|
||||
* // enable mouse motion events for the layer's subcomponents
|
||||
* ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
|
||||
* }
|
||||
*
|
||||
* public void uninstallUI(JComponent c) {
|
||||
* super.uninstallUI(c);
|
||||
* // reset the layer event mask
|
||||
* ((JLayer) c).setLayerEventMask(0);
|
||||
* }
|
||||
*
|
||||
* // overridden method which catches MouseMotion events
|
||||
* public void eventDispatched(AWTEvent e, JLayer<? extends JComponent> l) {
|
||||
* System.out.println("AWTEvent detected: " + e);
|
||||
* }
|
||||
* };
|
||||
* // create a component to be decorated with the layer
|
||||
* JPanel panel = new JPanel();
|
||||
* panel.add(new JButton("JButton"));
|
||||
*
|
||||
* // create the layer for the panel using our custom layerUI
|
||||
* return new JLayer<JComponent>(panel, layerUI);
|
||||
* }
|
||||
*
|
||||
* private static void createAndShowGUI() {
|
||||
* final JFrame frame = new JFrame();
|
||||
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
*
|
||||
* // work with the layer as with any other Swing component
|
||||
* frame.add(createLayer());
|
||||
*
|
||||
* frame.setSize(200, 200);
|
||||
* frame.setLocationRelativeTo(null);
|
||||
* frame.setVisible(true);
|
||||
* }
|
||||
*
|
||||
* public static void main(String[] args) throws Exception {
|
||||
* SwingUtilities.invokeAndWait(new Runnable() {
|
||||
* public void run() {
|
||||
* createAndShowGUI();
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <b>Note:</b> {@code JLayer} doesn't support the following methods:
|
||||
* <ul>
|
||||
* <li>{@link Container#add(java.awt.Component)}</li>
|
||||
* <li>{@link Container#add(String, java.awt.Component)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, int)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, Object)}</li>
|
||||
* <li>{@link Container#add(java.awt.Component, Object, int)}</li>
|
||||
* </ul>
|
||||
* using any of of them will cause {@code UnsupportedOperationException} to be thrown,
|
||||
* to add a component to {@code JLayer}
|
||||
* use {@link #setView(Component)} or {@link #setGlassPane(JPanel)}.
|
||||
*
|
||||
* @param <V> the type of {@code JLayer}'s view component
|
||||
*
|
||||
* @see #JLayer(Component)
|
||||
* @see #setView(Component)
|
||||
* @see #getView()
|
||||
* @see javax.swing.plaf.LayerUI
|
||||
* @see #JLayer(Component, LayerUI)
|
||||
* @see #setUI(javax.swing.plaf.LayerUI)
|
||||
* @see #getUI()
|
||||
* @since 1.7
|
||||
*
|
||||
* @author Alexander Potochkin
|
||||
*/
|
||||
public final class JLayer<V extends Component>
|
||||
extends JComponent
|
||||
implements Scrollable, PropertyChangeListener, Accessible {
|
||||
private V view;
|
||||
// this field is necessary because JComponent.ui is transient
|
||||
// when layerUI is serializable
|
||||
private LayerUI<? super V> layerUI;
|
||||
private JPanel glassPane;
|
||||
private long eventMask;
|
||||
private transient boolean isPainting;
|
||||
private transient boolean isPaintingImmediately;
|
||||
|
||||
private static final LayerEventController eventController =
|
||||
new LayerEventController();
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object with a {@code null} view component
|
||||
* and default {@link javax.swing.plaf.LayerUI}.
|
||||
*
|
||||
* @see #setView
|
||||
* @see #setUI
|
||||
*/
|
||||
public JLayer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object
|
||||
* with default {@link javax.swing.plaf.LayerUI}.
|
||||
*
|
||||
* @param view the component to be decorated by this {@code JLayer}
|
||||
*
|
||||
* @see #setUI
|
||||
*/
|
||||
public JLayer(V view) {
|
||||
this(view, new LayerUI<V>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code JLayer} object with the specified view component
|
||||
* and {@link javax.swing.plaf.LayerUI} object.
|
||||
*
|
||||
* @param view the component to be decorated
|
||||
* @param ui the {@link javax.swing.plaf.LayerUI} delegate
|
||||
* to be used by this {@code JLayer}
|
||||
*/
|
||||
public JLayer(V view, LayerUI<V> ui) {
|
||||
setGlassPane(createGlassPane());
|
||||
setView(view);
|
||||
setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code JLayer}'s view component or {@code null}.
|
||||
* <br>This is a bound property.
|
||||
*
|
||||
* @return the {@code JLayer}'s view component
|
||||
* or {@code null} if none exists
|
||||
*
|
||||
* @see #setView(Component)
|
||||
*/
|
||||
public V getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code JLayer}'s view component, which can be {@code null}.
|
||||
* <br>This is a bound property.
|
||||
*
|
||||
* @param view the view component for this {@code JLayer}
|
||||
*
|
||||
* @see #getView()
|
||||
*/
|
||||
public void setView(V view) {
|
||||
Component oldView = getView();
|
||||
if (oldView != null) {
|
||||
super.remove(oldView);
|
||||
}
|
||||
if (view != null) {
|
||||
super.addImpl(view, null, getComponentCount());
|
||||
}
|
||||
this.view = view;
|
||||
firePropertyChange("view", oldView, view);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link javax.swing.plaf.LayerUI} which will perform painting
|
||||
* and receive input events for this {@code JLayer}.
|
||||
*
|
||||
* @param ui the {@link javax.swing.plaf.LayerUI} for this {@code JLayer}
|
||||
*/
|
||||
public void setUI(LayerUI<? super V> ui) {
|
||||
this.layerUI = ui;
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link javax.swing.plaf.LayerUI} for this {@code JLayer}.
|
||||
*
|
||||
* @return the {@code LayerUI} for this {@code JLayer}
|
||||
*/
|
||||
public LayerUI<? super V> getUI() {
|
||||
return layerUI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code JLayer}'s glassPane component or {@code null}.
|
||||
* <br>This is a bound property.
|
||||
*
|
||||
* @return the {@code JLayer}'s glassPane component
|
||||
* or {@code null} if none exists
|
||||
*
|
||||
* @see #setGlassPane(JPanel)
|
||||
*/
|
||||
public JPanel getGlassPane() {
|
||||
return glassPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code JLayer}'s glassPane component, which can be {@code null}.
|
||||
* <br>This is a bound property.
|
||||
*
|
||||
* @param glassPane the glassPane component of this {@code JLayer}
|
||||
*
|
||||
* @see #getGlassPane()
|
||||
*/
|
||||
public void setGlassPane(JPanel glassPane) {
|
||||
Component oldGlassPane = getGlassPane();
|
||||
boolean isGlassPaneVisible = false;
|
||||
if (oldGlassPane != null) {
|
||||
isGlassPaneVisible = oldGlassPane.isVisible();
|
||||
super.remove(oldGlassPane);
|
||||
}
|
||||
if (glassPane != null) {
|
||||
AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
|
||||
new Rectangle());
|
||||
glassPane.setVisible(isGlassPaneVisible);
|
||||
super.addImpl(glassPane, null, 0);
|
||||
}
|
||||
this.glassPane = glassPane;
|
||||
firePropertyChange("glassPane", oldGlassPane, glassPane);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the constructor methods to create a default {@code glassPane}.
|
||||
* By default this method creates a new JPanel with visibility set to true
|
||||
* and opacity set to false.
|
||||
*
|
||||
* @return the default {@code glassPane}
|
||||
*/
|
||||
public JPanel createGlassPane() {
|
||||
return new DefaultLayerGlassPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the layout manager for this container. This method is
|
||||
* overridden to prevent the layout manager from being set.
|
||||
* <p>Note: If {@code mgr} is non-{@code null}, this
|
||||
* method will throw an exception as layout managers are not supported on
|
||||
* a {@code JLayer}.
|
||||
*
|
||||
* @param mgr the specified layout manager
|
||||
* @exception IllegalArgumentException this method is not supported
|
||||
*/
|
||||
public void setLayout(LayoutManager mgr) {
|
||||
if (mgr != null) {
|
||||
throw new IllegalArgumentException("JLayer.setLayout() not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-{@code null} border, or non-zero insets, isn't supported, to prevent the geometry
|
||||
* of this component from becoming complex enough to inhibit
|
||||
* subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border,
|
||||
* add it to a {@code JPanel} that has a border.
|
||||
* <p>Note: If {@code border} is non-{@code null}, this
|
||||
* method will throw an exception as borders are not supported on
|
||||
* a {@code JLayer}.
|
||||
*
|
||||
* @param border the {@code Border} to set
|
||||
* @exception IllegalArgumentException this method is not supported
|
||||
*/
|
||||
public void setBorder(Border border) {
|
||||
if (border != null) {
|
||||
throw new IllegalArgumentException("JLayer.setBorder() not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not supported by {@code JLayer}
|
||||
* and always throws {@code UnsupportedOperationException}
|
||||
*
|
||||
* @throws UnsupportedOperationException this method is not supported
|
||||
*
|
||||
* @see #setView(Component)
|
||||
* @see #setGlassPane(JPanel)
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Adding components to JLayer is not supported, " +
|
||||
"use setView() or setGlassPane() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void remove(Component comp) {
|
||||
if (comp == null) {
|
||||
super.remove(comp);
|
||||
} else if (comp == getView()) {
|
||||
setView(null);
|
||||
} else if (comp == getGlassPane()) {
|
||||
setGlassPane(null);
|
||||
} else {
|
||||
super.remove(comp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeAll() {
|
||||
if (view != null) {
|
||||
setView(null);
|
||||
}
|
||||
if (glassPane != null) {
|
||||
setGlassPane(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns {@code true} to cause painting to originate from {@code JLayer},
|
||||
* or one of its ancestors.
|
||||
*
|
||||
* @return true
|
||||
* @see JComponent#isPaintingOrigin()
|
||||
*/
|
||||
protected boolean isPaintingOrigin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates its functionality to the
|
||||
* {@link javax.swing.plaf.LayerUI#paintImmediately(int, int, int, int, JLayer)} method,
|
||||
* if {@code LayerUI} is set.
|
||||
*
|
||||
* @param x the x value of the region to be painted
|
||||
* @param y the y value of the region to be painted
|
||||
* @param w the width of the region to be painted
|
||||
* @param h the height of the region to be painted
|
||||
*/
|
||||
public void paintImmediately(int x, int y, int w, int h) {
|
||||
if (!isPaintingImmediately && getUI() != null) {
|
||||
isPaintingImmediately = true;
|
||||
try {
|
||||
getUI().paintImmediately(x, y, w, h, this);
|
||||
} finally {
|
||||
isPaintingImmediately = false;
|
||||
}
|
||||
} else {
|
||||
super.paintImmediately(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
|
||||
*
|
||||
* @param g the {@code Graphics} to render to
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
if (!isPainting) {
|
||||
isPainting = true;
|
||||
try {
|
||||
super.paintComponent(g);
|
||||
} finally {
|
||||
isPainting = false;
|
||||
}
|
||||
} else {
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is empty, because all painting is done by
|
||||
* {@link #paint(Graphics)} and
|
||||
* {@link javax.swing.plaf.LayerUI#update(Graphics, JComponent)} methods
|
||||
*/
|
||||
protected void paintComponent(Graphics g) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@code JLayer} overrides the default implementation of
|
||||
* this method (in {@code JComponent}) to return {@code false}.
|
||||
* This ensures
|
||||
* that the drawing machinery will call the {@code JLayer}'s
|
||||
* {@code paint}
|
||||
* implementation rather than messaging the {@code JLayer}'s
|
||||
* children directly.
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean isOptimizedDrawingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (getUI() != null) {
|
||||
getUI().applyPropertyChange(evt, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the events from JLayer and <b>all its descendants</b>
|
||||
* defined by the specified event mask parameter
|
||||
* to be delivered to the
|
||||
* {@link LayerUI#eventDispatched(AWTEvent, JLayer)} method.
|
||||
* <p>
|
||||
* Events are delivered provided that {@code LayerUI} is set
|
||||
* for this {@code JLayer} and the {@code JLayer}
|
||||
* is displayable.
|
||||
* <p>
|
||||
* The following example shows how to correctly use this method
|
||||
* in the {@code LayerUI} implementations:
|
||||
* <pre>
|
||||
* public void installUI(JComponent c) {
|
||||
* super.installUI(c);
|
||||
* JLayer l = (JLayer) c;
|
||||
* // this LayerUI will receive only key and focus events
|
||||
* l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
|
||||
* }
|
||||
*
|
||||
* public void uninstallUI(JComponent c) {
|
||||
* super.uninstallUI(c);
|
||||
* JLayer l = (JLayer) c;
|
||||
* // JLayer must be returned to its initial state
|
||||
* l.setLayerEventMask(0);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* By default {@code JLayer} receives no events and its event mask is {@code 0}.
|
||||
*
|
||||
* @param layerEventMask the bitmask of event types to receive
|
||||
*
|
||||
* @see #getLayerEventMask()
|
||||
* @see LayerUI#eventDispatched(AWTEvent, JLayer)
|
||||
* @see Component#isDisplayable()
|
||||
*/
|
||||
public void setLayerEventMask(long layerEventMask) {
|
||||
long oldEventMask = getLayerEventMask();
|
||||
this.eventMask = layerEventMask;
|
||||
firePropertyChange("layerEventMask", oldEventMask, layerEventMask);
|
||||
if (layerEventMask != oldEventMask) {
|
||||
disableEvents(oldEventMask);
|
||||
enableEvents(eventMask);
|
||||
if (isDisplayable()) {
|
||||
eventController.updateAWTEventListener(
|
||||
oldEventMask, layerEventMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitmap of event mask to receive by this {@code JLayer}
|
||||
* and its {@code LayerUI}.
|
||||
* <p>
|
||||
* It means that {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method
|
||||
* will only receive events that match the event mask.
|
||||
* <p>
|
||||
* By default {@code JLayer} receives no events.
|
||||
*
|
||||
* @return the bitmask of event types to receive for this {@code JLayer}
|
||||
*/
|
||||
public long getLayerEventMask() {
|
||||
return eventMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates its functionality to the {@link javax.swing.plaf.LayerUI#updateUI(JLayer)} method,
|
||||
* if {@code LayerUI} is set.
|
||||
*/
|
||||
public void updateUI() {
|
||||
if (getUI() != null) {
|
||||
getUI().updateUI(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the viewport for a view component.
|
||||
* <p>
|
||||
* If the view component of this layer implements {@link Scrollable}, this method delegates its
|
||||
* implementation to the view component.
|
||||
*
|
||||
* @return the preferred size of the viewport for a view component
|
||||
*
|
||||
* @see Scrollable
|
||||
*/
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
if (getView() instanceof Scrollable) {
|
||||
return ((Scrollable)getView()).getPreferredScrollableViewportSize();
|
||||
}
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one block of rows or columns, depending on the value of orientation.
|
||||
* <p>
|
||||
* If the view component of this layer implements {@link Scrollable}, this method delegates its
|
||||
* implementation to the view component.
|
||||
*
|
||||
* @return the "block" increment for scrolling in the specified direction
|
||||
*
|
||||
* @see Scrollable
|
||||
*/
|
||||
public int getScrollableBlockIncrement(Rectangle visibleRect,
|
||||
int orientation, int direction) {
|
||||
if (getView() instanceof Scrollable) {
|
||||
return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
|
||||
orientation, direction);
|
||||
}
|
||||
return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
|
||||
visibleRect.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the height of the viewport does not
|
||||
* determine the height of the layer, unless the preferred height
|
||||
* of the layer is smaller than the height of the viewport.
|
||||
* <p>
|
||||
* If the view component of this layer implements {@link Scrollable}, this method delegates its
|
||||
* implementation to the view component.
|
||||
*
|
||||
* @return whether the layer should track the height of the viewport
|
||||
*
|
||||
* @see Scrollable
|
||||
*/
|
||||
public boolean getScrollableTracksViewportHeight() {
|
||||
if (getView() instanceof Scrollable) {
|
||||
return ((Scrollable)getView()).getScrollableTracksViewportHeight();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code false} to indicate that the width of the viewport does not
|
||||
* determine the width of the layer, unless the preferred width
|
||||
* of the layer is smaller than the width of the viewport.
|
||||
* <p>
|
||||
* If the view component of this layer implements {@link Scrollable}, this method delegates its
|
||||
* implementation to the view component.
|
||||
*
|
||||
* @return whether the layer should track the width of the viewport
|
||||
*
|
||||
* @see Scrollable
|
||||
*/
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
if (getView() instanceof Scrollable) {
|
||||
return ((Scrollable)getView()).getScrollableTracksViewportWidth();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scroll increment, which is required for components
|
||||
* that display logical rows or columns in order to completely expose
|
||||
* one new row or column, depending on the value of orientation.
|
||||
* Ideally, components should handle a partially exposed row or column
|
||||
* by returning the distance required to completely expose the item.
|
||||
* <p>
|
||||
* Scrolling containers, like {@code JScrollPane}, will use this method
|
||||
* each time the user requests a unit scroll.
|
||||
* <p>
|
||||
* If the view component of this layer implements {@link Scrollable}, this method delegates its
|
||||
* implementation to the view component.
|
||||
*
|
||||
* @return The "unit" increment for scrolling in the specified direction.
|
||||
* This value should always be positive.
|
||||
*
|
||||
* @see Scrollable
|
||||
*/
|
||||
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
|
||||
int direction) {
|
||||
if (getView() instanceof Scrollable) {
|
||||
return ((Scrollable) getView()).getScrollableUnitIncrement(
|
||||
visibleRect, orientation, direction);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
if (layerUI != null) {
|
||||
setUI(layerUI);
|
||||
}
|
||||
if (eventMask != 0) {
|
||||
eventController.updateAWTEventListener(0, eventMask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
eventController.updateAWTEventListener(0, eventMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
eventController.updateAWTEventListener(eventMask, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
|
||||
* if {@code LayerUI} is set.
|
||||
*/
|
||||
public void doLayout() {
|
||||
if (getUI() != null) {
|
||||
getUI().doLayout(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this {@code JLayer}.
|
||||
*
|
||||
* @return the AccessibleContext associated with this {@code JLayer}.
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJComponent() {
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.PANEL;
|
||||
}
|
||||
};
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* static AWTEventListener to be shared with all AbstractLayerUIs
|
||||
*/
|
||||
private static class LayerEventController implements AWTEventListener {
|
||||
private ArrayList<Long> layerMaskList =
|
||||
new ArrayList<Long>();
|
||||
|
||||
private long currentEventMask;
|
||||
|
||||
private static final long ACCEPTED_EVENTS =
|
||||
AWTEvent.COMPONENT_EVENT_MASK |
|
||||
AWTEvent.CONTAINER_EVENT_MASK |
|
||||
AWTEvent.FOCUS_EVENT_MASK |
|
||||
AWTEvent.KEY_EVENT_MASK |
|
||||
AWTEvent.MOUSE_WHEEL_EVENT_MASK |
|
||||
AWTEvent.MOUSE_MOTION_EVENT_MASK |
|
||||
AWTEvent.MOUSE_EVENT_MASK |
|
||||
AWTEvent.INPUT_METHOD_EVENT_MASK |
|
||||
AWTEvent.HIERARCHY_EVENT_MASK |
|
||||
AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void eventDispatched(AWTEvent event) {
|
||||
Object source = event.getSource();
|
||||
if (source instanceof Component) {
|
||||
Component component = (Component) source;
|
||||
while (component != null) {
|
||||
if (component instanceof JLayer) {
|
||||
JLayer l = (JLayer) component;
|
||||
LayerUI ui = l.getUI();
|
||||
if (ui != null &&
|
||||
isEventEnabled(l.getLayerEventMask(), event.getID()) &&
|
||||
(!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
|
||||
ui.eventDispatched(event, l);
|
||||
}
|
||||
}
|
||||
component = component.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAWTEventListener(long oldEventMask, long newEventMask) {
|
||||
if (oldEventMask != 0) {
|
||||
layerMaskList.remove(oldEventMask);
|
||||
}
|
||||
if (newEventMask != 0) {
|
||||
layerMaskList.add(newEventMask);
|
||||
}
|
||||
long combinedMask = 0;
|
||||
for (Long mask : layerMaskList) {
|
||||
combinedMask |= mask;
|
||||
}
|
||||
// filter out all unaccepted events
|
||||
combinedMask &= ACCEPTED_EVENTS;
|
||||
if (combinedMask == 0) {
|
||||
removeAWTEventListener();
|
||||
} else if (getCurrentEventMask() != combinedMask) {
|
||||
removeAWTEventListener();
|
||||
addAWTEventListener(combinedMask);
|
||||
}
|
||||
currentEventMask = combinedMask;
|
||||
}
|
||||
|
||||
private long getCurrentEventMask() {
|
||||
return currentEventMask;
|
||||
}
|
||||
|
||||
private void addAWTEventListener(final long eventMask) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Toolkit.getDefaultToolkit().
|
||||
addAWTEventListener(LayerEventController.this, eventMask);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void removeAWTEventListener() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Toolkit.getDefaultToolkit().
|
||||
removeAWTEventListener(LayerEventController.this);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isEventEnabled(long eventMask, int id) {
|
||||
return (((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 &&
|
||||
id >= ComponentEvent.COMPONENT_FIRST &&
|
||||
id <= ComponentEvent.COMPONENT_LAST)
|
||||
|| ((eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 &&
|
||||
id >= ContainerEvent.CONTAINER_FIRST &&
|
||||
id <= ContainerEvent.CONTAINER_LAST)
|
||||
|| ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 &&
|
||||
id >= FocusEvent.FOCUS_FIRST &&
|
||||
id <= FocusEvent.FOCUS_LAST)
|
||||
|| ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 &&
|
||||
id >= KeyEvent.KEY_FIRST &&
|
||||
id <= KeyEvent.KEY_LAST)
|
||||
|| ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 &&
|
||||
id == MouseEvent.MOUSE_WHEEL)
|
||||
|| ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 &&
|
||||
(id == MouseEvent.MOUSE_MOVED ||
|
||||
id == MouseEvent.MOUSE_DRAGGED))
|
||||
|| ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 &&
|
||||
id != MouseEvent.MOUSE_MOVED &&
|
||||
id != MouseEvent.MOUSE_DRAGGED &&
|
||||
id != MouseEvent.MOUSE_WHEEL &&
|
||||
id >= MouseEvent.MOUSE_FIRST &&
|
||||
id <= MouseEvent.MOUSE_LAST)
|
||||
|| ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 &&
|
||||
id >= InputMethodEvent.INPUT_METHOD_FIRST &&
|
||||
id <= InputMethodEvent.INPUT_METHOD_LAST)
|
||||
|| ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
|
||||
id == HierarchyEvent.HIERARCHY_CHANGED)
|
||||
|| ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
|
||||
(id == HierarchyEvent.ANCESTOR_MOVED ||
|
||||
id == HierarchyEvent.ANCESTOR_RESIZED)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default glassPane for the {@link javax.swing.JLayer}.
|
||||
* It is a subclass of {@code JPanel} which is non opaque by default.
|
||||
*/
|
||||
private static class DefaultLayerGlassPane extends JPanel {
|
||||
/**
|
||||
* Creates a new {@link DefaultLayerGlassPane}
|
||||
*/
|
||||
public DefaultLayerGlassPane() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* First, implementation of this method iterates through
|
||||
* glassPane's child components and returns {@code true}
|
||||
* if any of them is visible and contains passed x,y point.
|
||||
* After that it checks if no mouseListeners is attached to this component
|
||||
* and no mouse cursor is set, then it returns {@code false},
|
||||
* otherwise calls the super implementation of this method.
|
||||
*
|
||||
* @param x the <i>x</i> coordinate of the point
|
||||
* @param y the <i>y</i> coordinate of the point
|
||||
* @return true if this component logically contains x,y
|
||||
*/
|
||||
public boolean contains(int x, int y) {
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
Component c = getComponent(i);
|
||||
Point point = SwingUtilities.convertPoint(this, new Point(x, y), c);
|
||||
if(c.isVisible() && c.contains(point)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (getMouseListeners().length == 0
|
||||
&& getMouseMotionListeners().length == 0
|
||||
&& getMouseWheelListeners().length == 0
|
||||
&& !isCursorSet()) {
|
||||
return false;
|
||||
}
|
||||
return super.contains(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
786
jdkSrc/jdk8/javax/swing/JLayeredPane.java
Normal file
786
jdkSrc/jdk8/javax/swing/JLayeredPane.java
Normal file
@@ -0,0 +1,786 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* <code>JLayeredPane</code> adds depth to a JFC/Swing container,
|
||||
* allowing components to overlap each other when needed.
|
||||
* An <code>Integer</code> object specifies each component's depth in the
|
||||
* container, where higher-numbered components sit "on top" of other
|
||||
* components.
|
||||
* For task-oriented documentation and examples of using layered panes see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html">How to Use a Layered Pane</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
*
|
||||
* <TABLE STYLE="FLOAT:RIGHT" BORDER="0" SUMMARY="layout">
|
||||
* <TR>
|
||||
* <TD ALIGN="CENTER">
|
||||
* <P STYLE="TEXT-ALIGN:CENTER"><IMG SRC="doc-files/JLayeredPane-1.gif"
|
||||
* alt="The following text describes this image."
|
||||
* WIDTH="269" HEIGHT="264" STYLE="FLOAT:BOTTOM; BORDER=0">
|
||||
* </TD>
|
||||
* </TR>
|
||||
* </TABLE>
|
||||
* For convenience, <code>JLayeredPane</code> divides the depth-range
|
||||
* into several different layers. Putting a component into one of those
|
||||
* layers makes it easy to ensure that components overlap properly,
|
||||
* without having to worry about specifying numbers for specific depths:
|
||||
* <DL>
|
||||
* <DT><FONT SIZE="2">DEFAULT_LAYER</FONT></DT>
|
||||
* <DD>The standard layer, where most components go. This the bottommost
|
||||
* layer.
|
||||
* <DT><FONT SIZE="2">PALETTE_LAYER</FONT></DT>
|
||||
* <DD>The palette layer sits over the default layer. Useful for floating
|
||||
* toolbars and palettes, so they can be positioned above other components.
|
||||
* <DT><FONT SIZE="2">MODAL_LAYER</FONT></DT>
|
||||
* <DD>The layer used for modal dialogs. They will appear on top of any
|
||||
* toolbars, palettes, or standard components in the container.
|
||||
* <DT><FONT SIZE="2">POPUP_LAYER</FONT></DT>
|
||||
* <DD>The popup layer displays above dialogs. That way, the popup windows
|
||||
* associated with combo boxes, tooltips, and other help text will appear
|
||||
* above the component, palette, or dialog that generated them.
|
||||
* <DT><FONT SIZE="2">DRAG_LAYER</FONT></DT>
|
||||
* <DD>When dragging a component, reassigning it to the drag layer ensures
|
||||
* that it is positioned over every other component in the container. When
|
||||
* finished dragging, it can be reassigned to its normal layer.
|
||||
* </DL>
|
||||
* The <code>JLayeredPane</code> methods <code>moveToFront(Component)</code>,
|
||||
* <code>moveToBack(Component)</code> and <code>setPosition</code> can be used
|
||||
* to reposition a component within its layer. The <code>setLayer</code> method
|
||||
* can also be used to change the component's current layer.
|
||||
*
|
||||
* <h2>Details</h2>
|
||||
* <code>JLayeredPane</code> manages its list of children like
|
||||
* <code>Container</code>, but allows for the definition of a several
|
||||
* layers within itself. Children in the same layer are managed exactly
|
||||
* like the normal <code>Container</code> object,
|
||||
* with the added feature that when children components overlap, children
|
||||
* in higher layers display above the children in lower layers.
|
||||
* <p>
|
||||
* Each layer is a distinct integer number. The layer attribute can be set
|
||||
* on a <code>Component</code> by passing an <code>Integer</code>
|
||||
* object during the add call.<br> For example:
|
||||
* <PRE>
|
||||
* layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
|
||||
* or
|
||||
* layeredPane.add(child, new Integer(10));
|
||||
* </PRE>
|
||||
* The layer attribute can also be set on a Component by calling<PRE>
|
||||
* layeredPaneParent.setLayer(child, 10)</PRE>
|
||||
* on the <code>JLayeredPane</code> that is the parent of component. The layer
|
||||
* should be set <i>before</i> adding the child to the parent.
|
||||
* <p>
|
||||
* Higher number layers display above lower number layers. So, using
|
||||
* numbers for the layers and letters for individual components, a
|
||||
* representative list order would look like this:<PRE>
|
||||
* 5a, 5b, 5c, 2a, 2b, 2c, 1a </PRE>
|
||||
* where the leftmost components are closest to the top of the display.
|
||||
* <p>
|
||||
* A component can be moved to the top or bottom position within its
|
||||
* layer by calling <code>moveToFront</code> or <code>moveToBack</code>.
|
||||
* <p>
|
||||
* The position of a component within a layer can also be specified directly.
|
||||
* Valid positions range from 0 up to one less than the number of
|
||||
* components in that layer. A value of -1 indicates the bottommost
|
||||
* position. A value of 0 indicates the topmost position. Unlike layer
|
||||
* numbers, higher position values are <i>lower</i> in the display.
|
||||
* <blockquote>
|
||||
* <b>Note:</b> This sequence (defined by java.awt.Container) is the reverse
|
||||
* of the layer numbering sequence. Usually though, you will use <code>moveToFront</code>,
|
||||
* <code>moveToBack</code>, and <code>setLayer</code>.
|
||||
* </blockquote>
|
||||
* Here are some examples using the method add(Component, layer, position):
|
||||
* Calling add(5x, 5, -1) results in:<PRE>
|
||||
* 5a, 5b, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
|
||||
*
|
||||
* Calling add(5z, 5, 2) results in:<PRE>
|
||||
* 5a, 5b, 5z, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
|
||||
*
|
||||
* Calling add(3a, 3, 7) results in:<PRE>
|
||||
* 5a, 5b, 5z, 5c, 5x, 3a, 2a, 2b, 2c, 1a </PRE>
|
||||
*
|
||||
* Using normal paint/event mechanics results in 1a appearing at the bottom
|
||||
* and 5a being above all other components.
|
||||
* <p>
|
||||
* <b>Note:</b> that these layers are simply a logical construct and LayoutManagers
|
||||
* will affect all child components of this container without regard for
|
||||
* layer settings.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JLayeredPane extends JComponent implements Accessible {
|
||||
/// Watch the values in getObjectForLayer()
|
||||
/** Convenience object defining the Default layer. Equivalent to new Integer(0).*/
|
||||
public final static Integer DEFAULT_LAYER = new Integer(0);
|
||||
/** Convenience object defining the Palette layer. Equivalent to new Integer(100).*/
|
||||
public final static Integer PALETTE_LAYER = new Integer(100);
|
||||
/** Convenience object defining the Modal layer. Equivalent to new Integer(200).*/
|
||||
public final static Integer MODAL_LAYER = new Integer(200);
|
||||
/** Convenience object defining the Popup layer. Equivalent to new Integer(300).*/
|
||||
public final static Integer POPUP_LAYER = new Integer(300);
|
||||
/** Convenience object defining the Drag layer. Equivalent to new Integer(400).*/
|
||||
public final static Integer DRAG_LAYER = new Integer(400);
|
||||
/** Convenience object defining the Frame Content layer.
|
||||
* This layer is normally only use to position the contentPane and menuBar
|
||||
* components of JFrame.
|
||||
* Equivalent to new Integer(-30000).
|
||||
* @see JFrame
|
||||
*/
|
||||
public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
|
||||
|
||||
/** Bound property */
|
||||
public final static String LAYER_PROPERTY = "layeredContainerLayer";
|
||||
// Hashtable to store layer values for non-JComponent components
|
||||
private Hashtable<Component,Integer> componentToLayer;
|
||||
private boolean optimizedDrawingPossible = true;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Container Override methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/** Create a new JLayeredPane */
|
||||
public JLayeredPane() {
|
||||
setLayout(null);
|
||||
}
|
||||
|
||||
private void validateOptimizedDrawing() {
|
||||
boolean layeredComponentFound = false;
|
||||
synchronized(getTreeLock()) {
|
||||
Integer layer;
|
||||
|
||||
for (Component c : getComponents()) {
|
||||
layer = null;
|
||||
|
||||
if(SunToolkit.isInstanceOf(c, "javax.swing.JInternalFrame") ||
|
||||
(c instanceof JComponent &&
|
||||
(layer = (Integer)((JComponent)c).
|
||||
getClientProperty(LAYER_PROPERTY)) != null))
|
||||
{
|
||||
if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
|
||||
continue;
|
||||
layeredComponentFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(layeredComponentFound)
|
||||
optimizedDrawingPossible = false;
|
||||
else
|
||||
optimizedDrawingPossible = true;
|
||||
}
|
||||
|
||||
protected void addImpl(Component comp, Object constraints, int index) {
|
||||
int layer;
|
||||
int pos;
|
||||
|
||||
if(constraints instanceof Integer) {
|
||||
layer = ((Integer)constraints).intValue();
|
||||
setLayer(comp, layer);
|
||||
} else
|
||||
layer = getLayer(comp);
|
||||
|
||||
pos = insertIndexForLayer(layer, index);
|
||||
super.addImpl(comp, constraints, pos);
|
||||
comp.validate();
|
||||
comp.repaint();
|
||||
validateOptimizedDrawing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the indexed component from this pane.
|
||||
* This is the absolute index, ignoring layers.
|
||||
*
|
||||
* @param index an int specifying the component to remove
|
||||
* @see #getIndexOf
|
||||
*/
|
||||
public void remove(int index) {
|
||||
Component c = getComponent(index);
|
||||
super.remove(index);
|
||||
if (c != null && !(c instanceof JComponent)) {
|
||||
getComponentToLayer().remove(c);
|
||||
}
|
||||
validateOptimizedDrawing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the components from this container.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public void removeAll() {
|
||||
Component[] children = getComponents();
|
||||
Hashtable<Component, Integer> cToL = getComponentToLayer();
|
||||
for (int counter = children.length - 1; counter >= 0; counter--) {
|
||||
Component c = children[counter];
|
||||
if (c != null && !(c instanceof JComponent)) {
|
||||
cToL.remove(c);
|
||||
}
|
||||
}
|
||||
super.removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if components in the pane can overlap, which makes
|
||||
* optimized drawing impossible. Otherwise, returns true.
|
||||
*
|
||||
* @return false if components can overlap, else true
|
||||
* @see JComponent#isOptimizedDrawingEnabled
|
||||
*/
|
||||
public boolean isOptimizedDrawingEnabled() {
|
||||
return optimizedDrawingPossible;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// New methods for managing layers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/** Sets the layer property on a JComponent. This method does not cause
|
||||
* any side effects like setLayer() (painting, add/remove, etc).
|
||||
* Normally you should use the instance method setLayer(), in order to
|
||||
* get the desired side-effects (like repainting).
|
||||
*
|
||||
* @param c the JComponent to move
|
||||
* @param layer an int specifying the layer to move it to
|
||||
* @see #setLayer
|
||||
*/
|
||||
public static void putLayer(JComponent c, int layer) {
|
||||
/// MAKE SURE THIS AND setLayer(Component c, int layer, int position) are SYNCED
|
||||
Integer layerObj;
|
||||
|
||||
layerObj = new Integer(layer);
|
||||
c.putClientProperty(LAYER_PROPERTY, layerObj);
|
||||
}
|
||||
|
||||
/** Gets the layer property for a JComponent, it
|
||||
* does not cause any side effects like setLayer(). (painting, add/remove, etc)
|
||||
* Normally you should use the instance method getLayer().
|
||||
*
|
||||
* @param c the JComponent to check
|
||||
* @return an int specifying the component's layer
|
||||
*/
|
||||
public static int getLayer(JComponent c) {
|
||||
Integer i;
|
||||
if((i = (Integer)c.getClientProperty(LAYER_PROPERTY)) != null)
|
||||
return i.intValue();
|
||||
return DEFAULT_LAYER.intValue();
|
||||
}
|
||||
|
||||
/** Convenience method that returns the first JLayeredPane which
|
||||
* contains the specified component. Note that all JFrames have a
|
||||
* JLayeredPane at their root, so any component in a JFrame will
|
||||
* have a JLayeredPane parent.
|
||||
*
|
||||
* @param c the Component to check
|
||||
* @return the JLayeredPane that contains the component, or
|
||||
* null if no JLayeredPane is found in the component
|
||||
* hierarchy
|
||||
* @see JFrame
|
||||
* @see JRootPane
|
||||
*/
|
||||
public static JLayeredPane getLayeredPaneAbove(Component c) {
|
||||
if(c == null) return null;
|
||||
|
||||
Component parent = c.getParent();
|
||||
while(parent != null && !(parent instanceof JLayeredPane))
|
||||
parent = parent.getParent();
|
||||
return (JLayeredPane)parent;
|
||||
}
|
||||
|
||||
/** Sets the layer attribute on the specified component,
|
||||
* making it the bottommost component in that layer.
|
||||
* Should be called before adding to parent.
|
||||
*
|
||||
* @param c the Component to set the layer for
|
||||
* @param layer an int specifying the layer to set, where
|
||||
* lower numbers are closer to the bottom
|
||||
*/
|
||||
public void setLayer(Component c, int layer) {
|
||||
setLayer(c, layer, -1);
|
||||
}
|
||||
|
||||
/** Sets the layer attribute for the specified component and
|
||||
* also sets its position within that layer.
|
||||
*
|
||||
* @param c the Component to set the layer for
|
||||
* @param layer an int specifying the layer to set, where
|
||||
* lower numbers are closer to the bottom
|
||||
* @param position an int specifying the position within the
|
||||
* layer, where 0 is the topmost position and -1
|
||||
* is the bottommost position
|
||||
*/
|
||||
public void setLayer(Component c, int layer, int position) {
|
||||
Integer layerObj;
|
||||
layerObj = getObjectForLayer(layer);
|
||||
|
||||
if(layer == getLayer(c) && position == getPosition(c)) {
|
||||
repaint(c.getBounds());
|
||||
return;
|
||||
}
|
||||
|
||||
/// MAKE SURE THIS AND putLayer(JComponent c, int layer) are SYNCED
|
||||
if(c instanceof JComponent)
|
||||
((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj);
|
||||
else
|
||||
getComponentToLayer().put(c, layerObj);
|
||||
|
||||
if(c.getParent() == null || c.getParent() != this) {
|
||||
repaint(c.getBounds());
|
||||
return;
|
||||
}
|
||||
|
||||
int index = insertIndexForLayer(c, layer, position);
|
||||
|
||||
setComponentZOrder(c, index);
|
||||
repaint(c.getBounds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layer attribute for the specified Component.
|
||||
*
|
||||
* @param c the Component to check
|
||||
* @return an int specifying the component's current layer
|
||||
*/
|
||||
public int getLayer(Component c) {
|
||||
Integer i;
|
||||
if(c instanceof JComponent)
|
||||
i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY);
|
||||
else
|
||||
i = getComponentToLayer().get(c);
|
||||
|
||||
if(i == null)
|
||||
return DEFAULT_LAYER.intValue();
|
||||
return i.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the specified Component.
|
||||
* This is the absolute index, ignoring layers.
|
||||
* Index numbers, like position numbers, have the topmost component
|
||||
* at index zero. Larger numbers are closer to the bottom.
|
||||
*
|
||||
* @param c the Component to check
|
||||
* @return an int specifying the component's index
|
||||
*/
|
||||
public int getIndexOf(Component c) {
|
||||
int i, count;
|
||||
|
||||
count = getComponentCount();
|
||||
for(i = 0; i < count; i++) {
|
||||
if(c == getComponent(i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* Moves the component to the top of the components in its current layer
|
||||
* (position 0).
|
||||
*
|
||||
* @param c the Component to move
|
||||
* @see #setPosition(Component, int)
|
||||
*/
|
||||
public void moveToFront(Component c) {
|
||||
setPosition(c, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the component to the bottom of the components in its current layer
|
||||
* (position -1).
|
||||
*
|
||||
* @param c the Component to move
|
||||
* @see #setPosition(Component, int)
|
||||
*/
|
||||
public void moveToBack(Component c) {
|
||||
setPosition(c, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the component to <code>position</code> within its current layer,
|
||||
* where 0 is the topmost position within the layer and -1 is the bottommost
|
||||
* position.
|
||||
* <p>
|
||||
* <b>Note:</b> Position numbering is defined by java.awt.Container, and
|
||||
* is the opposite of layer numbering. Lower position numbers are closer
|
||||
* to the top (0 is topmost), and higher position numbers are closer to
|
||||
* the bottom.
|
||||
*
|
||||
* @param c the Component to move
|
||||
* @param position an int in the range -1..N-1, where N is the number of
|
||||
* components in the component's current layer
|
||||
*/
|
||||
public void setPosition(Component c, int position) {
|
||||
setLayer(c, getLayer(c), position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relative position of the component within its layer.
|
||||
*
|
||||
* @param c the Component to check
|
||||
* @return an int giving the component's position, where 0 is the
|
||||
* topmost position and the highest index value = the count
|
||||
* count of components at that layer, minus 1
|
||||
*
|
||||
* @see #getComponentCountInLayer
|
||||
*/
|
||||
public int getPosition(Component c) {
|
||||
int i, startLayer, curLayer, startLocation, pos = 0;
|
||||
|
||||
getComponentCount();
|
||||
startLocation = getIndexOf(c);
|
||||
|
||||
if(startLocation == -1)
|
||||
return -1;
|
||||
|
||||
startLayer = getLayer(c);
|
||||
for(i = startLocation - 1; i >= 0; i--) {
|
||||
curLayer = getLayer(getComponent(i));
|
||||
if(curLayer == startLayer)
|
||||
pos++;
|
||||
else
|
||||
return pos;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/** Returns the highest layer value from all current children.
|
||||
* Returns 0 if there are no children.
|
||||
*
|
||||
* @return an int indicating the layer of the topmost component in the
|
||||
* pane, or zero if there are no children
|
||||
*/
|
||||
public int highestLayer() {
|
||||
if(getComponentCount() > 0)
|
||||
return getLayer(getComponent(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns the lowest layer value from all current children.
|
||||
* Returns 0 if there are no children.
|
||||
*
|
||||
* @return an int indicating the layer of the bottommost component in the
|
||||
* pane, or zero if there are no children
|
||||
*/
|
||||
public int lowestLayer() {
|
||||
int count = getComponentCount();
|
||||
if(count > 0)
|
||||
return getLayer(getComponent(count-1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of children currently in the specified layer.
|
||||
*
|
||||
* @param layer an int specifying the layer to check
|
||||
* @return an int specifying the number of components in that layer
|
||||
*/
|
||||
public int getComponentCountInLayer(int layer) {
|
||||
int i, count, curLayer;
|
||||
int layerCount = 0;
|
||||
|
||||
count = getComponentCount();
|
||||
for(i = 0; i < count; i++) {
|
||||
curLayer = getLayer(getComponent(i));
|
||||
if(curLayer == layer) {
|
||||
layerCount++;
|
||||
/// Short circut the counting when we have them all
|
||||
} else if(layerCount > 0 || curLayer < layer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return layerCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the components in the specified layer.
|
||||
*
|
||||
* @param layer an int specifying the layer to check
|
||||
* @return an array of Components contained in that layer
|
||||
*/
|
||||
public Component[] getComponentsInLayer(int layer) {
|
||||
int i, count, curLayer;
|
||||
int layerCount = 0;
|
||||
Component[] results;
|
||||
|
||||
results = new Component[getComponentCountInLayer(layer)];
|
||||
count = getComponentCount();
|
||||
for(i = 0; i < count; i++) {
|
||||
curLayer = getLayer(getComponent(i));
|
||||
if(curLayer == layer) {
|
||||
results[layerCount++] = getComponent(i);
|
||||
/// Short circut the counting when we have them all
|
||||
} else if(layerCount > 0 || curLayer < layer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints this JLayeredPane within the specified graphics context.
|
||||
*
|
||||
* @param g the Graphics context within which to paint
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
if(isOpaque()) {
|
||||
Rectangle r = g.getClipBounds();
|
||||
Color c = getBackground();
|
||||
if(c == null)
|
||||
c = Color.lightGray;
|
||||
g.setColor(c);
|
||||
if (r != null) {
|
||||
g.fillRect(r.x, r.y, r.width, r.height);
|
||||
}
|
||||
else {
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Implementation Details
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns the hashtable that maps components to layers.
|
||||
*
|
||||
* @return the Hashtable used to map components to their layers
|
||||
*/
|
||||
protected Hashtable<Component,Integer> getComponentToLayer() {
|
||||
if(componentToLayer == null)
|
||||
componentToLayer = new Hashtable<Component,Integer>(4);
|
||||
return componentToLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Integer object associated with a specified layer.
|
||||
*
|
||||
* @param layer an int specifying the layer
|
||||
* @return an Integer object for that layer
|
||||
*/
|
||||
protected Integer getObjectForLayer(int layer) {
|
||||
Integer layerObj;
|
||||
switch(layer) {
|
||||
case 0:
|
||||
layerObj = DEFAULT_LAYER;
|
||||
break;
|
||||
case 100:
|
||||
layerObj = PALETTE_LAYER;
|
||||
break;
|
||||
case 200:
|
||||
layerObj = MODAL_LAYER;
|
||||
break;
|
||||
case 300:
|
||||
layerObj = POPUP_LAYER;
|
||||
break;
|
||||
case 400:
|
||||
layerObj = DRAG_LAYER;
|
||||
break;
|
||||
default:
|
||||
layerObj = new Integer(layer);
|
||||
}
|
||||
return layerObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive method that determines the proper location to
|
||||
* insert a new child based on layer and position requests.
|
||||
*
|
||||
* @param layer an int specifying the layer
|
||||
* @param position an int specifying the position within the layer
|
||||
* @return an int giving the (absolute) insertion-index
|
||||
*
|
||||
* @see #getIndexOf
|
||||
*/
|
||||
protected int insertIndexForLayer(int layer, int position) {
|
||||
return insertIndexForLayer(null, layer, position);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is an extended version of insertIndexForLayer()
|
||||
* to support setLayer which uses Container.setZOrder which does
|
||||
* not remove the component from the containment hierarchy though
|
||||
* we need to ignore it when calculating the insertion index.
|
||||
*
|
||||
* @param comp component to ignore when determining index
|
||||
* @param layer an int specifying the layer
|
||||
* @param position an int specifying the position within the layer
|
||||
* @return an int giving the (absolute) insertion-index
|
||||
*
|
||||
* @see #getIndexOf
|
||||
*/
|
||||
private int insertIndexForLayer(Component comp, int layer, int position) {
|
||||
int i, count, curLayer;
|
||||
int layerStart = -1;
|
||||
int layerEnd = -1;
|
||||
int componentCount = getComponentCount();
|
||||
|
||||
ArrayList<Component> compList =
|
||||
new ArrayList<Component>(componentCount);
|
||||
for (int index = 0; index < componentCount; index++) {
|
||||
if (getComponent(index) != comp) {
|
||||
compList.add(getComponent(index));
|
||||
}
|
||||
}
|
||||
|
||||
count = compList.size();
|
||||
for (i = 0; i < count; i++) {
|
||||
curLayer = getLayer(compList.get(i));
|
||||
if (layerStart == -1 && curLayer == layer) {
|
||||
layerStart = i;
|
||||
}
|
||||
if (curLayer < layer) {
|
||||
if (i == 0) {
|
||||
// layer is greater than any current layer
|
||||
// [ ASSERT(layer > highestLayer()) ]
|
||||
layerStart = 0;
|
||||
layerEnd = 0;
|
||||
} else {
|
||||
layerEnd = i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// layer requested is lower than any current layer
|
||||
// [ ASSERT(layer < lowestLayer()) ]
|
||||
// put it on the bottom of the stack
|
||||
if (layerStart == -1 && layerEnd == -1)
|
||||
return count;
|
||||
|
||||
// In the case of a single layer entry handle the degenerative cases
|
||||
if (layerStart != -1 && layerEnd == -1)
|
||||
layerEnd = count;
|
||||
|
||||
if (layerEnd != -1 && layerStart == -1)
|
||||
layerStart = layerEnd;
|
||||
|
||||
// If we are adding to the bottom, return the last element
|
||||
if (position == -1)
|
||||
return layerEnd;
|
||||
|
||||
// Otherwise make sure the requested position falls in the
|
||||
// proper range
|
||||
if (position > -1 && layerStart + position <= layerEnd)
|
||||
return layerStart + position;
|
||||
|
||||
// Otherwise return the end of the layer
|
||||
return layerEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JLayeredPane. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JLayeredPane.
|
||||
*/
|
||||
protected String paramString() {
|
||||
String optimizedDrawingPossibleString = (optimizedDrawingPossible ?
|
||||
"true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",optimizedDrawingPossible=" + optimizedDrawingPossibleString;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JLayeredPane.
|
||||
* For layered panes, the AccessibleContext takes the form of an
|
||||
* AccessibleJLayeredPane.
|
||||
* A new AccessibleJLayeredPane instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJLayeredPane that serves as the
|
||||
* AccessibleContext of this JLayeredPane
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJLayeredPane();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JLayeredPane</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to layered pane user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJLayeredPane extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.LAYERED_PANE;
|
||||
}
|
||||
}
|
||||
}
|
||||
3795
jdkSrc/jdk8/javax/swing/JList.java
Normal file
3795
jdkSrc/jdk8/javax/swing/JList.java
Normal file
File diff suppressed because it is too large
Load Diff
1622
jdkSrc/jdk8/javax/swing/JMenu.java
Normal file
1622
jdkSrc/jdk8/javax/swing/JMenu.java
Normal file
File diff suppressed because it is too large
Load Diff
774
jdkSrc/jdk8/javax/swing/JMenuBar.java
Normal file
774
jdkSrc/jdk8/javax/swing/JMenuBar.java
Normal file
@@ -0,0 +1,774 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.*;
|
||||
import java.beans.Transient;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* An implementation of a menu bar. You add <code>JMenu</code> objects to the
|
||||
* menu bar to construct a menu. When the user selects a <code>JMenu</code>
|
||||
* object, its associated <code>JPopupMenu</code> is displayed, allowing the
|
||||
* user to select one of the <code>JMenuItems</code> on it.
|
||||
* <p>
|
||||
* For information and examples of using menu bars see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* By default, pressing the Tab key does not transfer focus from a <code>
|
||||
* JMenuBar</code> which is added to a container together with other Swing
|
||||
* components, because the <code>focusTraversalKeysEnabled</code> property
|
||||
* of <code>JMenuBar</code> is set to <code>false</code>. To resolve this,
|
||||
* you should call the <code>JMenuBar.setFocusTraversalKeysEnabled(true)</code>
|
||||
* method.
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* description: A container for holding and displaying menus.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @author Arnaud Weber
|
||||
* @see JMenu
|
||||
* @see JPopupMenu
|
||||
* @see JMenuItem
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JMenuBar extends JComponent implements Accessible,MenuElement
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "MenuBarUI";
|
||||
|
||||
/*
|
||||
* Model for the selected subcontrol.
|
||||
*/
|
||||
private transient SingleSelectionModel selectionModel;
|
||||
|
||||
private boolean paintBorder = true;
|
||||
private Insets margin = null;
|
||||
|
||||
/* diagnostic aids -- should be false for production builds. */
|
||||
private static final boolean TRACE = false; // trace creates and disposes
|
||||
private static final boolean VERBOSE = false; // show reuse hits/misses
|
||||
private static final boolean DEBUG = false; // show bad params, misc.
|
||||
|
||||
/**
|
||||
* Creates a new menu bar.
|
||||
*/
|
||||
public JMenuBar() {
|
||||
super();
|
||||
setFocusTraversalKeysEnabled(false);
|
||||
setSelectionModel(new DefaultSingleSelectionModel());
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menubar's current UI.
|
||||
* @see #setUI
|
||||
*/
|
||||
public MenuBarUI getUI() {
|
||||
return (MenuBarUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the L&F object that renders this component.
|
||||
*
|
||||
* @param ui the new MenuBarUI L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(MenuBarUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property with a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((MenuBarUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "MenuBarUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the model object that handles single selections.
|
||||
*
|
||||
* @return the <code>SingleSelectionModel</code> property
|
||||
* @see SingleSelectionModel
|
||||
*/
|
||||
public SingleSelectionModel getSelectionModel() {
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the model object to handle single selections.
|
||||
*
|
||||
* @param model the <code>SingleSelectionModel</code> to use
|
||||
* @see SingleSelectionModel
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* description: The selection model, recording which child is selected.
|
||||
*/
|
||||
public void setSelectionModel(SingleSelectionModel model) {
|
||||
SingleSelectionModel oldValue = selectionModel;
|
||||
this.selectionModel = model;
|
||||
firePropertyChange("selectionModel", oldValue, selectionModel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends the specified menu to the end of the menu bar.
|
||||
*
|
||||
* @param c the <code>JMenu</code> component to add
|
||||
* @return the menu component
|
||||
*/
|
||||
public JMenu add(JMenu c) {
|
||||
super.add(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menu at the specified position in the menu bar.
|
||||
*
|
||||
* @param index an integer giving the position in the menu bar, where
|
||||
* 0 is the first position
|
||||
* @return the <code>JMenu</code> at that position, or <code>null</code> if
|
||||
* if there is no <code>JMenu</code> at that position (ie. if
|
||||
* it is a <code>JMenuItem</code>)
|
||||
*/
|
||||
public JMenu getMenu(int index) {
|
||||
Component c = getComponentAtIndex(index);
|
||||
if (c instanceof JMenu)
|
||||
return (JMenu) c;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items in the menu bar.
|
||||
*
|
||||
* @return the number of items in the menu bar
|
||||
*/
|
||||
public int getMenuCount() {
|
||||
return getComponentCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the help menu that appears when the user selects the
|
||||
* "help" option in the menu bar. This method is not yet implemented
|
||||
* and will throw an exception.
|
||||
*
|
||||
* @param menu the JMenu that delivers help to the user
|
||||
*/
|
||||
public void setHelpMenu(JMenu menu) {
|
||||
throw new Error("setHelpMenu() not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the help menu for the menu bar. This method is not yet
|
||||
* implemented and will throw an exception.
|
||||
*
|
||||
* @return the <code>JMenu</code> that delivers help to the user
|
||||
*/
|
||||
@Transient
|
||||
public JMenu getHelpMenu() {
|
||||
throw new Error("getHelpMenu() not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
*
|
||||
* @param i an integer specifying the position, where 0 is first
|
||||
* @return the <code>Component</code> at the position,
|
||||
* or <code>null</code> for an invalid index
|
||||
* @deprecated replaced by <code>getComponent(int i)</code>
|
||||
*/
|
||||
@Deprecated
|
||||
public Component getComponentAtIndex(int i) {
|
||||
if(i < 0 || i >= getComponentCount()) {
|
||||
return null;
|
||||
}
|
||||
return getComponent(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the specified component.
|
||||
*
|
||||
* @param c the <code>Component</code> to find
|
||||
* @return an integer giving the component's position, where 0 is first;
|
||||
* or -1 if it can't be found
|
||||
*/
|
||||
public int getComponentIndex(Component c) {
|
||||
int ncomponents = this.getComponentCount();
|
||||
Component[] component = this.getComponents();
|
||||
for (int i = 0 ; i < ncomponents ; i++) {
|
||||
Component comp = component[i];
|
||||
if (comp == c)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently selected component, producing a
|
||||
* a change to the selection model.
|
||||
*
|
||||
* @param sel the <code>Component</code> to select
|
||||
*/
|
||||
public void setSelected(Component sel) {
|
||||
SingleSelectionModel model = getSelectionModel();
|
||||
int index = getComponentIndex(sel);
|
||||
model.setSelectedIndex(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the menu bar currently has a component selected.
|
||||
*
|
||||
* @return true if a selection has been made, else false
|
||||
*/
|
||||
public boolean isSelected() {
|
||||
return selectionModel.isSelected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the menu bars border should be painted.
|
||||
*
|
||||
* @return true if the border should be painted, else false
|
||||
*/
|
||||
public boolean isBorderPainted() {
|
||||
return paintBorder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the border should be painted.
|
||||
*
|
||||
* @param b if true and border property is not <code>null</code>,
|
||||
* the border is painted.
|
||||
* @see #isBorderPainted
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: Whether the border should be painted.
|
||||
*/
|
||||
public void setBorderPainted(boolean b) {
|
||||
boolean oldValue = paintBorder;
|
||||
paintBorder = b;
|
||||
firePropertyChange("borderPainted", oldValue, paintBorder);
|
||||
if (b != oldValue) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the menubar's border if <code>BorderPainted</code>
|
||||
* property is true.
|
||||
*
|
||||
* @param g the <code>Graphics</code> context to use for painting
|
||||
* @see JComponent#paint
|
||||
* @see JComponent#setBorder
|
||||
*/
|
||||
protected void paintBorder(Graphics g) {
|
||||
if (isBorderPainted()) {
|
||||
super.paintBorder(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the margin between the menubar's border and
|
||||
* its menus. Setting to <code>null</code> will cause the menubar to
|
||||
* use the default margins.
|
||||
*
|
||||
* @param m an Insets object containing the margin values
|
||||
* @see Insets
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The space between the menubar's border and its contents
|
||||
*/
|
||||
public void setMargin(Insets m) {
|
||||
Insets old = margin;
|
||||
this.margin = m;
|
||||
firePropertyChange("margin", old, m);
|
||||
if (old == null || !old.equals(m)) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the margin between the menubar's border and
|
||||
* its menus. If there is no previous margin, it will create
|
||||
* a default margin with zero size.
|
||||
*
|
||||
* @return an <code>Insets</code> object containing the margin values
|
||||
* @see Insets
|
||||
*/
|
||||
public Insets getMargin() {
|
||||
if(margin == null) {
|
||||
return new Insets(0,0,0,0);
|
||||
} else {
|
||||
return margin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implemented to be a <code>MenuElement</code> -- does nothing.
|
||||
*
|
||||
* @see #getSubElements
|
||||
*/
|
||||
public void processMouseEvent(MouseEvent event,MenuElement path[],MenuSelectionManager manager) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented to be a <code>MenuElement</code> -- does nothing.
|
||||
*
|
||||
* @see #getSubElements
|
||||
*/
|
||||
public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented to be a <code>MenuElement</code> -- does nothing.
|
||||
*
|
||||
* @see #getSubElements
|
||||
*/
|
||||
public void menuSelectionChanged(boolean isIncluded) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented to be a <code>MenuElement</code> -- returns the
|
||||
* menus in this menu bar.
|
||||
* This is the reason for implementing the <code>MenuElement</code>
|
||||
* interface -- so that the menu bar can be treated the same as
|
||||
* other menu elements.
|
||||
* @return an array of menu items in the menu bar.
|
||||
*/
|
||||
public MenuElement[] getSubElements() {
|
||||
MenuElement result[];
|
||||
Vector<MenuElement> tmp = new Vector<MenuElement>();
|
||||
int c = getComponentCount();
|
||||
int i;
|
||||
Component m;
|
||||
|
||||
for(i=0 ; i < c ; i++) {
|
||||
m = getComponent(i);
|
||||
if(m instanceof MenuElement)
|
||||
tmp.addElement((MenuElement) m);
|
||||
}
|
||||
|
||||
result = new MenuElement[tmp.size()];
|
||||
for(i=0,c=tmp.size() ; i < c ; i++)
|
||||
result[i] = tmp.elementAt(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented to be a <code>MenuElement</code>. Returns this object.
|
||||
*
|
||||
* @return the current <code>Component</code> (this)
|
||||
* @see #getSubElements
|
||||
*/
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JMenuBar</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JMenuBar</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String paintBorderString = (paintBorder ?
|
||||
"true" : "false");
|
||||
String marginString = (margin != null ?
|
||||
margin.toString() : "");
|
||||
|
||||
return super.paramString() +
|
||||
",margin=" + marginString +
|
||||
",paintBorder=" + paintBorderString;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JMenuBar.
|
||||
* For JMenuBars, the AccessibleContext takes the form of an
|
||||
* AccessibleJMenuBar.
|
||||
* A new AccessibleJMenuBar instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJMenuBar that serves as the
|
||||
* AccessibleContext of this JMenuBar
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJMenuBar();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JMenuBar</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to menu bar user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJMenuBar extends AccessibleJComponent
|
||||
implements AccessibleSelection {
|
||||
|
||||
/**
|
||||
* Get the accessible state set of this object.
|
||||
*
|
||||
* @return an instance of AccessibleState containing the current state
|
||||
* of the object
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
return states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.MENU_BAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AccessibleSelection associated with this object. In the
|
||||
* implementation of the Java Accessibility API for this class,
|
||||
* return this object, which is responsible for implementing the
|
||||
* AccessibleSelection interface on behalf of itself.
|
||||
*
|
||||
* @return this object
|
||||
*/
|
||||
public AccessibleSelection getAccessibleSelection() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1 if a menu is currently selected in this menu bar.
|
||||
*
|
||||
* @return 1 if a menu is currently selected, else 0
|
||||
*/
|
||||
public int getAccessibleSelectionCount() {
|
||||
if (isSelected()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently selected menu if one is selected,
|
||||
* otherwise null.
|
||||
*/
|
||||
public Accessible getAccessibleSelection(int i) {
|
||||
if (isSelected()) {
|
||||
if (i != 0) { // single selection model for JMenuBar
|
||||
return null;
|
||||
}
|
||||
int j = getSelectionModel().getSelectedIndex();
|
||||
if (getComponentAtIndex(j) instanceof Accessible) {
|
||||
return (Accessible) getComponentAtIndex(j);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current child of this object is selected.
|
||||
*
|
||||
* @param i the zero-based index of the child in this Accessible
|
||||
* object.
|
||||
* @see AccessibleContext#getAccessibleChild
|
||||
*/
|
||||
public boolean isAccessibleChildSelected(int i) {
|
||||
return (i == getSelectionModel().getSelectedIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the nth menu in the menu bar, forcing it to
|
||||
* pop up. If another menu is popped up, this will force
|
||||
* it to close. If the nth menu is already selected, this
|
||||
* method has no effect.
|
||||
*
|
||||
* @param i the zero-based index of selectable items
|
||||
* @see #getAccessibleStateSet
|
||||
*/
|
||||
public void addAccessibleSelection(int i) {
|
||||
// first close up any open menu
|
||||
int j = getSelectionModel().getSelectedIndex();
|
||||
if (i == j) {
|
||||
return;
|
||||
}
|
||||
if (j >= 0 && j < getMenuCount()) {
|
||||
JMenu menu = getMenu(j);
|
||||
if (menu != null) {
|
||||
MenuSelectionManager.defaultManager().setSelectedPath(null);
|
||||
// menu.setPopupMenuVisible(false);
|
||||
}
|
||||
}
|
||||
// now popup the new menu
|
||||
getSelectionModel().setSelectedIndex(i);
|
||||
JMenu menu = getMenu(i);
|
||||
if (menu != null) {
|
||||
MenuElement me[] = new MenuElement[3];
|
||||
me[0] = JMenuBar.this;
|
||||
me[1] = menu;
|
||||
me[2] = menu.getPopupMenu();
|
||||
MenuSelectionManager.defaultManager().setSelectedPath(me);
|
||||
// menu.setPopupMenuVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the nth selected item in the object from the object's
|
||||
* selection. If the nth item isn't currently selected, this
|
||||
* method has no effect. Otherwise, it closes the popup menu.
|
||||
*
|
||||
* @param i the zero-based index of selectable items
|
||||
*/
|
||||
public void removeAccessibleSelection(int i) {
|
||||
if (i >= 0 && i < getMenuCount()) {
|
||||
JMenu menu = getMenu(i);
|
||||
if (menu != null) {
|
||||
MenuSelectionManager.defaultManager().setSelectedPath(null);
|
||||
// menu.setPopupMenuVisible(false);
|
||||
}
|
||||
getSelectionModel().setSelectedIndex(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the selection in the object, so that nothing in the
|
||||
* object is selected. This will close any open menu.
|
||||
*/
|
||||
public void clearAccessibleSelection() {
|
||||
int i = getSelectionModel().getSelectedIndex();
|
||||
if (i >= 0 && i < getMenuCount()) {
|
||||
JMenu menu = getMenu(i);
|
||||
if (menu != null) {
|
||||
MenuSelectionManager.defaultManager().setSelectedPath(null);
|
||||
// menu.setPopupMenuVisible(false);
|
||||
}
|
||||
}
|
||||
getSelectionModel().setSelectedIndex(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally causes every selected item in the object to be selected
|
||||
* if the object supports multiple selections. This method
|
||||
* makes no sense in a menu bar, and so does nothing.
|
||||
*/
|
||||
public void selectAllAccessibleSelection() {
|
||||
}
|
||||
} // internal class AccessibleJMenuBar
|
||||
|
||||
|
||||
/**
|
||||
* Subclassed to check all the child menus.
|
||||
* @since 1.3
|
||||
*/
|
||||
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
|
||||
int condition, boolean pressed) {
|
||||
// See if we have a local binding.
|
||||
boolean retValue = super.processKeyBinding(ks, e, condition, pressed);
|
||||
if (!retValue) {
|
||||
MenuElement[] subElements = getSubElements();
|
||||
for (MenuElement subElement : subElements) {
|
||||
if (processBindingForKeyStrokeRecursive(
|
||||
subElement, ks, e, condition, pressed)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
static boolean processBindingForKeyStrokeRecursive(MenuElement elem,
|
||||
KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
|
||||
if (elem == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Component c = elem.getComponent();
|
||||
|
||||
if ( !(c.isVisible() || (c instanceof JPopupMenu)) || !c.isEnabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c != null && c instanceof JComponent &&
|
||||
((JComponent)c).processKeyBinding(ks, e, condition, pressed)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MenuElement[] subElements = elem.getSubElements();
|
||||
for (MenuElement subElement : subElements) {
|
||||
if (processBindingForKeyStrokeRecursive(subElement, ks, e, condition, pressed)) {
|
||||
return true;
|
||||
// We don't, pass along to children JMenu's
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides <code>JComponent.addNotify</code> to register this
|
||||
* menu bar with the current keyboard manager.
|
||||
*/
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
KeyboardManager.getCurrentManager().registerMenuBar(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides <code>JComponent.removeNotify</code> to unregister this
|
||||
* menu bar with the current keyboard manager.
|
||||
*/
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
KeyboardManager.getCurrentManager().unregisterMenuBar(this);
|
||||
}
|
||||
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
|
||||
Object[] kvData = new Object[4];
|
||||
int n = 0;
|
||||
|
||||
if (selectionModel instanceof Serializable) {
|
||||
kvData[n++] = "selectionModel";
|
||||
kvData[n++] = selectionModel;
|
||||
}
|
||||
|
||||
s.writeObject(kvData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See JComponent.readObject() for information about serialization
|
||||
* in Swing.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
Object[] kvData = (Object[])(s.readObject());
|
||||
|
||||
for(int i = 0; i < kvData.length; i += 2) {
|
||||
if (kvData[i] == null) {
|
||||
break;
|
||||
}
|
||||
else if (kvData[i].equals("selectionModel")) {
|
||||
selectionModel = (SingleSelectionModel)kvData[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
949
jdkSrc/jdk8/javax/swing/JMenuItem.java
Normal file
949
jdkSrc/jdk8/javax/swing/JMenuItem.java
Normal file
@@ -0,0 +1,949 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* An implementation of an item in a menu. A menu item is essentially a button
|
||||
* sitting in a list. When the user selects the "button", the action
|
||||
* associated with the menu item is performed. A <code>JMenuItem</code>
|
||||
* contained in a <code>JPopupMenu</code> performs exactly that function.
|
||||
* <p>
|
||||
* Menu items can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a menu item has many benefits beyond directly
|
||||
* configuring a menu item. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* For further documentation and for examples, see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>
|
||||
* in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: An item which can be selected in a menu.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @see JPopupMenu
|
||||
* @see JMenu
|
||||
* @see JCheckBoxMenuItem
|
||||
* @see JRadioButtonMenuItem
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JMenuItem extends AbstractButton implements Accessible,MenuElement {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "MenuItemUI";
|
||||
|
||||
/* diagnostic aids -- should be false for production builds. */
|
||||
private static final boolean TRACE = false; // trace creates and disposes
|
||||
private static final boolean VERBOSE = false; // show reuse hits/misses
|
||||
private static final boolean DEBUG = false; // show bad params, misc.
|
||||
|
||||
private boolean isMouseDragged = false;
|
||||
|
||||
/**
|
||||
* Creates a <code>JMenuItem</code> with no set text or icon.
|
||||
*/
|
||||
public JMenuItem() {
|
||||
this(null, (Icon)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JMenuItem</code> with the specified icon.
|
||||
*
|
||||
* @param icon the icon of the <code>JMenuItem</code>
|
||||
*/
|
||||
public JMenuItem(Icon icon) {
|
||||
this(null, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JMenuItem</code> with the specified text.
|
||||
*
|
||||
* @param text the text of the <code>JMenuItem</code>
|
||||
*/
|
||||
public JMenuItem(String text) {
|
||||
this(text, (Icon)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a menu item whose properties are taken from the
|
||||
* specified <code>Action</code>.
|
||||
*
|
||||
* @param a the action of the <code>JMenuItem</code>
|
||||
* @since 1.3
|
||||
*/
|
||||
public JMenuItem(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JMenuItem</code> with the specified text and icon.
|
||||
*
|
||||
* @param text the text of the <code>JMenuItem</code>
|
||||
* @param icon the icon of the <code>JMenuItem</code>
|
||||
*/
|
||||
public JMenuItem(String text, Icon icon) {
|
||||
setModel(new DefaultButtonModel());
|
||||
init(text, icon);
|
||||
initFocusability();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JMenuItem</code> with the specified text and
|
||||
* keyboard mnemonic.
|
||||
*
|
||||
* @param text the text of the <code>JMenuItem</code>
|
||||
* @param mnemonic the keyboard mnemonic for the <code>JMenuItem</code>
|
||||
*/
|
||||
public JMenuItem(String text, int mnemonic) {
|
||||
setModel(new DefaultButtonModel());
|
||||
init(text, null);
|
||||
setMnemonic(mnemonic);
|
||||
initFocusability();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setModel(ButtonModel newModel) {
|
||||
super.setModel(newModel);
|
||||
if(newModel instanceof DefaultButtonModel) {
|
||||
((DefaultButtonModel)newModel).setMenuItem(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inititalizes the focusability of the the <code>JMenuItem</code>.
|
||||
* <code>JMenuItem</code>'s are focusable, but subclasses may
|
||||
* want to be, this provides them the opportunity to override this
|
||||
* and invoke something else, or nothing at all. Refer to
|
||||
* {@link javax.swing.JMenu#initFocusability} for the motivation of
|
||||
* this.
|
||||
*/
|
||||
void initFocusability() {
|
||||
setFocusable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the menu item with the specified text and icon.
|
||||
*
|
||||
* @param text the text of the <code>JMenuItem</code>
|
||||
* @param icon the icon of the <code>JMenuItem</code>
|
||||
*/
|
||||
protected void init(String text, Icon icon) {
|
||||
if(text != null) {
|
||||
setText(text);
|
||||
}
|
||||
|
||||
if(icon != null) {
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
// Listen for Focus events
|
||||
addFocusListener(new MenuItemFocusListener());
|
||||
setUIProperty("borderPainted", Boolean.FALSE);
|
||||
setFocusPainted(false);
|
||||
setHorizontalTextPosition(JButton.TRAILING);
|
||||
setHorizontalAlignment(JButton.LEADING);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
private static class MenuItemFocusListener implements FocusListener,
|
||||
Serializable {
|
||||
public void focusGained(FocusEvent event) {}
|
||||
public void focusLost(FocusEvent event) {
|
||||
// When focus is lost, repaint if
|
||||
// the focus information is painted
|
||||
JMenuItem mi = (JMenuItem)event.getSource();
|
||||
if(mi.isFocusPainted()) {
|
||||
mi.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the look and feel object that renders this component.
|
||||
*
|
||||
* @param ui the <code>JMenuItemUI</code> L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(MenuItemUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property with a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((MenuItemUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the suffix used to construct the name of the L&F class used to
|
||||
* render this component.
|
||||
*
|
||||
* @return the string "MenuItemUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Identifies the menu item as "armed". If the mouse button is
|
||||
* released while it is over this item, the menu's action event
|
||||
* will fire. If the mouse button is released elsewhere, the
|
||||
* event will not fire and the menu item will be disarmed.
|
||||
*
|
||||
* @param b true to arm the menu item so it can be selected
|
||||
* @beaninfo
|
||||
* description: Mouse release will fire an action event
|
||||
* hidden: true
|
||||
*/
|
||||
public void setArmed(boolean b) {
|
||||
ButtonModel model = getModel();
|
||||
|
||||
boolean oldValue = model.isArmed();
|
||||
if(model.isArmed() != b) {
|
||||
model.setArmed(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the menu item is "armed".
|
||||
*
|
||||
* @return true if the menu item is armed, and it can be selected
|
||||
* @see #setArmed
|
||||
*/
|
||||
public boolean isArmed() {
|
||||
ButtonModel model = getModel();
|
||||
return model.isArmed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the menu item.
|
||||
*
|
||||
* @param b true to enable the item
|
||||
* @beaninfo
|
||||
* description: Does the component react to user interaction
|
||||
* bound: true
|
||||
* preferred: true
|
||||
*/
|
||||
public void setEnabled(boolean b) {
|
||||
// Make sure we aren't armed!
|
||||
if (!b && !UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
|
||||
setArmed(false);
|
||||
}
|
||||
super.setEnabled(b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true since <code>Menu</code>s, by definition,
|
||||
* should always be on top of all other windows. If the menu is
|
||||
* in an internal frame false is returned due to the rollover effect
|
||||
* for windows laf where the menu is not always on top.
|
||||
*/
|
||||
// package private
|
||||
boolean alwaysOnTop() {
|
||||
// Fix for bug #4482165
|
||||
if (SwingUtilities.getAncestorOfClass(JInternalFrame.class, this) !=
|
||||
null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* The keystroke which acts as the menu item's accelerator
|
||||
*/
|
||||
private KeyStroke accelerator;
|
||||
|
||||
/**
|
||||
* Sets the key combination which invokes the menu item's
|
||||
* action listeners without navigating the menu hierarchy. It is the
|
||||
* UI's responsibility to install the correct action. Note that
|
||||
* when the keyboard accelerator is typed, it will work whether or
|
||||
* not the menu is currently displayed.
|
||||
*
|
||||
* @param keyStroke the <code>KeyStroke</code> which will
|
||||
* serve as an accelerator
|
||||
* @beaninfo
|
||||
* description: The keystroke combination which will invoke the
|
||||
* JMenuItem's actionlisteners without navigating the
|
||||
* menu hierarchy
|
||||
* bound: true
|
||||
* preferred: true
|
||||
*/
|
||||
public void setAccelerator(KeyStroke keyStroke) {
|
||||
KeyStroke oldAccelerator = accelerator;
|
||||
this.accelerator = keyStroke;
|
||||
repaint();
|
||||
revalidate();
|
||||
firePropertyChange("accelerator", oldAccelerator, accelerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>KeyStroke</code> which serves as an accelerator
|
||||
* for the menu item.
|
||||
* @return a <code>KeyStroke</code> object identifying the
|
||||
* accelerator key
|
||||
*/
|
||||
public KeyStroke getAccelerator() {
|
||||
return this.accelerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
protected void configurePropertiesFromAction(Action a) {
|
||||
super.configurePropertiesFromAction(a);
|
||||
configureAcceleratorFromAction(a);
|
||||
}
|
||||
|
||||
void setIconFromAction(Action a) {
|
||||
Icon icon = null;
|
||||
if (a != null) {
|
||||
icon = (Icon)a.getValue(Action.SMALL_ICON);
|
||||
}
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
void largeIconChanged(Action a) {
|
||||
}
|
||||
|
||||
void smallIconChanged(Action a) {
|
||||
setIconFromAction(a);
|
||||
}
|
||||
|
||||
void configureAcceleratorFromAction(Action a) {
|
||||
KeyStroke ks = (a==null) ? null :
|
||||
(KeyStroke)a.getValue(Action.ACCELERATOR_KEY);
|
||||
setAccelerator(ks);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
protected void actionPropertyChanged(Action action, String propertyName) {
|
||||
if (propertyName == Action.ACCELERATOR_KEY) {
|
||||
configureAcceleratorFromAction(action);
|
||||
}
|
||||
else {
|
||||
super.actionPropertyChanged(action, propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a mouse event forwarded from the
|
||||
* <code>MenuSelectionManager</code> and changes the menu
|
||||
* selection, if necessary, by using the
|
||||
* <code>MenuSelectionManager</code>'s API.
|
||||
* <p>
|
||||
* Note: you do not have to forward the event to sub-components.
|
||||
* This is done automatically by the <code>MenuSelectionManager</code>.
|
||||
*
|
||||
* @param e a <code>MouseEvent</code>
|
||||
* @param path the <code>MenuElement</code> path array
|
||||
* @param manager the <code>MenuSelectionManager</code>
|
||||
*/
|
||||
public void processMouseEvent(MouseEvent e,MenuElement path[],MenuSelectionManager manager) {
|
||||
processMenuDragMouseEvent(
|
||||
new MenuDragMouseEvent(e.getComponent(), e.getID(),
|
||||
e.getWhen(),
|
||||
e.getModifiers(), e.getX(), e.getY(),
|
||||
e.getXOnScreen(), e.getYOnScreen(),
|
||||
e.getClickCount(), e.isPopupTrigger(),
|
||||
path, manager));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes a key event forwarded from the
|
||||
* <code>MenuSelectionManager</code> and changes the menu selection,
|
||||
* if necessary, by using <code>MenuSelectionManager</code>'s API.
|
||||
* <p>
|
||||
* Note: you do not have to forward the event to sub-components.
|
||||
* This is done automatically by the <code>MenuSelectionManager</code>.
|
||||
*
|
||||
* @param e a <code>KeyEvent</code>
|
||||
* @param path the <code>MenuElement</code> path array
|
||||
* @param manager the <code>MenuSelectionManager</code>
|
||||
*/
|
||||
public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
|
||||
if (DEBUG) {
|
||||
System.out.println("in JMenuItem.processKeyEvent/3 for " + getText() +
|
||||
" " + KeyStroke.getKeyStrokeForEvent(e));
|
||||
}
|
||||
MenuKeyEvent mke = new MenuKeyEvent(e.getComponent(), e.getID(),
|
||||
e.getWhen(), e.getModifiers(),
|
||||
e.getKeyCode(), e.getKeyChar(),
|
||||
path, manager);
|
||||
processMenuKeyEvent(mke);
|
||||
|
||||
if (mke.isConsumed()) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handles mouse drag in a menu.
|
||||
*
|
||||
* @param e a <code>MenuDragMouseEvent</code> object
|
||||
*/
|
||||
public void processMenuDragMouseEvent(MenuDragMouseEvent e) {
|
||||
switch (e.getID()) {
|
||||
case MouseEvent.MOUSE_ENTERED:
|
||||
isMouseDragged = false; fireMenuDragMouseEntered(e); break;
|
||||
case MouseEvent.MOUSE_EXITED:
|
||||
isMouseDragged = false; fireMenuDragMouseExited(e); break;
|
||||
case MouseEvent.MOUSE_DRAGGED:
|
||||
isMouseDragged = true; fireMenuDragMouseDragged(e); break;
|
||||
case MouseEvent.MOUSE_RELEASED:
|
||||
if(isMouseDragged) fireMenuDragMouseReleased(e); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a keystroke in a menu.
|
||||
*
|
||||
* @param e a <code>MenuKeyEvent</code> object
|
||||
*/
|
||||
public void processMenuKeyEvent(MenuKeyEvent e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("in JMenuItem.processMenuKeyEvent for " + getText()+
|
||||
" " + KeyStroke.getKeyStrokeForEvent(e));
|
||||
}
|
||||
switch (e.getID()) {
|
||||
case KeyEvent.KEY_PRESSED:
|
||||
fireMenuKeyPressed(e); break;
|
||||
case KeyEvent.KEY_RELEASED:
|
||||
fireMenuKeyReleased(e); break;
|
||||
case KeyEvent.KEY_TYPED:
|
||||
fireMenuKeyTyped(e); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuMouseDragEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuDragMouseEntered(MenuDragMouseEvent event) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuDragMouseListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuDragMouseListener)listeners[i+1]).menuDragMouseEntered(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuDragMouseEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuDragMouseExited(MenuDragMouseEvent event) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuDragMouseListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuDragMouseListener)listeners[i+1]).menuDragMouseExited(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuDragMouseEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuDragMouseDragged(MenuDragMouseEvent event) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuDragMouseListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuDragMouseListener)listeners[i+1]).menuDragMouseDragged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuDragMouseEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuDragMouseReleased(MenuDragMouseEvent event) {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuDragMouseListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuDragMouseListener)listeners[i+1]).menuDragMouseReleased(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuKeyEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuKeyPressed(MenuKeyEvent event) {
|
||||
if (DEBUG) {
|
||||
System.out.println("in JMenuItem.fireMenuKeyPressed for " + getText()+
|
||||
" " + KeyStroke.getKeyStrokeForEvent(event));
|
||||
}
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuKeyListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuKeyListener)listeners[i+1]).menuKeyPressed(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuKeyEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuKeyReleased(MenuKeyEvent event) {
|
||||
if (DEBUG) {
|
||||
System.out.println("in JMenuItem.fireMenuKeyReleased for " + getText()+
|
||||
" " + KeyStroke.getKeyStrokeForEvent(event));
|
||||
}
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuKeyListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuKeyListener)listeners[i+1]).menuKeyReleased(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type.
|
||||
*
|
||||
* @param event a <code>MenuKeyEvent</code>
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireMenuKeyTyped(MenuKeyEvent event) {
|
||||
if (DEBUG) {
|
||||
System.out.println("in JMenuItem.fireMenuKeyTyped for " + getText()+
|
||||
" " + KeyStroke.getKeyStrokeForEvent(event));
|
||||
}
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==MenuKeyListener.class) {
|
||||
// Lazily create the event:
|
||||
((MenuKeyListener)listeners[i+1]).menuKeyTyped(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the <code>MenuSelectionManager</code> when the
|
||||
* <code>MenuElement</code> is selected or unselected.
|
||||
*
|
||||
* @param isIncluded true if this menu item is on the part of the menu
|
||||
* path that changed, false if this menu is part of the
|
||||
* a menu path that changed, but this particular part of
|
||||
* that path is still the same
|
||||
* @see MenuSelectionManager#setSelectedPath(MenuElement[])
|
||||
*/
|
||||
public void menuSelectionChanged(boolean isIncluded) {
|
||||
setArmed(isIncluded);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an array containing the sub-menu
|
||||
* components for this menu component.
|
||||
*
|
||||
* @return an array of <code>MenuElement</code>s
|
||||
*/
|
||||
public MenuElement[] getSubElements() {
|
||||
return new MenuElement[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>java.awt.Component</code> used to paint
|
||||
* this object. The returned component will be used to convert
|
||||
* events and detect if an event is inside a menu component.
|
||||
*
|
||||
* @return the <code>Component</code> that paints this menu item
|
||||
*/
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>MenuDragMouseListener</code> to the menu item.
|
||||
*
|
||||
* @param l the <code>MenuDragMouseListener</code> to be added
|
||||
*/
|
||||
public void addMenuDragMouseListener(MenuDragMouseListener l) {
|
||||
listenerList.add(MenuDragMouseListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a <code>MenuDragMouseListener</code> from the menu item.
|
||||
*
|
||||
* @param l the <code>MenuDragMouseListener</code> to be removed
|
||||
*/
|
||||
public void removeMenuDragMouseListener(MenuDragMouseListener l) {
|
||||
listenerList.remove(MenuDragMouseListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>MenuDragMouseListener</code>s added
|
||||
* to this JMenuItem with addMenuDragMouseListener().
|
||||
*
|
||||
* @return all of the <code>MenuDragMouseListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public MenuDragMouseListener[] getMenuDragMouseListeners() {
|
||||
return listenerList.getListeners(MenuDragMouseListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>MenuKeyListener</code> to the menu item.
|
||||
*
|
||||
* @param l the <code>MenuKeyListener</code> to be added
|
||||
*/
|
||||
public void addMenuKeyListener(MenuKeyListener l) {
|
||||
listenerList.add(MenuKeyListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a <code>MenuKeyListener</code> from the menu item.
|
||||
*
|
||||
* @param l the <code>MenuKeyListener</code> to be removed
|
||||
*/
|
||||
public void removeMenuKeyListener(MenuKeyListener l) {
|
||||
listenerList.remove(MenuKeyListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>MenuKeyListener</code>s added
|
||||
* to this JMenuItem with addMenuKeyListener().
|
||||
*
|
||||
* @return all of the <code>MenuKeyListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public MenuKeyListener[] getMenuKeyListeners() {
|
||||
return listenerList.getListeners(MenuKeyListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* See JComponent.readObject() for information about serialization
|
||||
* in Swing.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JMenuItem</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JMenuItem</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Returns the <code>AccessibleContext</code> associated with this
|
||||
* <code>JMenuItem</code>. For <code>JMenuItem</code>s,
|
||||
* the <code>AccessibleContext</code> takes the form of an
|
||||
* <code>AccessibleJMenuItem</code>.
|
||||
* A new AccessibleJMenuItme instance is created if necessary.
|
||||
*
|
||||
* @return an <code>AccessibleJMenuItem</code> that serves as the
|
||||
* <code>AccessibleContext</code> of this <code>JMenuItem</code>
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJMenuItem();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JMenuItem</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to menu item user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJMenuItem extends AccessibleAbstractButton implements ChangeListener {
|
||||
|
||||
private boolean isArmed = false;
|
||||
private boolean hasFocus = false;
|
||||
private boolean isPressed = false;
|
||||
private boolean isSelected = false;
|
||||
|
||||
AccessibleJMenuItem() {
|
||||
super();
|
||||
JMenuItem.this.addChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.MENU_ITEM;
|
||||
}
|
||||
|
||||
private void fireAccessibilityFocusedEvent(JMenuItem toCheck) {
|
||||
MenuElement [] path =
|
||||
MenuSelectionManager.defaultManager().getSelectedPath();
|
||||
if (path.length > 0) {
|
||||
Object menuItem = path[path.length - 1];
|
||||
if (toCheck == menuItem) {
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.FOCUSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports the change listener interface and fires property changes.
|
||||
*/
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
|
||||
Boolean.valueOf(false), Boolean.valueOf(true));
|
||||
if (JMenuItem.this.getModel().isArmed()) {
|
||||
if (!isArmed) {
|
||||
isArmed = true;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.ARMED);
|
||||
// Fix for 4848220 moved here to avoid major memory leak
|
||||
// Here we will fire the event in case of JMenuItem
|
||||
// See bug 4910323 for details [zav]
|
||||
fireAccessibilityFocusedEvent(JMenuItem.this);
|
||||
}
|
||||
} else {
|
||||
if (isArmed) {
|
||||
isArmed = false;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
AccessibleState.ARMED, null);
|
||||
}
|
||||
}
|
||||
if (JMenuItem.this.isFocusOwner()) {
|
||||
if (!hasFocus) {
|
||||
hasFocus = true;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.FOCUSED);
|
||||
}
|
||||
} else {
|
||||
if (hasFocus) {
|
||||
hasFocus = false;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
AccessibleState.FOCUSED, null);
|
||||
}
|
||||
}
|
||||
if (JMenuItem.this.getModel().isPressed()) {
|
||||
if (!isPressed) {
|
||||
isPressed = true;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.PRESSED);
|
||||
}
|
||||
} else {
|
||||
if (isPressed) {
|
||||
isPressed = false;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
AccessibleState.PRESSED, null);
|
||||
}
|
||||
}
|
||||
if (JMenuItem.this.getModel().isSelected()) {
|
||||
if (!isSelected) {
|
||||
isSelected = true;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.CHECKED);
|
||||
|
||||
// Fix for 4848220 moved here to avoid major memory leak
|
||||
// Here we will fire the event in case of JMenu
|
||||
// See bug 4910323 for details [zav]
|
||||
fireAccessibilityFocusedEvent(JMenuItem.this);
|
||||
}
|
||||
} else {
|
||||
if (isSelected) {
|
||||
isSelected = false;
|
||||
firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
AccessibleState.CHECKED, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // inner class AccessibleJMenuItem
|
||||
|
||||
|
||||
}
|
||||
2600
jdkSrc/jdk8/javax/swing/JOptionPane.java
Normal file
2600
jdkSrc/jdk8/javax/swing/JOptionPane.java
Normal file
File diff suppressed because it is too large
Load Diff
248
jdkSrc/jdk8/javax/swing/JPanel.java
Normal file
248
jdkSrc/jdk8/javax/swing/JPanel.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* <code>JPanel</code> is a generic lightweight container.
|
||||
* For examples and task-oriented documentation for JPanel, see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/panel.html">How to Use Panels</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* description: A generic lightweight container.
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
* @author Steve Wilson
|
||||
*/
|
||||
public class JPanel extends JComponent implements Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "PanelUI";
|
||||
|
||||
/**
|
||||
* Creates a new JPanel with the specified layout manager and buffering
|
||||
* strategy.
|
||||
*
|
||||
* @param layout the LayoutManager to use
|
||||
* @param isDoubleBuffered a boolean, true for double-buffering, which
|
||||
* uses additional memory space to achieve fast, flicker-free
|
||||
* updates
|
||||
*/
|
||||
public JPanel(LayoutManager layout, boolean isDoubleBuffered) {
|
||||
setLayout(layout);
|
||||
setDoubleBuffered(isDoubleBuffered);
|
||||
setUIProperty("opaque", Boolean.TRUE);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new buffered JPanel with the specified layout manager
|
||||
*
|
||||
* @param layout the LayoutManager to use
|
||||
*/
|
||||
public JPanel(LayoutManager layout) {
|
||||
this(layout, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>JPanel</code> with <code>FlowLayout</code>
|
||||
* and the specified buffering strategy.
|
||||
* If <code>isDoubleBuffered</code> is true, the <code>JPanel</code>
|
||||
* will use a double buffer.
|
||||
*
|
||||
* @param isDoubleBuffered a boolean, true for double-buffering, which
|
||||
* uses additional memory space to achieve fast, flicker-free
|
||||
* updates
|
||||
*/
|
||||
public JPanel(boolean isDoubleBuffered) {
|
||||
this(new FlowLayout(), isDoubleBuffered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>JPanel</code> with a double buffer
|
||||
* and a flow layout.
|
||||
*/
|
||||
public JPanel() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property with a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((PanelUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the look and feel (L&amp;F) object that renders this component.
|
||||
*
|
||||
* @return the PanelUI object that renders this component
|
||||
* @since 1.4
|
||||
*/
|
||||
public PanelUI getUI() {
|
||||
return (PanelUI)ui;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the look and feel (L&F) object that renders this component.
|
||||
*
|
||||
* @param ui the PanelUI L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @since 1.4
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(PanelUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that specifies the name of the L&F class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return "PanelUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: A string that specifies the name of the L&F class.
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JPanel. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JPanel.
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JPanel.
|
||||
* For JPanels, the AccessibleContext takes the form of an
|
||||
* AccessibleJPanel.
|
||||
* A new AccessibleJPanel instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJPanel that serves as the
|
||||
* AccessibleContext of this JPanel
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJPanel();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JPanel</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to panel user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJPanel extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.PANEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
665
jdkSrc/jdk8/javax/swing/JPasswordField.java
Normal file
665
jdkSrc/jdk8/javax/swing/JPasswordField.java
Normal file
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* <code>JPasswordField</code> is a lightweight component that allows
|
||||
* the editing of a single line of text where the view indicates
|
||||
* something was typed, but does not show the original characters.
|
||||
* You can find further information and examples in
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <code>JPasswordField</code> is intended
|
||||
* to be source-compatible with <code>java.awt.TextField</code>
|
||||
* used with <code>echoChar</code> set. It is provided separately
|
||||
* to make it easier to safely change the UI for the
|
||||
* <code>JTextField</code> without affecting password entries.
|
||||
* <p>
|
||||
* <strong>NOTE:</strong>
|
||||
* By default, JPasswordField disables input methods; otherwise, input
|
||||
* characters could be visible while they were composed using input methods.
|
||||
* If an application needs the input methods support, please use the
|
||||
* inherited method, <code>enableInputMethods(true)</code>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: Allows the editing of a line of text but doesn't show the characters.
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
*/
|
||||
public class JPasswordField extends JTextField {
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JPasswordField</code>,
|
||||
* with a default document, <code>null</code> starting
|
||||
* text string, and 0 column width.
|
||||
*/
|
||||
public JPasswordField() {
|
||||
this(null,null,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JPasswordField</code> initialized
|
||||
* with the specified text. The document model is set to the
|
||||
* default, and the number of columns to 0.
|
||||
*
|
||||
* @param text the text to be displayed, <code>null</code> if none
|
||||
*/
|
||||
public JPasswordField(String text) {
|
||||
this(null, text, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new empty <code>JPasswordField</code> with the specified
|
||||
* number of columns. A default model is created, and the initial string
|
||||
* is set to <code>null</code>.
|
||||
*
|
||||
* @param columns the number of columns >= 0
|
||||
*/
|
||||
public JPasswordField(int columns) {
|
||||
this(null, null, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JPasswordField</code> initialized with
|
||||
* the specified text and columns. The document model is set to
|
||||
* the default.
|
||||
*
|
||||
* @param text the text to be displayed, <code>null</code> if none
|
||||
* @param columns the number of columns >= 0
|
||||
*/
|
||||
public JPasswordField(String text, int columns) {
|
||||
this(null, text, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JPasswordField</code> that uses the
|
||||
* given text storage model and the given number of columns.
|
||||
* This is the constructor through which the other constructors feed.
|
||||
* The echo character is set to '*', but may be changed by the current
|
||||
* Look and Feel. If the document model is
|
||||
* <code>null</code>, a default one will be created.
|
||||
*
|
||||
* @param doc the text storage to use
|
||||
* @param txt the text to be displayed, <code>null</code> if none
|
||||
* @param columns the number of columns to use to calculate
|
||||
* the preferred width >= 0; if columns is set to zero, the
|
||||
* preferred width will be whatever naturally results from
|
||||
* the component implementation
|
||||
*/
|
||||
public JPasswordField(Document doc, String txt, int columns) {
|
||||
super(doc, txt, columns);
|
||||
// We could either leave this on, which wouldn't be secure,
|
||||
// or obscure the composted text, which essentially makes displaying
|
||||
// it useless. Therefore, we turn off input methods.
|
||||
enableInputMethods(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "PasswordFieldUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.6
|
||||
*/
|
||||
public void updateUI() {
|
||||
if(!echoCharSet) {
|
||||
echoChar = '*';
|
||||
}
|
||||
super.updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character to be used for echoing. The default is '*'.
|
||||
* The default may be different depending on the currently running Look
|
||||
* and Feel. For example, Metal/Ocean's default is a bullet character.
|
||||
*
|
||||
* @return the echo character, 0 if unset
|
||||
* @see #setEchoChar
|
||||
* @see #echoCharIsSet
|
||||
*/
|
||||
public char getEchoChar() {
|
||||
return echoChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the echo character for this <code>JPasswordField</code>.
|
||||
* Note that this is largely a suggestion, since the
|
||||
* view that gets installed can use whatever graphic techniques
|
||||
* it desires to represent the field. Setting a value of 0 indicates
|
||||
* that you wish to see the text as it is typed, similar to
|
||||
* the behavior of a standard <code>JTextField</code>.
|
||||
*
|
||||
* @param c the echo character to display
|
||||
* @see #echoCharIsSet
|
||||
* @see #getEchoChar
|
||||
* @beaninfo
|
||||
* description: character to display in place of the real characters
|
||||
* attribute: visualUpdate true
|
||||
*/
|
||||
public void setEchoChar(char c) {
|
||||
echoChar = c;
|
||||
echoCharSet = true;
|
||||
repaint();
|
||||
revalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this <code>JPasswordField</code> has a character
|
||||
* set for echoing. A character is considered to be set if the echo
|
||||
* character is not 0.
|
||||
*
|
||||
* @return true if a character is set for echoing
|
||||
* @see #setEchoChar
|
||||
* @see #getEchoChar
|
||||
*/
|
||||
public boolean echoCharIsSet() {
|
||||
return echoChar != 0;
|
||||
}
|
||||
|
||||
// --- JTextComponent methods ----------------------------------
|
||||
|
||||
/**
|
||||
* Invokes <code>provideErrorFeedback</code> on the current
|
||||
* look and feel, which typically initiates an error beep.
|
||||
* The normal behavior of transferring the
|
||||
* currently selected range in the associated text model
|
||||
* to the system clipboard, and removing the contents from
|
||||
* the model, is not acceptable for a password field.
|
||||
*/
|
||||
public void cut() {
|
||||
if (getClientProperty("JPasswordField.cutCopyAllowed") != Boolean.TRUE) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback(this);
|
||||
} else {
|
||||
super.cut();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes <code>provideErrorFeedback</code> on the current
|
||||
* look and feel, which typically initiates an error beep.
|
||||
* The normal behavior of transferring the
|
||||
* currently selected range in the associated text model
|
||||
* to the system clipboard, and leaving the contents from
|
||||
* the model, is not acceptable for a password field.
|
||||
*/
|
||||
public void copy() {
|
||||
if (getClientProperty("JPasswordField.cutCopyAllowed") != Boolean.TRUE) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback(this);
|
||||
} else {
|
||||
super.copy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text contained in this <code>TextComponent</code>.
|
||||
* If the underlying document is <code>null</code>, will give a
|
||||
* <code>NullPointerException</code>.
|
||||
* <p>
|
||||
* For security reasons, this method is deprecated. Use the
|
||||
<code>* getPassword</code> method instead.
|
||||
* @deprecated As of Java 2 platform v1.2,
|
||||
* replaced by <code>getPassword</code>.
|
||||
* @return the text
|
||||
*/
|
||||
@Deprecated
|
||||
public String getText() {
|
||||
return super.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a portion of the text represented by the
|
||||
* component. Returns an empty string if length is 0.
|
||||
* <p>
|
||||
* For security reasons, this method is deprecated. Use the
|
||||
* <code>getPassword</code> method instead.
|
||||
* @deprecated As of Java 2 platform v1.2,
|
||||
* replaced by <code>getPassword</code>.
|
||||
* @param offs the offset >= 0
|
||||
* @param len the length >= 0
|
||||
* @return the text
|
||||
* @exception BadLocationException if the offset or length are invalid
|
||||
*/
|
||||
@Deprecated
|
||||
public String getText(int offs, int len) throws BadLocationException {
|
||||
return super.getText(offs, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text contained in this <code>TextComponent</code>.
|
||||
* If the underlying document is <code>null</code>, will give a
|
||||
* <code>NullPointerException</code>. For stronger
|
||||
* security, it is recommended that the returned character array be
|
||||
* cleared after use by setting each character to zero.
|
||||
*
|
||||
* @return the text
|
||||
*/
|
||||
public char[] getPassword() {
|
||||
Document doc = getDocument();
|
||||
Segment txt = new Segment();
|
||||
try {
|
||||
doc.getText(0, doc.getLength(), txt); // use the non-String API
|
||||
} catch (BadLocationException e) {
|
||||
return null;
|
||||
}
|
||||
char[] retValue = new char[txt.count];
|
||||
System.arraycopy(txt.array, txt.offset, retValue, 0, txt.count);
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- variables -----------------------------------------------
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "PasswordFieldUI";
|
||||
|
||||
private char echoChar;
|
||||
|
||||
private boolean echoCharSet = false;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JPasswordField</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JPasswordField</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString() +
|
||||
",echoChar=" + echoChar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is a hack to get around the fact that we cannot
|
||||
* directly override setUIProperty because part of the inheritance hierarchy
|
||||
* goes outside of the javax.swing package, and therefore calling a package
|
||||
* private method isn't allowed. This method should return true if the property
|
||||
* was handled, and false otherwise.
|
||||
*/
|
||||
boolean customSetUIProperty(String propertyName, Object value) {
|
||||
if (propertyName == "echoChar") {
|
||||
if (!echoCharSet) {
|
||||
setEchoChar((Character)value);
|
||||
echoCharSet = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Returns the <code>AccessibleContext</code> associated with this
|
||||
* <code>JPasswordField</code>. For password fields, the
|
||||
* <code>AccessibleContext</code> takes the form of an
|
||||
* <code>AccessibleJPasswordField</code>.
|
||||
* A new <code>AccessibleJPasswordField</code> instance is created
|
||||
* if necessary.
|
||||
*
|
||||
* @return an <code>AccessibleJPasswordField</code> that serves as the
|
||||
* <code>AccessibleContext</code> of this
|
||||
* <code>JPasswordField</code>
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJPasswordField();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JPasswordField</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to password field user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJPasswordField extends AccessibleJTextField {
|
||||
|
||||
/**
|
||||
* Gets the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object (AccessibleRole.PASSWORD_TEXT)
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.PASSWORD_TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>AccessibleText</code> for the <code>JPasswordField</code>.
|
||||
* The returned object also implements the
|
||||
* <code>AccessibleExtendedText</code> interface.
|
||||
*
|
||||
* @return <code>AccessibleText</code> for the JPasswordField
|
||||
* @see javax.accessibility.AccessibleContext
|
||||
* @see javax.accessibility.AccessibleContext#getAccessibleText
|
||||
* @see javax.accessibility.AccessibleText
|
||||
* @see javax.accessibility.AccessibleExtendedText
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public AccessibleText getAccessibleText() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a String filled with password echo characters. The String
|
||||
* contains one echo character for each character (including whitespace)
|
||||
* that the user entered in the JPasswordField.
|
||||
*/
|
||||
private String getEchoString(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
char[] buffer = new char[str.length()];
|
||||
Arrays.fill(buffer, getEchoChar());
|
||||
return new String(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>String</code> at a given <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code> or
|
||||
* <code>SENTENCE</code> to retrieve
|
||||
* @param index an index within the text
|
||||
* @return a <code>String</code> if <code>part</code> and
|
||||
* <code>index</code> are valid.
|
||||
* Otherwise, <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getAtIndex(int part, int index) {
|
||||
String str = null;
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
str = super.getAtIndex(part, index);
|
||||
} else {
|
||||
// Treat the text displayed in the JPasswordField
|
||||
// as one word and sentence.
|
||||
char password[] = getPassword();
|
||||
if (password == null ||
|
||||
index < 0 || index >= password.length) {
|
||||
return null;
|
||||
}
|
||||
str = new String(password);
|
||||
}
|
||||
return getEchoString(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>String</code> after a given <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code> or
|
||||
* <code>SENTENCE</code> to retrieve
|
||||
* @param index an index within the text
|
||||
* @return a <code>String</code> if <code>part</code> and
|
||||
* <code>index</code> are valid.
|
||||
* Otherwise, <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getAfterIndex(int part, int index) {
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
String str = super.getAfterIndex(part, index);
|
||||
return getEchoString(str);
|
||||
} else {
|
||||
// There is no word or sentence after the text
|
||||
// displayed in the JPasswordField.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>String</code> before a given <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code> or
|
||||
* <code>SENTENCE</code> to retrieve
|
||||
* @param index an index within the text
|
||||
* @return a <code>String</code> if <code>part</code> and
|
||||
* <code>index</code> are valid.
|
||||
* Otherwise, <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getBeforeIndex(int part, int index) {
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
String str = super.getBeforeIndex(part, index);
|
||||
return getEchoString(str);
|
||||
} else {
|
||||
// There is no word or sentence before the text
|
||||
// displayed in the JPasswordField.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text between two <code>indices</code>.
|
||||
*
|
||||
* @param startIndex the start index in the text
|
||||
* @param endIndex the end index in the text
|
||||
* @return the text string if the indices are valid.
|
||||
* Otherwise, <code>null</code> is returned
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getTextRange(int startIndex, int endIndex) {
|
||||
String str = super.getTextRange(startIndex, endIndex);
|
||||
return getEchoString(str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the <code>AccessibleTextSequence</code> at a given
|
||||
* <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code>,
|
||||
* <code>SENTENCE</code>, <code>LINE</code> or <code>ATTRIBUTE_RUN</code> to
|
||||
* retrieve
|
||||
* @param index an index within the text
|
||||
* @return an <code>AccessibleTextSequence</code> specifying the text if
|
||||
* <code>part</code> and <code>index</code> are valid. Otherwise,
|
||||
* <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
* @see javax.accessibility.AccessibleExtendedText#LINE
|
||||
* @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public AccessibleTextSequence getTextSequenceAt(int part, int index) {
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
AccessibleTextSequence seq = super.getTextSequenceAt(part, index);
|
||||
if (seq == null) {
|
||||
return null;
|
||||
}
|
||||
return new AccessibleTextSequence(seq.startIndex, seq.endIndex,
|
||||
getEchoString(seq.text));
|
||||
} else {
|
||||
// Treat the text displayed in the JPasswordField
|
||||
// as one word, sentence, line and attribute run
|
||||
char password[] = getPassword();
|
||||
if (password == null ||
|
||||
index < 0 || index >= password.length) {
|
||||
return null;
|
||||
}
|
||||
String text = new String(password);
|
||||
return new AccessibleTextSequence(0, password.length - 1,
|
||||
getEchoString(text));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>AccessibleTextSequence</code> after a given
|
||||
* <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code>,
|
||||
* <code>SENTENCE</code>, <code>LINE</code> or <code>ATTRIBUTE_RUN</code> to
|
||||
* retrieve
|
||||
* @param index an index within the text
|
||||
* @return an <code>AccessibleTextSequence</code> specifying the text if
|
||||
* <code>part</code> and <code>index</code> are valid. Otherwise,
|
||||
* <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
* @see javax.accessibility.AccessibleExtendedText#LINE
|
||||
* @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public AccessibleTextSequence getTextSequenceAfter(int part, int index) {
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
AccessibleTextSequence seq = super.getTextSequenceAfter(part, index);
|
||||
if (seq == null) {
|
||||
return null;
|
||||
}
|
||||
return new AccessibleTextSequence(seq.startIndex, seq.endIndex,
|
||||
getEchoString(seq.text));
|
||||
} else {
|
||||
// There is no word, sentence, line or attribute run
|
||||
// after the text displayed in the JPasswordField.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>AccessibleTextSequence</code> before a given
|
||||
* <code>index</code>.
|
||||
*
|
||||
* @param part the <code>CHARACTER</code>, <code>WORD</code>,
|
||||
* <code>SENTENCE</code>, <code>LINE</code> or <code>ATTRIBUTE_RUN</code> to
|
||||
* retrieve
|
||||
* @param index an index within the text
|
||||
* @return an <code>AccessibleTextSequence</code> specifying the text if
|
||||
* <code>part</code> and <code>index</code> are valid. Otherwise,
|
||||
* <code>null</code> is returned
|
||||
*
|
||||
* @see javax.accessibility.AccessibleText#CHARACTER
|
||||
* @see javax.accessibility.AccessibleText#WORD
|
||||
* @see javax.accessibility.AccessibleText#SENTENCE
|
||||
* @see javax.accessibility.AccessibleExtendedText#LINE
|
||||
* @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public AccessibleTextSequence getTextSequenceBefore(int part, int index) {
|
||||
if (part == AccessibleText.CHARACTER) {
|
||||
AccessibleTextSequence seq = super.getTextSequenceBefore(part, index);
|
||||
if (seq == null) {
|
||||
return null;
|
||||
}
|
||||
return new AccessibleTextSequence(seq.startIndex, seq.endIndex,
|
||||
getEchoString(seq.text));
|
||||
} else {
|
||||
// There is no word, sentence, line or attribute run
|
||||
// before the text displayed in the JPasswordField.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1561
jdkSrc/jdk8/javax/swing/JPopupMenu.java
Normal file
1561
jdkSrc/jdk8/javax/swing/JPopupMenu.java
Normal file
File diff suppressed because it is too large
Load Diff
1126
jdkSrc/jdk8/javax/swing/JProgressBar.java
Normal file
1126
jdkSrc/jdk8/javax/swing/JProgressBar.java
Normal file
File diff suppressed because it is too large
Load Diff
300
jdkSrc/jdk8/javax/swing/JRadioButton.java
Normal file
300
jdkSrc/jdk8/javax/swing/JRadioButton.java
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a radio button -- an item that can be selected or
|
||||
* deselected, and which displays its state to the user.
|
||||
* Used with a {@link ButtonGroup} object to create a group of buttons
|
||||
* in which only one button at a time can be selected. (Create a ButtonGroup
|
||||
* object and use its <code>add</code> method to include the JRadioButton objects
|
||||
* in the group.)
|
||||
* <blockquote>
|
||||
* <strong>Note:</strong>
|
||||
* The ButtonGroup object is a logical grouping -- not a physical grouping.
|
||||
* To create a button panel, you should still create a {@link JPanel} or similar
|
||||
* container-object and add a {@link javax.swing.border.Border} to it to set it off from surrounding
|
||||
* components.
|
||||
* </blockquote>
|
||||
* <p>
|
||||
* Buttons can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a button has many benefits beyond directly
|
||||
* configuring a button. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
|
||||
* in <em>The Java Tutorial</em>
|
||||
* for further documentation.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component which can display it's state as selected or deselected.
|
||||
*
|
||||
* @see ButtonGroup
|
||||
* @see JCheckBox
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
public class JRadioButton extends JToggleButton implements Accessible {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "RadioButtonUI";
|
||||
|
||||
|
||||
/**
|
||||
* Creates an initially unselected radio button
|
||||
* with no set text.
|
||||
*/
|
||||
public JRadioButton () {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected radio button
|
||||
* with the specified image but no text.
|
||||
*
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JRadioButton(Icon icon) {
|
||||
this(null, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radiobutton where properties are taken from the
|
||||
* Action supplied.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JRadioButton(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button with the specified image
|
||||
* and selection state, but no text.
|
||||
*
|
||||
* @param icon the image that the button should display
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JRadioButton(Icon icon, boolean selected) {
|
||||
this(null, icon, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unselected radio button with the specified text.
|
||||
*
|
||||
* @param text the string displayed on the radio button
|
||||
*/
|
||||
public JRadioButton (String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button with the specified text
|
||||
* and selection state.
|
||||
*
|
||||
* @param text the string displayed on the radio button
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JRadioButton (String text, boolean selected) {
|
||||
this(text, null, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button that has the specified text and image,
|
||||
* and that is initially unselected.
|
||||
*
|
||||
* @param text the string displayed on the radio button
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JRadioButton(String text, Icon icon) {
|
||||
this(text, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button that has the specified text, image,
|
||||
* and selection state.
|
||||
*
|
||||
* @param text the string displayed on the radio button
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JRadioButton (String text, Icon icon, boolean selected) {
|
||||
super(text, icon, selected);
|
||||
setBorderPainted(false);
|
||||
setHorizontalAlignment(LEADING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ButtonUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return String "RadioButtonUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: A string that specifies the name of the L&F class.
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The icon for radio buttons comes from the look and feel,
|
||||
* not the Action.
|
||||
*/
|
||||
void setIconFromAction(Action a) {
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JRadioButton. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JRadioButton.
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JRadioButton.
|
||||
* For JRadioButtons, the AccessibleContext takes the form of an
|
||||
* AccessibleJRadioButton.
|
||||
* A new AccessibleJRadioButton instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJRadioButton that serves as the
|
||||
* AccessibleContext of this JRadioButton
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: The AccessibleContext associated with this Button
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJRadioButton();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JRadioButton</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to radio button
|
||||
* user-interface elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJRadioButton extends AccessibleJToggleButton {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the object
|
||||
* @see AccessibleRole
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.RADIO_BUTTON;
|
||||
}
|
||||
|
||||
} // inner class AccessibleJRadioButton
|
||||
}
|
||||
280
jdkSrc/jdk8/javax/swing/JRadioButtonMenuItem.java
Normal file
280
jdkSrc/jdk8/javax/swing/JRadioButtonMenuItem.java
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* An implementation of a radio button menu item.
|
||||
* A <code>JRadioButtonMenuItem</code> is
|
||||
* a menu item that is part of a group of menu items in which only one
|
||||
* item in the group can be selected. The selected item displays its
|
||||
* selected state. Selecting it causes any other selected item to
|
||||
* switch to the unselected state.
|
||||
* To control the selected state of a group of radio button menu items,
|
||||
* use a <code>ButtonGroup</code> object.
|
||||
* <p>
|
||||
* Menu items can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a menu item has many benefits beyond directly
|
||||
* configuring a menu item. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* For further documentation and examples see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component within a group of menu items which can be selected.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author David Karlton
|
||||
* @see ButtonGroup
|
||||
*/
|
||||
public class JRadioButtonMenuItem extends JMenuItem implements Accessible {
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "RadioButtonMenuItemUI";
|
||||
|
||||
/**
|
||||
* Creates a <code>JRadioButtonMenuItem</code> with no set text or icon.
|
||||
*/
|
||||
public JRadioButtonMenuItem() {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JRadioButtonMenuItem</code> with an icon.
|
||||
*
|
||||
* @param icon the <code>Icon</code> to display on the
|
||||
* <code>JRadioButtonMenuItem</code>
|
||||
*/
|
||||
public JRadioButtonMenuItem(Icon icon) {
|
||||
this(null, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>JRadioButtonMenuItem</code> with text.
|
||||
*
|
||||
* @param text the text of the <code>JRadioButtonMenuItem</code>
|
||||
*/
|
||||
public JRadioButtonMenuItem(String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button menu item whose properties are taken from the
|
||||
* <code>Action</code> supplied.
|
||||
*
|
||||
* @param a the <code>Action</code> on which to base the radio
|
||||
* button menu item
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JRadioButtonMenuItem(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button menu item with the specified text
|
||||
* and <code>Icon</code>.
|
||||
*
|
||||
* @param text the text of the <code>JRadioButtonMenuItem</code>
|
||||
* @param icon the icon to display on the <code>JRadioButtonMenuItem</code>
|
||||
*/
|
||||
public JRadioButtonMenuItem(String text, Icon icon) {
|
||||
this(text, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button menu item with the specified text
|
||||
* and selection state.
|
||||
*
|
||||
* @param text the text of the <code>CheckBoxMenuItem</code>
|
||||
* @param selected the selected state of the <code>CheckBoxMenuItem</code>
|
||||
*/
|
||||
public JRadioButtonMenuItem(String text, boolean selected) {
|
||||
this(text);
|
||||
setSelected(selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button menu item with the specified image
|
||||
* and selection state, but no text.
|
||||
*
|
||||
* @param icon the image that the button should display
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JRadioButtonMenuItem(Icon icon, boolean selected) {
|
||||
this(null, icon, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio button menu item that has the specified
|
||||
* text, image, and selection state. All other constructors
|
||||
* defer to this one.
|
||||
*
|
||||
* @param text the string displayed on the radio button
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JRadioButtonMenuItem(String text, Icon icon, boolean selected) {
|
||||
super(text, icon);
|
||||
setModel(new JToggleButton.ToggleButtonModel());
|
||||
setSelected(selected);
|
||||
setFocusable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "RadioButtonMenuItemUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this
|
||||
* <code>JRadioButtonMenuItem</code>. 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</code>.
|
||||
*
|
||||
* @return a string representation of this
|
||||
* <code>JRadioButtonMenuItem</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriden to return true, JRadioButtonMenuItem supports
|
||||
* the selected state.
|
||||
*/
|
||||
boolean shouldUpdateSelectedStateFromAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JRadioButtonMenuItem.
|
||||
* For JRadioButtonMenuItems, the AccessibleContext takes the form of an
|
||||
* AccessibleJRadioButtonMenuItem.
|
||||
* A new AccessibleJRadioButtonMenuItem instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJRadioButtonMenuItem that serves as the
|
||||
* AccessibleContext of this JRadioButtonMenuItem
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJRadioButtonMenuItem();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JRadioButtonMenuItem</code> class. It provides an
|
||||
* implementation of the Java Accessibility API appropriate to
|
||||
* <code>JRadioButtonMenuItem</code> user-interface elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem {
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.RADIO_BUTTON;
|
||||
}
|
||||
} // inner class AccessibleJRadioButtonMenuItem
|
||||
}
|
||||
1106
jdkSrc/jdk8/javax/swing/JRootPane.java
Normal file
1106
jdkSrc/jdk8/javax/swing/JRootPane.java
Normal file
File diff suppressed because it is too large
Load Diff
933
jdkSrc/jdk8/javax/swing/JScrollBar.java
Normal file
933
jdkSrc/jdk8/javax/swing/JScrollBar.java
Normal file
@@ -0,0 +1,933 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.awt.Component;
|
||||
import java.awt.Adjustable;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a scrollbar. The user positions the knob in the
|
||||
* scrollbar to determine the contents of the viewing area. The
|
||||
* program typically adjusts the display so that the end of the
|
||||
* scrollbar represents the end of the displayable contents, or 100%
|
||||
* of the contents. The start of the scrollbar is the beginning of the
|
||||
* displayable contents, or 0%. The position of the knob within
|
||||
* those bounds then translates to the corresponding percentage of
|
||||
* the displayable contents.
|
||||
* <p>
|
||||
* Typically, as the position of the knob in the scrollbar changes
|
||||
* a corresponding change is made to the position of the JViewport on
|
||||
* the underlying view, changing the contents of the JViewport.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JScrollPane
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component that helps determine the visible content range of an area.
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
public class JScrollBar extends JComponent implements Adjustable, Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ScrollBarUI";
|
||||
|
||||
/**
|
||||
* All changes from the model are treated as though the user moved
|
||||
* the scrollbar knob.
|
||||
*/
|
||||
private ChangeListener fwdAdjustmentEvents = new ModelListener();
|
||||
|
||||
|
||||
/**
|
||||
* The model that represents the scrollbar's minimum, maximum, extent
|
||||
* (aka "visibleAmount") and current value.
|
||||
* @see #setModel
|
||||
*/
|
||||
protected BoundedRangeModel model;
|
||||
|
||||
|
||||
/**
|
||||
* @see #setOrientation
|
||||
*/
|
||||
protected int orientation;
|
||||
|
||||
|
||||
/**
|
||||
* @see #setUnitIncrement
|
||||
*/
|
||||
protected int unitIncrement;
|
||||
|
||||
|
||||
/**
|
||||
* @see #setBlockIncrement
|
||||
*/
|
||||
protected int blockIncrement;
|
||||
|
||||
|
||||
private void checkOrientation(int orientation) {
|
||||
switch (orientation) {
|
||||
case VERTICAL:
|
||||
case HORIZONTAL:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a scrollbar with the specified orientation,
|
||||
* value, extent, minimum, and maximum.
|
||||
* The "extent" is the size of the viewable area. It is also known
|
||||
* as the "visible amount".
|
||||
* <p>
|
||||
* Note: Use <code>setBlockIncrement</code> to set the block
|
||||
* increment to a size slightly smaller than the view's extent.
|
||||
* That way, when the user jumps the knob to an adjacent position,
|
||||
* one or two lines of the original contents remain in view.
|
||||
*
|
||||
* @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
|
||||
*
|
||||
* @see #setOrientation
|
||||
* @see #setValue
|
||||
* @see #setVisibleAmount
|
||||
* @see #setMinimum
|
||||
* @see #setMaximum
|
||||
*/
|
||||
public JScrollBar(int orientation, int value, int extent, int min, int max)
|
||||
{
|
||||
checkOrientation(orientation);
|
||||
this.unitIncrement = 1;
|
||||
this.blockIncrement = (extent == 0) ? 1 : extent;
|
||||
this.orientation = orientation;
|
||||
this.model = new DefaultBoundedRangeModel(value, extent, min, max);
|
||||
this.model.addChangeListener(fwdAdjustmentEvents);
|
||||
setRequestFocusEnabled(false);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a scrollbar with the specified orientation
|
||||
* and the following initial values:
|
||||
* <pre>
|
||||
* minimum = 0
|
||||
* maximum = 100
|
||||
* value = 0
|
||||
* extent = 10
|
||||
* </pre>
|
||||
*/
|
||||
public JScrollBar(int orientation) {
|
||||
this(orientation, 0, 10, 0, 100);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a vertical scrollbar with the following initial values:
|
||||
* <pre>
|
||||
* minimum = 0
|
||||
* maximum = 100
|
||||
* value = 0
|
||||
* extent = 10
|
||||
* </pre>
|
||||
*/
|
||||
public JScrollBar() {
|
||||
this(VERTICAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the {@literal L&F} object that renders this component.
|
||||
*
|
||||
* @param ui the <code>ScrollBarUI</code> {@literal L&F} object
|
||||
* @see UIDefaults#getUI
|
||||
* @since 1.4
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel
|
||||
*/
|
||||
public void setUI(ScrollBarUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the delegate that implements the look and feel for
|
||||
* this component.
|
||||
*
|
||||
* @see JComponent#setUI
|
||||
*/
|
||||
public ScrollBarUI getUI() {
|
||||
return (ScrollBarUI)ui;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overrides <code>JComponent.updateUI</code>.
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ScrollBarUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the LookAndFeel class for this component.
|
||||
*
|
||||
* @return "ScrollBarUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the component's orientation (horizontal or vertical).
|
||||
*
|
||||
* @return VERTICAL or HORIZONTAL
|
||||
* @see #setOrientation
|
||||
* @see java.awt.Adjustable#getOrientation
|
||||
*/
|
||||
public int getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the scrollbar's orientation to either VERTICAL or
|
||||
* HORIZONTAL.
|
||||
*
|
||||
* @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
|
||||
* @see #getOrientation
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The scrollbar's orientation.
|
||||
* enum: VERTICAL JScrollBar.VERTICAL
|
||||
* HORIZONTAL JScrollBar.HORIZONTAL
|
||||
*/
|
||||
public void setOrientation(int orientation)
|
||||
{
|
||||
checkOrientation(orientation);
|
||||
int oldValue = this.orientation;
|
||||
this.orientation = orientation;
|
||||
firePropertyChange("orientation", oldValue, orientation);
|
||||
|
||||
if ((oldValue != orientation) && (accessibleContext != null)) {
|
||||
accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
((oldValue == VERTICAL)
|
||||
? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL),
|
||||
((orientation == VERTICAL)
|
||||
? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL));
|
||||
}
|
||||
if (orientation != oldValue) {
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns data model that handles the scrollbar's four
|
||||
* fundamental properties: minimum, maximum, value, extent.
|
||||
*
|
||||
* @see #setModel
|
||||
*/
|
||||
public BoundedRangeModel getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model that handles the scrollbar's four
|
||||
* fundamental properties: minimum, maximum, value, extent.
|
||||
*
|
||||
* @see #getModel
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* expert: true
|
||||
* description: The scrollbar's BoundedRangeModel.
|
||||
*/
|
||||
public void setModel(BoundedRangeModel newModel) {
|
||||
Integer oldValue = null;
|
||||
BoundedRangeModel oldModel = model;
|
||||
if (model != null) {
|
||||
model.removeChangeListener(fwdAdjustmentEvents);
|
||||
oldValue = Integer.valueOf(model.getValue());
|
||||
}
|
||||
model = newModel;
|
||||
if (model != null) {
|
||||
model.addChangeListener(fwdAdjustmentEvents);
|
||||
}
|
||||
|
||||
firePropertyChange("model", oldModel, model);
|
||||
|
||||
if (accessibleContext != null) {
|
||||
accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
|
||||
oldValue, new Integer(model.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the amount to change the scrollbar's value by,
|
||||
* given a unit up/down request. A ScrollBarUI implementation
|
||||
* typically calls this method when the user clicks on a scrollbar
|
||||
* up/down arrow and uses the result to update the scrollbar's
|
||||
* value. Subclasses my override this method to compute
|
||||
* a value, e.g. the change required to scroll up or down one
|
||||
* (variable height) line text or one row in a table.
|
||||
* <p>
|
||||
* The JScrollPane component creates scrollbars (by default)
|
||||
* that override this method and delegate to the viewports
|
||||
* Scrollable view, if it has one. The Scrollable interface
|
||||
* provides a more specialized version of this method.
|
||||
* <p>
|
||||
* Some look and feels implement custom scrolling behavior
|
||||
* and ignore this property.
|
||||
*
|
||||
* @param direction is -1 or 1 for up/down respectively
|
||||
* @return the value of the unitIncrement property
|
||||
* @see #setUnitIncrement
|
||||
* @see #setValue
|
||||
* @see Scrollable#getScrollableUnitIncrement
|
||||
*/
|
||||
public int getUnitIncrement(int direction) {
|
||||
return unitIncrement;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the unitIncrement property.
|
||||
* <p>
|
||||
* Note, that if the argument is equal to the value of Integer.MIN_VALUE,
|
||||
* the most look and feels will not provide the scrolling to the right/down.
|
||||
* <p>
|
||||
* Some look and feels implement custom scrolling behavior
|
||||
* and ignore this property.
|
||||
*
|
||||
* @see #getUnitIncrement
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: The scrollbar's unit increment.
|
||||
*/
|
||||
public void setUnitIncrement(int unitIncrement) {
|
||||
int oldValue = this.unitIncrement;
|
||||
this.unitIncrement = unitIncrement;
|
||||
firePropertyChange("unitIncrement", oldValue, unitIncrement);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the amount to change the scrollbar's value by,
|
||||
* given a block (usually "page") up/down request. A ScrollBarUI
|
||||
* implementation typically calls this method when the user clicks
|
||||
* above or below the scrollbar "knob" to change the value
|
||||
* up or down by large amount. Subclasses my override this
|
||||
* method to compute a value, e.g. the change required to scroll
|
||||
* up or down one paragraph in a text document.
|
||||
* <p>
|
||||
* The JScrollPane component creates scrollbars (by default)
|
||||
* that override this method and delegate to the viewports
|
||||
* Scrollable view, if it has one. The Scrollable interface
|
||||
* provides a more specialized version of this method.
|
||||
* <p>
|
||||
* Some look and feels implement custom scrolling behavior
|
||||
* and ignore this property.
|
||||
*
|
||||
* @param direction is -1 or 1 for up/down respectively
|
||||
* @return the value of the blockIncrement property
|
||||
* @see #setBlockIncrement
|
||||
* @see #setValue
|
||||
* @see Scrollable#getScrollableBlockIncrement
|
||||
*/
|
||||
public int getBlockIncrement(int direction) {
|
||||
return blockIncrement;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the blockIncrement property.
|
||||
* <p>
|
||||
* Note, that if the argument is equal to the value of Integer.MIN_VALUE,
|
||||
* the most look and feels will not provide the scrolling to the right/down.
|
||||
* <p>
|
||||
* Some look and feels implement custom scrolling behavior
|
||||
* and ignore this property.
|
||||
*
|
||||
* @see #getBlockIncrement()
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: The scrollbar's block increment.
|
||||
*/
|
||||
public void setBlockIncrement(int blockIncrement) {
|
||||
int oldValue = this.blockIncrement;
|
||||
this.blockIncrement = blockIncrement;
|
||||
firePropertyChange("blockIncrement", oldValue, blockIncrement);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For backwards compatibility with java.awt.Scrollbar.
|
||||
* @see Adjustable#getUnitIncrement
|
||||
* @see #getUnitIncrement(int)
|
||||
*/
|
||||
public int getUnitIncrement() {
|
||||
return unitIncrement;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For backwards compatibility with java.awt.Scrollbar.
|
||||
* @see Adjustable#getBlockIncrement
|
||||
* @see #getBlockIncrement(int)
|
||||
*/
|
||||
public int getBlockIncrement() {
|
||||
return blockIncrement;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the scrollbar's value.
|
||||
* @return the model's value property
|
||||
* @see #setValue
|
||||
*/
|
||||
public int getValue() {
|
||||
return getModel().getValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the scrollbar's value. This method just forwards the value
|
||||
* to the model.
|
||||
*
|
||||
* @see #getValue
|
||||
* @see BoundedRangeModel#setValue
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* description: The scrollbar's current value.
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
BoundedRangeModel m = getModel();
|
||||
int oldValue = m.getValue();
|
||||
m.setValue(value);
|
||||
|
||||
if (accessibleContext != null) {
|
||||
accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
|
||||
Integer.valueOf(oldValue),
|
||||
Integer.valueOf(m.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the scrollbar's extent, aka its "visibleAmount". In many
|
||||
* scrollbar look and feel implementations the size of the
|
||||
* scrollbar "knob" or "thumb" is proportional to the extent.
|
||||
*
|
||||
* @return the value of the model's extent property
|
||||
* @see #setVisibleAmount
|
||||
*/
|
||||
public int getVisibleAmount() {
|
||||
return getModel().getExtent();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the model's extent property.
|
||||
*
|
||||
* @see #getVisibleAmount
|
||||
* @see BoundedRangeModel#setExtent
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* description: The amount of the view that is currently visible.
|
||||
*/
|
||||
public void setVisibleAmount(int extent) {
|
||||
getModel().setExtent(extent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the minimum value supported by the scrollbar
|
||||
* (usually zero).
|
||||
*
|
||||
* @return the value of the model's minimum property
|
||||
* @see #setMinimum
|
||||
*/
|
||||
public int getMinimum() {
|
||||
return getModel().getMinimum();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's minimum property.
|
||||
*
|
||||
* @see #getMinimum
|
||||
* @see BoundedRangeModel#setMinimum
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* description: The scrollbar's minimum value.
|
||||
*/
|
||||
public void setMinimum(int minimum) {
|
||||
getModel().setMinimum(minimum);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The maximum value of the scrollbar is maximum - extent.
|
||||
*
|
||||
* @return the value of the model's maximum property
|
||||
* @see #setMaximum
|
||||
*/
|
||||
public int getMaximum() {
|
||||
return getModel().getMaximum();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's maximum property. Note that the scrollbar's value
|
||||
* can only be set to maximum - extent.
|
||||
*
|
||||
* @see #getMaximum
|
||||
* @see BoundedRangeModel#setMaximum
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* description: The scrollbar's maximum value.
|
||||
*/
|
||||
public void setMaximum(int maximum) {
|
||||
getModel().setMaximum(maximum);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* True if the scrollbar knob is being dragged.
|
||||
*
|
||||
* @return the value of the model's valueIsAdjusting property
|
||||
* @see #setValueIsAdjusting
|
||||
*/
|
||||
public boolean getValueIsAdjusting() {
|
||||
return getModel().getValueIsAdjusting();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the model's valueIsAdjusting property. Scrollbar look and
|
||||
* feel implementations should set this property to true when
|
||||
* a knob drag begins, and to false when the drag ends. The
|
||||
* scrollbar model will not generate ChangeEvents while
|
||||
* valueIsAdjusting is true.
|
||||
*
|
||||
* @see #getValueIsAdjusting
|
||||
* @see BoundedRangeModel#setValueIsAdjusting
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: True if the scrollbar thumb is being dragged.
|
||||
*/
|
||||
public void setValueIsAdjusting(boolean b) {
|
||||
BoundedRangeModel m = getModel();
|
||||
boolean oldValue = m.getValueIsAdjusting();
|
||||
m.setValueIsAdjusting(b);
|
||||
|
||||
if ((oldValue != b) && (accessibleContext != null)) {
|
||||
accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
((oldValue) ? AccessibleState.BUSY : null),
|
||||
((b) ? AccessibleState.BUSY : null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the four BoundedRangeModel properties after forcing
|
||||
* the arguments to obey the usual constraints:
|
||||
* <pre>
|
||||
* minimum ≤ value ≤ value+extent ≤ maximum
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @see BoundedRangeModel#setRangeProperties
|
||||
* @see #setValue
|
||||
* @see #setVisibleAmount
|
||||
* @see #setMinimum
|
||||
* @see #setMaximum
|
||||
*/
|
||||
public void setValues(int newValue, int newExtent, int newMin, int newMax)
|
||||
{
|
||||
BoundedRangeModel m = getModel();
|
||||
int oldValue = m.getValue();
|
||||
m.setRangeProperties(newValue, newExtent, newMin, newMax, m.getValueIsAdjusting());
|
||||
|
||||
if (accessibleContext != null) {
|
||||
accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
|
||||
Integer.valueOf(oldValue),
|
||||
Integer.valueOf(m.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an AdjustmentListener. Adjustment listeners are notified
|
||||
* each time the scrollbar's model changes. Adjustment events are
|
||||
* provided for backwards compatibility with java.awt.Scrollbar.
|
||||
* <p>
|
||||
* Note that the AdjustmentEvents type property will always have a
|
||||
* placeholder value of AdjustmentEvent.TRACK because all changes
|
||||
* to a BoundedRangeModels value are considered equivalent. To change
|
||||
* the value of a BoundedRangeModel one just sets its value property,
|
||||
* i.e. model.setValue(123). No information about the origin of the
|
||||
* change, e.g. it's a block decrement, is provided. We don't try
|
||||
* fabricate the origin of the change here.
|
||||
*
|
||||
* @param l the AdjustmentLister to add
|
||||
* @see #removeAdjustmentListener
|
||||
* @see BoundedRangeModel#addChangeListener
|
||||
*/
|
||||
public void addAdjustmentListener(AdjustmentListener l) {
|
||||
listenerList.add(AdjustmentListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an AdjustmentEvent listener.
|
||||
*
|
||||
* @param l the AdjustmentLister to remove
|
||||
* @see #addAdjustmentListener
|
||||
*/
|
||||
public void removeAdjustmentListener(AdjustmentListener l) {
|
||||
listenerList.remove(AdjustmentListener.class, l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>AdjustmentListener</code>s added
|
||||
* to this JScrollBar with addAdjustmentListener().
|
||||
*
|
||||
* @return all of the <code>AdjustmentListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public AdjustmentListener[] getAdjustmentListeners() {
|
||||
return listenerList.getListeners(AdjustmentListener.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify listeners that the scrollbar's model has changed.
|
||||
*
|
||||
* @see #addAdjustmentListener
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireAdjustmentValueChanged(int id, int type, int value) {
|
||||
fireAdjustmentValueChanged(id, type, value, getValueIsAdjusting());
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify listeners that the scrollbar's model has changed.
|
||||
*
|
||||
* @see #addAdjustmentListener
|
||||
* @see EventListenerList
|
||||
*/
|
||||
private void fireAdjustmentValueChanged(int id, int type, int value,
|
||||
boolean isAdjusting) {
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
AdjustmentEvent e = null;
|
||||
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
||||
if (listeners[i]==AdjustmentListener.class) {
|
||||
if (e == null) {
|
||||
e = new AdjustmentEvent(this, id, type, value, isAdjusting);
|
||||
}
|
||||
((AdjustmentListener)listeners[i+1]).adjustmentValueChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class listens to ChangeEvents on the model and forwards
|
||||
* AdjustmentEvents for the sake of backwards compatibility.
|
||||
* Unfortunately there's no way to determine the proper
|
||||
* type of the AdjustmentEvent as all updates to the model's
|
||||
* value are considered equivalent.
|
||||
*/
|
||||
private class ModelListener implements ChangeListener, Serializable {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
Object obj = e.getSource();
|
||||
if (obj instanceof BoundedRangeModel) {
|
||||
int id = AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED;
|
||||
int type = AdjustmentEvent.TRACK;
|
||||
BoundedRangeModel model = (BoundedRangeModel)obj;
|
||||
int value = model.getValue();
|
||||
boolean isAdjusting = model.getValueIsAdjusting();
|
||||
fireAdjustmentValueChanged(id, type, value, isAdjusting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PENDING(hmuller) - the next three methods should be removed
|
||||
|
||||
/**
|
||||
* The scrollbar is flexible along it's scrolling axis and
|
||||
* rigid along the other axis.
|
||||
*/
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension pref = getPreferredSize();
|
||||
if (orientation == VERTICAL) {
|
||||
return new Dimension(pref.width, 5);
|
||||
} else {
|
||||
return new Dimension(5, pref.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The scrollbar is flexible along it's scrolling axis and
|
||||
* rigid along the other axis.
|
||||
*/
|
||||
public Dimension getMaximumSize() {
|
||||
Dimension pref = getPreferredSize();
|
||||
if (getOrientation() == VERTICAL) {
|
||||
return new Dimension(pref.width, Short.MAX_VALUE);
|
||||
} else {
|
||||
return new Dimension(Short.MAX_VALUE, pref.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the component so that the knob position can be changed.
|
||||
* When the disabled, the knob position cannot be changed.
|
||||
*
|
||||
* @param x a boolean value, where true enables the component and
|
||||
* false disables it
|
||||
*/
|
||||
public void setEnabled(boolean x) {
|
||||
super.setEnabled(x);
|
||||
Component[] children = getComponents();
|
||||
for (Component child : children) {
|
||||
child.setEnabled(x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JScrollBar. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JScrollBar.
|
||||
*/
|
||||
protected String paramString() {
|
||||
String orientationString = (orientation == HORIZONTAL ?
|
||||
"HORIZONTAL" : "VERTICAL");
|
||||
|
||||
return super.paramString() +
|
||||
",blockIncrement=" + blockIncrement +
|
||||
",orientation=" + orientationString +
|
||||
",unitIncrement=" + unitIncrement;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JScrollBar.
|
||||
* For JScrollBar, the AccessibleContext takes the form of an
|
||||
* AccessibleJScrollBar.
|
||||
* A new AccessibleJScrollBar instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJScrollBar that serves as the
|
||||
* AccessibleContext of this JScrollBar
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJScrollBar();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JScrollBar</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to scroll bar user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJScrollBar extends AccessibleJComponent
|
||||
implements AccessibleValue {
|
||||
|
||||
/**
|
||||
* Get the state set of this object.
|
||||
*
|
||||
* @return an instance of AccessibleState containing the current state
|
||||
* of the object
|
||||
* @see AccessibleState
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
if (getValueIsAdjusting()) {
|
||||
states.add(AccessibleState.BUSY);
|
||||
}
|
||||
if (getOrientation() == VERTICAL) {
|
||||
states.add(AccessibleState.VERTICAL);
|
||||
} else {
|
||||
states.add(AccessibleState.HORIZONTAL);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.SCROLL_BAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AccessibleValue associated with this object. In the
|
||||
* implementation of the Java Accessibility API for this class,
|
||||
* return this object, which is responsible for implementing the
|
||||
* AccessibleValue interface on behalf of itself.
|
||||
*
|
||||
* @return this object
|
||||
*/
|
||||
public AccessibleValue getAccessibleValue() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the accessible value of this object.
|
||||
*
|
||||
* @return The current value of this object.
|
||||
*/
|
||||
public Number getCurrentAccessibleValue() {
|
||||
return Integer.valueOf(getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of this object as a Number.
|
||||
*
|
||||
* @return True if the value was set.
|
||||
*/
|
||||
public boolean setCurrentAccessibleValue(Number n) {
|
||||
// TIGER - 4422535
|
||||
if (n == null) {
|
||||
return false;
|
||||
}
|
||||
setValue(n.intValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum accessible value of this object.
|
||||
*
|
||||
* @return The minimum value of this object.
|
||||
*/
|
||||
public Number getMinimumAccessibleValue() {
|
||||
return Integer.valueOf(getMinimum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum accessible value of this object.
|
||||
*
|
||||
* @return The maximum value of this object.
|
||||
*/
|
||||
public Number getMaximumAccessibleValue() {
|
||||
// TIGER - 4422362
|
||||
return new Integer(model.getMaximum() - model.getExtent());
|
||||
}
|
||||
|
||||
} // AccessibleJScrollBar
|
||||
}
|
||||
1555
jdkSrc/jdk8/javax/swing/JScrollPane.java
Normal file
1555
jdkSrc/jdk8/javax/swing/JScrollPane.java
Normal file
File diff suppressed because it is too large
Load Diff
296
jdkSrc/jdk8/javax/swing/JSeparator.java
Normal file
296
jdkSrc/jdk8/javax/swing/JSeparator.java
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* <code>JSeparator</code> provides a general purpose component for
|
||||
* implementing divider lines - most commonly used as a divider
|
||||
* between menu items that breaks them up into logical groupings.
|
||||
* Instead of using <code>JSeparator</code> directly,
|
||||
* you can use the <code>JMenu</code> or <code>JPopupMenu</code>
|
||||
* <code>addSeparator</code> method to create and add a separator.
|
||||
* <code>JSeparator</code>s may also be used elsewhere in a GUI
|
||||
* wherever a visual divider is useful.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* For more information and examples see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A divider between menu items.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author Jeff Shapiro
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JSeparator extends JComponent implements SwingConstants, Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "SeparatorUI";
|
||||
|
||||
private int orientation = HORIZONTAL;
|
||||
|
||||
/** Creates a new horizontal separator. */
|
||||
public JSeparator()
|
||||
{
|
||||
this( HORIZONTAL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new separator with the specified horizontal or
|
||||
* vertical orientation.
|
||||
*
|
||||
* @param orientation an integer specifying
|
||||
* <code>SwingConstants.HORIZONTAL</code> or
|
||||
* <code>SwingConstants.VERTICAL</code>
|
||||
* @exception IllegalArgumentException if <code>orientation</code>
|
||||
* is neither <code>SwingConstants.HORIZONTAL</code> nor
|
||||
* <code>SwingConstants.VERTICAL</code>
|
||||
*/
|
||||
public JSeparator( int orientation )
|
||||
{
|
||||
checkOrientation( orientation );
|
||||
this.orientation = orientation;
|
||||
setFocusable(false);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the L&F object that renders this component.
|
||||
*
|
||||
* @return the SeparatorUI object that renders this component
|
||||
*/
|
||||
public SeparatorUI getUI() {
|
||||
return (SeparatorUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the L&F object that renders this component.
|
||||
*
|
||||
* @param ui the SeparatorUI L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(SeparatorUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((SeparatorUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "SeparatorUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the orientation of this separator.
|
||||
*
|
||||
* @return The value of the orientation property, one of the
|
||||
* following constants defined in <code>SwingConstants</code>:
|
||||
* <code>VERTICAL</code>, or
|
||||
* <code>HORIZONTAL</code>.
|
||||
*
|
||||
* @see SwingConstants
|
||||
* @see #setOrientation
|
||||
*/
|
||||
public int getOrientation() {
|
||||
return this.orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the orientation of the separator.
|
||||
* The default value of this property is HORIZONTAL.
|
||||
* @param orientation either <code>SwingConstants.HORIZONTAL</code>
|
||||
* or <code>SwingConstants.VERTICAL</code>
|
||||
* @exception IllegalArgumentException if <code>orientation</code>
|
||||
* is neither <code>SwingConstants.HORIZONTAL</code>
|
||||
* nor <code>SwingConstants.VERTICAL</code>
|
||||
*
|
||||
* @see SwingConstants
|
||||
* @see #getOrientation
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* preferred: true
|
||||
* enum: HORIZONTAL SwingConstants.HORIZONTAL
|
||||
* VERTICAL SwingConstants.VERTICAL
|
||||
* attribute: visualUpdate true
|
||||
* description: The orientation of the separator.
|
||||
*/
|
||||
public void setOrientation( int orientation ) {
|
||||
if (this.orientation == orientation) {
|
||||
return;
|
||||
}
|
||||
int oldValue = this.orientation;
|
||||
checkOrientation( orientation );
|
||||
this.orientation = orientation;
|
||||
firePropertyChange("orientation", oldValue, orientation);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void checkOrientation( int orientation )
|
||||
{
|
||||
switch ( orientation )
|
||||
{
|
||||
case VERTICAL:
|
||||
case HORIZONTAL:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "orientation must be one of: VERTICAL, HORIZONTAL" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JSeparator</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JSeparator</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String orientationString = (orientation == HORIZONTAL ?
|
||||
"HORIZONTAL" : "VERTICAL");
|
||||
|
||||
return super.paramString() +
|
||||
",orientation=" + orientationString;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JSeparator.
|
||||
* For separators, the AccessibleContext takes the form of an
|
||||
* AccessibleJSeparator.
|
||||
* A new AccessibleJSeparator instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJSeparator that serves as the
|
||||
* AccessibleContext of this JSeparator
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJSeparator();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JSeparator</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to separator user-interface elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJSeparator extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.SEPARATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
1520
jdkSrc/jdk8/javax/swing/JSlider.java
Normal file
1520
jdkSrc/jdk8/javax/swing/JSlider.java
Normal file
File diff suppressed because it is too large
Load Diff
2052
jdkSrc/jdk8/javax/swing/JSpinner.java
Normal file
2052
jdkSrc/jdk8/javax/swing/JSpinner.java
Normal file
File diff suppressed because it is too large
Load Diff
1253
jdkSrc/jdk8/javax/swing/JSplitPane.java
Normal file
1253
jdkSrc/jdk8/javax/swing/JSplitPane.java
Normal file
File diff suppressed because it is too large
Load Diff
2418
jdkSrc/jdk8/javax/swing/JTabbedPane.java
Normal file
2418
jdkSrc/jdk8/javax/swing/JTabbedPane.java
Normal file
File diff suppressed because it is too large
Load Diff
9606
jdkSrc/jdk8/javax/swing/JTable.java
Normal file
9606
jdkSrc/jdk8/javax/swing/JTable.java
Normal file
File diff suppressed because it is too large
Load Diff
814
jdkSrc/jdk8/javax/swing/JTextArea.java
Normal file
814
jdkSrc/jdk8/javax/swing/JTextArea.java
Normal file
@@ -0,0 +1,814 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A <code>JTextArea</code> is a multi-line area that displays plain text.
|
||||
* It is intended to be a lightweight component that provides source
|
||||
* compatibility with the <code>java.awt.TextArea</code> class where it can
|
||||
* reasonably do so.
|
||||
* You can find information and examples of using all the text components in
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
*
|
||||
* <p>
|
||||
* This component has capabilities not found in the
|
||||
* <code>java.awt.TextArea</code> class. The superclass should be
|
||||
* consulted for additional capabilities.
|
||||
* Alternative multi-line text classes with
|
||||
* more capabilities are <code>JTextPane</code> and <code>JEditorPane</code>.
|
||||
* <p>
|
||||
* The <code>java.awt.TextArea</code> internally handles scrolling.
|
||||
* <code>JTextArea</code> is different in that it doesn't manage scrolling,
|
||||
* but implements the swing <code>Scrollable</code> interface. This allows it
|
||||
* to be placed inside a <code>JScrollPane</code> if scrolling
|
||||
* behavior is desired, and used directly if scrolling is not desired.
|
||||
* <p>
|
||||
* The <code>java.awt.TextArea</code> has the ability to do line wrapping.
|
||||
* This was controlled by the horizontal scrolling policy. Since
|
||||
* scrolling is not done by <code>JTextArea</code> directly, backward
|
||||
* compatibility must be provided another way. <code>JTextArea</code> has
|
||||
* a bound property for line wrapping that controls whether or
|
||||
* not it will wrap lines. By default, the line wrapping property
|
||||
* is set to false (not wrapped).
|
||||
* <p>
|
||||
* <code>java.awt.TextArea</code> has two properties <code>rows</code>
|
||||
* and <code>columns</code> that are used to determine the preferred size.
|
||||
* <code>JTextArea</code> uses these properties to indicate the
|
||||
* preferred size of the viewport when placed inside a <code>JScrollPane</code>
|
||||
* to match the functionality provided by <code>java.awt.TextArea</code>.
|
||||
* <code>JTextArea</code> has a preferred size of what is needed to
|
||||
* display all of the text, so that it functions properly inside of
|
||||
* a <code>JScrollPane</code>. If the value for <code>rows</code>
|
||||
* or <code>columns</code> is equal to zero,
|
||||
* the preferred size along that axis is used for
|
||||
* the viewport preferred size along the same axis.
|
||||
* <p>
|
||||
* The <code>java.awt.TextArea</code> could be monitored for changes by adding
|
||||
* a <code>TextListener</code> for <code>TextEvent</code>s.
|
||||
* In the <code>JTextComponent</code> based
|
||||
* components, changes are broadcasted from the model via a
|
||||
* <code>DocumentEvent</code> to <code>DocumentListeners</code>.
|
||||
* The <code>DocumentEvent</code> gives
|
||||
* the location of the change and the kind of change if desired.
|
||||
* The code fragment might look something like:
|
||||
* <pre>
|
||||
* DocumentListener myListener = ??;
|
||||
* JTextArea myArea = ??;
|
||||
* myArea.getDocument().addDocumentListener(myListener);
|
||||
* </pre>
|
||||
*
|
||||
* <dl>
|
||||
* <dt><b><font size=+1>Newlines</font></b>
|
||||
* <dd>
|
||||
* For a discussion on how newlines are handled, see
|
||||
* <a href="text/DefaultEditorKit.html">DefaultEditorKit</a>.
|
||||
* </dl>
|
||||
*
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A multi-line area that displays plain text.
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* @see JTextPane
|
||||
* @see JEditorPane
|
||||
*/
|
||||
public class JTextArea extends JTextComponent {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "TextAreaUI";
|
||||
|
||||
/**
|
||||
* Constructs a new TextArea. A default model is set, the initial string
|
||||
* is null, and rows/columns are set to 0.
|
||||
*/
|
||||
public JTextArea() {
|
||||
this(null, null, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new TextArea with the specified text displayed.
|
||||
* A default model is created and rows/columns are set to 0.
|
||||
*
|
||||
* @param text the text to be displayed, or null
|
||||
*/
|
||||
public JTextArea(String text) {
|
||||
this(null, text, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new empty TextArea with the specified number of
|
||||
* rows and columns. A default model is created, and the initial
|
||||
* string is null.
|
||||
*
|
||||
* @param rows the number of rows >= 0
|
||||
* @param columns the number of columns >= 0
|
||||
* @exception IllegalArgumentException if the rows or columns
|
||||
* arguments are negative.
|
||||
*/
|
||||
public JTextArea(int rows, int columns) {
|
||||
this(null, null, rows, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new TextArea with the specified text and number
|
||||
* of rows and columns. A default model is created.
|
||||
*
|
||||
* @param text the text to be displayed, or null
|
||||
* @param rows the number of rows >= 0
|
||||
* @param columns the number of columns >= 0
|
||||
* @exception IllegalArgumentException if the rows or columns
|
||||
* arguments are negative.
|
||||
*/
|
||||
public JTextArea(String text, int rows, int columns) {
|
||||
this(null, text, rows, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new JTextArea with the given document model, and defaults
|
||||
* for all of the other arguments (null, 0, 0).
|
||||
*
|
||||
* @param doc the model to use
|
||||
*/
|
||||
public JTextArea(Document doc) {
|
||||
this(doc, null, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new JTextArea with the specified number of rows
|
||||
* and columns, and the given model. All of the constructors
|
||||
* feed through this constructor.
|
||||
*
|
||||
* @param doc the model to use, or create a default one if null
|
||||
* @param text the text to be displayed, null if none
|
||||
* @param rows the number of rows >= 0
|
||||
* @param columns the number of columns >= 0
|
||||
* @exception IllegalArgumentException if the rows or columns
|
||||
* arguments are negative.
|
||||
*/
|
||||
public JTextArea(Document doc, String text, int rows, int columns) {
|
||||
super();
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
if (doc == null) {
|
||||
doc = createDefaultModel();
|
||||
}
|
||||
setDocument(doc);
|
||||
if (text != null) {
|
||||
setText(text);
|
||||
select(0, 0);
|
||||
}
|
||||
if (rows < 0) {
|
||||
throw new IllegalArgumentException("rows: " + rows);
|
||||
}
|
||||
if (columns < 0) {
|
||||
throw new IllegalArgumentException("columns: " + columns);
|
||||
}
|
||||
LookAndFeel.installProperty(this,
|
||||
"focusTraversalKeysForward",
|
||||
JComponent.
|
||||
getManagingFocusForwardTraversalKeys());
|
||||
LookAndFeel.installProperty(this,
|
||||
"focusTraversalKeysBackward",
|
||||
JComponent.
|
||||
getManagingFocusBackwardTraversalKeys());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class ID for the UI.
|
||||
*
|
||||
* @return the ID ("TextAreaUI")
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default implementation of the model
|
||||
* to be used at construction if one isn't explicitly
|
||||
* given. A new instance of PlainDocument is returned.
|
||||
*
|
||||
* @return the default document model
|
||||
*/
|
||||
protected Document createDefaultModel() {
|
||||
return new PlainDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of characters to expand tabs to.
|
||||
* This will be multiplied by the maximum advance for
|
||||
* variable width fonts. A PropertyChange event ("tabSize") is fired
|
||||
* when the tab size changes.
|
||||
*
|
||||
* @param size number of characters to expand to
|
||||
* @see #getTabSize
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: the number of characters to expand tabs to
|
||||
*/
|
||||
public void setTabSize(int size) {
|
||||
Document doc = getDocument();
|
||||
if (doc != null) {
|
||||
int old = getTabSize();
|
||||
doc.putProperty(PlainDocument.tabSizeAttribute, Integer.valueOf(size));
|
||||
firePropertyChange("tabSize", old, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of characters used to expand tabs. If the document is
|
||||
* null or doesn't have a tab setting, return a default of 8.
|
||||
*
|
||||
* @return the number of characters
|
||||
*/
|
||||
public int getTabSize() {
|
||||
int size = 8;
|
||||
Document doc = getDocument();
|
||||
if (doc != null) {
|
||||
Integer i = (Integer) doc.getProperty(PlainDocument.tabSizeAttribute);
|
||||
if (i != null) {
|
||||
size = i.intValue();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the line-wrapping policy of the text area. If set
|
||||
* to true the lines will be wrapped if they are too long
|
||||
* to fit within the allocated width. If set to false,
|
||||
* the lines will always be unwrapped. A <code>PropertyChange</code>
|
||||
* event ("lineWrap") is fired when the policy is changed.
|
||||
* By default this property is false.
|
||||
*
|
||||
* @param wrap indicates if lines should be wrapped
|
||||
* @see #getLineWrap
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: should lines be wrapped
|
||||
*/
|
||||
public void setLineWrap(boolean wrap) {
|
||||
boolean old = this.wrap;
|
||||
this.wrap = wrap;
|
||||
firePropertyChange("lineWrap", old, wrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the line-wrapping policy of the text area. If set
|
||||
* to true the lines will be wrapped if they are too long
|
||||
* to fit within the allocated width. If set to false,
|
||||
* the lines will always be unwrapped.
|
||||
*
|
||||
* @return if lines will be wrapped
|
||||
*/
|
||||
public boolean getLineWrap() {
|
||||
return wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of wrapping used if the text area is wrapping
|
||||
* lines. If set to true the lines will be wrapped at word
|
||||
* boundaries (whitespace) if they are too long
|
||||
* to fit within the allocated width. If set to false,
|
||||
* the lines will be wrapped at character boundaries.
|
||||
* By default this property is false.
|
||||
*
|
||||
* @param word indicates if word boundaries should be used
|
||||
* for line wrapping
|
||||
* @see #getWrapStyleWord
|
||||
* @beaninfo
|
||||
* preferred: false
|
||||
* bound: true
|
||||
* description: should wrapping occur at word boundaries
|
||||
*/
|
||||
public void setWrapStyleWord(boolean word) {
|
||||
boolean old = this.word;
|
||||
this.word = word;
|
||||
firePropertyChange("wrapStyleWord", old, word);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the style of wrapping used if the text area is wrapping
|
||||
* lines. If set to true the lines will be wrapped at word
|
||||
* boundaries (ie whitespace) if they are too long
|
||||
* to fit within the allocated width. If set to false,
|
||||
* the lines will be wrapped at character boundaries.
|
||||
*
|
||||
* @return if the wrap style should be word boundaries
|
||||
* instead of character boundaries
|
||||
* @see #setWrapStyleWord
|
||||
*/
|
||||
public boolean getWrapStyleWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates an offset into the components text to a
|
||||
* line number.
|
||||
*
|
||||
* @param offset the offset >= 0
|
||||
* @return the line number >= 0
|
||||
* @exception BadLocationException thrown if the offset is
|
||||
* less than zero or greater than the document length.
|
||||
*/
|
||||
public int getLineOfOffset(int offset) throws BadLocationException {
|
||||
Document doc = getDocument();
|
||||
if (offset < 0) {
|
||||
throw new BadLocationException("Can't translate offset to line", -1);
|
||||
} else if (offset > doc.getLength()) {
|
||||
throw new BadLocationException("Can't translate offset to line", doc.getLength()+1);
|
||||
} else {
|
||||
Element map = getDocument().getDefaultRootElement();
|
||||
return map.getElementIndex(offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of lines contained in the area.
|
||||
*
|
||||
* @return the number of lines > 0
|
||||
*/
|
||||
public int getLineCount() {
|
||||
Element map = getDocument().getDefaultRootElement();
|
||||
return map.getElementCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the offset of the start of the given line.
|
||||
*
|
||||
* @param line the line number to translate >= 0
|
||||
* @return the offset >= 0
|
||||
* @exception BadLocationException thrown if the line is
|
||||
* less than zero or greater or equal to the number of
|
||||
* lines contained in the document (as reported by
|
||||
* getLineCount).
|
||||
*/
|
||||
public int getLineStartOffset(int line) throws BadLocationException {
|
||||
int lineCount = getLineCount();
|
||||
if (line < 0) {
|
||||
throw new BadLocationException("Negative line", -1);
|
||||
} else if (line >= lineCount) {
|
||||
throw new BadLocationException("No such line", getDocument().getLength()+1);
|
||||
} else {
|
||||
Element map = getDocument().getDefaultRootElement();
|
||||
Element lineElem = map.getElement(line);
|
||||
return lineElem.getStartOffset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the offset of the end of the given line.
|
||||
*
|
||||
* @param line the line >= 0
|
||||
* @return the offset >= 0
|
||||
* @exception BadLocationException Thrown if the line is
|
||||
* less than zero or greater or equal to the number of
|
||||
* lines contained in the document (as reported by
|
||||
* getLineCount).
|
||||
*/
|
||||
public int getLineEndOffset(int line) throws BadLocationException {
|
||||
int lineCount = getLineCount();
|
||||
if (line < 0) {
|
||||
throw new BadLocationException("Negative line", -1);
|
||||
} else if (line >= lineCount) {
|
||||
throw new BadLocationException("No such line", getDocument().getLength()+1);
|
||||
} else {
|
||||
Element map = getDocument().getDefaultRootElement();
|
||||
Element lineElem = map.getElement(line);
|
||||
int endOffset = lineElem.getEndOffset();
|
||||
// hide the implicit break at the end of the document
|
||||
return ((line == lineCount - 1) ? (endOffset - 1) : endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// --- java.awt.TextArea methods ---------------------------------
|
||||
|
||||
/**
|
||||
* Inserts the specified text at the specified position. Does nothing
|
||||
* if the model is null or if the text is null or empty.
|
||||
*
|
||||
* @param str the text to insert
|
||||
* @param pos the position at which to insert >= 0
|
||||
* @exception IllegalArgumentException if pos is an
|
||||
* invalid position in the model
|
||||
* @see TextComponent#setText
|
||||
* @see #replaceRange
|
||||
*/
|
||||
public void insert(String str, int pos) {
|
||||
Document doc = getDocument();
|
||||
if (doc != null) {
|
||||
try {
|
||||
doc.insertString(pos, str, null);
|
||||
} catch (BadLocationException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given text to the end of the document. Does nothing if
|
||||
* the model is null or the string is null or empty.
|
||||
*
|
||||
* @param str the text to insert
|
||||
* @see #insert
|
||||
*/
|
||||
public void append(String str) {
|
||||
Document doc = getDocument();
|
||||
if (doc != null) {
|
||||
try {
|
||||
doc.insertString(doc.getLength(), str, null);
|
||||
} catch (BadLocationException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces text from the indicated start to end position with the
|
||||
* new text specified. Does nothing if the model is null. Simply
|
||||
* does a delete if the new string is null or empty.
|
||||
*
|
||||
* @param str the text to use as the replacement
|
||||
* @param start the start position >= 0
|
||||
* @param end the end position >= start
|
||||
* @exception IllegalArgumentException if part of the range is an
|
||||
* invalid position in the model
|
||||
* @see #insert
|
||||
*/
|
||||
public void replaceRange(String str, int start, int end) {
|
||||
if (end < start) {
|
||||
throw new IllegalArgumentException("end before start");
|
||||
}
|
||||
Document doc = getDocument();
|
||||
if (doc != null) {
|
||||
try {
|
||||
if (doc instanceof AbstractDocument) {
|
||||
((AbstractDocument)doc).replace(start, end - start, str,
|
||||
null);
|
||||
}
|
||||
else {
|
||||
doc.remove(start, end - start);
|
||||
doc.insertString(start, str, null);
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the TextArea.
|
||||
*
|
||||
* @return the number of rows >= 0
|
||||
*/
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of rows for this TextArea. Calls invalidate() after
|
||||
* setting the new value.
|
||||
*
|
||||
* @param rows the number of rows >= 0
|
||||
* @exception IllegalArgumentException if rows is less than 0
|
||||
* @see #getRows
|
||||
* @beaninfo
|
||||
* description: the number of rows preferred for display
|
||||
*/
|
||||
public void setRows(int rows) {
|
||||
int oldVal = this.rows;
|
||||
if (rows < 0) {
|
||||
throw new IllegalArgumentException("rows less than zero.");
|
||||
}
|
||||
if (rows != oldVal) {
|
||||
this.rows = rows;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the meaning of the height of a row. This defaults to
|
||||
* the height of the font.
|
||||
*
|
||||
* @return the height >= 1
|
||||
*/
|
||||
protected int getRowHeight() {
|
||||
if (rowHeight == 0) {
|
||||
FontMetrics metrics = getFontMetrics(getFont());
|
||||
rowHeight = metrics.getHeight();
|
||||
}
|
||||
return rowHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns in the TextArea.
|
||||
*
|
||||
* @return number of columns >= 0
|
||||
*/
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of columns for this TextArea. Does an invalidate()
|
||||
* after setting the new value.
|
||||
*
|
||||
* @param columns the number of columns >= 0
|
||||
* @exception IllegalArgumentException if columns is less than 0
|
||||
* @see #getColumns
|
||||
* @beaninfo
|
||||
* description: the number of columns preferred for display
|
||||
*/
|
||||
public void setColumns(int columns) {
|
||||
int oldVal = this.columns;
|
||||
if (columns < 0) {
|
||||
throw new IllegalArgumentException("columns less than zero.");
|
||||
}
|
||||
if (columns != oldVal) {
|
||||
this.columns = columns;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets column width.
|
||||
* The meaning of what a column is can be considered a fairly weak
|
||||
* notion for some fonts. This method is used to define the width
|
||||
* of a column. By default this is defined to be the width of the
|
||||
* character <em>m</em> for the font used. This method can be
|
||||
* redefined to be some alternative amount.
|
||||
*
|
||||
* @return the column width >= 1
|
||||
*/
|
||||
protected int getColumnWidth() {
|
||||
if (columnWidth == 0) {
|
||||
FontMetrics metrics = getFontMetrics(getFont());
|
||||
columnWidth = metrics.charWidth('m');
|
||||
}
|
||||
return columnWidth;
|
||||
}
|
||||
|
||||
// --- Component methods -----------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the TextArea. This is the
|
||||
* maximum of the size needed to display the text and the
|
||||
* size requested for the viewport.
|
||||
*
|
||||
* @return the size
|
||||
*/
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension d = super.getPreferredSize();
|
||||
d = (d == null) ? new Dimension(400,400) : d;
|
||||
Insets insets = getInsets();
|
||||
|
||||
if (columns != 0) {
|
||||
d.width = Math.max(d.width, columns * getColumnWidth() +
|
||||
insets.left + insets.right);
|
||||
}
|
||||
if (rows != 0) {
|
||||
d.height = Math.max(d.height, rows * getRowHeight() +
|
||||
insets.top + insets.bottom);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current font. This removes cached row height and column
|
||||
* width so the new font will be reflected, and calls revalidate().
|
||||
*
|
||||
* @param f the font to use as the current font
|
||||
*/
|
||||
public void setFont(Font f) {
|
||||
super.setFont(f);
|
||||
rowHeight = 0;
|
||||
columnWidth = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JTextArea. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JTextArea.
|
||||
*/
|
||||
protected String paramString() {
|
||||
String wrapString = (wrap ?
|
||||
"true" : "false");
|
||||
String wordString = (word ?
|
||||
"true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",colums=" + columns +
|
||||
",columWidth=" + columnWidth +
|
||||
",rows=" + rows +
|
||||
",rowHeight=" + rowHeight +
|
||||
",word=" + wordString +
|
||||
",wrap=" + wrapString;
|
||||
}
|
||||
|
||||
// --- Scrollable methods ----------------------------------------
|
||||
|
||||
/**
|
||||
* Returns true if a viewport should always force the width of this
|
||||
* Scrollable to match the width of the viewport. This is implemented
|
||||
* to return true if the line wrapping policy is true, and false
|
||||
* if lines are not being wrapped.
|
||||
*
|
||||
* @return true if a viewport should force the Scrollables width
|
||||
* to match its own.
|
||||
*/
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return (wrap) ? true : super.getScrollableTracksViewportWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the viewport if this component
|
||||
* is embedded in a JScrollPane. This uses the desired column
|
||||
* and row settings if they have been set, otherwise the superclass
|
||||
* behavior is used.
|
||||
*
|
||||
* @return The preferredSize of a JViewport whose view is this Scrollable.
|
||||
* @see JViewport#getPreferredSize
|
||||
*/
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
Dimension size = super.getPreferredScrollableViewportSize();
|
||||
size = (size == null) ? new Dimension(400,400) : size;
|
||||
Insets insets = getInsets();
|
||||
|
||||
size.width = (columns == 0) ? size.width :
|
||||
columns * getColumnWidth() + insets.left + insets.right;
|
||||
size.height = (rows == 0) ? size.height :
|
||||
rows * getRowHeight() + insets.top + insets.bottom;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Components that display logical rows or columns should compute
|
||||
* the scroll increment that will completely expose one new row
|
||||
* or column, depending on the value of orientation. This is implemented
|
||||
* to use the values returned by the <code>getRowHeight</code> and
|
||||
* <code>getColumnWidth</code> methods.
|
||||
* <p>
|
||||
* Scrolling containers, like JScrollPane, will use this method
|
||||
* each time the user requests a unit scroll.
|
||||
*
|
||||
* @param visibleRect the view area visible within the viewport
|
||||
* @param orientation Either SwingConstants.VERTICAL or
|
||||
* SwingConstants.HORIZONTAL.
|
||||
* @param direction Less than zero to scroll up/left,
|
||||
* greater than zero for down/right.
|
||||
* @return The "unit" increment for scrolling in the specified direction
|
||||
* @exception IllegalArgumentException for an invalid orientation
|
||||
* @see JScrollBar#setUnitIncrement
|
||||
* @see #getRowHeight
|
||||
* @see #getColumnWidth
|
||||
*/
|
||||
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
switch (orientation) {
|
||||
case SwingConstants.VERTICAL:
|
||||
return getRowHeight();
|
||||
case SwingConstants.HORIZONTAL:
|
||||
return getColumnWidth();
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid orientation: " + orientation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JTextArea.
|
||||
* For JTextAreas, the AccessibleContext takes the form of an
|
||||
* AccessibleJTextArea.
|
||||
* A new AccessibleJTextArea instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJTextArea that serves as the
|
||||
* AccessibleContext of this JTextArea
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJTextArea();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JTextArea</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to text area user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJTextArea extends AccessibleJTextComponent {
|
||||
|
||||
/**
|
||||
* Gets the state set of this object.
|
||||
*
|
||||
* @return an instance of AccessibleStateSet describing the states
|
||||
* of the object
|
||||
* @see AccessibleStateSet
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
states.add(AccessibleState.MULTI_LINE);
|
||||
return states;
|
||||
}
|
||||
}
|
||||
|
||||
// --- variables -------------------------------------------------
|
||||
|
||||
private int rows;
|
||||
private int columns;
|
||||
private int columnWidth;
|
||||
private int rowHeight;
|
||||
private boolean wrap;
|
||||
private boolean word;
|
||||
|
||||
}
|
||||
961
jdkSrc/jdk8/javax/swing/JTextField.java
Normal file
961
jdkSrc/jdk8/javax/swing/JTextField.java
Normal file
@@ -0,0 +1,961 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import sun.swing.SwingUtilities2;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <code>JTextField</code> is a lightweight component that allows the editing
|
||||
* of a single line of text.
|
||||
* For information on and examples of using text fields,
|
||||
* see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>
|
||||
* in <em>The Java Tutorial.</em>
|
||||
*
|
||||
* <p>
|
||||
* <code>JTextField</code> is intended to be source-compatible
|
||||
* with <code>java.awt.TextField</code> where it is reasonable to do so. This
|
||||
* component has capabilities not found in the <code>java.awt.TextField</code>
|
||||
* class. The superclass should be consulted for additional capabilities.
|
||||
* <p>
|
||||
* <code>JTextField</code> has a method to establish the string used as the
|
||||
* command string for the action event that gets fired. The
|
||||
* <code>java.awt.TextField</code> used the text of the field as the command
|
||||
* string for the <code>ActionEvent</code>.
|
||||
* <code>JTextField</code> will use the command
|
||||
* string set with the <code>setActionCommand</code> method if not <code>null</code>,
|
||||
* otherwise it will use the text of the field as a compatibility with
|
||||
* <code>java.awt.TextField</code>.
|
||||
* <p>
|
||||
* The method <code>setEchoChar</code> and <code>getEchoChar</code>
|
||||
* are not provided directly to avoid a new implementation of a
|
||||
* pluggable look-and-feel inadvertently exposing password characters.
|
||||
* To provide password-like services a separate class <code>JPasswordField</code>
|
||||
* extends <code>JTextField</code> to provide this service with an independently
|
||||
* pluggable look-and-feel.
|
||||
* <p>
|
||||
* The <code>java.awt.TextField</code> could be monitored for changes by adding
|
||||
* a <code>TextListener</code> for <code>TextEvent</code>'s.
|
||||
* In the <code>JTextComponent</code> based
|
||||
* components, changes are broadcasted from the model via a
|
||||
* <code>DocumentEvent</code> to <code>DocumentListeners</code>.
|
||||
* The <code>DocumentEvent</code> gives
|
||||
* the location of the change and the kind of change if desired.
|
||||
* The code fragment might look something like:
|
||||
* <pre><code>
|
||||
* DocumentListener myListener = ??;
|
||||
* JTextField myArea = ??;
|
||||
* myArea.getDocument().addDocumentListener(myListener);
|
||||
* </code></pre>
|
||||
* <p>
|
||||
* The horizontal alignment of <code>JTextField</code> can be set to be left
|
||||
* justified, leading justified, centered, right justified or trailing justified.
|
||||
* Right/trailing justification is useful if the required size
|
||||
* of the field text is smaller than the size allocated to it.
|
||||
* This is determined by the <code>setHorizontalAlignment</code>
|
||||
* and <code>getHorizontalAlignment</code> methods. The default
|
||||
* is to be leading justified.
|
||||
* <p>
|
||||
* How the text field consumes VK_ENTER events depends
|
||||
* on whether the text field has any action listeners.
|
||||
* If so, then VK_ENTER results in the listeners
|
||||
* getting an ActionEvent,
|
||||
* and the VK_ENTER event is consumed.
|
||||
* This is compatible with how AWT text fields handle VK_ENTER events.
|
||||
* If the text field has no action listeners, then as of v 1.3 the VK_ENTER
|
||||
* event is not consumed. Instead, the bindings of ancestor components
|
||||
* are processed, which enables the default button feature of
|
||||
* JFC/Swing to work.
|
||||
* <p>
|
||||
* Customized fields can easily be created by extending the model and
|
||||
* changing the default model provided. For example, the following piece
|
||||
* of code will create a field that holds only upper case characters. It
|
||||
* will work even if text is pasted into from the clipboard or it is altered via
|
||||
* programmatic changes.
|
||||
* <pre><code>
|
||||
|
||||
public class UpperCaseField extends JTextField {
|
||||
|
||||
public UpperCaseField(int cols) {
|
||||
super(cols);
|
||||
}
|
||||
|
||||
protected Document createDefaultModel() {
|
||||
return new UpperCaseDocument();
|
||||
}
|
||||
|
||||
static class UpperCaseDocument extends PlainDocument {
|
||||
|
||||
public void insertString(int offs, String str, AttributeSet a)
|
||||
throws BadLocationException {
|
||||
|
||||
if (str == null) {
|
||||
return;
|
||||
}
|
||||
char[] upper = str.toCharArray();
|
||||
for (int i = 0; i < upper.length; i++) {
|
||||
upper[i] = Character.toUpperCase(upper[i]);
|
||||
}
|
||||
super.insertString(offs, new String(upper), a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* </code></pre>
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: A component which allows for the editing of a single line of text.
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* @see #setActionCommand
|
||||
* @see JPasswordField
|
||||
* @see #addActionListener
|
||||
*/
|
||||
public class JTextField extends JTextComponent implements SwingConstants {
|
||||
|
||||
/**
|
||||
* Constructs a new <code>TextField</code>. A default model is created,
|
||||
* the initial string is <code>null</code>,
|
||||
* and the number of columns is set to 0.
|
||||
*/
|
||||
public JTextField() {
|
||||
this(null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>TextField</code> initialized with the
|
||||
* specified text. A default model is created and the number of
|
||||
* columns is 0.
|
||||
*
|
||||
* @param text the text to be displayed, or <code>null</code>
|
||||
*/
|
||||
public JTextField(String text) {
|
||||
this(null, text, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new empty <code>TextField</code> with the specified
|
||||
* number of columns.
|
||||
* A default model is created and the initial string is set to
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param columns the number of columns to use to calculate
|
||||
* the preferred width; if columns is set to zero, the
|
||||
* preferred width will be whatever naturally results from
|
||||
* the component implementation
|
||||
*/
|
||||
public JTextField(int columns) {
|
||||
this(null, null, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>TextField</code> initialized with the
|
||||
* specified text and columns. A default model is created.
|
||||
*
|
||||
* @param text the text to be displayed, or <code>null</code>
|
||||
* @param columns the number of columns to use to calculate
|
||||
* the preferred width; if columns is set to zero, the
|
||||
* preferred width will be whatever naturally results from
|
||||
* the component implementation
|
||||
*/
|
||||
public JTextField(String text, int columns) {
|
||||
this(null, text, columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>JTextField</code> that uses the given text
|
||||
* storage model and the given number of columns.
|
||||
* This is the constructor through which the other constructors feed.
|
||||
* If the document is <code>null</code>, a default model is created.
|
||||
*
|
||||
* @param doc the text storage to use; if this is <code>null</code>,
|
||||
* a default will be provided by calling the
|
||||
* <code>createDefaultModel</code> method
|
||||
* @param text the initial string to display, or <code>null</code>
|
||||
* @param columns the number of columns to use to calculate
|
||||
* the preferred width >= 0; if <code>columns</code>
|
||||
* is set to zero, the preferred width will be whatever
|
||||
* naturally results from the component implementation
|
||||
* @exception IllegalArgumentException if <code>columns</code> < 0
|
||||
*/
|
||||
public JTextField(Document doc, String text, int columns) {
|
||||
if (columns < 0) {
|
||||
throw new IllegalArgumentException("columns less than zero.");
|
||||
}
|
||||
visibility = new DefaultBoundedRangeModel();
|
||||
visibility.addChangeListener(new ScrollRepainter());
|
||||
this.columns = columns;
|
||||
if (doc == null) {
|
||||
doc = createDefaultModel();
|
||||
}
|
||||
setDocument(doc);
|
||||
if (text != null) {
|
||||
setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class ID for a UI.
|
||||
*
|
||||
* @return the string "TextFieldUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Associates the editor with a text document.
|
||||
* The currently registered factory is used to build a view for
|
||||
* the document, which gets displayed by the editor after revalidation.
|
||||
* A PropertyChange event ("document") is propagated to each listener.
|
||||
*
|
||||
* @param doc the document to display/edit
|
||||
* @see #getDocument
|
||||
* @beaninfo
|
||||
* description: the text document model
|
||||
* bound: true
|
||||
* expert: true
|
||||
*/
|
||||
public void setDocument(Document doc) {
|
||||
if (doc != null) {
|
||||
doc.putProperty("filterNewlines", Boolean.TRUE);
|
||||
}
|
||||
super.setDocument(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to <code>revalidate</code> that come from within the
|
||||
* textfield itself will
|
||||
* be handled by validating the textfield, unless the textfield
|
||||
* is contained within a <code>JViewport</code>,
|
||||
* in which case this returns false.
|
||||
*
|
||||
* @return if the parent of this textfield is a <code>JViewPort</code>
|
||||
* return false, otherwise return true
|
||||
*
|
||||
* @see JComponent#revalidate
|
||||
* @see JComponent#isValidateRoot
|
||||
* @see java.awt.Container#isValidateRoot
|
||||
*/
|
||||
@Override
|
||||
public boolean isValidateRoot() {
|
||||
return !(SwingUtilities.getUnwrappedParent(this) instanceof JViewport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the horizontal alignment of the text.
|
||||
* Valid keys are:
|
||||
* <ul>
|
||||
* <li><code>JTextField.LEFT</code>
|
||||
* <li><code>JTextField.CENTER</code>
|
||||
* <li><code>JTextField.RIGHT</code>
|
||||
* <li><code>JTextField.LEADING</code>
|
||||
* <li><code>JTextField.TRAILING</code>
|
||||
* </ul>
|
||||
*
|
||||
* @return the horizontal alignment
|
||||
*/
|
||||
public int getHorizontalAlignment() {
|
||||
return horizontalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the horizontal alignment of the text.
|
||||
* Valid keys are:
|
||||
* <ul>
|
||||
* <li><code>JTextField.LEFT</code>
|
||||
* <li><code>JTextField.CENTER</code>
|
||||
* <li><code>JTextField.RIGHT</code>
|
||||
* <li><code>JTextField.LEADING</code>
|
||||
* <li><code>JTextField.TRAILING</code>
|
||||
* </ul>
|
||||
* <code>invalidate</code> and <code>repaint</code> are called when the
|
||||
* alignment is set,
|
||||
* and a <code>PropertyChange</code> event ("horizontalAlignment") is fired.
|
||||
*
|
||||
* @param alignment the alignment
|
||||
* @exception IllegalArgumentException if <code>alignment</code>
|
||||
* is not a valid key
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: Set the field alignment to LEFT, CENTER, RIGHT,
|
||||
* LEADING (the default) or TRAILING
|
||||
* enum: LEFT JTextField.LEFT CENTER JTextField.CENTER RIGHT JTextField.RIGHT
|
||||
* LEADING JTextField.LEADING TRAILING JTextField.TRAILING
|
||||
*/
|
||||
public void setHorizontalAlignment(int alignment) {
|
||||
if (alignment == horizontalAlignment) return;
|
||||
int oldValue = horizontalAlignment;
|
||||
if ((alignment == LEFT) || (alignment == CENTER) ||
|
||||
(alignment == RIGHT)|| (alignment == LEADING) ||
|
||||
(alignment == TRAILING)) {
|
||||
horizontalAlignment = alignment;
|
||||
} else {
|
||||
throw new IllegalArgumentException("horizontalAlignment");
|
||||
}
|
||||
firePropertyChange("horizontalAlignment", oldValue, horizontalAlignment);
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default implementation of the model
|
||||
* to be used at construction if one isn't explicitly
|
||||
* given. An instance of <code>PlainDocument</code> is returned.
|
||||
*
|
||||
* @return the default model implementation
|
||||
*/
|
||||
protected Document createDefaultModel() {
|
||||
return new PlainDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns in this <code>TextField</code>.
|
||||
*
|
||||
* @return the number of columns >= 0
|
||||
*/
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of columns in this <code>TextField</code>,
|
||||
* and then invalidate the layout.
|
||||
*
|
||||
* @param columns the number of columns >= 0
|
||||
* @exception IllegalArgumentException if <code>columns</code>
|
||||
* is less than 0
|
||||
* @beaninfo
|
||||
* description: the number of columns preferred for display
|
||||
*/
|
||||
public void setColumns(int columns) {
|
||||
int oldVal = this.columns;
|
||||
if (columns < 0) {
|
||||
throw new IllegalArgumentException("columns less than zero.");
|
||||
}
|
||||
if (columns != oldVal) {
|
||||
this.columns = columns;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column width.
|
||||
* The meaning of what a column is can be considered a fairly weak
|
||||
* notion for some fonts. This method is used to define the width
|
||||
* of a column. By default this is defined to be the width of the
|
||||
* character <em>m</em> for the font used. This method can be
|
||||
* redefined to be some alternative amount
|
||||
*
|
||||
* @return the column width >= 1
|
||||
*/
|
||||
protected int getColumnWidth() {
|
||||
if (columnWidth == 0) {
|
||||
FontMetrics metrics = getFontMetrics(getFont());
|
||||
columnWidth = metrics.charWidth('m');
|
||||
}
|
||||
return columnWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size <code>Dimensions</code> needed for this
|
||||
* <code>TextField</code>. If a non-zero number of columns has been
|
||||
* set, the width is set to the columns multiplied by
|
||||
* the column width.
|
||||
*
|
||||
* @return the dimension of this textfield
|
||||
*/
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
if (columns != 0) {
|
||||
Insets insets = getInsets();
|
||||
size.width = columns * getColumnWidth() +
|
||||
insets.left + insets.right;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current font. This removes cached row height and column
|
||||
* width so the new font will be reflected.
|
||||
* <code>revalidate</code> is called after setting the font.
|
||||
*
|
||||
* @param f the new font
|
||||
*/
|
||||
public void setFont(Font f) {
|
||||
super.setFont(f);
|
||||
columnWidth = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified action listener to receive
|
||||
* action events from this textfield.
|
||||
*
|
||||
* @param l the action listener to be added
|
||||
*/
|
||||
public synchronized void addActionListener(ActionListener l) {
|
||||
listenerList.add(ActionListener.class, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified action listener so that it no longer
|
||||
* receives action events from this textfield.
|
||||
*
|
||||
* @param l the action listener to be removed
|
||||
*/
|
||||
public synchronized void removeActionListener(ActionListener l) {
|
||||
if ((l != null) && (getAction() == l)) {
|
||||
setAction(null);
|
||||
} else {
|
||||
listenerList.remove(ActionListener.class, l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>ActionListener</code>s added
|
||||
* to this JTextField with addActionListener().
|
||||
*
|
||||
* @return all of the <code>ActionListener</code>s added or an empty
|
||||
* array if no listeners have been added
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized ActionListener[] getActionListeners() {
|
||||
return listenerList.getListeners(ActionListener.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all listeners that have registered interest for
|
||||
* notification on this event type. The event instance
|
||||
* is lazily created.
|
||||
* The listener list is processed in last to
|
||||
* first order.
|
||||
* @see EventListenerList
|
||||
*/
|
||||
protected void fireActionPerformed() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
int modifiers = 0;
|
||||
AWTEvent currentEvent = EventQueue.getCurrentEvent();
|
||||
if (currentEvent instanceof InputEvent) {
|
||||
modifiers = ((InputEvent)currentEvent).getModifiers();
|
||||
} else if (currentEvent instanceof ActionEvent) {
|
||||
modifiers = ((ActionEvent)currentEvent).getModifiers();
|
||||
}
|
||||
ActionEvent e =
|
||||
new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
|
||||
(command != null) ? command : getText(),
|
||||
EventQueue.getMostRecentEventTime(), modifiers);
|
||||
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ActionListener.class) {
|
||||
((ActionListener)listeners[i+1]).actionPerformed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command string used for action events.
|
||||
*
|
||||
* @param command the command string
|
||||
*/
|
||||
public void setActionCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
private Action action;
|
||||
private PropertyChangeListener actionPropertyChangeListener;
|
||||
|
||||
/**
|
||||
* Sets the <code>Action</code> for the <code>ActionEvent</code> source.
|
||||
* The new <code>Action</code> replaces
|
||||
* any previously set <code>Action</code> but does not affect
|
||||
* <code>ActionListeners</code> independently
|
||||
* added with <code>addActionListener</code>.
|
||||
* If the <code>Action</code> is already a registered
|
||||
* <code>ActionListener</code>
|
||||
* for the <code>ActionEvent</code> source, it is not re-registered.
|
||||
* <p>
|
||||
* Setting the <code>Action</code> results in immediately changing
|
||||
* all the properties described in <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a>.
|
||||
* Subsequently, the textfield's properties are automatically updated
|
||||
* as the <code>Action</code>'s properties change.
|
||||
* <p>
|
||||
* This method uses three other methods to set
|
||||
* and help track the <code>Action</code>'s property values.
|
||||
* It uses the <code>configurePropertiesFromAction</code> method
|
||||
* to immediately change the textfield's properties.
|
||||
* To track changes in the <code>Action</code>'s property values,
|
||||
* this method registers the <code>PropertyChangeListener</code>
|
||||
* returned by <code>createActionPropertyChangeListener</code>. The
|
||||
* default {@code PropertyChangeListener} invokes the
|
||||
* {@code actionPropertyChanged} method when a property in the
|
||||
* {@code Action} changes.
|
||||
*
|
||||
* @param a the <code>Action</code> for the <code>JTextField</code>,
|
||||
* or <code>null</code>
|
||||
* @since 1.3
|
||||
* @see Action
|
||||
* @see #getAction
|
||||
* @see #configurePropertiesFromAction
|
||||
* @see #createActionPropertyChangeListener
|
||||
* @see #actionPropertyChanged
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* attribute: visualUpdate true
|
||||
* description: the Action instance connected with this ActionEvent source
|
||||
*/
|
||||
public void setAction(Action a) {
|
||||
Action oldValue = getAction();
|
||||
if (action==null || !action.equals(a)) {
|
||||
action = a;
|
||||
if (oldValue!=null) {
|
||||
removeActionListener(oldValue);
|
||||
oldValue.removePropertyChangeListener(actionPropertyChangeListener);
|
||||
actionPropertyChangeListener = null;
|
||||
}
|
||||
configurePropertiesFromAction(action);
|
||||
if (action!=null) {
|
||||
// Don't add if it is already a listener
|
||||
if (!isListener(ActionListener.class, action)) {
|
||||
addActionListener(action);
|
||||
}
|
||||
// Reverse linkage:
|
||||
actionPropertyChangeListener = createActionPropertyChangeListener(action);
|
||||
action.addPropertyChangeListener(actionPropertyChangeListener);
|
||||
}
|
||||
firePropertyChange("action", oldValue, action);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isListener(Class c, ActionListener a) {
|
||||
boolean isListener = false;
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==c && listeners[i+1]==a) {
|
||||
isListener=true;
|
||||
}
|
||||
}
|
||||
return isListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently set <code>Action</code> for this
|
||||
* <code>ActionEvent</code> source, or <code>null</code>
|
||||
* if no <code>Action</code> is set.
|
||||
*
|
||||
* @return the <code>Action</code> for this <code>ActionEvent</code> source,
|
||||
* or <code>null</code>
|
||||
* @since 1.3
|
||||
* @see Action
|
||||
* @see #setAction
|
||||
*/
|
||||
public Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the properties on this textfield to match those in the specified
|
||||
* <code>Action</code>. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details as to which properties this sets.
|
||||
*
|
||||
* @param a the <code>Action</code> from which to get the properties,
|
||||
* or <code>null</code>
|
||||
* @since 1.3
|
||||
* @see Action
|
||||
* @see #setAction
|
||||
*/
|
||||
protected void configurePropertiesFromAction(Action a) {
|
||||
AbstractAction.setEnabledFromAction(this, a);
|
||||
AbstractAction.setToolTipTextFromAction(this, a);
|
||||
setActionCommandFromAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the textfield's state in response to property changes in
|
||||
* associated action. This method is invoked from the
|
||||
* {@code PropertyChangeListener} returned from
|
||||
* {@code createActionPropertyChangeListener}. Subclasses do not normally
|
||||
* need to invoke this. Subclasses that support additional {@code Action}
|
||||
* properties should override this and
|
||||
* {@code configurePropertiesFromAction}.
|
||||
* <p>
|
||||
* Refer to the table at <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for a list of
|
||||
* the properties this method sets.
|
||||
*
|
||||
* @param action the <code>Action</code> associated with this textfield
|
||||
* @param propertyName the name of the property that changed
|
||||
* @since 1.6
|
||||
* @see Action
|
||||
* @see #configurePropertiesFromAction
|
||||
*/
|
||||
protected void actionPropertyChanged(Action action, String propertyName) {
|
||||
if (propertyName == Action.ACTION_COMMAND_KEY) {
|
||||
setActionCommandFromAction(action);
|
||||
} else if (propertyName == "enabled") {
|
||||
AbstractAction.setEnabledFromAction(this, action);
|
||||
} else if (propertyName == Action.SHORT_DESCRIPTION) {
|
||||
AbstractAction.setToolTipTextFromAction(this, action);
|
||||
}
|
||||
}
|
||||
|
||||
private void setActionCommandFromAction(Action action) {
|
||||
setActionCommand((action == null) ? null :
|
||||
(String)action.getValue(Action.ACTION_COMMAND_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a <code>PropertyChangeListener</code> that is
|
||||
* responsible for listening for changes from the specified
|
||||
* <code>Action</code> and updating the appropriate properties.
|
||||
* <p>
|
||||
* <b>Warning:</b> If you subclass this do not create an anonymous
|
||||
* inner class. If you do the lifetime of the textfield will be tied to
|
||||
* that of the <code>Action</code>.
|
||||
*
|
||||
* @param a the textfield's action
|
||||
* @since 1.3
|
||||
* @see Action
|
||||
* @see #setAction
|
||||
*/
|
||||
protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
|
||||
return new TextFieldActionPropertyChangeListener(this, a);
|
||||
}
|
||||
|
||||
private static class TextFieldActionPropertyChangeListener extends
|
||||
ActionPropertyChangeListener<JTextField> {
|
||||
TextFieldActionPropertyChangeListener(JTextField tf, Action a) {
|
||||
super(tf, a);
|
||||
}
|
||||
|
||||
protected void actionPropertyChanged(JTextField textField,
|
||||
Action action,
|
||||
PropertyChangeEvent e) {
|
||||
if (AbstractAction.shouldReconfigure(e)) {
|
||||
textField.configurePropertiesFromAction(action);
|
||||
} else {
|
||||
textField.actionPropertyChanged(action, e.getPropertyName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the command list for the editor. This is
|
||||
* the list of commands supported by the plugged-in UI
|
||||
* augmented by the collection of commands that the
|
||||
* editor itself supports. These are useful for binding
|
||||
* to events, such as in a keymap.
|
||||
*
|
||||
* @return the command list
|
||||
*/
|
||||
public Action[] getActions() {
|
||||
return TextAction.augmentList(super.getActions(), defaultActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes action events occurring on this textfield by
|
||||
* dispatching them to any registered <code>ActionListener</code> objects.
|
||||
* This is normally called by the controller registered with
|
||||
* textfield.
|
||||
*/
|
||||
public void postActionEvent() {
|
||||
fireActionPerformed();
|
||||
}
|
||||
|
||||
// --- Scrolling support -----------------------------------
|
||||
|
||||
/**
|
||||
* Gets the visibility of the text field. This can
|
||||
* be adjusted to change the location of the visible
|
||||
* area if the size of the field is greater than
|
||||
* the area that was allocated to the field.
|
||||
*
|
||||
* <p>
|
||||
* The fields look-and-feel implementation manages
|
||||
* the values of the minimum, maximum, and extent
|
||||
* properties on the <code>BoundedRangeModel</code>.
|
||||
*
|
||||
* @return the visibility
|
||||
* @see BoundedRangeModel
|
||||
*/
|
||||
public BoundedRangeModel getHorizontalVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scroll offset, in pixels.
|
||||
*
|
||||
* @return the offset >= 0
|
||||
*/
|
||||
public int getScrollOffset() {
|
||||
return visibility.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scroll offset, in pixels.
|
||||
*
|
||||
* @param scrollOffset the offset >= 0
|
||||
*/
|
||||
public void setScrollOffset(int scrollOffset) {
|
||||
visibility.setValue(scrollOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the field left or right.
|
||||
*
|
||||
* @param r the region to scroll
|
||||
*/
|
||||
public void scrollRectToVisible(Rectangle r) {
|
||||
// convert to coordinate system of the bounded range
|
||||
Insets i = getInsets();
|
||||
int x0 = r.x + visibility.getValue() - i.left;
|
||||
int x1 = x0 + r.width;
|
||||
if (x0 < visibility.getValue()) {
|
||||
// Scroll to the left
|
||||
visibility.setValue(x0);
|
||||
} else if(x1 > visibility.getValue() + visibility.getExtent()) {
|
||||
// Scroll to the right
|
||||
visibility.setValue(x1 - visibility.getExtent());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the receiver has an <code>ActionListener</code>
|
||||
* installed.
|
||||
*/
|
||||
boolean hasActionListener() {
|
||||
// Guaranteed to return a non-null array
|
||||
Object[] listeners = listenerList.getListenerList();
|
||||
// Process the listeners last to first, notifying
|
||||
// those that are interested in this event
|
||||
for (int i = listeners.length-2; i>=0; i-=2) {
|
||||
if (listeners[i]==ActionListener.class) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- variables -------------------------------------------
|
||||
|
||||
/**
|
||||
* Name of the action to send notification that the
|
||||
* contents of the field have been accepted. Typically
|
||||
* this is bound to a carriage-return.
|
||||
*/
|
||||
public static final String notifyAction = "notify-field-accept";
|
||||
|
||||
private BoundedRangeModel visibility;
|
||||
private int horizontalAlignment = LEADING;
|
||||
private int columns;
|
||||
private int columnWidth;
|
||||
private String command;
|
||||
|
||||
private static final Action[] defaultActions = {
|
||||
new NotifyAction()
|
||||
};
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "TextFieldUI";
|
||||
|
||||
// --- Action implementations -----------------------------------
|
||||
|
||||
// Note that JFormattedTextField.CommitAction extends this
|
||||
static class NotifyAction extends TextAction {
|
||||
|
||||
NotifyAction() {
|
||||
super(notifyAction);
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JTextComponent target = getFocusedComponent();
|
||||
if (target instanceof JTextField) {
|
||||
JTextField field = (JTextField) target;
|
||||
field.postActionEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
JTextComponent target = getFocusedComponent();
|
||||
if (target instanceof JTextField) {
|
||||
return ((JTextField)target).hasActionListener();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ScrollRepainter implements ChangeListener, Serializable {
|
||||
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
repaint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JTextField</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JTextField</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String horizontalAlignmentString;
|
||||
if (horizontalAlignment == LEFT) {
|
||||
horizontalAlignmentString = "LEFT";
|
||||
} else if (horizontalAlignment == CENTER) {
|
||||
horizontalAlignmentString = "CENTER";
|
||||
} else if (horizontalAlignment == RIGHT) {
|
||||
horizontalAlignmentString = "RIGHT";
|
||||
} else if (horizontalAlignment == LEADING) {
|
||||
horizontalAlignmentString = "LEADING";
|
||||
} else if (horizontalAlignment == TRAILING) {
|
||||
horizontalAlignmentString = "TRAILING";
|
||||
} else horizontalAlignmentString = "";
|
||||
String commandString = (command != null ?
|
||||
command : "");
|
||||
|
||||
return super.paramString() +
|
||||
",columns=" + columns +
|
||||
",columnWidth=" + columnWidth +
|
||||
",command=" + commandString +
|
||||
",horizontalAlignment=" + horizontalAlignmentString;
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Gets the <code>AccessibleContext</code> associated with this
|
||||
* <code>JTextField</code>. For <code>JTextFields</code>,
|
||||
* the <code>AccessibleContext</code> takes the form of an
|
||||
* <code>AccessibleJTextField</code>.
|
||||
* A new <code>AccessibleJTextField</code> instance is created
|
||||
* if necessary.
|
||||
*
|
||||
* @return an <code>AccessibleJTextField</code> that serves as the
|
||||
* <code>AccessibleContext</code> of this <code>JTextField</code>
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJTextField();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JTextField</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to text field user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJTextField extends AccessibleJTextComponent {
|
||||
|
||||
/**
|
||||
* Gets the state set of this object.
|
||||
*
|
||||
* @return an instance of AccessibleStateSet describing the states
|
||||
* of the object
|
||||
* @see AccessibleState
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
states.add(AccessibleState.SINGLE_LINE);
|
||||
return states;
|
||||
}
|
||||
}
|
||||
}
|
||||
493
jdkSrc/jdk8/javax/swing/JTextPane.java
Normal file
493
jdkSrc/jdk8/javax/swing/JTextPane.java
Normal file
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.*;
|
||||
|
||||
/**
|
||||
* A text component that can be marked up with attributes that are
|
||||
* represented graphically.
|
||||
* You can find how-to information and examples of using text panes in
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
|
||||
* a section in <em>The Java Tutorial.</em>
|
||||
*
|
||||
* <p>
|
||||
* This component models paragraphs
|
||||
* that are composed of runs of character level attributes. Each
|
||||
* paragraph may have a logical style attached to it which contains
|
||||
* the default attributes to use if not overridden by attributes set
|
||||
* on the paragraph or character run. Components and images may
|
||||
* be embedded in the flow of text.
|
||||
*
|
||||
* <dl>
|
||||
* <dt><b><font size=+1>Newlines</font></b>
|
||||
* <dd>
|
||||
* For a discussion on how newlines are handled, see
|
||||
* <a href="text/DefaultEditorKit.html">DefaultEditorKit</a>.
|
||||
* </dl>
|
||||
*
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* description: A text component that can be marked up with attributes that are graphically represented.
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* @see javax.swing.text.StyledEditorKit
|
||||
*/
|
||||
public class JTextPane extends JEditorPane {
|
||||
|
||||
/**
|
||||
* Creates a new <code>JTextPane</code>. A new instance of
|
||||
* <code>StyledEditorKit</code> is
|
||||
* created and set, and the document model set to <code>null</code>.
|
||||
*/
|
||||
public JTextPane() {
|
||||
super();
|
||||
EditorKit editorKit = createDefaultEditorKit();
|
||||
String contentType = editorKit.getContentType();
|
||||
if (contentType != null
|
||||
&& getEditorKitClassNameForContentType(contentType) ==
|
||||
defaultEditorKitMap.get(contentType)) {
|
||||
setEditorKitForContentType(contentType, editorKit);
|
||||
}
|
||||
setEditorKit(editorKit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>JTextPane</code>, with a specified document model.
|
||||
* A new instance of <code>javax.swing.text.StyledEditorKit</code>
|
||||
* is created and set.
|
||||
*
|
||||
* @param doc the document model
|
||||
*/
|
||||
public JTextPane(StyledDocument doc) {
|
||||
this();
|
||||
setStyledDocument(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class ID for the UI.
|
||||
*
|
||||
* @return the string "TextPaneUI"
|
||||
*
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the editor with a text document. This
|
||||
* must be a <code>StyledDocument</code>.
|
||||
*
|
||||
* @param doc the document to display/edit
|
||||
* @exception IllegalArgumentException if <code>doc</code> can't
|
||||
* be narrowed to a <code>StyledDocument</code> which is the
|
||||
* required type of model for this text component
|
||||
*/
|
||||
public void setDocument(Document doc) {
|
||||
if (doc instanceof StyledDocument) {
|
||||
super.setDocument(doc);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Model must be StyledDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the editor with a text document.
|
||||
* The currently registered factory is used to build a view for
|
||||
* the document, which gets displayed by the editor.
|
||||
*
|
||||
* @param doc the document to display/edit
|
||||
*/
|
||||
public void setStyledDocument(StyledDocument doc) {
|
||||
super.setDocument(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the model associated with the editor.
|
||||
*
|
||||
* @return the model
|
||||
*/
|
||||
public StyledDocument getStyledDocument() {
|
||||
return (StyledDocument) getDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the currently selected content with new content
|
||||
* represented by the given string. If there is no selection
|
||||
* this amounts to an insert of the given text. If there
|
||||
* is no replacement text this amounts to a removal of the
|
||||
* current selection. The replacement text will have the
|
||||
* attributes currently defined for input at the point of
|
||||
* insertion. If the document is not editable, beep and return.
|
||||
*
|
||||
* @param content the content to replace the selection with
|
||||
*/
|
||||
@Override
|
||||
public void replaceSelection(String content) {
|
||||
replaceSelection(content, true);
|
||||
}
|
||||
|
||||
private void replaceSelection(String content, boolean checkEditable) {
|
||||
if (checkEditable && !isEditable()) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback(JTextPane.this);
|
||||
return;
|
||||
}
|
||||
Document doc = getStyledDocument();
|
||||
if (doc != null) {
|
||||
try {
|
||||
Caret caret = getCaret();
|
||||
boolean composedTextSaved = saveComposedText(caret.getDot());
|
||||
int p0 = Math.min(caret.getDot(), caret.getMark());
|
||||
int p1 = Math.max(caret.getDot(), caret.getMark());
|
||||
AttributeSet attr = getInputAttributes().copyAttributes();
|
||||
if (doc instanceof AbstractDocument) {
|
||||
((AbstractDocument)doc).replace(p0, p1 - p0, content,attr);
|
||||
}
|
||||
else {
|
||||
if (p0 != p1) {
|
||||
doc.remove(p0, p1 - p0);
|
||||
}
|
||||
if (content != null && content.length() > 0) {
|
||||
doc.insertString(p0, content, attr);
|
||||
}
|
||||
}
|
||||
if (composedTextSaved) {
|
||||
restoreComposedText();
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback(JTextPane.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a component into the document as a replacement
|
||||
* for the currently selected content. If there is no
|
||||
* selection the component is effectively inserted at the
|
||||
* current position of the caret. This is represented in
|
||||
* the associated document as an attribute of one character
|
||||
* of content.
|
||||
* <p>
|
||||
* The component given is the actual component used by the
|
||||
* JTextPane. Since components cannot be a child of more than
|
||||
* one container, this method should not be used in situations
|
||||
* where the model is shared by text components.
|
||||
* <p>
|
||||
* The component is placed relative to the text baseline
|
||||
* according to the value returned by
|
||||
* <code>Component.getAlignmentY</code>. For Swing components
|
||||
* this value can be conveniently set using the method
|
||||
* <code>JComponent.setAlignmentY</code>. For example, setting
|
||||
* a value of <code>0.75</code> will cause 75 percent of the
|
||||
* component to be above the baseline, and 25 percent of the
|
||||
* component to be below the baseline.
|
||||
*
|
||||
* @param c the component to insert
|
||||
*/
|
||||
public void insertComponent(Component c) {
|
||||
MutableAttributeSet inputAttributes = getInputAttributes();
|
||||
inputAttributes.removeAttributes(inputAttributes);
|
||||
StyleConstants.setComponent(inputAttributes, c);
|
||||
replaceSelection(" ", false);
|
||||
inputAttributes.removeAttributes(inputAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an icon into the document as a replacement
|
||||
* for the currently selected content. If there is no
|
||||
* selection the icon is effectively inserted at the
|
||||
* current position of the caret. This is represented in
|
||||
* the associated document as an attribute of one character
|
||||
* of content.
|
||||
*
|
||||
* @param g the icon to insert
|
||||
* @see Icon
|
||||
*/
|
||||
public void insertIcon(Icon g) {
|
||||
MutableAttributeSet inputAttributes = getInputAttributes();
|
||||
inputAttributes.removeAttributes(inputAttributes);
|
||||
StyleConstants.setIcon(inputAttributes, g);
|
||||
replaceSelection(" ", false);
|
||||
inputAttributes.removeAttributes(inputAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new style into the logical style hierarchy. Style attributes
|
||||
* resolve from bottom up so an attribute specified in a child
|
||||
* will override an attribute specified in the parent.
|
||||
*
|
||||
* @param nm the name of the style (must be unique within the
|
||||
* collection of named styles). The name may be <code>null</code>
|
||||
* if the style is unnamed, but the caller is responsible
|
||||
* for managing the reference returned as an unnamed style can't
|
||||
* be fetched by name. An unnamed style may be useful for things
|
||||
* like character attribute overrides such as found in a style
|
||||
* run.
|
||||
* @param parent the parent style. This may be <code>null</code>
|
||||
* if unspecified
|
||||
* attributes need not be resolved in some other style.
|
||||
* @return the new <code>Style</code>
|
||||
*/
|
||||
public Style addStyle(String nm, Style parent) {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
return doc.addStyle(nm, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a named non-<code>null</code> style previously added to
|
||||
* the document.
|
||||
*
|
||||
* @param nm the name of the style to remove
|
||||
*/
|
||||
public void removeStyle(String nm) {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
doc.removeStyle(nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a named non-<code>null</code> style previously added.
|
||||
*
|
||||
* @param nm the name of the style
|
||||
* @return the <code>Style</code>
|
||||
*/
|
||||
public Style getStyle(String nm) {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
return doc.getStyle(nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logical style to use for the paragraph at the
|
||||
* current caret position. If attributes aren't explicitly set
|
||||
* for character and paragraph attributes they will resolve
|
||||
* through the logical style assigned to the paragraph, which
|
||||
* in term may resolve through some hierarchy completely
|
||||
* independent of the element hierarchy in the document.
|
||||
*
|
||||
* @param s the logical style to assign to the paragraph,
|
||||
* or <code>null</code> for no style
|
||||
*/
|
||||
public void setLogicalStyle(Style s) {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
doc.setLogicalStyle(getCaretPosition(), s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the logical style assigned to the paragraph represented
|
||||
* by the current position of the caret, or <code>null</code>.
|
||||
*
|
||||
* @return the <code>Style</code>
|
||||
*/
|
||||
public Style getLogicalStyle() {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
return doc.getLogicalStyle(getCaretPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the character attributes in effect at the
|
||||
* current location of the caret, or <code>null</code>.
|
||||
*
|
||||
* @return the attributes, or <code>null</code>
|
||||
*/
|
||||
public AttributeSet getCharacterAttributes() {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
Element run = doc.getCharacterElement(getCaretPosition());
|
||||
if (run != null) {
|
||||
return run.getAttributes();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given attributes to character
|
||||
* content. If there is a selection, the attributes
|
||||
* are applied to the selection range. If there
|
||||
* is no selection, the attributes are applied to
|
||||
* the input attribute set which defines the attributes
|
||||
* for any new text that gets inserted.
|
||||
*
|
||||
* @param attr the attributes
|
||||
* @param replace if true, then replace the existing attributes first
|
||||
*/
|
||||
public void setCharacterAttributes(AttributeSet attr, boolean replace) {
|
||||
int p0 = getSelectionStart();
|
||||
int p1 = getSelectionEnd();
|
||||
if (p0 != p1) {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
|
||||
} else {
|
||||
MutableAttributeSet inputAttributes = getInputAttributes();
|
||||
if (replace) {
|
||||
inputAttributes.removeAttributes(inputAttributes);
|
||||
}
|
||||
inputAttributes.addAttributes(attr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the current paragraph attributes in effect
|
||||
* at the location of the caret, or <code>null</code> if none.
|
||||
*
|
||||
* @return the attributes
|
||||
*/
|
||||
public AttributeSet getParagraphAttributes() {
|
||||
StyledDocument doc = getStyledDocument();
|
||||
Element paragraph = doc.getParagraphElement(getCaretPosition());
|
||||
if (paragraph != null) {
|
||||
return paragraph.getAttributes();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given attributes to paragraphs. If
|
||||
* there is a selection, the attributes are applied
|
||||
* to the paragraphs that intersect the selection.
|
||||
* If there is no selection, the attributes are applied
|
||||
* to the paragraph at the current caret position.
|
||||
*
|
||||
* @param attr the non-<code>null</code> attributes
|
||||
* @param replace if true, replace the existing attributes first
|
||||
*/
|
||||
public void setParagraphAttributes(AttributeSet attr, boolean replace) {
|
||||
int p0 = getSelectionStart();
|
||||
int p1 = getSelectionEnd();
|
||||
StyledDocument doc = getStyledDocument();
|
||||
doc.setParagraphAttributes(p0, p1 - p0, attr, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input attributes for the pane.
|
||||
*
|
||||
* @return the attributes
|
||||
*/
|
||||
public MutableAttributeSet getInputAttributes() {
|
||||
return getStyledEditorKit().getInputAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the editor kit.
|
||||
*
|
||||
* @return the editor kit
|
||||
*/
|
||||
protected final StyledEditorKit getStyledEditorKit() {
|
||||
return (StyledEditorKit) getEditorKit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "TextPaneUI";
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*
|
||||
* @param s the output stream
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- JEditorPane ------------------------------------
|
||||
|
||||
/**
|
||||
* Creates the <code>EditorKit</code> to use by default. This
|
||||
* is implemented to return <code>javax.swing.text.StyledEditorKit</code>.
|
||||
*
|
||||
* @return the editor kit
|
||||
*/
|
||||
protected EditorKit createDefaultEditorKit() {
|
||||
return new StyledEditorKit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently installed kit for handling
|
||||
* content. This is the bound property that
|
||||
* establishes the content type of the editor.
|
||||
*
|
||||
* @param kit the desired editor behavior
|
||||
* @exception IllegalArgumentException if kit is not a
|
||||
* <code>StyledEditorKit</code>
|
||||
*/
|
||||
public final void setEditorKit(EditorKit kit) {
|
||||
if (kit instanceof StyledEditorKit) {
|
||||
super.setEditorKit(kit);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Must be StyledEditorKit");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JTextPane</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JTextPane</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
}
|
||||
424
jdkSrc/jdk8/javax/swing/JToggleButton.java
Normal file
424
jdkSrc/jdk8/javax/swing/JToggleButton.java
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of a two-state button.
|
||||
* The <code>JRadioButton</code> and <code>JCheckBox</code> classes
|
||||
* are subclasses of this class.
|
||||
* For information on using them see
|
||||
* <a
|
||||
href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* Buttons can be configured, and to some degree controlled, by
|
||||
* <code><a href="Action.html">Action</a></code>s. Using an
|
||||
* <code>Action</code> with a button has many benefits beyond directly
|
||||
* configuring a button. Refer to <a href="Action.html#buttonActions">
|
||||
* Swing Components Supporting <code>Action</code></a> for more
|
||||
* details, and you can find more information in <a
|
||||
* href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
|
||||
* to Use Actions</a>, a section in <em>The Java Tutorial</em>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer false
|
||||
* description: An implementation of a two-state button.
|
||||
*
|
||||
* @see JRadioButton
|
||||
* @see JCheckBox
|
||||
* @author Jeff Dinkins
|
||||
*/
|
||||
public class JToggleButton extends AbstractButton implements Accessible {
|
||||
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ToggleButtonUI";
|
||||
|
||||
/**
|
||||
* Creates an initially unselected toggle button
|
||||
* without setting the text or image.
|
||||
*/
|
||||
public JToggleButton () {
|
||||
this(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an initially unselected toggle button
|
||||
* with the specified image but no text.
|
||||
*
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JToggleButton(Icon icon) {
|
||||
this(null, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a toggle button with the specified image
|
||||
* and selection state, but no text.
|
||||
*
|
||||
* @param icon the image that the button should display
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JToggleButton(Icon icon, boolean selected) {
|
||||
this(null, icon, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unselected toggle button with the specified text.
|
||||
*
|
||||
* @param text the string displayed on the toggle button
|
||||
*/
|
||||
public JToggleButton (String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a toggle button with the specified text
|
||||
* and selection state.
|
||||
*
|
||||
* @param text the string displayed on the toggle button
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JToggleButton (String text, boolean selected) {
|
||||
this(text, null, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a toggle button where properties are taken from the
|
||||
* Action supplied.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JToggleButton(Action a) {
|
||||
this();
|
||||
setAction(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a toggle button that has the specified text and image,
|
||||
* and that is initially unselected.
|
||||
*
|
||||
* @param text the string displayed on the button
|
||||
* @param icon the image that the button should display
|
||||
*/
|
||||
public JToggleButton(String text, Icon icon) {
|
||||
this(text, icon, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a toggle button with the specified text, image, and
|
||||
* selection state.
|
||||
*
|
||||
* @param text the text of the toggle button
|
||||
* @param icon the image that the button should display
|
||||
* @param selected if true, the button is initially selected;
|
||||
* otherwise, the button is initially unselected
|
||||
*/
|
||||
public JToggleButton (String text, Icon icon, boolean selected) {
|
||||
// Create the model
|
||||
setModel(new ToggleButtonModel());
|
||||
|
||||
model.setSelected(selected);
|
||||
|
||||
// initialize
|
||||
init(text, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ButtonUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that specifies the name of the l&f class
|
||||
* that renders this component.
|
||||
*
|
||||
* @return String "ToggleButtonUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* description: A string that specifies the name of the L&F class
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overriden to return true, JToggleButton supports
|
||||
* the selected state.
|
||||
*/
|
||||
boolean shouldUpdateSelectedStateFromAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
|
||||
/**
|
||||
* The ToggleButton model
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
public static class ToggleButtonModel extends DefaultButtonModel {
|
||||
|
||||
/**
|
||||
* Creates a new ToggleButton Model
|
||||
*/
|
||||
public ToggleButtonModel () {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the button is selected.
|
||||
*/
|
||||
public boolean isSelected() {
|
||||
// if(getGroup() != null) {
|
||||
// return getGroup().isSelected(this);
|
||||
// } else {
|
||||
return (stateMask & SELECTED) != 0;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the selected state of the button.
|
||||
* @param b true selects the toggle button,
|
||||
* false deselects the toggle button.
|
||||
*/
|
||||
public void setSelected(boolean b) {
|
||||
ButtonGroup group = getGroup();
|
||||
if (group != null) {
|
||||
// use the group model instead
|
||||
group.setSelected(this, b);
|
||||
b = group.isSelected(this);
|
||||
}
|
||||
|
||||
if (isSelected() == b) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= SELECTED;
|
||||
} else {
|
||||
stateMask &= ~SELECTED;
|
||||
}
|
||||
|
||||
// Send ChangeEvent
|
||||
fireStateChanged();
|
||||
|
||||
// Send ItemEvent
|
||||
fireItemStateChanged(
|
||||
new ItemEvent(this,
|
||||
ItemEvent.ITEM_STATE_CHANGED,
|
||||
this,
|
||||
this.isSelected() ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pressed state of the toggle button.
|
||||
*/
|
||||
public void setPressed(boolean b) {
|
||||
if ((isPressed() == b) || !isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b == false && isArmed()) {
|
||||
setSelected(!this.isSelected());
|
||||
}
|
||||
|
||||
if (b) {
|
||||
stateMask |= PRESSED;
|
||||
} else {
|
||||
stateMask &= ~PRESSED;
|
||||
}
|
||||
|
||||
fireStateChanged();
|
||||
|
||||
if(!isPressed() && isArmed()) {
|
||||
int modifiers = 0;
|
||||
AWTEvent currentEvent = EventQueue.getCurrentEvent();
|
||||
if (currentEvent instanceof InputEvent) {
|
||||
modifiers = ((InputEvent)currentEvent).getModifiers();
|
||||
} else if (currentEvent instanceof ActionEvent) {
|
||||
modifiers = ((ActionEvent)currentEvent).getModifiers();
|
||||
}
|
||||
fireActionPerformed(
|
||||
new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
|
||||
getActionCommand(),
|
||||
EventQueue.getMostRecentEventTime(),
|
||||
modifiers));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See readObject() and writeObject() in JComponent for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this JToggleButton. 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</code>.
|
||||
*
|
||||
* @return a string representation of this JToggleButton.
|
||||
*/
|
||||
protected String paramString() {
|
||||
return super.paramString();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JToggleButton.
|
||||
* For toggle buttons, the AccessibleContext takes the form of an
|
||||
* AccessibleJToggleButton.
|
||||
* A new AccessibleJToggleButton instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJToggleButton that serves as the
|
||||
* AccessibleContext of this JToggleButton
|
||||
* @beaninfo
|
||||
* expert: true
|
||||
* description: The AccessibleContext associated with this ToggleButton.
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJToggleButton();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JToggleButton</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to toggle button user-interface
|
||||
* elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
protected class AccessibleJToggleButton extends AccessibleAbstractButton
|
||||
implements ItemListener {
|
||||
|
||||
public AccessibleJToggleButton() {
|
||||
super();
|
||||
JToggleButton.this.addItemListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire accessible property change events when the state of the
|
||||
* toggle button changes.
|
||||
*/
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
JToggleButton tb = (JToggleButton) e.getSource();
|
||||
if (JToggleButton.this.accessibleContext != null) {
|
||||
if (tb.isSelected()) {
|
||||
JToggleButton.this.accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
null, AccessibleState.CHECKED);
|
||||
} else {
|
||||
JToggleButton.this.accessibleContext.firePropertyChange(
|
||||
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
|
||||
AccessibleState.CHECKED, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.TOGGLE_BUTTON;
|
||||
}
|
||||
} // inner class AccessibleJToggleButton
|
||||
}
|
||||
871
jdkSrc/jdk8/javax/swing/JToolBar.java
Normal file
871
jdkSrc/jdk8/javax/swing/JToolBar.java
Normal file
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.ComponentOrientation;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.LayoutManager2;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
||||
/**
|
||||
* <code>JToolBar</code> provides a component that is useful for
|
||||
* displaying commonly used <code>Action</code>s or controls.
|
||||
* For examples and information on using tool bars see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html">How to Use Tool Bars</a>,
|
||||
* a section in <em>The Java Tutorial</em>.
|
||||
*
|
||||
* <p>
|
||||
* With most look and feels,
|
||||
* the user can drag out a tool bar into a separate window
|
||||
* (unless the <code>floatable</code> property is set to <code>false</code>).
|
||||
* For drag-out to work correctly, it is recommended that you add
|
||||
* <code>JToolBar</code> instances to one of the four "sides" of a
|
||||
* container whose layout manager is a <code>BorderLayout</code>,
|
||||
* and do not add children to any of the other four "sides".
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* description: A component which displays commonly used controls or Actions.
|
||||
*
|
||||
* @author Georges Saab
|
||||
* @author Jeff Shapiro
|
||||
* @see Action
|
||||
*/
|
||||
public class JToolBar extends JComponent implements SwingConstants, Accessible
|
||||
{
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ToolBarUI";
|
||||
|
||||
private boolean paintBorder = true;
|
||||
private Insets margin = null;
|
||||
private boolean floatable = true;
|
||||
private int orientation = HORIZONTAL;
|
||||
|
||||
/**
|
||||
* Creates a new tool bar; orientation defaults to <code>HORIZONTAL</code>.
|
||||
*/
|
||||
public JToolBar()
|
||||
{
|
||||
this( HORIZONTAL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tool bar with the specified <code>orientation</code>.
|
||||
* The <code>orientation</code> must be either <code>HORIZONTAL</code>
|
||||
* or <code>VERTICAL</code>.
|
||||
*
|
||||
* @param orientation the orientation desired
|
||||
*/
|
||||
public JToolBar( int orientation )
|
||||
{
|
||||
this(null, orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tool bar with the specified <code>name</code>. The
|
||||
* name is used as the title of the undocked tool bar. The default
|
||||
* orientation is <code>HORIZONTAL</code>.
|
||||
*
|
||||
* @param name the name of the tool bar
|
||||
* @since 1.3
|
||||
*/
|
||||
public JToolBar( String name ) {
|
||||
this(name, HORIZONTAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tool bar with a specified <code>name</code> and
|
||||
* <code>orientation</code>.
|
||||
* All other constructors call this constructor.
|
||||
* If <code>orientation</code> is an invalid value, an exception will
|
||||
* be thrown.
|
||||
*
|
||||
* @param name the name of the tool bar
|
||||
* @param orientation the initial orientation -- it must be
|
||||
* either <code>HORIZONTAL</code> or <code>VERTICAL</code>
|
||||
* @exception IllegalArgumentException if orientation is neither
|
||||
* <code>HORIZONTAL</code> nor <code>VERTICAL</code>
|
||||
* @since 1.3
|
||||
*/
|
||||
public JToolBar( String name , int orientation) {
|
||||
setName(name);
|
||||
checkOrientation( orientation );
|
||||
|
||||
this.orientation = orientation;
|
||||
DefaultToolBarLayout layout = new DefaultToolBarLayout( orientation );
|
||||
setLayout( layout );
|
||||
|
||||
addPropertyChangeListener( layout );
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tool bar's current UI.
|
||||
* @see #setUI
|
||||
*/
|
||||
public ToolBarUI getUI() {
|
||||
return (ToolBarUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the L&F object that renders this component.
|
||||
*
|
||||
* @param ui the <code>ToolBarUI</code> L&F object
|
||||
* @see UIDefaults#getUI
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* attribute: visualUpdate true
|
||||
* description: The UI object that implements the Component's LookAndFeel.
|
||||
*/
|
||||
public void setUI(ToolBarUI ui) {
|
||||
super.setUI(ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification from the <code>UIFactory</code> that the L&F has changed.
|
||||
* Called to replace the UI with the latest version from the
|
||||
* <code>UIFactory</code>.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ToolBarUI)UIManager.getUI(this));
|
||||
// GTKLookAndFeel installs a different LayoutManager, and sets it
|
||||
// to null after changing the look and feel, so, install the default
|
||||
// if the LayoutManager is null.
|
||||
if (getLayout() == null) {
|
||||
setLayout(new DefaultToolBarLayout(getOrientation()));
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "ToolBarUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index of the specified component.
|
||||
* (Note: Separators occupy index positions.)
|
||||
*
|
||||
* @param c the <code>Component</code> to find
|
||||
* @return an integer indicating the component's position,
|
||||
* where 0 is first
|
||||
*/
|
||||
public int getComponentIndex(Component c) {
|
||||
int ncomponents = this.getComponentCount();
|
||||
Component[] component = this.getComponents();
|
||||
for (int i = 0 ; i < ncomponents ; i++) {
|
||||
Component comp = component[i];
|
||||
if (comp == c)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component at the specified index.
|
||||
*
|
||||
* @param i the component's position, where 0 is first
|
||||
* @return the <code>Component</code> at that position,
|
||||
* or <code>null</code> for an invalid index
|
||||
*
|
||||
*/
|
||||
public Component getComponentAtIndex(int i) {
|
||||
int ncomponents = this.getComponentCount();
|
||||
if ( i >= 0 && i < ncomponents) {
|
||||
Component[] component = this.getComponents();
|
||||
return component[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the margin between the tool bar's border and
|
||||
* its buttons. Setting to <code>null</code> causes the tool bar to
|
||||
* use the default margins. The tool bar's default <code>Border</code>
|
||||
* object uses this value to create the proper margin.
|
||||
* However, if a non-default border is set on the tool bar,
|
||||
* it is that <code>Border</code> object's responsibility to create the
|
||||
* appropriate margin space (otherwise this property will
|
||||
* effectively be ignored).
|
||||
*
|
||||
* @param m an <code>Insets</code> object that defines the space
|
||||
* between the border and the buttons
|
||||
* @see Insets
|
||||
* @beaninfo
|
||||
* description: The margin between the tool bar's border and contents
|
||||
* bound: true
|
||||
* expert: true
|
||||
*/
|
||||
public void setMargin(Insets m)
|
||||
{
|
||||
Insets old = margin;
|
||||
margin = m;
|
||||
firePropertyChange("margin", old, m);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the margin between the tool bar's border and
|
||||
* its buttons.
|
||||
*
|
||||
* @return an <code>Insets</code> object containing the margin values
|
||||
* @see Insets
|
||||
*/
|
||||
public Insets getMargin()
|
||||
{
|
||||
if(margin == null) {
|
||||
return new Insets(0,0,0,0);
|
||||
} else {
|
||||
return margin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>borderPainted</code> property.
|
||||
*
|
||||
* @return the value of the <code>borderPainted</code> property
|
||||
* @see #setBorderPainted
|
||||
*/
|
||||
public boolean isBorderPainted()
|
||||
{
|
||||
return paintBorder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>borderPainted</code> property, which is
|
||||
* <code>true</code> if the border should be painted.
|
||||
* The default value for this property is <code>true</code>.
|
||||
* Some look and feels might not implement painted borders;
|
||||
* they will ignore this property.
|
||||
*
|
||||
* @param b if true, the border is painted
|
||||
* @see #isBorderPainted
|
||||
* @beaninfo
|
||||
* description: Does the tool bar paint its borders?
|
||||
* bound: true
|
||||
* expert: true
|
||||
*/
|
||||
public void setBorderPainted(boolean b)
|
||||
{
|
||||
if ( paintBorder != b )
|
||||
{
|
||||
boolean old = paintBorder;
|
||||
paintBorder = b;
|
||||
firePropertyChange("borderPainted", old, b);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the tool bar's border if the <code>borderPainted</code> property
|
||||
* is <code>true</code>.
|
||||
*
|
||||
* @param g the <code>Graphics</code> context in which the painting
|
||||
* is done
|
||||
* @see JComponent#paint
|
||||
* @see JComponent#setBorder
|
||||
*/
|
||||
protected void paintBorder(Graphics g)
|
||||
{
|
||||
if (isBorderPainted())
|
||||
{
|
||||
super.paintBorder(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>floatable</code> property.
|
||||
*
|
||||
* @return the value of the <code>floatable</code> property
|
||||
*
|
||||
* @see #setFloatable
|
||||
*/
|
||||
public boolean isFloatable()
|
||||
{
|
||||
return floatable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>floatable</code> property,
|
||||
* which must be <code>true</code> for the user to move the tool bar.
|
||||
* Typically, a floatable tool bar can be
|
||||
* dragged into a different position within the same container
|
||||
* or out into its own window.
|
||||
* The default value of this property is <code>true</code>.
|
||||
* Some look and feels might not implement floatable tool bars;
|
||||
* they will ignore this property.
|
||||
*
|
||||
* @param b if <code>true</code>, the tool bar can be moved;
|
||||
* <code>false</code> otherwise
|
||||
* @see #isFloatable
|
||||
* @beaninfo
|
||||
* description: Can the tool bar be made to float by the user?
|
||||
* bound: true
|
||||
* preferred: true
|
||||
*/
|
||||
public void setFloatable( boolean b )
|
||||
{
|
||||
if ( floatable != b )
|
||||
{
|
||||
boolean old = floatable;
|
||||
floatable = b;
|
||||
|
||||
firePropertyChange("floatable", old, b);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current orientation of the tool bar. The value is either
|
||||
* <code>HORIZONTAL</code> or <code>VERTICAL</code>.
|
||||
*
|
||||
* @return an integer representing the current orientation -- either
|
||||
* <code>HORIZONTAL</code> or <code>VERTICAL</code>
|
||||
* @see #setOrientation
|
||||
*/
|
||||
public int getOrientation()
|
||||
{
|
||||
return this.orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the orientation of the tool bar. The orientation must have
|
||||
* either the value <code>HORIZONTAL</code> or <code>VERTICAL</code>.
|
||||
* If <code>orientation</code> is
|
||||
* an invalid value, an exception will be thrown.
|
||||
*
|
||||
* @param o the new orientation -- either <code>HORIZONTAL</code> or
|
||||
* <code>VERTICAL</code>
|
||||
* @exception IllegalArgumentException if orientation is neither
|
||||
* <code>HORIZONTAL</code> nor <code>VERTICAL</code>
|
||||
* @see #getOrientation
|
||||
* @beaninfo
|
||||
* description: The current orientation of the tool bar
|
||||
* bound: true
|
||||
* preferred: true
|
||||
* enum: HORIZONTAL SwingConstants.HORIZONTAL
|
||||
* VERTICAL SwingConstants.VERTICAL
|
||||
*/
|
||||
public void setOrientation( int o )
|
||||
{
|
||||
checkOrientation( o );
|
||||
|
||||
if ( orientation != o )
|
||||
{
|
||||
int old = orientation;
|
||||
orientation = o;
|
||||
|
||||
firePropertyChange("orientation", old, o);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rollover state of this toolbar. If the rollover state is true
|
||||
* then the border of the toolbar buttons will be drawn only when the
|
||||
* mouse pointer hovers over them. The default value of this property
|
||||
* is false.
|
||||
* <p>
|
||||
* The implementation of a look and feel may choose to ignore this
|
||||
* property.
|
||||
*
|
||||
* @param rollover true for rollover toolbar buttons; otherwise false
|
||||
* @since 1.4
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* preferred: true
|
||||
* attribute: visualUpdate true
|
||||
* description: Will draw rollover button borders in the toolbar.
|
||||
*/
|
||||
public void setRollover(boolean rollover) {
|
||||
putClientProperty("JToolBar.isRollover",
|
||||
rollover ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rollover state.
|
||||
*
|
||||
* @return true if rollover toolbar buttons are to be drawn; otherwise false
|
||||
* @see #setRollover(boolean)
|
||||
* @since 1.4
|
||||
*/
|
||||
public boolean isRollover() {
|
||||
Boolean rollover = (Boolean)getClientProperty("JToolBar.isRollover");
|
||||
if (rollover != null) {
|
||||
return rollover.booleanValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkOrientation( int orientation )
|
||||
{
|
||||
switch ( orientation )
|
||||
{
|
||||
case VERTICAL:
|
||||
case HORIZONTAL:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "orientation must be one of: VERTICAL, HORIZONTAL" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a separator of default size to the end of the tool bar.
|
||||
* The default size is determined by the current look and feel.
|
||||
*/
|
||||
public void addSeparator()
|
||||
{
|
||||
addSeparator(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a separator of a specified size to the end
|
||||
* of the tool bar.
|
||||
*
|
||||
* @param size the <code>Dimension</code> of the separator
|
||||
*/
|
||||
public void addSeparator( Dimension size )
|
||||
{
|
||||
JToolBar.Separator s = new JToolBar.Separator( size );
|
||||
add(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new <code>JButton</code> which dispatches the action.
|
||||
*
|
||||
* @param a the <code>Action</code> object to add as a new menu item
|
||||
* @return the new button which dispatches the action
|
||||
*/
|
||||
public JButton add(Action a) {
|
||||
JButton b = createActionComponent(a);
|
||||
b.setAction(a);
|
||||
add(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method which creates the <code>JButton</code> for
|
||||
* <code>Action</code>s added to the <code>JToolBar</code>.
|
||||
* The default name is empty if a <code>null</code> action is passed.
|
||||
*
|
||||
* @param a the <code>Action</code> for the button to be added
|
||||
* @return the newly created button
|
||||
* @see Action
|
||||
* @since 1.3
|
||||
*/
|
||||
protected JButton createActionComponent(Action a) {
|
||||
JButton b = new JButton() {
|
||||
protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
|
||||
PropertyChangeListener pcl = createActionChangeListener(this);
|
||||
if (pcl==null) {
|
||||
pcl = super.createActionPropertyChangeListener(a);
|
||||
}
|
||||
return pcl;
|
||||
}
|
||||
};
|
||||
if (a != null && (a.getValue(Action.SMALL_ICON) != null ||
|
||||
a.getValue(Action.LARGE_ICON_KEY) != null)) {
|
||||
b.setHideActionText(true);
|
||||
}
|
||||
b.setHorizontalTextPosition(JButton.CENTER);
|
||||
b.setVerticalTextPosition(JButton.BOTTOM);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a properly configured <code>PropertyChangeListener</code>
|
||||
* which updates the control as changes to the <code>Action</code> occur,
|
||||
* or <code>null</code> if the default
|
||||
* property change listener for the control is desired.
|
||||
*
|
||||
* @return <code>null</code>
|
||||
*/
|
||||
protected PropertyChangeListener createActionChangeListener(JButton b) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a <code>JButton</code> is being added, it is initially
|
||||
* set to be disabled.
|
||||
*
|
||||
* @param comp the component to be enhanced
|
||||
* @param constraints the constraints to be enforced on the component
|
||||
* @param index the index of the component
|
||||
*
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index) {
|
||||
if (comp instanceof Separator) {
|
||||
if (getOrientation() == VERTICAL) {
|
||||
( (Separator)comp ).setOrientation(JSeparator.HORIZONTAL);
|
||||
} else {
|
||||
( (Separator)comp ).setOrientation(JSeparator.VERTICAL);
|
||||
}
|
||||
}
|
||||
super.addImpl(comp, constraints, index);
|
||||
if (comp instanceof JButton) {
|
||||
((JButton)comp).setDefaultCapable(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A toolbar-specific separator. An object with dimension but
|
||||
* no contents used to divide buttons on a tool bar into groups.
|
||||
*/
|
||||
static public class Separator extends JSeparator
|
||||
{
|
||||
private Dimension separatorSize;
|
||||
|
||||
/**
|
||||
* Creates a new toolbar separator with the default size
|
||||
* as defined by the current look and feel.
|
||||
*/
|
||||
public Separator()
|
||||
{
|
||||
this( null ); // let the UI define the default size
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new toolbar separator with the specified size.
|
||||
*
|
||||
* @param size the <code>Dimension</code> of the separator
|
||||
*/
|
||||
public Separator( Dimension size )
|
||||
{
|
||||
super( JSeparator.HORIZONTAL );
|
||||
setSeparatorSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "ToolBarSeparatorUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID()
|
||||
{
|
||||
return "ToolBarSeparatorUI";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the separator.
|
||||
*
|
||||
* @param size the new <code>Dimension</code> of the separator
|
||||
*/
|
||||
public void setSeparatorSize( Dimension size )
|
||||
{
|
||||
if (size != null) {
|
||||
separatorSize = size;
|
||||
} else {
|
||||
super.updateUI();
|
||||
}
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the separator
|
||||
*
|
||||
* @return the <code>Dimension</code> object containing the separator's
|
||||
* size (This is a reference, NOT a copy!)
|
||||
*/
|
||||
public Dimension getSeparatorSize()
|
||||
{
|
||||
return separatorSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum size for the separator.
|
||||
*
|
||||
* @return the <code>Dimension</code> object containing the separator's
|
||||
* minimum size
|
||||
*/
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
if (separatorSize != null) {
|
||||
return separatorSize.getSize();
|
||||
} else {
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum size for the separator.
|
||||
*
|
||||
* @return the <code>Dimension</code> object containing the separator's
|
||||
* maximum size
|
||||
*/
|
||||
public Dimension getMaximumSize()
|
||||
{
|
||||
if (separatorSize != null) {
|
||||
return separatorSize.getSize();
|
||||
} else {
|
||||
return super.getMaximumSize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred size for the separator.
|
||||
*
|
||||
* @return the <code>Dimension</code> object containing the separator's
|
||||
* preferred size
|
||||
*/
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
if (separatorSize != null) {
|
||||
return separatorSize.getSize();
|
||||
} else {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code> in
|
||||
* <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JToolBar</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JToolBar</code>.
|
||||
*/
|
||||
protected String paramString() {
|
||||
String paintBorderString = (paintBorder ?
|
||||
"true" : "false");
|
||||
String marginString = (margin != null ?
|
||||
margin.toString() : "");
|
||||
String floatableString = (floatable ?
|
||||
"true" : "false");
|
||||
String orientationString = (orientation == HORIZONTAL ?
|
||||
"HORIZONTAL" : "VERTICAL");
|
||||
|
||||
return super.paramString() +
|
||||
",floatable=" + floatableString +
|
||||
",margin=" + marginString +
|
||||
",orientation=" + orientationString +
|
||||
",paintBorder=" + paintBorderString;
|
||||
}
|
||||
|
||||
|
||||
private class DefaultToolBarLayout
|
||||
implements LayoutManager2, Serializable, PropertyChangeListener, UIResource {
|
||||
|
||||
BoxLayout lm;
|
||||
|
||||
DefaultToolBarLayout(int orientation) {
|
||||
if (orientation == JToolBar.VERTICAL) {
|
||||
lm = new BoxLayout(JToolBar.this, BoxLayout.PAGE_AXIS);
|
||||
} else {
|
||||
lm = new BoxLayout(JToolBar.this, BoxLayout.LINE_AXIS);
|
||||
}
|
||||
}
|
||||
|
||||
public void addLayoutComponent(String name, Component comp) {
|
||||
lm.addLayoutComponent(name, comp);
|
||||
}
|
||||
|
||||
public void addLayoutComponent(Component comp, Object constraints) {
|
||||
lm.addLayoutComponent(comp, constraints);
|
||||
}
|
||||
|
||||
public void removeLayoutComponent(Component comp) {
|
||||
lm.removeLayoutComponent(comp);
|
||||
}
|
||||
|
||||
public Dimension preferredLayoutSize(Container target) {
|
||||
return lm.preferredLayoutSize(target);
|
||||
}
|
||||
|
||||
public Dimension minimumLayoutSize(Container target) {
|
||||
return lm.minimumLayoutSize(target);
|
||||
}
|
||||
|
||||
public Dimension maximumLayoutSize(Container target) {
|
||||
return lm.maximumLayoutSize(target);
|
||||
}
|
||||
|
||||
public void layoutContainer(Container target) {
|
||||
lm.layoutContainer(target);
|
||||
}
|
||||
|
||||
public float getLayoutAlignmentX(Container target) {
|
||||
return lm.getLayoutAlignmentX(target);
|
||||
}
|
||||
|
||||
public float getLayoutAlignmentY(Container target) {
|
||||
return lm.getLayoutAlignmentY(target);
|
||||
}
|
||||
|
||||
public void invalidateLayout(Container target) {
|
||||
lm.invalidateLayout(target);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
String name = e.getPropertyName();
|
||||
if( name.equals("orientation") ) {
|
||||
int o = ((Integer)e.getNewValue()).intValue();
|
||||
|
||||
if (o == JToolBar.VERTICAL)
|
||||
lm = new BoxLayout(JToolBar.this, BoxLayout.PAGE_AXIS);
|
||||
else {
|
||||
lm = new BoxLayout(JToolBar.this, BoxLayout.LINE_AXIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setLayout(LayoutManager mgr) {
|
||||
LayoutManager oldMgr = getLayout();
|
||||
if (oldMgr instanceof PropertyChangeListener) {
|
||||
removePropertyChangeListener((PropertyChangeListener)oldMgr);
|
||||
}
|
||||
super.setLayout(mgr);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JToolBar.
|
||||
* For tool bars, the AccessibleContext takes the form of an
|
||||
* AccessibleJToolBar.
|
||||
* A new AccessibleJToolBar instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJToolBar that serves as the
|
||||
* AccessibleContext of this JToolBar
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJToolBar();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JToolBar</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to toolbar user-interface elements.
|
||||
*/
|
||||
protected class AccessibleJToolBar extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the state of this object.
|
||||
*
|
||||
* @return an instance of AccessibleStateSet containing the current
|
||||
* state set of the object
|
||||
* @see AccessibleState
|
||||
*/
|
||||
public AccessibleStateSet getAccessibleStateSet() {
|
||||
AccessibleStateSet states = super.getAccessibleStateSet();
|
||||
// FIXME: [[[WDW - need to add orientation from BoxLayout]]]
|
||||
// FIXME: [[[WDW - need to do SELECTABLE if SelectionModel is added]]]
|
||||
return states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.TOOL_BAR;
|
||||
}
|
||||
} // inner class AccessibleJToolBar
|
||||
}
|
||||
292
jdkSrc/jdk8/javax/swing/JToolTip.java
Normal file
292
jdkSrc/jdk8/javax/swing/JToolTip.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.accessibility.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* Used to display a "Tip" for a Component. Typically components provide api
|
||||
* to automate the process of using <code>ToolTip</code>s.
|
||||
* For example, any Swing component can use the <code>JComponent</code>
|
||||
* <code>setToolTipText</code> method to specify the text
|
||||
* for a standard tooltip. A component that wants to create a custom
|
||||
* <code>ToolTip</code>
|
||||
* display can override <code>JComponent</code>'s <code>createToolTip</code>
|
||||
* method and use a subclass of this class.
|
||||
* <p>
|
||||
* See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
|
||||
* in <em>The Java Tutorial</em>
|
||||
* for further documentation.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JComponent#setToolTipText
|
||||
* @see JComponent#createToolTip
|
||||
* @author Dave Moore
|
||||
* @author Rich Shiavi
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JToolTip extends JComponent implements Accessible {
|
||||
/**
|
||||
* @see #getUIClassID
|
||||
* @see #readObject
|
||||
*/
|
||||
private static final String uiClassID = "ToolTipUI";
|
||||
|
||||
String tipText;
|
||||
JComponent component;
|
||||
|
||||
/** Creates a tool tip. */
|
||||
public JToolTip() {
|
||||
setOpaque(true);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the L&F object that renders this component.
|
||||
*
|
||||
* @return the <code>ToolTipUI</code> object that renders this component
|
||||
*/
|
||||
public ToolTipUI getUI() {
|
||||
return (ToolTipUI)ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the UI property to a value from the current look and feel.
|
||||
*
|
||||
* @see JComponent#updateUI
|
||||
*/
|
||||
public void updateUI() {
|
||||
setUI((ToolTipUI)UIManager.getUI(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the L&F class that renders this component.
|
||||
*
|
||||
* @return the string "ToolTipUI"
|
||||
* @see JComponent#getUIClassID
|
||||
* @see UIDefaults#getUI
|
||||
*/
|
||||
public String getUIClassID() {
|
||||
return uiClassID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the text to show when the tool tip is displayed.
|
||||
* The string <code>tipText</code> may be <code>null</code>.
|
||||
*
|
||||
* @param tipText the <code>String</code> to display
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* description: Sets the text of the tooltip
|
||||
*/
|
||||
public void setTipText(String tipText) {
|
||||
String oldValue = this.tipText;
|
||||
this.tipText = tipText;
|
||||
firePropertyChange("tiptext", oldValue, tipText);
|
||||
|
||||
if (!Objects.equals(oldValue, tipText)) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text that is shown when the tool tip is displayed.
|
||||
* The returned value may be <code>null</code>.
|
||||
*
|
||||
* @return the <code>String</code> that is displayed
|
||||
*/
|
||||
public String getTipText() {
|
||||
return tipText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the component that the tooltip describes.
|
||||
* The component <code>c</code> may be <code>null</code>
|
||||
* and will have no effect.
|
||||
* <p>
|
||||
* This is a bound property.
|
||||
*
|
||||
* @param c the <code>JComponent</code> being described
|
||||
* @see JComponent#createToolTip
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* description: Sets the component that the tooltip describes.
|
||||
*/
|
||||
public void setComponent(JComponent c) {
|
||||
JComponent oldValue = this.component;
|
||||
|
||||
component = c;
|
||||
firePropertyChange("component", oldValue, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component the tooltip applies to.
|
||||
* The returned value may be <code>null</code>.
|
||||
*
|
||||
* @return the component that the tooltip describes
|
||||
*
|
||||
* @see JComponent#createToolTip
|
||||
*/
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns true since tooltips, by definition,
|
||||
* should always be on top of all other windows.
|
||||
*/
|
||||
// package private
|
||||
boolean alwaysOnTop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See <code>readObject</code> and <code>writeObject</code>
|
||||
* in <code>JComponent</code> for more
|
||||
* information about serialization in Swing.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||
s.defaultWriteObject();
|
||||
if (getUIClassID().equals(uiClassID)) {
|
||||
byte count = JComponent.getWriteObjCounter(this);
|
||||
JComponent.setWriteObjCounter(this, --count);
|
||||
if (count == 0 && ui != null) {
|
||||
ui.installUI(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JToolTip</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JToolTip</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String tipTextString = (tipText != null ?
|
||||
tipText : "");
|
||||
|
||||
return super.paramString() +
|
||||
",tipText=" + tipTextString;
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JToolTip.
|
||||
* For tool tips, the AccessibleContext takes the form of an
|
||||
* AccessibleJToolTip.
|
||||
* A new AccessibleJToolTip instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJToolTip that serves as the
|
||||
* AccessibleContext of this JToolTip
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJToolTip();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JToolTip</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to tool tip user-interface elements.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJToolTip extends AccessibleJComponent {
|
||||
|
||||
/**
|
||||
* Get the accessible description of this object.
|
||||
*
|
||||
* @return a localized String describing this object.
|
||||
*/
|
||||
public String getAccessibleDescription() {
|
||||
String description = accessibleDescription;
|
||||
|
||||
// fallback to client property
|
||||
if (description == null) {
|
||||
description = (String)getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
|
||||
}
|
||||
if (description == null) {
|
||||
description = getTipText();
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of this object.
|
||||
*
|
||||
* @return an instance of AccessibleRole describing the role of the
|
||||
* object
|
||||
*/
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.TOOL_TIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
5570
jdkSrc/jdk8/javax/swing/JTree.java
Normal file
5570
jdkSrc/jdk8/javax/swing/JTree.java
Normal file
File diff suppressed because it is too large
Load Diff
1765
jdkSrc/jdk8/javax/swing/JViewport.java
Normal file
1765
jdkSrc/jdk8/javax/swing/JViewport.java
Normal file
File diff suppressed because it is too large
Load Diff
673
jdkSrc/jdk8/javax/swing/JWindow.java
Normal file
673
jdkSrc/jdk8/javax/swing/JWindow.java
Normal file
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.accessibility.*;
|
||||
|
||||
/**
|
||||
* A <code>JWindow</code> is a container that can be displayed anywhere on the
|
||||
* user's desktop. It does not have the title bar, window-management buttons,
|
||||
* or other trimmings associated with a <code>JFrame</code>, but it is still a
|
||||
* "first-class citizen" of the user's desktop, and can exist anywhere
|
||||
* on it.
|
||||
* <p>
|
||||
* The <code>JWindow</code> component contains a <code>JRootPane</code>
|
||||
* as its only child. The <code>contentPane</code> should be the parent
|
||||
* of any children of the <code>JWindow</code>.
|
||||
* As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
|
||||
* methods of this class are overridden, so that they delegate calls
|
||||
* to the corresponding methods of the {@code ContentPane}.
|
||||
* For example, you can add a child component to a window as follows:
|
||||
* <pre>
|
||||
* window.add(child);
|
||||
* </pre>
|
||||
* And the child will be added to the contentPane.
|
||||
* The <code>contentPane</code> will always be non-<code>null</code>.
|
||||
* Attempting to set it to <code>null</code> will cause the <code>JWindow</code>
|
||||
* to throw an exception. The default <code>contentPane</code> will have a
|
||||
* <code>BorderLayout</code> manager set on it.
|
||||
* Refer to {@link javax.swing.RootPaneContainer}
|
||||
* for details on adding, removing and setting the <code>LayoutManager</code>
|
||||
* of a <code>JWindow</code>.
|
||||
* <p>
|
||||
* Please see the {@link JRootPane} documentation for a complete description of
|
||||
* the <code>contentPane</code>, <code>glassPane</code>, and
|
||||
* <code>layeredPane</code> components.
|
||||
* <p>
|
||||
* In a multi-screen environment, you can create a <code>JWindow</code>
|
||||
* on a different screen device. See {@link java.awt.Window} for more
|
||||
* information.
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Swing is not thread safe. For more
|
||||
* information see <a
|
||||
* href="package-summary.html#threading">Swing's Threading
|
||||
* Policy</a>.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see JRootPane
|
||||
*
|
||||
* @beaninfo
|
||||
* attribute: isContainer true
|
||||
* attribute: containerDelegate getContentPane
|
||||
* description: A toplevel window which has no system border or controls.
|
||||
*
|
||||
* @author David Kloba
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class JWindow extends Window implements Accessible,
|
||||
RootPaneContainer,
|
||||
TransferHandler.HasGetTransferHandler
|
||||
{
|
||||
/**
|
||||
* The <code>JRootPane</code> instance that manages the
|
||||
* <code>contentPane</code>
|
||||
* and optional <code>menuBar</code> for this frame, as well as the
|
||||
* <code>glassPane</code>.
|
||||
*
|
||||
* @see #getRootPane
|
||||
* @see #setRootPane
|
||||
*/
|
||||
protected JRootPane rootPane;
|
||||
|
||||
/**
|
||||
* If true then calls to <code>add</code> and <code>setLayout</code>
|
||||
* will be forwarded to the <code>contentPane</code>. This is initially
|
||||
* false, but is set to true when the <code>JWindow</code> is constructed.
|
||||
*
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean rootPaneCheckingEnabled = false;
|
||||
|
||||
/**
|
||||
* The <code>TransferHandler</code> for this window.
|
||||
*/
|
||||
private TransferHandler transferHandler;
|
||||
|
||||
/**
|
||||
* Creates a window with no specified owner. This window will not be
|
||||
* focusable.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @throws HeadlessException if
|
||||
* <code>GraphicsEnvironment.isHeadless()</code> returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #isFocusableWindow
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JWindow() {
|
||||
this((Frame)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a window with the specified <code>GraphicsConfiguration</code>
|
||||
* of a screen device. This window will not be focusable.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param gc the <code>GraphicsConfiguration</code> that is used
|
||||
* to construct the new window with; if gc is <code>null</code>,
|
||||
* the system default <code>GraphicsConfiguration</code>
|
||||
* is assumed
|
||||
* @throws HeadlessException If
|
||||
* <code>GraphicsEnvironment.isHeadless()</code> returns true.
|
||||
* @throws IllegalArgumentException if <code>gc</code> is not from
|
||||
* a screen device.
|
||||
*
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #isFocusableWindow
|
||||
* @see JComponent#getDefaultLocale
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JWindow(GraphicsConfiguration gc) {
|
||||
this(null, gc);
|
||||
super.setFocusableWindowState(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a window with the specified owner frame.
|
||||
* If <code>owner</code> is <code>null</code>, the shared owner
|
||||
* will be used and this window will not be focusable. Also,
|
||||
* this window will not be focusable unless its owner is showing
|
||||
* on the screen.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param owner the frame from which the window is displayed
|
||||
* @throws HeadlessException if GraphicsEnvironment.isHeadless()
|
||||
* returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #isFocusableWindow
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JWindow(Frame owner) {
|
||||
super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner);
|
||||
if (owner == null) {
|
||||
WindowListener ownerShutdownListener =
|
||||
SwingUtilities.getSharedOwnerFrameShutdownListener();
|
||||
addWindowListener(ownerShutdownListener);
|
||||
}
|
||||
windowInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a window with the specified owner window. This window
|
||||
* will not be focusable unless its owner is showing on the screen.
|
||||
* If <code>owner</code> is <code>null</code>, the shared owner
|
||||
* will be used and this window will not be focusable.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param owner the window from which the window is displayed
|
||||
* @throws HeadlessException if
|
||||
* <code>GraphicsEnvironment.isHeadless()</code> returns true.
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #isFocusableWindow
|
||||
* @see JComponent#getDefaultLocale
|
||||
*/
|
||||
public JWindow(Window owner) {
|
||||
super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
|
||||
owner);
|
||||
if (owner == null) {
|
||||
WindowListener ownerShutdownListener =
|
||||
SwingUtilities.getSharedOwnerFrameShutdownListener();
|
||||
addWindowListener(ownerShutdownListener);
|
||||
}
|
||||
windowInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a window with the specified owner window and
|
||||
* <code>GraphicsConfiguration</code> of a screen device. If
|
||||
* <code>owner</code> is <code>null</code>, the shared owner will be used
|
||||
* and this window will not be focusable.
|
||||
* <p>
|
||||
* This constructor sets the component's locale property to the value
|
||||
* returned by <code>JComponent.getDefaultLocale</code>.
|
||||
*
|
||||
* @param owner the window from which the window is displayed
|
||||
* @param gc the <code>GraphicsConfiguration</code> that is used
|
||||
* to construct the new window with; if gc is <code>null</code>,
|
||||
* the system default <code>GraphicsConfiguration</code>
|
||||
* is assumed, unless <code>owner</code> is also null, in which
|
||||
* case the <code>GraphicsConfiguration</code> from the
|
||||
* shared owner frame will be used.
|
||||
* @throws HeadlessException if
|
||||
* <code>GraphicsEnvironment.isHeadless()</code> returns true.
|
||||
* @throws IllegalArgumentException if <code>gc</code> is not from
|
||||
* a screen device.
|
||||
*
|
||||
* @see java.awt.GraphicsEnvironment#isHeadless
|
||||
* @see #isFocusableWindow
|
||||
* @see JComponent#getDefaultLocale
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public JWindow(Window owner, GraphicsConfiguration gc) {
|
||||
super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
|
||||
owner, gc);
|
||||
if (owner == null) {
|
||||
WindowListener ownerShutdownListener =
|
||||
SwingUtilities.getSharedOwnerFrameShutdownListener();
|
||||
addWindowListener(ownerShutdownListener);
|
||||
}
|
||||
windowInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the constructors to init the <code>JWindow</code> properly.
|
||||
*/
|
||||
protected void windowInit() {
|
||||
setLocale( JComponent.getDefaultLocale() );
|
||||
setRootPane(createRootPane());
|
||||
setRootPaneCheckingEnabled(true);
|
||||
sun.awt.SunToolkit.checkAndSetPolicy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the constructor methods to create the default
|
||||
* <code>rootPane</code>.
|
||||
*/
|
||||
protected JRootPane createRootPane() {
|
||||
JRootPane rp = new JRootPane();
|
||||
// NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
|
||||
// is NO reason for the RootPane not to be opaque. For painting to
|
||||
// work the contentPane must be opaque, therefor the RootPane can
|
||||
// also be opaque.
|
||||
rp.setOpaque(true);
|
||||
return rp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @return true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded; false otherwise
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected boolean isRootPaneCheckingEnabled() {
|
||||
return rootPaneCheckingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code transferHandler} property, which is a mechanism to
|
||||
* support transfer of data into this component. Use {@code null}
|
||||
* if the component does not support data transfer operations.
|
||||
* <p>
|
||||
* If the system property {@code suppressSwingDropSupport} is {@code false}
|
||||
* (the default) and the current drop target on this component is either
|
||||
* {@code null} or not a user-set drop target, this method will change the
|
||||
* drop target as follows: If {@code newHandler} is {@code null} it will
|
||||
* clear the drop target. If not {@code null} it will install a new
|
||||
* {@code DropTarget}.
|
||||
* <p>
|
||||
* Note: When used with {@code JWindow}, {@code TransferHandler} only
|
||||
* provides data import capability, as the data export related methods
|
||||
* are currently typed to {@code JComponent}.
|
||||
* <p>
|
||||
* Please see
|
||||
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
|
||||
* How to Use Drag and Drop and Data Transfer</a>, a section in
|
||||
* <em>The Java Tutorial</em>, for more information.
|
||||
*
|
||||
* @param newHandler the new {@code TransferHandler}
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #getTransferHandler
|
||||
* @see java.awt.Component#setDropTarget
|
||||
* @since 1.6
|
||||
*
|
||||
* @beaninfo
|
||||
* bound: true
|
||||
* hidden: true
|
||||
* description: Mechanism for transfer of data into the component
|
||||
*/
|
||||
public void setTransferHandler(TransferHandler newHandler) {
|
||||
TransferHandler oldHandler = transferHandler;
|
||||
transferHandler = newHandler;
|
||||
SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler);
|
||||
firePropertyChange("transferHandler", oldHandler, newHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>transferHandler</code> property.
|
||||
*
|
||||
* @return the value of the <code>transferHandler</code> property
|
||||
*
|
||||
* @see TransferHandler
|
||||
* @see #setTransferHandler
|
||||
* @since 1.6
|
||||
*/
|
||||
public TransferHandler getTransferHandler() {
|
||||
return transferHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>paint(g)</code>. This method was overridden to
|
||||
* prevent an unnecessary call to clear the background.
|
||||
*
|
||||
* @param g the <code>Graphics</code> context in which to paint
|
||||
*/
|
||||
public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether calls to <code>add</code> and
|
||||
* <code>setLayout</code> are forwarded to the <code>contentPane</code>.
|
||||
*
|
||||
* @param enabled true if <code>add</code> and <code>setLayout</code>
|
||||
* are forwarded, false if they should operate directly on the
|
||||
* <code>JWindow</code>.
|
||||
*
|
||||
* @see #addImpl
|
||||
* @see #setLayout
|
||||
* @see #isRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: Whether the add and setLayout methods are forwarded
|
||||
*/
|
||||
protected void setRootPaneCheckingEnabled(boolean enabled) {
|
||||
rootPaneCheckingEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the specified child <code>Component</code>.
|
||||
* This method is overridden to conditionally forward calls to the
|
||||
* <code>contentPane</code>.
|
||||
* By default, children are added to the <code>contentPane</code> instead
|
||||
* of the frame, refer to {@link javax.swing.RootPaneContainer} for
|
||||
* details.
|
||||
*
|
||||
* @param comp the component to be enhanced
|
||||
* @param constraints the constraints to be respected
|
||||
* @param index the index
|
||||
* @exception IllegalArgumentException if <code>index</code> is invalid
|
||||
* @exception IllegalArgumentException if adding the container's parent
|
||||
* to itself
|
||||
* @exception IllegalArgumentException if adding a window to a container
|
||||
*
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
protected void addImpl(Component comp, Object constraints, int index)
|
||||
{
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().add(comp, constraints, index);
|
||||
}
|
||||
else {
|
||||
super.addImpl(comp, constraints, index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified component from the container. If
|
||||
* <code>comp</code> is not the <code>rootPane</code>, this will forward
|
||||
* the call to the <code>contentPane</code>. This will do nothing if
|
||||
* <code>comp</code> is not a child of the <code>JWindow</code> or
|
||||
* <code>contentPane</code>.
|
||||
*
|
||||
* @param comp the component to be removed
|
||||
* @throws NullPointerException if <code>comp</code> is null
|
||||
* @see #add
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void remove(Component comp) {
|
||||
if (comp == rootPane) {
|
||||
super.remove(comp);
|
||||
} else {
|
||||
getContentPane().remove(comp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>LayoutManager</code>.
|
||||
* Overridden to conditionally forward the call to the
|
||||
* <code>contentPane</code>.
|
||||
* Refer to {@link javax.swing.RootPaneContainer} for
|
||||
* more information.
|
||||
*
|
||||
* @param manager the <code>LayoutManager</code>
|
||||
* @see #setRootPaneCheckingEnabled
|
||||
* @see javax.swing.RootPaneContainer
|
||||
*/
|
||||
public void setLayout(LayoutManager manager) {
|
||||
if(isRootPaneCheckingEnabled()) {
|
||||
getContentPane().setLayout(manager);
|
||||
}
|
||||
else {
|
||||
super.setLayout(manager);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the <code>rootPane</code> object for this window.
|
||||
* @return the <code>rootPane</code> property for this window
|
||||
*
|
||||
* @see #setRootPane
|
||||
* @see RootPaneContainer#getRootPane
|
||||
*/
|
||||
public JRootPane getRootPane() {
|
||||
return rootPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the new <code>rootPane</code> object for this window.
|
||||
* This method is called by the constructor.
|
||||
*
|
||||
* @param root the new <code>rootPane</code> property
|
||||
* @see #getRootPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: the RootPane object for this window.
|
||||
*/
|
||||
protected void setRootPane(JRootPane root) {
|
||||
if(rootPane != null) {
|
||||
remove(rootPane);
|
||||
}
|
||||
rootPane = root;
|
||||
if(rootPane != null) {
|
||||
boolean checkingEnabled = isRootPaneCheckingEnabled();
|
||||
try {
|
||||
setRootPaneCheckingEnabled(false);
|
||||
add(rootPane, BorderLayout.CENTER);
|
||||
}
|
||||
finally {
|
||||
setRootPaneCheckingEnabled(checkingEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the <code>Container</code> which is the <code>contentPane</code>
|
||||
* for this window.
|
||||
*
|
||||
* @return the <code>contentPane</code> property
|
||||
* @see #setContentPane
|
||||
* @see RootPaneContainer#getContentPane
|
||||
*/
|
||||
public Container getContentPane() {
|
||||
return getRootPane().getContentPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>contentPane</code> property for this window.
|
||||
* This method is called by the constructor.
|
||||
*
|
||||
* @param contentPane the new <code>contentPane</code>
|
||||
*
|
||||
* @exception IllegalComponentStateException (a runtime
|
||||
* exception) if the content pane parameter is <code>null</code>
|
||||
* @see #getContentPane
|
||||
* @see RootPaneContainer#setContentPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The client area of the window where child
|
||||
* components are normally inserted.
|
||||
*/
|
||||
public void setContentPane(Container contentPane) {
|
||||
getRootPane().setContentPane(contentPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>layeredPane</code> object for this window.
|
||||
*
|
||||
* @return the <code>layeredPane</code> property
|
||||
* @see #setLayeredPane
|
||||
* @see RootPaneContainer#getLayeredPane
|
||||
*/
|
||||
public JLayeredPane getLayeredPane() {
|
||||
return getRootPane().getLayeredPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>layeredPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
*
|
||||
* @param layeredPane the new <code>layeredPane</code> object
|
||||
*
|
||||
* @exception IllegalComponentStateException (a runtime
|
||||
* exception) if the content pane parameter is <code>null</code>
|
||||
* @see #getLayeredPane
|
||||
* @see RootPaneContainer#setLayeredPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: The pane which holds the various window layers.
|
||||
*/
|
||||
public void setLayeredPane(JLayeredPane layeredPane) {
|
||||
getRootPane().setLayeredPane(layeredPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>glassPane Component</code> for this window.
|
||||
*
|
||||
* @return the <code>glassPane</code> property
|
||||
* @see #setGlassPane
|
||||
* @see RootPaneContainer#getGlassPane
|
||||
*/
|
||||
public Component getGlassPane() {
|
||||
return getRootPane().getGlassPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>glassPane</code> property.
|
||||
* This method is called by the constructor.
|
||||
* @param glassPane the <code>glassPane</code> object for this window
|
||||
*
|
||||
* @see #getGlassPane
|
||||
* @see RootPaneContainer#setGlassPane
|
||||
*
|
||||
* @beaninfo
|
||||
* hidden: true
|
||||
* description: A transparent pane used for menu rendering.
|
||||
*/
|
||||
public void setGlassPane(Component glassPane) {
|
||||
getRootPane().setGlassPane(glassPane);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
JComponent.getGraphicsInvoked(this);
|
||||
return super.getGraphics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaints the specified rectangle of this component within
|
||||
* <code>time</code> milliseconds. Refer to <code>RepaintManager</code>
|
||||
* for details on how the repaint is handled.
|
||||
*
|
||||
* @param time maximum time in milliseconds before update
|
||||
* @param x the <i>x</i> coordinate
|
||||
* @param y the <i>y</i> coordinate
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
* @see RepaintManager
|
||||
* @since 1.6
|
||||
*/
|
||||
public void repaint(long time, int x, int y, int width, int height) {
|
||||
if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
|
||||
RepaintManager.currentManager(this).addDirtyRegion(
|
||||
this, x, y, width, height);
|
||||
}
|
||||
else {
|
||||
super.repaint(time, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JWindow</code>.
|
||||
* 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</code>.
|
||||
*
|
||||
* @return a string representation of this <code>JWindow</code>
|
||||
*/
|
||||
protected String paramString() {
|
||||
String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
|
||||
"true" : "false");
|
||||
|
||||
return super.paramString() +
|
||||
",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Accessibility support
|
||||
////////////////
|
||||
|
||||
/** The accessible context property. */
|
||||
protected AccessibleContext accessibleContext = null;
|
||||
|
||||
/**
|
||||
* Gets the AccessibleContext associated with this JWindow.
|
||||
* For JWindows, the AccessibleContext takes the form of an
|
||||
* AccessibleJWindow.
|
||||
* A new AccessibleJWindow instance is created if necessary.
|
||||
*
|
||||
* @return an AccessibleJWindow that serves as the
|
||||
* AccessibleContext of this JWindow
|
||||
*/
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessibleJWindow();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class implements accessibility support for the
|
||||
* <code>JWindow</code> class. It provides an implementation of the
|
||||
* Java Accessibility API appropriate to window user-interface
|
||||
* elements.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected class AccessibleJWindow extends AccessibleAWTWindow {
|
||||
// everything is in the new parent, AccessibleAWTWindow
|
||||
}
|
||||
|
||||
}
|
||||
316
jdkSrc/jdk8/javax/swing/KeyStroke.java
Normal file
316
jdkSrc/jdk8/javax/swing/KeyStroke.java
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 javax.swing;
|
||||
|
||||
import java.awt.AWTKeyStroke;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
/**
|
||||
* A KeyStroke represents a key action on the keyboard, or equivalent input
|
||||
* device. KeyStrokes can correspond to only a press or release of a particular
|
||||
* key, just as KEY_PRESSED and KEY_RELEASED KeyEvents do; alternately, they
|
||||
* can correspond to typing a specific Java character, just as KEY_TYPED
|
||||
* KeyEvents do. In all cases, KeyStrokes can specify modifiers (alt, shift,
|
||||
* control, meta, altGraph, or a combination thereof) which must be present during the
|
||||
* action for an exact match.
|
||||
* <p>
|
||||
* KeyStrokes are used to define high-level (semantic) action events. Instead
|
||||
* of trapping every keystroke and throwing away the ones you are not
|
||||
* interested in, those keystrokes you care about automatically initiate
|
||||
* actions on the Components with which they are registered.
|
||||
* <p>
|
||||
* KeyStrokes are immutable, and are intended to be unique. Client code cannot
|
||||
* create a KeyStroke; a variant of <code>getKeyStroke</code> must be used
|
||||
* instead. These factory methods allow the KeyStroke implementation to cache
|
||||
* and share instances efficiently.
|
||||
* <p>
|
||||
* <strong>Warning:</strong>
|
||||
* Serialized objects of this class will not be compatible with
|
||||
* future Swing releases. The current serialization support is
|
||||
* appropriate for short term storage or RMI between applications running
|
||||
* the same version of Swing. As of 1.4, support for long term storage
|
||||
* of all JavaBeans™
|
||||
* has been added to the <code>java.beans</code> package.
|
||||
* Please see {@link java.beans.XMLEncoder}.
|
||||
*
|
||||
* @see javax.swing.text.Keymap
|
||||
* @see #getKeyStroke
|
||||
*
|
||||
* @author Arnaud Weber
|
||||
* @author David Mendenhall
|
||||
*/
|
||||
public class KeyStroke extends AWTKeyStroke {
|
||||
|
||||
/**
|
||||
* Serial Version ID.
|
||||
*/
|
||||
private static final long serialVersionUID = -9060180771037902530L;
|
||||
|
||||
private KeyStroke() {
|
||||
}
|
||||
private KeyStroke(char keyChar, int keyCode, int modifiers,
|
||||
boolean onKeyRelease) {
|
||||
super(keyChar, keyCode, modifiers, onKeyRelease);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared instance of a <code>KeyStroke</code>
|
||||
* that represents a <code>KEY_TYPED</code> event for the
|
||||
* specified character.
|
||||
*
|
||||
* @param keyChar the character value for a keyboard key
|
||||
* @return a KeyStroke object for that key
|
||||
*/
|
||||
public static KeyStroke getKeyStroke(char keyChar) {
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
return (KeyStroke)getAWTKeyStroke(keyChar);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of a KeyStroke, specifying whether the key is
|
||||
* considered to be activated when it is pressed or released. Unlike all
|
||||
* other factory methods in this class, the instances returned by this
|
||||
* method are not necessarily cached or shared.
|
||||
*
|
||||
* @param keyChar the character value for a keyboard key
|
||||
* @param onKeyRelease <code>true</code> if this KeyStroke corresponds to a
|
||||
* key release; <code>false</code> otherwise.
|
||||
* @return a KeyStroke object for that key
|
||||
* @deprecated use getKeyStroke(char)
|
||||
*/
|
||||
@Deprecated
|
||||
public static KeyStroke getKeyStroke(char keyChar, boolean onKeyRelease) {
|
||||
return new KeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, onKeyRelease);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared instance of a {@code KeyStroke}
|
||||
* that represents a {@code KEY_TYPED} event for the
|
||||
* specified Character object and a
|
||||
* set of modifiers. Note that the first parameter is of type Character
|
||||
* rather than char. This is to avoid inadvertent clashes with calls to
|
||||
* <code>getKeyStroke(int keyCode, int modifiers)</code>.
|
||||
*
|
||||
* The modifiers consist of any combination of following:<ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.META_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
|
||||
* </ul>
|
||||
* The old modifiers listed below also can be used, but they are
|
||||
* mapped to _DOWN_ modifiers. <ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_MASK
|
||||
* <li>java.awt.event.InputEvent.META_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
|
||||
* </ul>
|
||||
* also can be used, but they are mapped to _DOWN_ modifiers.
|
||||
*
|
||||
* Since these numbers are all different powers of two, any combination of
|
||||
* them is an integer in which each bit represents a different modifier
|
||||
* key. Use 0 to specify no modifiers.
|
||||
*
|
||||
* @param keyChar the Character object for a keyboard character
|
||||
* @param modifiers a bitwise-ored combination of any modifiers
|
||||
* @return an KeyStroke object for that key
|
||||
* @throws IllegalArgumentException if keyChar is null
|
||||
*
|
||||
* @see java.awt.event.InputEvent
|
||||
* @since 1.3
|
||||
*/
|
||||
public static KeyStroke getKeyStroke(Character keyChar, int modifiers) {
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
return (KeyStroke)getAWTKeyStroke(keyChar, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared instance of a KeyStroke, given a numeric key code and a
|
||||
* set of modifiers, specifying whether the key is activated when it is
|
||||
* pressed or released.
|
||||
* <p>
|
||||
* The "virtual key" constants defined in java.awt.event.KeyEvent can be
|
||||
* used to specify the key code. For example:<ul>
|
||||
* <li>java.awt.event.KeyEvent.VK_ENTER
|
||||
* <li>java.awt.event.KeyEvent.VK_TAB
|
||||
* <li>java.awt.event.KeyEvent.VK_SPACE
|
||||
* </ul>
|
||||
* Alternatively, the key code may be obtained by calling
|
||||
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
|
||||
*
|
||||
* The modifiers consist of any combination of:<ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.META_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
|
||||
* </ul>
|
||||
* The old modifiers <ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_MASK
|
||||
* <li>java.awt.event.InputEvent.META_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
|
||||
* </ul>
|
||||
* also can be used, but they are mapped to _DOWN_ modifiers.
|
||||
*
|
||||
* Since these numbers are all different powers of two, any combination of
|
||||
* them is an integer in which each bit represents a different modifier
|
||||
* key. Use 0 to specify no modifiers.
|
||||
*
|
||||
* @param keyCode an int specifying the numeric code for a keyboard key
|
||||
* @param modifiers a bitwise-ored combination of any modifiers
|
||||
* @param onKeyRelease <code>true</code> if the KeyStroke should represent
|
||||
* a key release; <code>false</code> otherwise.
|
||||
* @return a KeyStroke object for that key
|
||||
*
|
||||
* @see java.awt.event.KeyEvent
|
||||
* @see java.awt.event.InputEvent
|
||||
*/
|
||||
public static KeyStroke getKeyStroke(int keyCode, int modifiers,
|
||||
boolean onKeyRelease) {
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
return (KeyStroke)getAWTKeyStroke(keyCode, modifiers,
|
||||
onKeyRelease);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared instance of a KeyStroke, given a numeric key code and a
|
||||
* set of modifiers. The returned KeyStroke will correspond to a key press.
|
||||
* <p>
|
||||
* The "virtual key" constants defined in java.awt.event.KeyEvent can be
|
||||
* used to specify the key code. For example:<ul>
|
||||
* <li>java.awt.event.KeyEvent.VK_ENTER
|
||||
* <li>java.awt.event.KeyEvent.VK_TAB
|
||||
* <li>java.awt.event.KeyEvent.VK_SPACE
|
||||
* </ul>
|
||||
* Alternatively, the key code may be obtained by calling
|
||||
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
|
||||
*
|
||||
* The modifiers consist of any combination of:<ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.META_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
|
||||
* </ul>
|
||||
* The old modifiers <ul>
|
||||
* <li>java.awt.event.InputEvent.SHIFT_MASK
|
||||
* <li>java.awt.event.InputEvent.CTRL_MASK
|
||||
* <li>java.awt.event.InputEvent.META_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_MASK
|
||||
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
|
||||
* </ul>
|
||||
* also can be used, but they are mapped to _DOWN_ modifiers.
|
||||
*
|
||||
* Since these numbers are all different powers of two, any combination of
|
||||
* them is an integer in which each bit represents a different modifier
|
||||
* key. Use 0 to specify no modifiers.
|
||||
*
|
||||
* @param keyCode an int specifying the numeric code for a keyboard key
|
||||
* @param modifiers a bitwise-ored combination of any modifiers
|
||||
* @return a KeyStroke object for that key
|
||||
*
|
||||
* @see java.awt.event.KeyEvent
|
||||
* @see java.awt.event.InputEvent
|
||||
*/
|
||||
public static KeyStroke getKeyStroke(int keyCode, int modifiers) {
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
return (KeyStroke)getAWTKeyStroke(keyCode, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a KeyStroke which represents the stroke which generated a given
|
||||
* KeyEvent.
|
||||
* <p>
|
||||
* This method obtains the keyChar from a KeyTyped event, and the keyCode
|
||||
* from a KeyPressed or KeyReleased event. The KeyEvent modifiers are
|
||||
* obtained for all three types of KeyEvent.
|
||||
*
|
||||
* @param anEvent the KeyEvent from which to obtain the KeyStroke
|
||||
* @throws NullPointerException if <code>anEvent</code> is null
|
||||
* @return the KeyStroke that precipitated the event
|
||||
*/
|
||||
public static KeyStroke getKeyStrokeForEvent(KeyEvent anEvent) {
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
return (KeyStroke)getAWTKeyStrokeForEvent(anEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string and returns a <code>KeyStroke</code>.
|
||||
* The string must have the following syntax:
|
||||
* <pre>
|
||||
* <modifiers>* (<typedID> | <pressedReleasedID>)
|
||||
*
|
||||
* modifiers := shift | control | ctrl | meta | alt | altGraph
|
||||
* typedID := typed <typedKey>
|
||||
* typedKey := string of length 1 giving Unicode character.
|
||||
* pressedReleasedID := (pressed | released) key
|
||||
* key := KeyEvent key code name, i.e. the name following "VK_".
|
||||
* </pre>
|
||||
* If typed, pressed or released is not specified, pressed is assumed. Here
|
||||
* are some examples:
|
||||
* <pre>
|
||||
* "INSERT" => getKeyStroke(KeyEvent.VK_INSERT, 0);
|
||||
* "control DELETE" => getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
|
||||
* "alt shift X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
|
||||
* "alt shift released X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
|
||||
* "typed a" => getKeyStroke('a');
|
||||
* </pre>
|
||||
*
|
||||
* In order to maintain backward-compatibility, specifying a null String,
|
||||
* or a String which is formatted incorrectly, returns null.
|
||||
*
|
||||
* @param s a String formatted as described above
|
||||
* @return a KeyStroke object for that String, or null if the specified
|
||||
* String is null, or is formatted incorrectly
|
||||
*
|
||||
* @see java.awt.event.KeyEvent
|
||||
*/
|
||||
public static KeyStroke getKeyStroke(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
synchronized (AWTKeyStroke.class) {
|
||||
registerSubclass(KeyStroke.class);
|
||||
try {
|
||||
return (KeyStroke)getAWTKeyStroke(s);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
392
jdkSrc/jdk8/javax/swing/KeyboardManager.java
Normal file
392
jdkSrc/jdk8/javax/swing/KeyboardManager.java
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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 javax.swing;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.applet.*;
|
||||
import java.beans.*;
|
||||
import javax.swing.event.*;
|
||||
import sun.awt.EmbeddedFrame;
|
||||
|
||||
/**
|
||||
* The KeyboardManager class is used to help dispatch keyboard actions for the
|
||||
* WHEN_IN_FOCUSED_WINDOW style actions. Actions with other conditions are handled
|
||||
* directly in JComponent.
|
||||
*
|
||||
* Here's a description of the symantics of how keyboard dispatching should work
|
||||
* atleast as I understand it.
|
||||
*
|
||||
* KeyEvents are dispatched to the focused component. The focus manager gets first
|
||||
* crack at processing this event. If the focus manager doesn't want it, then
|
||||
* the JComponent calls super.processKeyEvent() this allows listeners a chance
|
||||
* to process the event.
|
||||
*
|
||||
* If none of the listeners "consumes" the event then the keybindings get a shot.
|
||||
* This is where things start to get interesting. First, KeyStokes defined with the
|
||||
* WHEN_FOCUSED condition get a chance. If none of these want the event, then the component
|
||||
* walks though it's parents looked for actions of type WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.
|
||||
*
|
||||
* If no one has taken it yet, then it winds up here. We then look for components registered
|
||||
* for WHEN_IN_FOCUSED_WINDOW events and fire to them. Note that if none of those are found
|
||||
* then we pass the event to the menubars and let them have a crack at it. They're handled differently.
|
||||
*
|
||||
* Lastly, we check if we're looking at an internal frame. If we are and no one wanted the event
|
||||
* then we move up to the InternalFrame's creator and see if anyone wants the event (and so on and so on).
|
||||
*
|
||||
*
|
||||
* @see InputMap
|
||||
*/
|
||||
class KeyboardManager {
|
||||
|
||||
static KeyboardManager currentManager = new KeyboardManager();
|
||||
|
||||
/**
|
||||
* maps top-level containers to a sub-hashtable full of keystrokes
|
||||
*/
|
||||
Hashtable<Container, Hashtable> containerMap = new Hashtable<Container, Hashtable>();
|
||||
|
||||
/**
|
||||
* Maps component/keystroke pairs to a topLevel container
|
||||
* This is mainly used for fast unregister operations
|
||||
*/
|
||||
Hashtable<ComponentKeyStrokePair, Container> componentKeyStrokeMap = new Hashtable<ComponentKeyStrokePair, Container>();
|
||||
|
||||
public static KeyboardManager getCurrentManager() {
|
||||
return currentManager;
|
||||
}
|
||||
|
||||
public static void setCurrentManager(KeyboardManager km) {
|
||||
currentManager = km;
|
||||
}
|
||||
|
||||
/**
|
||||
* register keystrokes here which are for the WHEN_IN_FOCUSED_WINDOW
|
||||
* case.
|
||||
* Other types of keystrokes will be handled by walking the hierarchy
|
||||
* That simplifies some potentially hairy stuff.
|
||||
*/
|
||||
public void registerKeyStroke(KeyStroke k, JComponent c) {
|
||||
Container topContainer = getTopAncestor(c);
|
||||
if (topContainer == null) {
|
||||
return;
|
||||
}
|
||||
Hashtable keyMap = containerMap.get(topContainer);
|
||||
|
||||
if (keyMap == null) { // lazy evaluate one
|
||||
keyMap = registerNewTopContainer(topContainer);
|
||||
}
|
||||
|
||||
Object tmp = keyMap.get(k);
|
||||
if (tmp == null) {
|
||||
keyMap.put(k,c);
|
||||
} else if (tmp instanceof Vector) { // if there's a Vector there then add to it.
|
||||
Vector v = (Vector)tmp;
|
||||
if (!v.contains(c)) { // only add if this keystroke isn't registered for this component
|
||||
v.addElement(c);
|
||||
}
|
||||
} else if (tmp instanceof JComponent) {
|
||||
// if a JComponent is there then remove it and replace it with a vector
|
||||
// Then add the old compoennt and the new compoent to the vector
|
||||
// then insert the vector in the table
|
||||
if (tmp != c) { // this means this is already registered for this component, no need to dup
|
||||
Vector<JComponent> v = new Vector<JComponent>();
|
||||
v.addElement((JComponent) tmp);
|
||||
v.addElement(c);
|
||||
keyMap.put(k, v);
|
||||
}
|
||||
} else {
|
||||
System.out.println("Unexpected condition in registerKeyStroke");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
componentKeyStrokeMap.put(new ComponentKeyStrokePair(c,k), topContainer);
|
||||
|
||||
// Check for EmbeddedFrame case, they know how to process accelerators even
|
||||
// when focus is not in Java
|
||||
if (topContainer instanceof EmbeddedFrame) {
|
||||
((EmbeddedFrame)topContainer).registerAccelerator(k);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the top focusable Window, Applet, or InternalFrame
|
||||
*/
|
||||
private static Container getTopAncestor(JComponent c) {
|
||||
for(Container p = c.getParent(); p != null; p = p.getParent()) {
|
||||
if (p instanceof Window && ((Window)p).isFocusableWindow() ||
|
||||
p instanceof Applet || p instanceof JInternalFrame) {
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void unregisterKeyStroke(KeyStroke ks, JComponent c) {
|
||||
|
||||
// component may have already been removed from the hierarchy, we
|
||||
// need to look up the container using the componentKeyStrokeMap.
|
||||
|
||||
ComponentKeyStrokePair ckp = new ComponentKeyStrokePair(c,ks);
|
||||
|
||||
Container topContainer = componentKeyStrokeMap.get(ckp);
|
||||
|
||||
if (topContainer == null) { // never heard of this pairing, so bail
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable keyMap = containerMap.get(topContainer);
|
||||
if (keyMap == null) { // this should never happen, but I'm being safe
|
||||
Thread.dumpStack();
|
||||
return;
|
||||
}
|
||||
|
||||
Object tmp = keyMap.get(ks);
|
||||
if (tmp == null) { // this should never happen, but I'm being safe
|
||||
Thread.dumpStack();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tmp instanceof JComponent && tmp == c) {
|
||||
keyMap.remove(ks); // remove the KeyStroke from the Map
|
||||
//System.out.println("removed a stroke" + ks);
|
||||
} else if (tmp instanceof Vector ) { // this means there is more than one component reg for this key
|
||||
Vector v = (Vector)tmp;
|
||||
v.removeElement(c);
|
||||
if ( v.isEmpty() ) {
|
||||
keyMap.remove(ks); // remove the KeyStroke from the Map
|
||||
//System.out.println("removed a ks vector");
|
||||
}
|
||||
}
|
||||
|
||||
if ( keyMap.isEmpty() ) { // if no more bindings in this table
|
||||
containerMap.remove(topContainer); // remove table to enable GC
|
||||
//System.out.println("removed a container");
|
||||
}
|
||||
|
||||
componentKeyStrokeMap.remove(ckp);
|
||||
|
||||
// Check for EmbeddedFrame case, they know how to process accelerators even
|
||||
// when focus is not in Java
|
||||
if (topContainer instanceof EmbeddedFrame) {
|
||||
((EmbeddedFrame)topContainer).unregisterAccelerator(ks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the focused component (and none of
|
||||
* its ancestors) want the key event. This will look up the keystroke
|
||||
* to see if any chidren (or subchildren) of the specified container
|
||||
* want a crack at the event.
|
||||
* If one of them wants it, then it will "DO-THE-RIGHT-THING"
|
||||
*/
|
||||
public boolean fireKeyboardAction(KeyEvent e, boolean pressed, Container topAncestor) {
|
||||
|
||||
if (e.isConsumed()) {
|
||||
System.out.println("Acquired pre-used event!");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
// There may be two keystrokes associated with a low-level key event;
|
||||
// in this case a keystroke made of an extended key code has a priority.
|
||||
KeyStroke ks;
|
||||
KeyStroke ksE = null;
|
||||
|
||||
|
||||
if(e.getID() == KeyEvent.KEY_TYPED) {
|
||||
ks=KeyStroke.getKeyStroke(e.getKeyChar());
|
||||
} else {
|
||||
if(e.getKeyCode() != e.getExtendedKeyCode()) {
|
||||
ksE=KeyStroke.getKeyStroke(e.getExtendedKeyCode(), e.getModifiers(), !pressed);
|
||||
}
|
||||
ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed);
|
||||
}
|
||||
|
||||
Hashtable keyMap = containerMap.get(topAncestor);
|
||||
if (keyMap != null) { // this container isn't registered, so bail
|
||||
|
||||
Object tmp = null;
|
||||
// extended code has priority
|
||||
if( ksE != null ) {
|
||||
tmp = keyMap.get(ksE);
|
||||
if( tmp != null ) {
|
||||
ks = ksE;
|
||||
}
|
||||
}
|
||||
if( tmp == null ) {
|
||||
tmp = keyMap.get(ks);
|
||||
}
|
||||
|
||||
if (tmp == null) {
|
||||
// don't do anything
|
||||
} else if ( tmp instanceof JComponent) {
|
||||
JComponent c = (JComponent)tmp;
|
||||
if ( c.isShowing() && c.isEnabled() ) { // only give it out if enabled and visible
|
||||
fireBinding(c, ks, e, pressed);
|
||||
}
|
||||
} else if ( tmp instanceof Vector) { //more than one comp registered for this
|
||||
Vector v = (Vector)tmp;
|
||||
// There is no well defined order for WHEN_IN_FOCUSED_WINDOW
|
||||
// bindings, but we give precedence to those bindings just
|
||||
// added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW
|
||||
// bindings are accessed before those of the JRootPane (they
|
||||
// both have a WHEN_IN_FOCUSED_WINDOW binding for enter).
|
||||
for (int counter = v.size() - 1; counter >= 0; counter--) {
|
||||
JComponent c = (JComponent)v.elementAt(counter);
|
||||
//System.out.println("Trying collision: " + c + " vector = "+ v.size());
|
||||
if ( c.isShowing() && c.isEnabled() ) { // don't want to give these out
|
||||
fireBinding(c, ks, e, pressed);
|
||||
if (e.isConsumed())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println( "Unexpected condition in fireKeyboardAction " + tmp);
|
||||
// This means that tmp wasn't null, a JComponent, or a Vector. What is it?
|
||||
Thread.dumpStack();
|
||||
}
|
||||
}
|
||||
|
||||
if (e.isConsumed()) {
|
||||
return true;
|
||||
}
|
||||
// if no one else handled it, then give the menus a crack
|
||||
// The're handled differently. The key is to let any JMenuBars
|
||||
// process the event
|
||||
if ( keyMap != null) {
|
||||
Vector v = (Vector)keyMap.get(JMenuBar.class);
|
||||
if (v != null) {
|
||||
Enumeration iter = v.elements();
|
||||
while (iter.hasMoreElements()) {
|
||||
JMenuBar mb = (JMenuBar)iter.nextElement();
|
||||
if ( mb.isShowing() && mb.isEnabled() ) { // don't want to give these out
|
||||
boolean extended = (ksE != null) && !ksE.equals(ks);
|
||||
if (extended) {
|
||||
fireBinding(mb, ksE, e, pressed);
|
||||
}
|
||||
if (!extended || !e.isConsumed()) {
|
||||
fireBinding(mb, ks, e, pressed);
|
||||
}
|
||||
if (e.isConsumed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return e.isConsumed();
|
||||
}
|
||||
|
||||
void fireBinding(JComponent c, KeyStroke ks, KeyEvent e, boolean pressed) {
|
||||
if (c.processKeyBinding(ks, e, JComponent.WHEN_IN_FOCUSED_WINDOW,
|
||||
pressed)) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerMenuBar(JMenuBar mb) {
|
||||
Container top = getTopAncestor(mb);
|
||||
if (top == null) {
|
||||
return;
|
||||
}
|
||||
Hashtable keyMap = containerMap.get(top);
|
||||
|
||||
if (keyMap == null) { // lazy evaluate one
|
||||
keyMap = registerNewTopContainer(top);
|
||||
}
|
||||
// use the menubar class as the key
|
||||
Vector menuBars = (Vector)keyMap.get(JMenuBar.class);
|
||||
|
||||
if (menuBars == null) { // if we don't have a list of menubars,
|
||||
// then make one.
|
||||
menuBars = new Vector();
|
||||
keyMap.put(JMenuBar.class, menuBars);
|
||||
}
|
||||
|
||||
if (!menuBars.contains(mb)) {
|
||||
menuBars.addElement(mb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void unregisterMenuBar(JMenuBar mb) {
|
||||
Container topContainer = getTopAncestor(mb);
|
||||
if (topContainer == null) {
|
||||
return;
|
||||
}
|
||||
Hashtable keyMap = containerMap.get(topContainer);
|
||||
if (keyMap!=null) {
|
||||
Vector v = (Vector)keyMap.get(JMenuBar.class);
|
||||
if (v != null) {
|
||||
v.removeElement(mb);
|
||||
if (v.isEmpty()) {
|
||||
keyMap.remove(JMenuBar.class);
|
||||
if (keyMap.isEmpty()) {
|
||||
// remove table to enable GC
|
||||
containerMap.remove(topContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Hashtable registerNewTopContainer(Container topContainer) {
|
||||
Hashtable keyMap = new Hashtable();
|
||||
containerMap.put(topContainer, keyMap);
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to create keys for a hashtable
|
||||
* which looks up topContainers based on component, keystroke pairs
|
||||
* This is used to make unregistering KeyStrokes fast
|
||||
*/
|
||||
class ComponentKeyStrokePair {
|
||||
Object component;
|
||||
Object keyStroke;
|
||||
|
||||
public ComponentKeyStrokePair(Object comp, Object key) {
|
||||
component = comp;
|
||||
keyStroke = key;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ( !(o instanceof ComponentKeyStrokePair)) {
|
||||
return false;
|
||||
}
|
||||
ComponentKeyStrokePair ckp = (ComponentKeyStrokePair)o;
|
||||
return ((component.equals(ckp.component)) && (keyStroke.equals(ckp.keyStroke)));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return component.hashCode() * keyStroke.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end KeyboardManager
|
||||
159
jdkSrc/jdk8/javax/swing/LayoutComparator.java
Normal file
159
jdkSrc/jdk8/javax/swing/LayoutComparator.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2008, 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 javax.swing;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
import java.awt.Component;
|
||||
import java.awt.ComponentOrientation;
|
||||
import java.awt.Window;
|
||||
|
||||
|
||||
/**
|
||||
* Comparator which attempts to sort Components based on their size and
|
||||
* position. Code adapted from original javax.swing.DefaultFocusManager
|
||||
* implementation.
|
||||
*
|
||||
* @author David Mendenhall
|
||||
*/
|
||||
final class LayoutComparator implements Comparator<Component>, java.io.Serializable {
|
||||
|
||||
private static final int ROW_TOLERANCE = 10;
|
||||
|
||||
private boolean horizontal = true;
|
||||
private boolean leftToRight = true;
|
||||
|
||||
void setComponentOrientation(ComponentOrientation orientation) {
|
||||
horizontal = orientation.isHorizontal();
|
||||
leftToRight = orientation.isLeftToRight();
|
||||
}
|
||||
|
||||
public int compare(Component a, Component b) {
|
||||
if (a == b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Row/Column algorithm only applies to siblings. If 'a' and 'b'
|
||||
// aren't siblings, then we need to find their most inferior
|
||||
// ancestors which share a parent. Compute the ancestory lists for
|
||||
// each Component and then search from the Window down until the
|
||||
// hierarchy branches.
|
||||
if (a.getParent() != b.getParent()) {
|
||||
LinkedList<Component> aAncestory = new LinkedList<Component>();
|
||||
|
||||
for(; a != null; a = a.getParent()) {
|
||||
aAncestory.add(a);
|
||||
if (a instanceof Window) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (a == null) {
|
||||
// 'a' is not part of a Window hierarchy. Can't cope.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
LinkedList<Component> bAncestory = new LinkedList<Component>();
|
||||
|
||||
for(; b != null; b = b.getParent()) {
|
||||
bAncestory.add(b);
|
||||
if (b instanceof Window) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (b == null) {
|
||||
// 'b' is not part of a Window hierarchy. Can't cope.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
for (ListIterator<Component>
|
||||
aIter = aAncestory.listIterator(aAncestory.size()),
|
||||
bIter = bAncestory.listIterator(bAncestory.size()); ;) {
|
||||
if (aIter.hasPrevious()) {
|
||||
a = aIter.previous();
|
||||
} else {
|
||||
// a is an ancestor of b
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bIter.hasPrevious()) {
|
||||
b = bIter.previous();
|
||||
} else {
|
||||
// b is an ancestor of a
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a != b) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ax = a.getX(), ay = a.getY(), bx = b.getX(), by = b.getY();
|
||||
|
||||
int zOrder = a.getParent().getComponentZOrder(a) - b.getParent().getComponentZOrder(b);
|
||||
if (horizontal) {
|
||||
if (leftToRight) {
|
||||
|
||||
// LT - Western Europe (optional for Japanese, Chinese, Korean)
|
||||
|
||||
if (Math.abs(ay - by) < ROW_TOLERANCE) {
|
||||
return (ax < bx) ? -1 : ((ax > bx) ? 1 : zOrder);
|
||||
} else {
|
||||
return (ay < by) ? -1 : 1;
|
||||
}
|
||||
} else { // !leftToRight
|
||||
|
||||
// RT - Middle East (Arabic, Hebrew)
|
||||
|
||||
if (Math.abs(ay - by) < ROW_TOLERANCE) {
|
||||
return (ax > bx) ? -1 : ((ax < bx) ? 1 : zOrder);
|
||||
} else {
|
||||
return (ay < by) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
} else { // !horizontal
|
||||
if (leftToRight) {
|
||||
|
||||
// TL - Mongolian
|
||||
|
||||
if (Math.abs(ax - bx) < ROW_TOLERANCE) {
|
||||
return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder);
|
||||
} else {
|
||||
return (ax < bx) ? -1 : 1;
|
||||
}
|
||||
} else { // !leftToRight
|
||||
|
||||
// TR - Japanese, Chinese, Korean
|
||||
|
||||
if (Math.abs(ax - bx) < ROW_TOLERANCE) {
|
||||
return (ay < by) ? -1 : ((ay > by) ? 1 : zOrder);
|
||||
} else {
|
||||
return (ax > bx) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user