From 1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06 Mon Sep 17 00:00:00 2001
From: Tom Tromey The purpose of this class is to serve as a facade over a number of
- * classes which collectively represent the semantics of a button: the
- * button's model, its listeners, its action, and its look and feel. Some
- * parts of a button's state are stored explicitly in this class, other
- * parts are delegates to the model. Some methods related to buttons are
- * implemented in this class, other methods pass through to the current
- * model or look and feel. Furthermore this class is supposed to serve as a base class for
+ * This class is supposed to serve as a base class for
* several kinds of buttons with similar but non-identical semantics:
- * toggle buttons (radio buttons and checkboxes), simple "push" buttons,
- * menu items.
Buttons have many properties, some of which are stored in this class * while others are delegated to the button's model. The following properties @@ -571,7 +567,9 @@ public abstract class AbstractButton extends JComponent if(text != null) this.text = text; - default_icon = icon; + if (icon != null) + default_icon = icon; + actionListener = createActionListener(); changeListener = createChangeListener(); itemListener = createItemListener(); @@ -724,7 +722,7 @@ public abstract class AbstractButton extends JComponent } /** - * Calls {@link ItemListener.itemStateChanged} on each ItemListener in + * Calls {@link ItemListener#itemStateChanged} on each ItemListener in * the button's listener list. * * @param e The event signifying that the button's model changed state @@ -739,7 +737,7 @@ public abstract class AbstractButton extends JComponent } /** - * Calls {@link ActionListener.actionPerformed} on each {@link + * Calls {@link ActionListener#actionPerformed} on each {@link * ActionListener} in the button's listener list. * * @param e The event signifying that the button's model was clicked @@ -762,7 +760,7 @@ public abstract class AbstractButton extends JComponent } /** - * Calls {@link ChangeEvent.stateChanged} on each {@link ChangeListener} + * Calls {@link ChangeListener#stateChanged} on each {@link ChangeListener} * in the button's listener list. */ protected void fireStateChanged() @@ -1130,7 +1128,7 @@ public abstract class AbstractButton extends JComponent * PropertyChangeListener.
* *This method also configures several of the button's properties from - * the Action, by calling {@link configurePropertiesFromAction}, and + * the Action, by calling {@link #configurePropertiesFromAction}, and * subscribes the button to the Action as a PropertyChangeListener. * Subsequent changes to the Action will thus reconfigure the button * automatically.
@@ -1363,7 +1361,7 @@ public abstract class AbstractButton extends JComponent *null
, in which case an icon is constructed, based on the
* default icon.
*
- * @param disabledIcon The new "disabledIcon" property
+ * @param d The new "disabledIcon" property
*/
public void setDisabledIcon(Icon d)
{
@@ -1393,7 +1391,7 @@ public abstract class AbstractButton extends JComponent
* focused, but no special decoration is painted to indicate the presence
* of focus.
*
- * @param b The new "paintFocus" property
+ * @param p The new "paintFocus" property
*/
public void setFocusPainted(boolean p)
{
@@ -1421,8 +1419,8 @@ public abstract class AbstractButton extends JComponent
*
* @throws IllegalArgumentException If key is not one of the valid constants
*
- * @see setHorizontalTextPosition()
- * @see setHorizontalAlignment()
+ * @see #setHorizontalTextPosition(int)
+ * @see #setHorizontalAlignment(int)
*/
protected int checkHorizontalKey(int key, String exception)
{
@@ -1453,8 +1451,8 @@ public abstract class AbstractButton extends JComponent
*
* @throws IllegalArgumentException If key is not one of the valid constants
*
- * @see setVerticalTextPosition()
- * @see setVerticalAlignment()
+ * @see #setVerticalTextPosition(int)
+ * @see #setVerticalAlignment(int)
*/
protected int checkVerticalKey(int key, String exception)
{
@@ -1527,7 +1525,7 @@ public abstract class AbstractButton extends JComponent
* A factory method which should return an {@link ActionListener} that * propagates events from the button's {@link ButtonModel} to any of the * button's ActionListeners. By default, this is an inner class which - * calls {@link AbstractButton.fireActionPerformed} with a modified copy + * calls {@link AbstractButton#fireActionPerformed} with a modified copy * of the incoming model {@link ActionEvent}.
* *The button calls this method during construction, stores the @@ -1553,10 +1551,10 @@ public abstract class AbstractButton extends JComponent *
A factory method which should return a {@link PropertyChangeListener} * that accepts changes to the specified {@link Action} and reconfigure * the {@link AbstractButton}, by default using the {@link - * configurePropertiesFromAction} method.
+ * #configurePropertiesFromAction} method. * *The button calls this method whenever a new Action is assigned to
- * the button's "action" property, via {@link setAction}, and stores the
+ * the button's "action" property, via {@link #setAction}, and stores the
* resulting PropertyChangeListener in its
* actionPropertyChangeListener
member field. The button
* then subscribes the listener to the button's new action. If the
@@ -1600,7 +1598,7 @@ public abstract class AbstractButton extends JComponent
* AbstractButton may wish to override the listener used to subscribe to
* such ChangeEvents. By default, the listener just propagates the
* {@link ChangeEvent} to the button's ChangeListeners, via the {@link
- * AbstractButton.fireStateChanged} method.
The button calls this method during construction, stores the
* resulting ChangeListener in its changeListener
member
@@ -1628,7 +1626,7 @@ public abstract class AbstractButton extends JComponent
* AbstractButton may wish to override the listener used to subscribe to
* such ItemEvents. By default, the listener just propagates the
* {@link ItemEvent} to the button's ItemListeners, via the {@link
- * AbstractButton.fireItemStateChanged} method.
The button calls this method during construction, stores the
* resulting ItemListener in its changeListener
member
@@ -1737,7 +1735,7 @@ public abstract class AbstractButton extends JComponent
* paint this icon when the "rolloverEnabled" property of the button is
* true
and the mouse rolls over the button.
*
- * @param rolloverIcon The new rollover icon
+ * @param r The new rollover icon
*/
public void setRolloverIcon(Icon r)
{
@@ -1770,7 +1768,7 @@ public abstract class AbstractButton extends JComponent
* is true
, the "selected" property of the button's model is
* true
, and the mouse rolls over the button.
*
- * @param rolloverSelectedIcon The new rollover selected icon
+ * @param r The new rollover selected icon
*/
public void setRolloverSelectedIcon(Icon r)
{
@@ -1805,7 +1803,7 @@ public abstract class AbstractButton extends JComponent
* button is false
or the mouse is not currently rolled
* over the button.
*
- * @param selectedIcon The new selected icon
+ * @param s The new selected icon
*/
public void setSelectedIcon(Icon s)
{
diff --git a/libjava/classpath/javax/swing/AbstractCellEditor.java b/libjava/classpath/javax/swing/AbstractCellEditor.java
index 86d3017..4ed1580 100644
--- a/libjava/classpath/javax/swing/AbstractCellEditor.java
+++ b/libjava/classpath/javax/swing/AbstractCellEditor.java
@@ -46,11 +46,10 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
/**
- * The abstract superclass for table and tree cells. This provides some
+ * An abstract superclass for table and tree cell editors. This provides some
* common shared functionality.
*
- * @author Andrew Selkirk
- * @version 1.0
+ * @author Andrew Selkirk
*/
public abstract class AbstractCellEditor
implements CellEditor, Serializable
diff --git a/libjava/classpath/javax/swing/AbstractListModel.java b/libjava/classpath/javax/swing/AbstractListModel.java
index a924b73..8973e52 100644
--- a/libjava/classpath/javax/swing/AbstractListModel.java
+++ b/libjava/classpath/javax/swing/AbstractListModel.java
@@ -46,11 +46,10 @@ import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
/**
- * AbstractListModel
+ * Provides standard implementations of some methods in {@link ListModel}.
*
* @author Ronald Veldema
* @author Andrew Selkirk
- * @version 1.0
*/
public abstract class AbstractListModel implements ListModel, Serializable
{
@@ -88,7 +87,7 @@ public abstract class AbstractListModel implements ListModel, Serializable
/**
* Call {@link ListDataListener#contentsChanged} on each element of the
- * {@link listenerList} which is a {@link ListDataListener}. The event
+ * {@link #listenerList} which is a {@link ListDataListener}. The event
* fired has type {@ListDataEvent.CONTENTS_CHANGED} and represents a
* change to the data elements in the range [startIndex, endIndex]
* inclusive.
@@ -110,7 +109,7 @@ public abstract class AbstractListModel implements ListModel, Serializable
/**
* Call {@link ListDataListener#intervalAdded} on each element of the
- * {@link listenerList} which is a {@link ListDataListener}. The event
+ * {@link #listenerList} which is a {@link ListDataListener}. The event
* fired has type {@ListDataEvent.INTERVAL_ADDED} and represents an
* addition of the data elements in the range [startIndex, endIndex]
* inclusive.
@@ -132,7 +131,7 @@ public abstract class AbstractListModel implements ListModel, Serializable
/**
* Call {@link ListDataListener#intervalRemoved} on each element of the
- * {@link listenerList} which is a {@link ListDataListener}. The event
+ * {@link #listenerList} which is a {@link ListDataListener}. The event
* fired has type {@ListDataEvent.INTERVAL_REMOVED} and represents a
* removal of the data elements in the range [startIndex, endIndex]
* inclusive.
@@ -155,7 +154,7 @@ public abstract class AbstractListModel implements ListModel, Serializable
/**
* Return the subset of {@link EventListener} objects found in this
- * object's {@link listenerList} which are elements of the specified
+ * object's {@link #listenerList} which are elements of the specified
* type.
*
* @param listenerType The type of listeners to select
@@ -170,7 +169,7 @@ public abstract class AbstractListModel implements ListModel, Serializable
/**
* A synonym for getListeners(ListDataListener.class)
.
*
- * @return The set of ListDataListeners found in the {@link listenerList}
+ * @return The set of ListDataListeners found in the {@link #listenerList}
*/
public ListDataListener[] getListDataListeners()
{
diff --git a/libjava/classpath/javax/swing/AbstractSpinnerModel.java b/libjava/classpath/javax/swing/AbstractSpinnerModel.java
index 05a9892..d61113b 100644
--- a/libjava/classpath/javax/swing/AbstractSpinnerModel.java
+++ b/libjava/classpath/javax/swing/AbstractSpinnerModel.java
@@ -45,9 +45,10 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
/**
- * AbstractSpinnerModel
- * @author Ka-Hing Cheung
- * @version 1.0
+ * Provides standard implementations for some of the methods in
+ * {@link SpinnerModel}.
+ *
+ * @author Ka-Hing Cheung
*/
public abstract class AbstractSpinnerModel implements SpinnerModel
{
diff --git a/libjava/classpath/javax/swing/Action.java b/libjava/classpath/javax/swing/Action.java
index 17168c3..3dd6353 100644
--- a/libjava/classpath/javax/swing/Action.java
+++ b/libjava/classpath/javax/swing/Action.java
@@ -41,7 +41,7 @@ import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
/**
- * An action provides a convenient central point of control for some task
+ * Provides a convenient central point of control for some task
* that can be triggered by more than one control in a Swing user interface
* (for example, a menu item and a toolbar button).
*
diff --git a/libjava/classpath/javax/swing/ActionMap.java b/libjava/classpath/javax/swing/ActionMap.java
index c609257..c14bafd 100644
--- a/libjava/classpath/javax/swing/ActionMap.java
+++ b/libjava/classpath/javax/swing/ActionMap.java
@@ -49,6 +49,14 @@ import java.util.Set;
/**
+ * Maps arbitrary keys (usually Strings) to {@link Action} instances. This
+ * is used in combination with {@link InputMap}s.
+ *
+ * If a component receives an input event, this is looked up in
+ * the component's InputMap
. The result is an object which
+ * serves as a key to the components ActionMap
. Finally
+ * the Action
that is stored is executed.
+ *
* @author Andrew Selkirk
* @author Michael Koch
*/
diff --git a/libjava/classpath/javax/swing/BorderFactory.java b/libjava/classpath/javax/swing/BorderFactory.java
index b084b61..45cf3bb 100644
--- a/libjava/classpath/javax/swing/BorderFactory.java
+++ b/libjava/classpath/javax/swing/BorderFactory.java
@@ -50,6 +50,11 @@ import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import javax.swing.border.TitledBorder;
+/**
+ * A factory for commonly used borders.
+ *
+ * @author original author unknown
+ */
public class BorderFactory
{
private BorderFactory()
@@ -257,7 +262,7 @@ public class BorderFactory
* justification (left) and using the default font and text color determined
* by the current look and feel.
*
- * @param order The Border object to add the title to
+ * @param border The Border object to add the title to
* @param title A String containing the text of the title
*
* @return The TitledBorder object
diff --git a/libjava/classpath/javax/swing/BoundedRangeModel.java b/libjava/classpath/javax/swing/BoundedRangeModel.java
index 5f85000..5ca5a7e 100644
--- a/libjava/classpath/javax/swing/BoundedRangeModel.java
+++ b/libjava/classpath/javax/swing/BoundedRangeModel.java
@@ -1,5 +1,5 @@
/* BoundedRangeModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +38,17 @@ exception statement from your version. */
package javax.swing;
+import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
- * The data model that is used in components that display a range of values,
+ * The data model that represents a range that is constrained to fit
+ * within specified bounds. The range is defined as value
+ * to value + extent
, where both value
and
+ * extent
are integers, and extent >= 0
. The bounds
+ * are defined by integers minimum
and maximum
.
+ *
+ * This type of model is used in components that display a range of values,
* like {@link JProgressBar} and {@link JSlider}.
*
* @author Andrew Selkirk
@@ -49,16 +56,18 @@ import javax.swing.event.ChangeListener;
public interface BoundedRangeModel
{
/**
- * getValue
+ * Returns the current value for the model.
*
- * @return int
+ * @return The current value for the model.
*
* @see #setValue(int)
*/
int getValue();
/**
- * setValue
+ * Sets the value for the model and sends a {@link ChangeEvent} to
+ * all registered listeners. The new value must satisfy the constraint
+ * min <= value <= value + extent <= max
.
*
* @param value the value
*
@@ -67,16 +76,20 @@ public interface BoundedRangeModel
void setValue(int value);
/**
- * getMinimum
+ * Returns the lower bound for the model. The start of the model's range
+ * (see {@link #getValue()}) cannot be less than this lower bound.
*
- * @return int
+ * @return The lower bound for the model.
*
* @see #setMinimum(int)
+ * @see #getMaximum()
*/
int getMinimum();
/**
- * setMinimum
+ * Sets the lower bound for the model and sends a {@link ChangeEvent} to all
+ * registered listeners. The new minimum must be less than or equal to the
+ * start value of the model's range (as returned by {@link #getValue()}).
*
* @param minimum the minimum value
*
@@ -85,16 +98,22 @@ public interface BoundedRangeModel
void setMinimum(int minimum);
/**
- * getMaximum
+ * Returns the upper bound for the model. This sets an upper limit for the
+ * end value of the model's range ({@link #getValue()} +
+ * {@link #getExtent()}).
*
- * @return int
+ * @return The upper bound for the model.
*
* @see #setMaximum(int)
+ * @see #getMinimum()
*/
int getMaximum();
/**
- * setMaximum
+ * Sets the upper bound for the model and sends a {@link ChangeEvent} to all
+ * registered listeners. The new maximum must be greater than or equal to the
+ * end value of the model's range (as returned by {@link #getValue()} +
+ * {@link #getExtent()}).
*
* @param maximum the maximum value
*
@@ -108,12 +127,12 @@ public interface BoundedRangeModel
* @return true
if value is adjusting,
* otherwise false
*
- * @see setValueIsAdjusting(boolean)
+ * @see #setValueIsAdjusting(boolean)
*/
boolean getValueIsAdjusting();
/**
- * setValueIsAdjusting
+ * Sets the valueIsAdjusting
property.
*
* @param adjusting true
if adjusting,
* false
otherwise
@@ -132,7 +151,8 @@ public interface BoundedRangeModel
int getExtent();
/**
- * setExtent
+ * Sets the extent, which is the length of the model's range, and sends a
+ * {@link ChangeEvent} to all registered listeners.
*
* @param extent the extent
*
@@ -141,12 +161,14 @@ public interface BoundedRangeModel
void setExtent(int extent);
/**
- * setRangeProperties
+ * Sets all the properties for the model in a single call.
+ *
* @param value the value
* @param extent the extent
* @param minnimum the minimum value
* @param maximum the maximum value
- * @param adjusting TODO
+ * @param adjusting a flag that indicates the model is being adjusted
+ * continuously.
*/
void setRangeProperties(int value, int extent, int minimum, int maximum,
boolean adjusting);
@@ -156,7 +178,7 @@ public interface BoundedRangeModel
*
* @param listener the listener to add
*
- * @see #removeChangeListener(javax.swing.event.ChangeListener)
+ * @see #removeChangeListener(ChangeListener)
*/
void addChangeListener(ChangeListener listener);
@@ -165,7 +187,7 @@ public interface BoundedRangeModel
*
* @param listener the listener to remove
*
- * @see #addChangeListener(javax.swing.event.ChangeListener)
+ * @see #addChangeListener(ChangeListener)
*/
void removeChangeListener(ChangeListener listener);
}
diff --git a/libjava/classpath/javax/swing/Box.java b/libjava/classpath/javax/swing/Box.java
index 546a282..b2cb44a 100644
--- a/libjava/classpath/javax/swing/Box.java
+++ b/libjava/classpath/javax/swing/Box.java
@@ -60,6 +60,9 @@ public class Box extends JComponent implements Accessible
{
private static final long serialVersionUID = 1525417495883046342L;
+ /**
+ * Provides accessibility support for Box
es.
+ */
// FIXME: disable to make libjava compile; visibility rules are broken
protected class AccessibleBox // extends Container.AccessibleAWTContainer
{
@@ -82,6 +85,9 @@ public class Box extends JComponent implements Accessible
{
private static final long serialVersionUID = -1204263191910183998L;
+ /**
+ * Provides accessibility support for Box.Filler
.
+ */
// FIXME: disable to make libjava compile; visibility rules are broken
protected class AccessibleBoxFiller // extends Component.AccessibleAWTComponent
{
diff --git a/libjava/classpath/javax/swing/BoxLayout.java b/libjava/classpath/javax/swing/BoxLayout.java
index 5dfe1d6..28bb539 100644
--- a/libjava/classpath/javax/swing/BoxLayout.java
+++ b/libjava/classpath/javax/swing/BoxLayout.java
@@ -53,7 +53,8 @@ import java.util.Vector;
import gnu.java.awt.AWTUtilities;
/**
- * A layout for swing components.
+ * A layout that stacks the children of a container in a Box, either
+ * horizontally or vertically.
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
* @author Roman Kennke (roman@kennke.org)
@@ -150,7 +151,8 @@ public class BoxLayout implements LayoutManager2, Serializable
* direction. This will be insets.top
for vertical direction
* and insets.left
for horizontal direction.
*
- * @param the {@link Insets} object from which to return the lower bounds
+ * @param insets the {@link Insets} object from which to return the lower
+ * bounds
*
* @return the lower bounds of the {@link Insets} object according to this
* direction
@@ -226,7 +228,8 @@ public class BoxLayout implements LayoutManager2, Serializable
* direction. This will be insets.top
for vertical direction
* and insets.left
for horizontal direction.
*
- * @param the {@link Insets} object from which to return the lower bounds
+ * @param insets the {@link Insets} object from which to return the lower
+ * bounds
*
* @return the lower bounds of the {@link Insets} object according to this
* direction
diff --git a/libjava/classpath/javax/swing/ButtonGroup.java b/libjava/classpath/javax/swing/ButtonGroup.java
index bea8aea..3de1d4b 100644
--- a/libjava/classpath/javax/swing/ButtonGroup.java
+++ b/libjava/classpath/javax/swing/ButtonGroup.java
@@ -43,7 +43,25 @@ import java.util.Vector;
/**
- * DOCUMENT ME!
+ * Logically groups a set of buttons, so that only one of the buttons in
+ * a ButtonGroup
can be selected at the same time. If one
+ * button in a ButtonGroup
is selected, all other buttons
+ * are automatically deselected.
+ *
+ * While ButtonGroup
can be used for all buttons that are derived
+ * from {@link AbstractButton}, it is normally only used for
+ * {@link JRadioButton}s, {@link JRadioButtonMenuItem}s and
+ * {@link JToggleButton}s.
+ *
+ * You could use it for {@link JCheckBox}es, but for the sake of usability
+ * this is strongly discouraged because the common expectation of checkboxes
+ * is that the user is allowed to make multiple selections.
+ *
+ * It makes no sense to put {@link JButton}s or {@link JMenuItem}s in
+ * a ButtonGroup
because they don't implement the
+ * selected
semantics.
+ *
+ * @author original author unknown
*/
public class ButtonGroup implements Serializable
{
diff --git a/libjava/classpath/javax/swing/CellRendererPane.java b/libjava/classpath/javax/swing/CellRendererPane.java
index db7a143..886d5c5 100644
--- a/libjava/classpath/javax/swing/CellRendererPane.java
+++ b/libjava/classpath/javax/swing/CellRendererPane.java
@@ -48,12 +48,11 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
/**
- * The CellRendererPane's purpose is to paint the cells of JList, JTable and
- * JTree. It intercepts the usual paint tree, so that we don't walk up and
+ * Paints the cells of JList, JTable and JTree.
+ * It intercepts the usual paint tree, so that we don't walk up and
* repaint everything.
*
- * @author Andrew Selkirk
- * @version 1.0
+ * @author Andrew Selkirk
*/
public class CellRendererPane
extends Container
@@ -62,7 +61,7 @@ public class CellRendererPane
private static final long serialVersionUID = -7642183829532984273L;
/**
- * AccessibleCellRendererPane
+ * Provides accessibility support for CellRendererPanes.
*/
protected class AccessibleCellRendererPane extends AccessibleAWTContainer
{
@@ -70,7 +69,6 @@ public class CellRendererPane
/**
* Constructor AccessibleCellRendererPane
- * @param component TODO
*/
protected AccessibleCellRendererPane()
{
diff --git a/libjava/classpath/javax/swing/ComponentInputMap.java b/libjava/classpath/javax/swing/ComponentInputMap.java
index 4ecc058..f95c310 100644
--- a/libjava/classpath/javax/swing/ComponentInputMap.java
+++ b/libjava/classpath/javax/swing/ComponentInputMap.java
@@ -39,6 +39,9 @@ package javax.swing;
/**
+ * An {@link InputMap} that is associated with a particular {@link JComponent}.
+ * The component is notified when its ComponentInputMap
changes.
+ *
* @author Andrew Selkirk
* @author Michael Koch
*/
@@ -70,7 +73,7 @@ public class ComponentInputMap extends InputMap
* If actionMapKey is null an existing entry will be removed.
*
* @param keystroke the keystroke for the entry
- * @param actionMapKey the action.
+ * @param value the action.
*/
public void put(KeyStroke keystroke, Object value)
{
@@ -90,7 +93,7 @@ public class ComponentInputMap extends InputMap
/**
* Remove an entry from the InputMap
.
*
- * @param key the key of the entry to remove
+ * @param keystroke the key of the entry to remove
*/
public void remove(KeyStroke keystroke)
{
@@ -103,7 +106,7 @@ public class ComponentInputMap extends InputMap
*
* @param parentMap the new parent
*
- * @exception IllegalArgument if parentMap is not a
+ * @exception IllegalArgumentException if parentMap is not a
* ComponentInputMap
or not associated with the same component
*/
public void setParent(InputMap parentMap)
diff --git a/libjava/classpath/javax/swing/DebugGraphics.java b/libjava/classpath/javax/swing/DebugGraphics.java
index e73c120..137b823 100644
--- a/libjava/classpath/javax/swing/DebugGraphics.java
+++ b/libjava/classpath/javax/swing/DebugGraphics.java
@@ -50,9 +50,11 @@ import java.text.AttributedCharacterIterator;
/**
- * DebugGraphics
- * @author Andrew Selkirk
- * @version 1.0
+ * An extension of {@link Graphics} that can be used for debugging
+ * custom Swing widgets. DebugGraphics
has the ability to
+ * draw slowly and can log drawing actions.
+ *
+ * @author Andrew Selkirk
*/
public class DebugGraphics extends Graphics
{
diff --git a/libjava/classpath/javax/swing/DefaultBoundedRangeModel.java b/libjava/classpath/javax/swing/DefaultBoundedRangeModel.java
index 53c0fb3..10de4b9 100644
--- a/libjava/classpath/javax/swing/DefaultBoundedRangeModel.java
+++ b/libjava/classpath/javax/swing/DefaultBoundedRangeModel.java
@@ -47,7 +47,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
/**
- * A default implementation of BoundedRangeModel
.
+ * The default implementation of BoundedRangeModel
.
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
@@ -413,7 +413,7 @@ public class DefaultBoundedRangeModel
/**
* Retrieves the current listeners of the specified class.
*
- * @param c the class of listeners; usually {@link
+ * @param listenerType the class of listeners; usually {@link
* ChangeListener}.class
.
*
* @return an array with the currently subscribed listeners, or
diff --git a/libjava/classpath/javax/swing/DefaultButtonModel.java b/libjava/classpath/javax/swing/DefaultButtonModel.java
index 2cfb9e9..f7d09d5 100644
--- a/libjava/classpath/javax/swing/DefaultButtonModel.java
+++ b/libjava/classpath/javax/swing/DefaultButtonModel.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing;
+import java.awt.ItemSelectable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
@@ -51,7 +52,8 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
/**
- * The pUrpose of this class is to model the dynamic state of an abstract
+ * The default implementation of {@link ButtonModel}.
+ * The purpose of this class is to model the dynamic state of an abstract
* button. The concrete button type holding this state may be a a "toggle"
* button (checkbox, radio button) or a "push" button (menu button, button).
* If the model is disabled, only the "selected" property can be changed. An
@@ -265,9 +267,9 @@ public class DefaultButtonModel implements ButtonModel, Serializable
}
/**
- * Inform each ItemListener in the {@link listenerList} that an ItemEvent
+ * Inform each ItemListener in the {@link #listenerList} that an ItemEvent
* has occurred. This happens in response to any change to the {@link
- * stateMask} field.
+ * #stateMask} field.
*
* @param e The ItemEvent to fire
*/
@@ -280,9 +282,9 @@ public class DefaultButtonModel implements ButtonModel, Serializable
}
/**
- * Inform each ActionListener in the {@link listenerList} that an
+ * Inform each ActionListener in the {@link #listenerList} that an
* ActionEvent has occurred. This happens in response to the any change to
- * the {@link stateMask} field which makes the enabled, armed and pressed
+ * the {@link #stateMask} field which makes the enabled, armed and pressed
* properties all simultaneously true
.
*
* @param e The ActionEvent to fire
@@ -296,7 +298,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable
}
/**
- * Inform each ChangeListener in the {@link listenerList} that a ChangeEvent
+ * Inform each ChangeListener in the {@link #listenerList} that a ChangeEvent
* has occurred. This happens in response to the any change to a property
* of the model.
*/
@@ -395,13 +397,13 @@ public class DefaultButtonModel implements ButtonModel, Serializable
else
stateMask = stateMask & (~PRESSED);
- // notify interested ChangeListeners
- fireStateChanged();
-
// if button is armed and was released, fire action event
if (!p && isArmed())
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
actionCommand));
+
+ // notify interested ChangeListeners
+ fireStateChanged();
}
/**
diff --git a/libjava/classpath/javax/swing/DefaultCellEditor.java b/libjava/classpath/javax/swing/DefaultCellEditor.java
index e67e2f5..00e0086 100644
--- a/libjava/classpath/javax/swing/DefaultCellEditor.java
+++ b/libjava/classpath/javax/swing/DefaultCellEditor.java
@@ -43,16 +43,24 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.EventObject;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.event.CellEditorListener;
import javax.swing.table.TableCellEditor;
import javax.swing.tree.TreeCellEditor;
/**
- * DefaultCellEditor
- * @author Andrew Selkirk
- * @version 1.0
+ * The default implementation of {@link TableCellEditor} and
+ * {@link TreeCellEditor}. It provides editor components for
+ * some standard object types.
+ *
+ * @author Andrew Selkirk
+ *
+ * @status mostly unimplemented
*/
public class DefaultCellEditor
extends AbstractCellEditor
@@ -61,7 +69,9 @@ public class DefaultCellEditor
private static final long serialVersionUID = 3564035141373880027L;
/**
- * EditorDelegate
+ * Delegates a couple of method calls (such as {@link #isCellEditable)
+ * to the component it contains and listens for events that indicate
+ * that editing has stopped.
*/
protected class EditorDelegate
implements ActionListener, ItemListener, Serializable
@@ -75,8 +85,6 @@ public class DefaultCellEditor
/**
* Constructor EditorDelegate
- *
- * @param value0 TODO
*/
protected EditorDelegate()
{
@@ -87,8 +95,10 @@ public class DefaultCellEditor
*
* @param event TODO
*/
- public void setValue(Object event)
+ public void setValue(Object value)
{
+ // TODO: should be setting the value in the editorComp
+ this.value = value;
}
/**
@@ -98,7 +108,8 @@ public class DefaultCellEditor
*/
public Object getCellEditorValue()
{
- return null; // TODO
+ // TODO: should be getting the updated value from the editorComp
+ return value;
} // getCellEditorValue()
/**
@@ -110,7 +121,10 @@ public class DefaultCellEditor
*/
public boolean isCellEditable(EventObject event)
{
- return false; // TODO
+ if (event == null || !(event instanceof MouseEvent) ||
+ (((MouseEvent) event).getClickCount() >= getClickCountToStart()))
+ return true;
+ return false;
} // isCellEditable()
/**
@@ -122,7 +136,8 @@ public class DefaultCellEditor
*/
public boolean shouldSelectCell(EventObject event)
{
- return false; // TODO
+ // return true to indicate that the editing cell may be selected
+ return true;
} // shouldSelectCell()
/**
@@ -132,7 +147,8 @@ public class DefaultCellEditor
*/
public boolean stopCellEditing()
{
- return false; // TODO
+ fireEditingStopped();
+ return true;
} // stopCellEditing()
/**
@@ -140,7 +156,7 @@ public class DefaultCellEditor
*/
public void cancelCellEditing()
{
- // TODO
+ fireEditingCanceled();
} // cancelCellEditing()
/**
@@ -152,7 +168,8 @@ public class DefaultCellEditor
*/
public boolean startCellEditing(EventObject event)
{
- return false; // TODO
+ // return true to indicate that editing has begun
+ return true;
} // startCellEditing()
/**
@@ -162,7 +179,7 @@ public class DefaultCellEditor
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ stopCellEditing();
} // actionPerformed()
/**
@@ -172,9 +189,23 @@ public class DefaultCellEditor
*/
public void itemStateChanged(ItemEvent event)
{
- // TODO
+ stopCellEditing();
} // itemStateChanged()
+ void fireEditingStopped()
+ {
+ CellEditorListener[] listeners = getCellEditorListeners();
+ for (int index = 0; index < listeners.length; index++)
+ listeners[index].editingStopped(changeEvent);
+
+ }
+
+ void fireEditingCanceled()
+ {
+ CellEditorListener[] listeners = getCellEditorListeners();
+ for (int index = 0; index < listeners.length; index++)
+ listeners[index].editingCanceled(changeEvent);
+ }
} // EditorDelegate
/**
@@ -199,7 +230,8 @@ public class DefaultCellEditor
*/
public DefaultCellEditor(JTextField textfield)
{
- // TODO
+ editorComponent = textfield;
+ clickCountToStart = 3;
} // DefaultCellEditor()
/**
@@ -209,7 +241,8 @@ public class DefaultCellEditor
*/
public DefaultCellEditor(JCheckBox checkbox)
{
- // TODO
+ editorComponent = checkbox;
+ clickCountToStart = 1;
} // DefaultCellEditor()
/**
@@ -219,7 +252,8 @@ public class DefaultCellEditor
*/
public DefaultCellEditor(JComboBox combobox)
{
- // TODO
+ editorComponent = combobox;
+ clickCountToStart = 1;
} // DefaultCellEditor()
/**
@@ -229,7 +263,7 @@ public class DefaultCellEditor
*/
public Component getComponent()
{
- return null; // TODO
+ return editorComponent;
} // getComponent()
/**
@@ -239,7 +273,7 @@ public class DefaultCellEditor
*/
public int getClickCountToStart()
{
- return 0; // TODO
+ return clickCountToStart;
} // getClickCountToStart()
/**
@@ -249,7 +283,7 @@ public class DefaultCellEditor
*/
public void setClickCountToStart(int count)
{
- // TODO
+ clickCountToStart = count;
} // setClickCountToStart()
/**
@@ -259,7 +293,7 @@ public class DefaultCellEditor
*/
public Object getCellEditorValue()
{
- return null; // TODO
+ return delegate.getCellEditorValue();
} // getCellEditorValue()
/**
@@ -271,7 +305,7 @@ public class DefaultCellEditor
*/
public boolean isCellEditable(EventObject event)
{
- return false; // TODO
+ return delegate.isCellEditable(event);
} // isCellEditable()
/**
@@ -283,7 +317,7 @@ public class DefaultCellEditor
*/
public boolean shouldSelectCell(EventObject event)
{
- return false; // TODO
+ return delegate.shouldSelectCell(event);
} // shouldSelectCell()
/**
@@ -293,7 +327,7 @@ public class DefaultCellEditor
*/
public boolean stopCellEditing()
{
- return false; // TODO
+ return delegate.stopCellEditing();
} // stopCellEditing()
/**
@@ -301,27 +335,53 @@ public class DefaultCellEditor
*/
public void cancelCellEditing()
{
- // TODO
+ delegate.cancelCellEditing();
} // cancelCellEditing()
/**
- * getTreeCellEditorComponent
+ * Sets an initial value for the editor.
+ * This will cause the editor to stopEditing and lose any partially
+ * edited value if the editor is editing when this method is called.
+ * Returns the component that should be added to the client's Component
+ * hierarchy. Once installed in the client's hierarchy this component will
+ * then be able to draw and receive user input.
*
- * @param tree TODO
- * @param value TODO
- * @param isSelected TODO
- * @param expanded TODO
- * @param leaf TODO
- * @param row TODO
+ * @param tree - the JTree that is asking the editor to edit; this
+ * parameter can be null
+ * @param value - the value of the cell to be edited
+ * @param isSelected - true is the cell is to be renderer with selection
+ * highlighting
+ * @param expanded - true if the node is expanded
+ * @param leaf - true if the node is a leaf node
+ * @param row - the row index of the node being edited
*
- * @returns Component
+ * @returns Component the component for editing
*/
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected,
boolean expanded, boolean leaf,
int row)
{
- return null; // TODO
+ if (editorComponent instanceof JTextField)
+ {
+ ((JTextField)editorComponent).setText(value.toString());
+ delegate = new EditorDelegate();
+ ((JTextField)editorComponent).addActionListener(delegate);
+ }
+ else if (editorComponent instanceof JCheckBox)
+ {
+ ((JCheckBox)editorComponent).setText(value.toString());
+ delegate = new EditorDelegate();
+ ((JCheckBox)editorComponent).addActionListener(delegate);
+ }
+ else if (editorComponent instanceof JComboBox)
+ {
+ ((JComboBox)editorComponent).setSelectedItem(value.toString());
+ delegate = new EditorDelegate();
+ ((JComboBox)editorComponent).addActionListener(delegate);
+ }
+
+ return editorComponent;
} // getTreeCellEditorComponent()
/**
@@ -335,10 +395,30 @@ public class DefaultCellEditor
*
* @returns Component
*/
- public Component getTableCellEditorComponent(JTable tree, Object value,
+ public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column)
{
- return null; // TODO
+ // NOTE: as specified by Sun, we don't call new() everytime, we return
+ // editorComponent on each call to getTableCellEditorComponent or
+ // getTreeCellEditorComponent. However, currently JTextFields have a
+ // problem with getting rid of old text, so without calling new() there
+ // are some strange results. If you edit more than one cell in the table
+ // text from previously edited cells may unexpectedly show up in the
+ // cell you are currently editing. This will be fixed automatically
+ // when JTextField is fixed.
+ if (editorComponent instanceof JTextField)
+ {
+ ((JTextField)editorComponent).setText(value.toString());
+ delegate = new EditorDelegate();
+ ((JTextField)editorComponent).addActionListener(delegate);
+ }
+ else
+ {
+ // TODO
+ }
+ return editorComponent;
} // getTableCellEditorComponent()
+
+
}
diff --git a/libjava/classpath/javax/swing/DefaultComboBoxModel.java b/libjava/classpath/javax/swing/DefaultComboBoxModel.java
index 1cea886..b48b968 100644
--- a/libjava/classpath/javax/swing/DefaultComboBoxModel.java
+++ b/libjava/classpath/javax/swing/DefaultComboBoxModel.java
@@ -43,7 +43,8 @@ import java.util.Vector;
/**
- * DefaultComboBoxModel is a data model for JComboBox. This model keeps track
+ * The default implementation of {@link MutableComboBoxModel}.
+ * This model keeps track
* of elements contained in the JComboBox as well as the current combo box
* selection. Whenever selection in the JComboBox changes, the ComboBoxModel
* will fire ListDataEvents to ComboBox's ListDataListeners.
@@ -51,7 +52,6 @@ import java.util.Vector;
* @author Andrew Selkirk
* @author Olga Rodimina
* @author Robert Schuster
- * @version 1.0
*/
public class DefaultComboBoxModel extends AbstractListModel
implements MutableComboBoxModel, Serializable
diff --git a/libjava/classpath/javax/swing/DefaultDesktopManager.java b/libjava/classpath/javax/swing/DefaultDesktopManager.java
index 15ed262..2b8977e 100644
--- a/libjava/classpath/javax/swing/DefaultDesktopManager.java
+++ b/libjava/classpath/javax/swing/DefaultDesktopManager.java
@@ -49,8 +49,8 @@ import java.io.Serializable;
import javax.swing.JInternalFrame.JDesktopIcon;
/**
- * DefaultDesktopManager is the default implementation of DesktopManager for
- * swing. It implements the basic beaviours for JInternalFrames in arbitrary
+ * The default implementation of DesktopManager for
+ * Swing. It implements the basic beaviours for JInternalFrames in arbitrary
* parents. The methods provided by the class are not meant to be called by
* the user, instead, the JInternalFrame methods will call these methods.
*/
diff --git a/libjava/classpath/javax/swing/DefaultFocusManager.java b/libjava/classpath/javax/swing/DefaultFocusManager.java
index dd8e604..08db651 100644
--- a/libjava/classpath/javax/swing/DefaultFocusManager.java
+++ b/libjava/classpath/javax/swing/DefaultFocusManager.java
@@ -43,9 +43,11 @@ import java.awt.event.KeyEvent;
import java.util.Stack;
/**
- * DefaultFocusManager
- * @author Andrew Selkirk
- * @version 1.0
+ * This class has been obsoleted by the new
+ * {@link java.awt.KeyboardFocusManager} and
+ * {@link java.awt.DefaultKeyboardFocusManager} API.
+ *
+ * @author Andrew Selkirk
*/
public class DefaultFocusManager extends FocusManager {
diff --git a/libjava/classpath/javax/swing/DefaultListCellRenderer.java b/libjava/classpath/javax/swing/DefaultListCellRenderer.java
index 0f2417d..5a34ba7 100644
--- a/libjava/classpath/javax/swing/DefaultListCellRenderer.java
+++ b/libjava/classpath/javax/swing/DefaultListCellRenderer.java
@@ -46,17 +46,23 @@ import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
/**
- * DefaultListCellRenderer. This class is responsible for rendering list
- * cells.
+ * The default implementation {@link ListCellRenderer}. It provides a standard
+ * renderer for data objects of all types via {@link Object#toString()}.
*
* @author Andrew Selkirk
- * @version 1.0
*/
public class DefaultListCellRenderer extends JLabel
implements ListCellRenderer, Serializable
{
private static final long serialVersionUID = 7708947179685189462L;
+ /**
+ * Subclasses DefaultListCellRenderers
and implements
+ * {@link javax.swing.plaf.UIResource}. This is used by
+ * {@link javax.swing.plaf.ListUI} subclasses to provide a default for
+ * the List.cellRenderer
property. If you want to override
+ * this property, use DefaultListCellRenderer
or a subclass.
+ */
public static class UIResource extends DefaultListCellRenderer
implements javax.swing.plaf.UIResource
{
diff --git a/libjava/classpath/javax/swing/DefaultListModel.java b/libjava/classpath/javax/swing/DefaultListModel.java
index d7ff259..fdbbb56 100644
--- a/libjava/classpath/javax/swing/DefaultListModel.java
+++ b/libjava/classpath/javax/swing/DefaultListModel.java
@@ -41,7 +41,7 @@ import java.util.Enumeration;
import java.util.Vector;
/**
- * This is a default subclass of the {@link AbstractListModel}, used by
+ * The default implementation of {@link AbstractListModel}, used by
* {@link javax.swing.JList} and similar objects as the model of a list of
* values. The implementation is based on an underlying {@link
* java.util.Vector}.
diff --git a/libjava/classpath/javax/swing/DefaultListSelectionModel.java b/libjava/classpath/javax/swing/DefaultListSelectionModel.java
index d08ca6f..f8d544d 100644
--- a/libjava/classpath/javax/swing/DefaultListSelectionModel.java
+++ b/libjava/classpath/javax/swing/DefaultListSelectionModel.java
@@ -1,5 +1,5 @@
/* DefaultListSelectionModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,10 +47,10 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
- *
This class provides a default implementation of {@link - * ListSelectioModel}, which is used by {@link javax.swing.JList} and + * The default implementation of {@link ListSelectionModel}, + * which is used by {@link javax.swing.JList} and * similar classes to manage the selection status of a number of data - * elements.
+ * elements. * *The class is organized abstractly as a set of intervals of
* integers. Each interval indicates an inclusive range of indices in a
@@ -104,7 +104,7 @@ public class DefaultListSelectionModel implements Cloneable,
* controls the range of indices provided in any {@link
* ListSelectionEvent} fired by the selectionModel. Let
* [A,L]
be the range of indices between {@link
- * anchorSelectionIndex} and {@link leadSelectionIndex} inclusive, and
+ * #anchorSelectionIndex} and {@link #leadSelectionIndex} inclusive, and
* let [i0,i1]
be the range of indices changed in a given
* call which generates a {@link ListSelectionEvent}. Then when this
* property is true
, the {@link ListSelectionEvent} contains
@@ -232,7 +232,7 @@ public class DefaultListSelectionModel implements Cloneable,
* which changed selection status between the beginning and end of the
* method.
true
if this is the final change
@@ -636,8 +636,8 @@ public class DefaultListSelectionModel implements Cloneable,
*
* @param listener The listener to add
*
- * @see removeListSelectionListener
- * @see getListSelectionListeners
+ * @see #removeListSelectionListener
+ * @see #getListSelectionListeners
*/
public void addListSelectionListener(ListSelectionListener listener)
{
@@ -649,8 +649,8 @@ public class DefaultListSelectionModel implements Cloneable,
*
* @param listener The listener to remove
*
- * @see addListSelectionListener
- * @see getListSelectionListeners
+ * @see #addListSelectionListener
+ * @see #getListSelectionListeners
*/
public void removeListSelectionListener(ListSelectionListener listener)
{
@@ -664,7 +664,7 @@ public class DefaultListSelectionModel implements Cloneable,
*
* @return The array
*
- * @see getListSelectionListener
+ * @see #getListSelectionListeners
* @since 1.3
*/
public EventListener[] getListeners(Class listenerType)
@@ -677,9 +677,9 @@ public class DefaultListSelectionModel implements Cloneable,
*
* @return the array
*
- * @see addListSelectionListener
- * @see removeListSelectionListener
- * @see getListeners
+ * @see #addListSelectionListener
+ * @see #removeListSelectionListener
+ * @see #getListeners
* @since 1.4
*/
public ListSelectionListener[] getListSelectionListeners()
diff --git a/libjava/classpath/javax/swing/DefaultSingleSelectionModel.java b/libjava/classpath/javax/swing/DefaultSingleSelectionModel.java
index 039883e..8f4d405 100644
--- a/libjava/classpath/javax/swing/DefaultSingleSelectionModel.java
+++ b/libjava/classpath/javax/swing/DefaultSingleSelectionModel.java
@@ -46,7 +46,8 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
/**
- * DefaultSingleSelectionModel
+ * The default implementation of {@link SingleSelectionModel}, used in
+ * {@link JTabbedPane}, {@link JMenuBar} and {@link JPopupMenu}.
*
* @author Andrew Selkirk
*/
diff --git a/libjava/classpath/javax/swing/FocusManager.java b/libjava/classpath/javax/swing/FocusManager.java
index 9f898e6..179fa6f 100644
--- a/libjava/classpath/javax/swing/FocusManager.java
+++ b/libjava/classpath/javax/swing/FocusManager.java
@@ -44,9 +44,11 @@ import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
/**
- * FocusManager
- * @author Andrew Selkirk
- * @version 1.0
+ * This class has been obsoleted by the new
+ * {@link java.awt.KeyboardFocusManager} and
+ * {@link java.awt.DefaultKeyboardFocusManager} API.
+ *
+ * @author Andrew Selkirk
*/
public abstract class FocusManager
extends DefaultKeyboardFocusManager
diff --git a/libjava/classpath/javax/swing/GrayFilter.java b/libjava/classpath/javax/swing/GrayFilter.java
index 1a88f6f..b920b08 100644
--- a/libjava/classpath/javax/swing/GrayFilter.java
+++ b/libjava/classpath/javax/swing/GrayFilter.java
@@ -43,6 +43,12 @@ import java.awt.Toolkit;
import java.awt.image.FilteredImageSource;
import java.awt.image.RGBImageFilter;
+/**
+ * Produces grayscale images out of colored images. This is used to provide
+ * default disabled icons for buttons.
+ *
+ * @author original author unknown
+ */
public class GrayFilter extends RGBImageFilter
{
private boolean b;
diff --git a/libjava/classpath/javax/swing/Icon.java b/libjava/classpath/javax/swing/Icon.java
index c00eee4..c73ad2d 100644
--- a/libjava/classpath/javax/swing/Icon.java
+++ b/libjava/classpath/javax/swing/Icon.java
@@ -1,5 +1,5 @@
/* Icon.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,7 +46,28 @@ import java.awt.Graphics;
*/
public interface Icon
{
+ /**
+ * Returns the height of the icon.
+ *
+ * @return The height of the icon.
+ */
int getIconHeight();
+
+ /**
+ * Returns the width of the icon.
+ *
+ * @return The width of the icon.
+ */
int getIconWidth();
+
+ /**
+ * Draws the icon at the location (x, y) on the specified graphics device.
+ *
+ * @param c a component related to the icon in some way (can be ignored by
+ some implementing classes).
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
void paintIcon(Component c, Graphics g, int x, int y);
}
diff --git a/libjava/classpath/javax/swing/ImageIcon.java b/libjava/classpath/javax/swing/ImageIcon.java
index 36f23d2..b650cd8 100644
--- a/libjava/classpath/javax/swing/ImageIcon.java
+++ b/libjava/classpath/javax/swing/ImageIcon.java
@@ -53,6 +53,9 @@ import javax.accessibility.AccessibleIcon;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleStateSet;
+/**
+ * An {@link Icon} implementation that is backed by an {@link Image}.
+ */
public class ImageIcon
implements Icon, Serializable, Accessible
{
@@ -219,92 +222,181 @@ public class ImageIcon
/** The AccessibleContext of this ImageIcon. */
private AccessibleContext accessibleContext;
+ /**
+ * Creates an ImageIcon without any properties set.
+ */
public ImageIcon()
{
}
-
- public ImageIcon(String file)
+
+ /**
+ * Constructs an ImageIcon given a filename. The icon's description
+ * is initially set to the filename itself. A filename of "" means
+ * create a blank icon.
+ *
+ * @param filename name of file to load or "" for a blank icon
+ */
+ public ImageIcon(String filename)
{
- this(file, file);
+ this(filename, filename);
}
- public ImageIcon(String file, String description)
+ /**
+ * Constructs an ImageIcon from the given filename, setting its
+ * description to the given description. A filename of "" means
+ * create a blank icon.
+ *
+ * @param filename name of file to load or "" for a blank icon
+ * @param description human-readable description of this icon
+ */
+ public ImageIcon(String filename, String description)
{
- this(Toolkit.getDefaultToolkit().getImage(file), description);
+ this(Toolkit.getDefaultToolkit().getImage(filename), description);
}
+ /**
+ * Creates an ImageIcon from the given byte array without any
+ * description set.
+ */
public ImageIcon(byte[] imageData)
{
this(imageData, null);
}
+ /**
+ * Creates an ImageIcon from the given byte array and sets the given
+ * description.
+ */
public ImageIcon(byte[] imageData, String description)
{
this(Toolkit.getDefaultToolkit().createImage(imageData), description);
}
+ /**
+ * Creates an ImageIcon from the given URL without any description
+ * set.
+ */
public ImageIcon(URL url)
{
this(url, null);
}
+ /**
+ * Creates an ImageIcon from the given URL and sets the given
+ * description.
+ */
public ImageIcon(URL url, String description)
{
this(Toolkit.getDefaultToolkit().getImage(url), description);
}
+ /**
+ * Creates an ImageIcon from the given Image without any description
+ * set.
+ */
public ImageIcon(Image image)
{
this(image, null);
}
+ /**
+ * Creates an ImageIcon from the given Image and sets the given
+ * description.
+ */
public ImageIcon(Image image, String description)
{
setImage(image);
setDescription(description);
}
-
+
+ /**
+ * Returns the ImageObserver that is used for all Image
+ * operations. Defaults to null when not explicitly set.
+ */
public ImageObserver getImageObserver()
{
return observer;
}
+ /**
+ * Sets the ImageObserver that will be used for all Image
+ * operations. Can be set to null (the default) when no observer is
+ * needed.
+ */
public void setImageObserver(ImageObserver newObserver)
{
observer = newObserver;
}
+ /**
+ * Returns the backing Image for this ImageIcon. Might be set to
+ * null in which case no image is shown.
+ */
public Image getImage()
{
return image;
}
+ /**
+ * Explicitly sets the backing Image for this ImageIcon. Will call
+ * loadImage() to make sure that the Image is completely loaded
+ * before returning.
+ */
public void setImage(Image image)
{
loadImage(image);
this.image = image;
}
+ /**
+ * Returns a human readable description for this ImageIcon or null
+ * when no description is set or available.
+ */
public String getDescription()
{
return description;
}
+ /**
+ * Sets a human readable description for this ImageIcon. Can be set
+ * to null when no description is available.
+ */
public void setDescription(String description)
{
this.description = description;
}
+ /**
+ * Returns the the height of the backing Image, or -1 if the backing
+ * Image is null. The getHeight() method of the Image will be called
+ * with the set observer of this ImageIcon.
+ */
public int getIconHeight()
{
+ if (image == null)
+ return -1;
+
return image.getHeight(observer);
}
+ /**
+ * Returns the the width of the backing Image, or -1 if the backing
+ * Image is null. The getWidth() method of the Image will be called
+ * with the set observer of this ImageIcon.
+ */
public int getIconWidth()
{
+ if (image == null)
+ return -1;
+
return image.getWidth(observer);
}
+ /**
+ * Calls g.drawImage()
on the backing Image using the
+ * set observer of this ImageIcon. If the set observer is null, the
+ * given Component is used as observer.
+ */
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.drawImage(image, x, y, observer != null ? observer : c);
@@ -338,9 +430,9 @@ public class ImageIcon
*
* @return the load status of the icon image
*
- * @see {@link MediaTracker.COMPLETE}
- * @see {@link MediaTracker.ABORTED}
- * @see {@link MediaTracker.ERRORED}
+ * @see MediaTracker#COMPLETE
+ * @see MediaTracker#ABORTED
+ * @see MediaTracker#ERRORED
*/
public int getImageLoadStatus()
{
diff --git a/libjava/classpath/javax/swing/InputMap.java b/libjava/classpath/javax/swing/InputMap.java
index afc431d..a7ec38c 100644
--- a/libjava/classpath/javax/swing/InputMap.java
+++ b/libjava/classpath/javax/swing/InputMap.java
@@ -49,6 +49,14 @@ import java.util.Set;
/**
+ * Maps {@link KeyStroke}s to arbitrary objects, usually Strings. This
+ * is used in combination with {@link ActionMap}s.
+ *
+ * If a component receives an input event, this is looked up in
+ * the component's InputMap
. The result is an object which
+ * serves as a key to the components ActionMap
. Finally
+ * the Action
that is stored is executed.
+ *
* @author Andrew Selkirk
* @author Michael Koch
*
@@ -80,7 +88,7 @@ public class InputMap
/**
* Returns the binding for keystroke.
*
- * @param key the key of the enty
+ * @param keystroke the key of the enty
*
* @return the binding associated with keystroke may be null
*/
@@ -111,7 +119,7 @@ public class InputMap
/**
* Remove an entry from the InputMap
.
*
- * @param key the key of the entry to remove
+ * @param keystroke the key of the entry to remove
*/
public void remove(KeyStroke keystroke)
{
diff --git a/libjava/classpath/javax/swing/InputVerifier.java b/libjava/classpath/javax/swing/InputVerifier.java
index 836c1a5..8e02ab8 100644
--- a/libjava/classpath/javax/swing/InputVerifier.java
+++ b/libjava/classpath/javax/swing/InputVerifier.java
@@ -39,9 +39,12 @@ package javax.swing;
/**
- * InputVerifier
+ * Verifies the user input on a component before the focus is shifted.
+ * It is sometimes necessary that input components have a valid state before
+ * they loose focus. Such components can have a InputVerifier
+ * subclass registered, that permits or vetos a focus change request.
+ *
* @author Andrew Selkirk
- * @version 1.0
*/
public abstract class InputVerifier
{
diff --git a/libjava/classpath/javax/swing/InternalFrameFocusTraversalPolicy.java b/libjava/classpath/javax/swing/InternalFrameFocusTraversalPolicy.java
index 0609f09..4780a67 100644
--- a/libjava/classpath/javax/swing/InternalFrameFocusTraversalPolicy.java
+++ b/libjava/classpath/javax/swing/InternalFrameFocusTraversalPolicy.java
@@ -42,11 +42,16 @@ import java.awt.Component;
import java.awt.FocusTraversalPolicy;
/**
+ * A {@link FocusTraversalPolicy} that provides the additional capability
+ * to determine a {@link JInternalFrame}'s initially focused component
+ * when it is selected.
+ *
* @author Michael Koch
*
* @since 1.4
*/
-public abstract class InternalFrameFocusTraversalPolicy extends FocusTraversalPolicy
+public abstract class InternalFrameFocusTraversalPolicy
+ extends FocusTraversalPolicy
{
public Component getInitialComponent(JInternalFrame frame)
{
diff --git a/libjava/classpath/javax/swing/JApplet.java b/libjava/classpath/javax/swing/JApplet.java
index 95a05c0..cafb2da 100644
--- a/libjava/classpath/javax/swing/JApplet.java
+++ b/libjava/classpath/javax/swing/JApplet.java
@@ -49,6 +49,11 @@ import java.awt.event.KeyEvent;
import javax.accessibility.AccessibleContext;
+/**
+ * A top-level container that is usually used in web browsers.
+ *
+ * @author original author unknown
+ */
public class JApplet extends Applet
implements RootPaneContainer
{
diff --git a/libjava/classpath/javax/swing/JButton.java b/libjava/classpath/javax/swing/JButton.java
index 0234e47..5653fbf 100644
--- a/libjava/classpath/javax/swing/JButton.java
+++ b/libjava/classpath/javax/swing/JButton.java
@@ -39,21 +39,45 @@ package javax.swing;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
import javax.swing.plaf.ButtonUI;
/**
- * An instance of JButton can be added to a panel, frame etc
+ * A general purpose push button. JButton
s can display a label,
+ * an {@link Icon} or both.
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
public class JButton extends AbstractButton
implements Accessible
{
+
+ /**
+ * Accessibility support for JButtons.
+ */
+ protected class AccessibleJButton
+ extends AbstractButton.AccessibleAbstractButton
+ {
+ /**
+ * Returns the accessible role that this component represents.
+ * This is {@link AccessibleRole#PUSH_BUTTON} for JButton
s.
+ *
+ * @return the accessible role that this component represents
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PUSH_BUTTON;
+ }
+ }
+
private static final long serialVersionUID = -1907255238954382202L;
boolean def;
boolean is_def;
+ /** The AccessibleContext for this JButton. */
+ AccessibleJButton accessibleContext;
+
public JButton()
{
this(null, null);
@@ -96,8 +120,9 @@ public class JButton extends AbstractButton
public AccessibleContext getAccessibleContext()
{
- // Gets the AccessibleContext associated with this JButton.
- return null;
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJButton();
+ return accessibleContext;
}
public String getUIClassID()
diff --git a/libjava/classpath/javax/swing/JCheckBox.java b/libjava/classpath/javax/swing/JCheckBox.java
index 5e7e80c..a743308 100644
--- a/libjava/classpath/javax/swing/JCheckBox.java
+++ b/libjava/classpath/javax/swing/JCheckBox.java
@@ -41,7 +41,16 @@ package javax.swing;
import javax.accessibility.AccessibleContext;
/**
- * An instance of JCheckbox can be added to a panel, frame etc
+ * A small box that displays a check or not, depending on it's
+ * selected
state. This works very similar to
+ * {@link JToggleButton} and {@link JRadioButton}, but in UI design it
+ * has different semantics. JCheckBox
es are usually
+ * used in multiple-choice scenarios, where a user can select 0..n
+ * of n different options. (This is in contrast to the general RadioButton
+ * semantics where the user can select exactly one of n options).
+ *
+ * Note however that this semantics is in no way enforced by the
+ * JCheckBox
.
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
diff --git a/libjava/classpath/javax/swing/JCheckBoxMenuItem.java b/libjava/classpath/javax/swing/JCheckBoxMenuItem.java
index 46a42ad..f9dd565 100644
--- a/libjava/classpath/javax/swing/JCheckBoxMenuItem.java
+++ b/libjava/classpath/javax/swing/JCheckBoxMenuItem.java
@@ -46,11 +46,14 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
/**
- * This class represents JCheckBoxMenuItem. Its behaviour is very similar
- * to JCheckBoxButton. Just like the JCheckBoxButton, user can check and
- * uncheck this menu item by clicking on it. Also setSelected()/setState()
- * can be use used for the same purpose. JCheckBoxMenuItem uses
- * ToggleButtonModel to keep track of its selection.
+ * A menu item that displays a checkbox. Its behaviour is very similar
+ * to {@link JCheckBox}. Just like the JCheckBox
, user can check
+ * and uncheck this menu item by clicking on it. Also {@link #setSelected()}
+ * and {@link #setState()} can be use used for the same purpose.
+ * JCheckBoxMenuItem
uses
+ * ToggleButtonModel
to keep track of its selection.
+ *
+ * @author original author unknown
*/
public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
Accessible
@@ -146,6 +149,7 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
super(text, icon);
setModel(new JToggleButton.ToggleButtonModel());
this.state = state;
+ this.setVisible(true);
}
private void writeObject(ObjectOutputStream stream) throws IOException
@@ -232,6 +236,9 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
return accessibleContext;
}
+ /**
+ * Accessibility support for JCheckBoxMenuItem
.
+ */
protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem
{
private static final long serialVersionUID = 1079958073579370777L;
diff --git a/libjava/classpath/javax/swing/JColorChooser.java b/libjava/classpath/javax/swing/JColorChooser.java
index e16b981..4016b82 100644
--- a/libjava/classpath/javax/swing/JColorChooser.java
+++ b/libjava/classpath/javax/swing/JColorChooser.java
@@ -58,13 +58,15 @@ import javax.swing.plaf.ColorChooserUI;
/**
- * The JColorChooser is a Swing widget that offers users different ways to
+ * A Swing widget that offers users different ways to
* select a color. By default, three different panels are presented to the
* user that are capable of changing the selected color. There are three ways
* to utilize JColorChooser. The first is to build a JColorChooser and add it
* to the content pane. The second is to use the createDialog method to
* create a JDialog that holds a JColorChooser. The third is to show a
* JColorChooser in a JDialog directly using the showDialog method.
+ *
+ * @author original author unknown
*/
public class JColorChooser extends JComponent implements Accessible
{
@@ -72,7 +74,7 @@ public class JColorChooser extends JComponent implements Accessible
private static final long serialVersionUID = 9168066781620640889L;
/**
- * AccessibleJColorChooser
+ * Accessibility support for JColorChooser
.
*/
protected class AccessibleJColorChooser
extends JComponent.AccessibleJComponent
diff --git a/libjava/classpath/javax/swing/JComboBox.java b/libjava/classpath/javax/swing/JComboBox.java
index 4284ec8..47d1832 100644
--- a/libjava/classpath/javax/swing/JComboBox.java
+++ b/libjava/classpath/javax/swing/JComboBox.java
@@ -61,10 +61,10 @@ import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.ComboBoxUI;
/**
- * JComboBox. JComboBox is a container, that keeps track of elements added to
- * it by the user. JComboBox allows user to select any item in its list and
- * displays the selected item to the user. JComboBox also can show/hide popup
- * menu containing its list of item whenever the mouse is pressed over it.
+ * A component that allows a user to select any item in its list and
+ * displays the selected item to the user. JComboBox also can show/hide a
+ * popup menu containing its list of item whenever the mouse is pressed
+ * over it.
*
* @author Andrew Selkirk
* @author Olga Rodimina
@@ -1138,7 +1138,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
}
/**
- * AccessibleJComboBox
+ * Accessibility support for JComboBox
.
*/
protected class AccessibleJComboBox extends AccessibleJComponent
implements AccessibleAction, AccessibleSelection
diff --git a/libjava/classpath/javax/swing/JComponent.java b/libjava/classpath/javax/swing/JComponent.java
index 42a5317..dc7689b 100644
--- a/libjava/classpath/javax/swing/JComponent.java
+++ b/libjava/classpath/javax/swing/JComponent.java
@@ -38,12 +38,14 @@ exception statement from your version. */
package javax.swing;
+import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
+import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
@@ -51,6 +53,7 @@ import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.Window;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -71,6 +74,7 @@ import java.io.Serializable;
import java.util.EventListener;
import java.util.Hashtable;
import java.util.Locale;
+import java.util.Set;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
@@ -86,7 +90,7 @@ import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.plaf.ComponentUI;
/**
- * Every component in swing inherits from this class (JLabel, JButton, etc).
+ * The base class of all Swing components.
* It contains generic methods to manage events, properties and sizes. Actual
* drawing of the component is channeled to a look-and-feel class that is
* implemented elsewhere.
@@ -103,10 +107,17 @@ public abstract class JComponent extends Container implements Serializable
*/
protected AccessibleContext accessibleContext;
+ /**
+ * Basic accessibility support for JComponent
derived
+ * widgets.
+ */
public abstract class AccessibleJComponent
extends AccessibleAWTContainer
implements AccessibleExtendedComponent
{
+ /**
+ * Accessibility support for JComponent
's focus handler.
+ */
protected class AccessibleFocusHandler
implements FocusListener
{
@@ -115,6 +126,9 @@ public abstract class JComponent extends Container implements Serializable
public void focusLost(FocusEvent valevent){}
}
+ /**
+ * Accessibility support for JComponent
's container handler.
+ */
protected class AccessibleContainerHandler
implements ContainerListener
{
@@ -273,7 +287,7 @@ public abstract class JComponent extends Container implements Serializable
* repainting of the component are usually delegated to this object.
*
* @see #setUI
- * @see #getUI
+ * @see #getUIClassID
* @see #updateUI
*/
protected ComponentUI ui;
@@ -361,7 +375,7 @@ public abstract class JComponent extends Container implements Serializable
* Constant used to indicate that no condition has been assigned to a
* particular action.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
*/
public static final int UNDEFINED_CONDITION = -1;
@@ -369,7 +383,7 @@ public abstract class JComponent extends Container implements Serializable
* Constant used to indicate that an action should be performed only when
* the component has focus.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
*/
public static final int WHEN_FOCUSED = 0;
@@ -377,7 +391,7 @@ public abstract class JComponent extends Container implements Serializable
* Constant used to indicate that an action should be performed only when
* the component is an ancestor of the component which has focus.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
*/
public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
@@ -385,7 +399,7 @@ public abstract class JComponent extends Container implements Serializable
* Constant used to indicate that an action should be performed only when
* the component is in the window which has focus.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
*/
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
@@ -449,7 +463,10 @@ public abstract class JComponent extends Container implements Serializable
*/
public final void putClientProperty(Object key, Object value)
{
- getClientProperties().put(key, value);
+ if (value != null)
+ getClientProperties().put(key, value);
+ else
+ getClientProperties().remove(key);
}
/**
@@ -457,7 +474,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param listener The listener to unregister
*
- * @see addAncestorListener
+ * @see #addAncestorListener
*/
public void removeAncestorListener(AncestorListener listener)
{
@@ -469,7 +486,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param listener The listener to register
*
- * @see #addPropertyChangeListener
+ * @see #addPropertyChangeListener(PropertyChangeListener)
* @see #changeSupport
*/
public void removePropertyChangeListener(PropertyChangeListener listener)
@@ -484,7 +501,7 @@ public abstract class JComponent extends Container implements Serializable
* @param propertyName The property name to unregister the listener from
* @param listener The listener to unregister
*
- * @see #addPropertyChangeListener
+ * @see #addPropertyChangeListener(String, PropertyChangeListener)
* @see #changeSupport
*/
public void removePropertyChangeListener(String propertyName,
@@ -526,7 +543,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param listener The listener to register
*
- * @see #removePropertyChangeListener
+ * @see #removePropertyChangeListener(PropertyChangeListener)
* @see #changeSupport
*/
public void addPropertyChangeListener(PropertyChangeListener listener)
@@ -544,7 +561,7 @@ public abstract class JComponent extends Container implements Serializable
* @param propertyName The property name to listen to
* @param listener The listener to register
*
- * @see #removePropertyChangeListener
+ * @see #removePropertyChangeListener(String, PropertyChangeListener)
* @see #changeSupport
*/
public void addPropertyChangeListener(String propertyName,
@@ -712,8 +729,8 @@ public abstract class JComponent extends Container implements Serializable
* @param newValue The new value of the property
*
* @see #changeSupport
- * @see #addPropertyChangeListener
- * @see #removePropertyChangeListener
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ * @see #removePropertyChangeListener(PropertyChangeListener)
*/
protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue)
@@ -745,8 +762,8 @@ public abstract class JComponent extends Container implements Serializable
*
* @throws PropertyVetoException if the change was vetoed by a listener
*
- * @see addVetoableChangeListener
- * @see removeVetoableChangeListener
+ * @see #addVetoableChangeListener
+ * @see #removeVetoableChangeListener
*/
protected void fireVetoableChange(String propertyName, Object oldValue,
Object newValue)
@@ -945,7 +962,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Get the component's maximum size. If the {@link #maximumSize} property
* has been explicitly set, it is returned. If the {@link #maximumSize}
- * property has not been set but the {@link ui} property has been, the
+ * property has not been set but the {@link #ui} property has been, the
* result of {@link ComponentUI#getMaximumSize} is returned. If neither
* property has been set, the result of {@link Container#getMaximumSize}
* is returned.
@@ -974,7 +991,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Get the component's minimum size. If the {@link #minimumSize} property
* has been explicitly set, it is returned. If the {@link #minimumSize}
- * property has not been set but the {@link ui} property has been, the
+ * property has not been set but the {@link #ui} property has been, the
* result of {@link ComponentUI#getMinimumSize} is returned. If neither
* property has been set, the result of {@link Container#getMinimumSize}
* is returned.
@@ -1003,7 +1020,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Get the component's preferred size. If the {@link #preferredSize}
* property has been explicitly set, it is returned. If the {@link
- * #preferredSize} property has not been set but the {@link ui} property
+ * #preferredSize} property has not been set but the {@link #ui} property
* has been, the result of {@link ComponentUI#getPreferredSize} is
* returned. If neither property has been set, the result of {@link
* Container#getPreferredSize} is returned.
@@ -1077,7 +1094,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Return the value of the {@link #nextFocusableComponent} property.
+ * Return the value of the nextFocusableComponent
property.
*
* @return The current value of the property, or null
* if none has been set.
@@ -1132,7 +1149,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Return the {@link #toolTip} property of this component, creating it and
+ * Return the toolTip
property of this component, creating it and
* setting it if it is currently null
. This method can be
* overridden in subclasses which wish to control the exact form of
* tooltip created.
@@ -1149,7 +1166,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Return the location at which the {@link #toolTip} property should be
+ * Return the location at which the {@link #toolTipText} property should be
* displayed, when triggered by a particular mouse event.
*
* @param event The event the tooltip is being presented in response to
@@ -1167,7 +1184,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param text The new property value
*
- * @see #getToolTipText
+ * @see #getToolTipText()
*/
public void setToolTipText(String text)
{
@@ -1218,7 +1235,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Return the top level ancestral container (usually a {@link
- * java.awt.Window} or {@link java.awt.Applet}) which this component is
+ * java.awt.Window} or {@link java.applet.Applet}) which this component is
* contained within, or null
if no ancestors exist.
*
* @return The top level container, if it exists
@@ -1275,9 +1292,9 @@ public abstract class JComponent extends Container implements Serializable
* displayable, focusable, visible components.
*
* This method should not be called by clients; it is intended for - * focus implementations. Use {@link Component#requestFocus} instead.
+ * focus implementations. Use {@link Component#requestFocus()} instead. * - * @see {@link Component#requestFocus} + * @see Component#requestFocus() */ public void grabFocus() { @@ -1317,8 +1334,8 @@ public abstract class JComponent extends Container implements Serializable * @returntrue
if you want this component to manage its own
* focus, otherwise (by default) false
*
- * @deprecated 1.4 Use {@link Component.setFocusTraversalKeys(int,Set)} and
- * {@link Container.setFocusCycleRoot(boolean)} instead
+ * @deprecated 1.4 Use {@link Component#setFocusTraversalKeys(int, Set)} and
+ * {@link Container#setFocusCycleRoot(boolean)} instead
*/
public boolean isManagingFocus()
{
@@ -1326,7 +1343,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Return the current value of the {@link opaque} property.
+ * Return the current value of the {@link #opaque} property.
*
* @return The current property value
*/
@@ -1370,10 +1387,10 @@ public abstract class JComponent extends Container implements Serializable
/**
* Return true
if this component is a validation root; this
- * will cause calls to {@link #invalidate} in this component's children
+ * will cause calls to {@link #invalidate()} in this component's children
* to be "captured" at this component, and not propagate to its parents.
* For most components this should return false
, but some
- * components such as {@link JViewPort} will want to return
+ * components such as {@link JViewport} will want to return
* true
.
*
* @return Whether this component is a validation root
@@ -1386,7 +1403,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Paint the component. This is a delicate process, and should only be * called from the repaint thread, under control of the {@link - * RepaintManager}. Client code should usually call {@link #repaint} to + * RepaintManager}. Client code should usually call {@link #repaint()} to * trigger painting.
* *This method will acquire a double buffer from the {@link
@@ -1410,7 +1427,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param g The graphics context to paint with
*
- * @see #paintImmediately
+ * @see #paintImmediately(Rectangle)
*/
public void paint(Graphics g)
{
@@ -1633,18 +1650,18 @@ public abstract class JComponent extends Container implements Serializable
* to fetch mapping tables from keystrokes to commands, and commands to
* actions, respectively, and modify those mappings directly.
*
- * @param anAction The action to be registered
- * @param aCommand The command to deliver in the delivered {@link
- * java.awt.ActionEvent}
- * @param aKeyStroke The keystroke to register on
- * @param aCondition One of the values {@link #UNDEFINED_CONDITION},
+ * @param act The action to be registered
+ * @param cmd The command to deliver in the delivered {@link
+ * java.awt.event.ActionEvent}
+ * @param stroke The keystroke to register on
+ * @param cond One of the values {@link #UNDEFINED_CONDITION},
* {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
* {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
* be met for the action to be fired
*
* @see #unregisterKeyboardAction
- * @see #getConditionForKeystroke
- * @see #resetKeyboardActiond
+ * @see #getConditionForKeyStroke
+ * @see #resetKeyboardActions
*/
public void registerKeyboardAction(ActionListener act,
String cmd,
@@ -1724,7 +1741,7 @@ public abstract class JComponent extends Container implements Serializable
* Return the condition that determines whether a registered action
* occurs in response to the specified keystroke.
*
- * @param aKeyStroke The keystroke to return the condition of
+ * @param ks The keystroke to return the condition of
*
* @return One of the values {@link #UNDEFINED_CONDITION}, {@link
* #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
@@ -1733,9 +1750,9 @@ public abstract class JComponent extends Container implements Serializable
* @deprecated As of 1.3 KeyStrokes can be registered with multiple
* simultaneous conditions.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
* @see #unregisterKeyboardAction
- * @see #resetKeyboardActiond
+ * @see #resetKeyboardActions
*/
public int getConditionForKeyStroke(KeyStroke ks)
{
@@ -1756,7 +1773,7 @@ public abstract class JComponent extends Container implements Serializable
* Get the ActionListener (typically an {@link Action} object) which is
* associated with a particular keystroke.
*
- * @param aKeyStroke The keystroke to retrieve the action of
+ * @param ks The keystroke to retrieve the action of
*
* @return The action associated with the specified keystroke
*
@@ -1796,12 +1813,52 @@ public abstract class JComponent extends Container implements Serializable
super.processKeyEvent(e);
processComponentKeyEvent(e);
- // FIXME: this needs to be elaborated significantly, to do all the
- // focus / ancestor / window searching for the various binding modes.
- if (! e.isConsumed() &&
- processKeyBinding(KeyStroke.getKeyStrokeForEvent(e),
+ if (e.isConsumed())
+ return;
+
+ // Input maps are checked in this order:
+ // 1. The focused component's WHEN_FOCUSED map is checked.
+ // 2. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map.
+ // 3. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps of the focused
+ // component's parent, then its parent's parent, and so on.
+ // Note: Input maps for disabled components are skipped.
+ // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in
+ // the focused window are searched.
+
+ if (processKeyBinding(KeyStroke.getKeyStrokeForEvent(e),
e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
+ // This is step 1 from above comment.
e.consume();
+ else if (processKeyBinding(KeyStroke.getKeyStrokeForEvent(e),
+ e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+ e.getID() == KeyEvent.KEY_PRESSED))
+ // This is step 2 from above comment.
+ e.consume();
+ else
+ {
+ // This is step 3 from above comment.
+ Container current = this;
+ while ((current = current.getParent()) instanceof JComponent)
+ {
+ if (((JComponent)current).processKeyBinding
+ (KeyStroke.getKeyStrokeForEvent(e), e,
+ WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+ e.getID() == KeyEvent.KEY_PRESSED))
+ {
+ e.consume();
+ break;
+ }
+ if (current instanceof Window || current instanceof Applet
+ || current instanceof JInternalFrame)
+ break;
+ }
+ if (e.isConsumed())
+ return;
+
+ // This is step 4 from above comment.
+ // FIXME: Implement. Note, should use ComponentInputMaps rather
+ // than walking the entire containment hierarchy.
+ }
}
protected boolean processKeyBinding(KeyStroke ks,
@@ -1833,11 +1890,11 @@ public abstract class JComponent extends Container implements Serializable
/**
* Remove a keyboard action registry.
*
- * @param stroke The keystroke to unregister
+ * @param aKeyStroke The keystroke to unregister
*
- * @see #registerKeyboardAction
- * @see #getConditionForKeystroke
- * @see #resetKeyboardActiond
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
+ * @see #getConditionForKeyStroke
+ * @see #resetKeyboardActions
*/
public void unregisterKeyboardAction(KeyStroke aKeyStroke)
{
@@ -1848,9 +1905,9 @@ public abstract class JComponent extends Container implements Serializable
/**
* Reset all keyboard action registries.
*
- * @see #registerKeyboardAction
+ * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
* @see #unregisterKeyboardAction
- * @see #getConditionForKeystroke
+ * @see #getConditionForKeyStroke
*/
public void resetKeyboardActions()
{
@@ -1902,7 +1959,7 @@ public abstract class JComponent extends Container implements Serializable
* Request focus on the default component of this component's {@link
* FocusTraversalPolicy}.
*
- * @return The result of {@link #requestFocus}
+ * @return The result of {@link #requestFocus()}
*
* @deprecated Use {@link #requestFocus()} on the default component provided
* from the {@link FocusTraversalPolicy} instead.
@@ -1986,7 +2043,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #enabled} property.
+ * Set the value of the enabled
property.
*
* @param enable The new value of the property
*/
@@ -1998,7 +2055,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #font} property.
+ * Set the value of the font
property.
*
* @param f The new value of the property
*/
@@ -2008,7 +2065,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #background} property.
+ * Set the value of the background
property.
*
* @param bg The new value of the property
*/
@@ -2018,7 +2075,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #foreground} property.
+ * Set the value of the foreground
property.
*
* @param fg The new value of the property
*/
@@ -2091,7 +2148,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @return The current value of the property
*
- * @see ComponentUI#setTransferHandler
+ * @see #setTransferHandler
*/
public TransferHandler getTransferHandler()
@@ -2104,7 +2161,7 @@ public abstract class JComponent extends Container implements Serializable
*
* @param newHandler The new value of the property
*
- * @see ComponentUI#getTransferHandler
+ * @see #getTransferHandler
*/
public void setTransferHandler(TransferHandler newHandler)
@@ -2142,7 +2199,7 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Call {@link paint}.
+ * Call {@link #paint}.
*
* @param g The graphics context to paint into
*/
@@ -2155,7 +2212,7 @@ public abstract class JComponent extends Container implements Serializable
* Get the value of the UIClassID property. This property should be a key
* in the {@link UIDefaults} table managed by {@link UIManager}, the
* value of which is the name of a class to load for the component's
- * {@link ui} property.
+ * {@link #ui} property.
*
* @return A "symbolic" name which will map to a class to use for the
* component's UI, such as "ComponentUI"
@@ -2169,10 +2226,10 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Install a new UI delegate as the component's {@link ui} property. In
- * the process, this will call {@link ComponentUI.uninstallUI} on any
- * existing value for the {@link ui} property, and {@link
- * ComponentUI.installUI} on the new UI delegate.
+ * Install a new UI delegate as the component's {@link #ui} property. In
+ * the process, this will call {@link ComponentUI#uninstallUI} on any
+ * existing value for the {@link #ui} property, and {@link
+ * ComponentUI#installUI} on the new UI delegate.
*
* @param newUI The new UI delegate to install
*
@@ -2198,7 +2255,7 @@ public abstract class JComponent extends Container implements Serializable
* This method should be overridden in subclasses. In JComponent, the
* method does nothing. In subclasses, it should a UI delegate
* (corresponding to the symbolic name returned from {@link
- * getUIClassID}) from the {@link UIManager}, and calls {@link setUI}
+ * #getUIClassID}) from the {@link UIManager}, and calls {@link #setUI}
* with the new delegate.
*/
public void updateUI()
@@ -2273,9 +2330,9 @@ public abstract class JComponent extends Container implements Serializable
* situations in which it is not possible to get the focus. So developers
* should not assume that the component has the focus until it receives
* a {@link java.awt.event.FocusEvent} with a value of
- * {@link java.awt.event.FocusEvent.FOCUS_GAINED}.
+ * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
*
- * @see {@link Component#requestFocus()}
+ * @see Component#requestFocus()
*/
public void requestFocus()
{
@@ -2288,15 +2345,15 @@ public abstract class JComponent extends Container implements Serializable
* by look and feel implementations.
*
* You should not use this method directly. Instead you are strongly
- * encouraged to call {@link #requestFocus} or {@link #requestFocusInWindow}
- * instead.
+ * encouraged to call {@link #requestFocus()} or
+ * {@link #requestFocusInWindow()} instead.
*
* @param temporary if the focus change is temporary
*
* @return false
if the focus change request will definitly
* fail, true
if it will likely succeed
*
- * @see {@link Component#requestFocus(boolean)}
+ * @see Component#requestFocus(boolean)
*
* @since 1.4
*/
@@ -2317,12 +2374,12 @@ public abstract class JComponent extends Container implements Serializable
* situations in which it is not possible to get the focus. So developers
* should not assume that the component has the focus until it receives
* a {@link java.awt.event.FocusEvent} with a value of
- * {@link java.awt.event.FocusEvent.FOCUS_GAINED}.
+ * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
*
* @return false
if the focus change request will definitly
* fail, true
if it will likely succeed
*
- * @see {@link Component#requestFocusInWindow()}
+ * @see Component#requestFocusInWindow()
*/
public boolean requestFocusInWindow()
{
@@ -2337,15 +2394,15 @@ public abstract class JComponent extends Container implements Serializable
* by look and feel implementations.
*
* You should not use this method directly. Instead you are strongly
- * encouraged to call {@link #requestFocus} or {@link #requestFocusInWindow}
- * instead.
+ * encouraged to call {@link #requestFocus()} or
+ * {@link #requestFocusInWindow()} instead.
*
* @param temporary if the focus change is temporary
*
* @return false
if the focus change request will definitly
* fail, true
if it will likely succeed
*
- * @see {@link Component#requestFocus(boolean)}
+ * @see Component#requestFocus(boolean)
*
* @since 1.4
*/
@@ -2426,7 +2483,8 @@ public abstract class JComponent extends Container implements Serializable
* has changed.
*
* This method is called before the component is actually removed from
- * its parent, so the parent is still visible through {@link #getParent}.
+ * its parent, so the parent is still visible through
+ * {@link Component#getParent}.
*/
public void removeNotify()
{
@@ -2585,7 +2643,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* Prints this component to the given Graphics context. A call to this
* method results in calls to the methods {@link #printComponent},
- * {@link #printBorder} and {@link printChildren} in this order.
+ * {@link #printBorder} and {@link #printChildren} in this order.
*
* Double buffering is temporarily turned off so the painting goes directly
* to the supplied Graphics context.
diff --git a/libjava/classpath/javax/swing/JDesktopPane.java b/libjava/classpath/javax/swing/JDesktopPane.java
index ff51211..f4c80ec 100644
--- a/libjava/classpath/javax/swing/JDesktopPane.java
+++ b/libjava/classpath/javax/swing/JDesktopPane.java
@@ -48,7 +48,7 @@ import javax.swing.plaf.DesktopPaneUI;
/**
* JDesktopPane is a container (usually for JInternalFrames) that simulates a
- * desktop. Typically, the user will create JInternalFrames and place thme in
+ * desktop. Typically, the user will create JInternalFrames and place them in
* a JDesktopPane. The user can then interact with JInternalFrames like they
* usually would with JFrames. The actions (minimize, maximize, close, etc)
* are done by using a DesktopManager that is associated with the
diff --git a/libjava/classpath/javax/swing/JDialog.java b/libjava/classpath/javax/swing/JDialog.java
index 83865f8..0f528ab 100644
--- a/libjava/classpath/javax/swing/JDialog.java
+++ b/libjava/classpath/javax/swing/JDialog.java
@@ -53,10 +53,15 @@ import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
/**
- * Unlike JComponent derivatives, JDialog inherits from java.awt.Dialog. But
- * also lets a look-and-feel component to its work.
+ * A dialog window. This is an extension of {@link java.awt.Dialog} that
+ * provides support for the Swing architecture. Most importantly it contains a
+ * {@link JRootPane} as it's only top-level child, that manages the content
+ * pane, the menu and a glass pane.
*
- * @author Ronald Veldema (rveldema_AT_cs.vu.nl)
+ * Also, unlike java.awt.Dialog
s, JDialogs support the
+ * Swing Pluggable Look & Feel architecture.
+ *
+ * @author Ronald Veldema (rveldema@cs.vu.nl)
*/
public class JDialog extends Dialog implements Accessible, WindowConstants,
RootPaneContainer
diff --git a/libjava/classpath/javax/swing/JEditorPane.java b/libjava/classpath/javax/swing/JEditorPane.java
index 63c79ff..e2f1319 100644
--- a/libjava/classpath/javax/swing/JEditorPane.java
+++ b/libjava/classpath/javax/swing/JEditorPane.java
@@ -39,7 +39,6 @@ exception statement from your version. */
package javax.swing;
import java.awt.Dimension;
-import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -52,7 +51,29 @@ import javax.swing.text.DefaultEditorKit;
import javax.swing.text.EditorKit;
import javax.swing.text.JTextComponent;
-
+/**
+ * A powerful text editor component that can handle different types of
+ * content.
+ *
+ * The JEditorPane text component is driven by an instance of
+ * {@link EditorKit}. The editor kit is responsible for providing
+ * a default {@link Document} implementation, a mechanism for loading
+ * and saving documents of its supported content type and providing
+ * a set of {@link Action}s for manipulating the content.
+ *
+ * By default the following content types are supported:
+ *
text/plain
: Plain text, handled by
+ * {@link javax.swing.text.DefaultEditorKit}.text/html
: HTML 4.0 styled text, handled by
+ * {@link javax.swing.text.html.HTMLEditorKit}.text/rtf
: RTF text, handled by
+ * {@link javax.swing.text.rtf.RTFEditorKit}.java.awt.Frame
s, JFrames support the
+ * Swing Pluggable Look & Feel architecture.
+ *
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
public class JFrame extends Frame
@@ -98,7 +104,7 @@ public class JFrame extends Frame
* @param gc the GraphicsConfiguration
that is used for
* the new JFrame
*
- * @see Frame(GraphicsConfiguration)
+ * @see Frame#Frame(GraphicsConfiguration)
*/
public JFrame(GraphicsConfiguration gc)
{
@@ -114,7 +120,7 @@ public class JFrame extends Frame
* @param gc the GraphicsConfiguration
that is used for
* the new JFrame
*
- * @see Frame(String, GraphicsConfiguration)
+ * @see Frame#Frame(String, GraphicsConfiguration)
*/
public JFrame(String title, GraphicsConfiguration gc)
{
diff --git a/libjava/classpath/javax/swing/JLabel.java b/libjava/classpath/javax/swing/JLabel.java
index 088f7d6..2e7ad98 100644
--- a/libjava/classpath/javax/swing/JLabel.java
+++ b/libjava/classpath/javax/swing/JLabel.java
@@ -41,17 +41,257 @@ package javax.swing;
import java.awt.Component;
import java.awt.Font;
import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleExtendedComponent;
+import javax.accessibility.AccessibleText;
import javax.swing.plaf.LabelUI;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
/**
* A swing widget that displays a text message and/or an icon.
*/
public class JLabel extends JComponent implements Accessible, SwingConstants
{
+
+ /**
+ * Accessibility support for JLabel.
+ */
+ protected class AccessibleJLabel
+ extends JComponent.AccessibleJComponent
+ implements AccessibleText, AccessibleExtendedComponent
+ {
+ /**
+ * Returns the selected text. This is an empty string since JLabels
+ * are not selectable.
+ *
+ * @return the selected text
+ */
+ public String getSelectedText()
+ {
+ // We return "" here since JLabel's text is not selectable.
+ return "";
+ }
+
+ /**
+ * Returns the start index of the selected text.
+ *
+ * @return the start index of the selected text
+ */
+ public int getSelectionStart()
+ {
+ // TODO: Figure out what should be returned here, because JLabels don't
+ // allow selection. I guess -1 for now.
+ return -1;
+ }
+
+ /**
+ * Returns the end index of the selected text.
+ *
+ * @return the end index of the selected text
+ */
+ public int getSelectionEnd()
+ {
+ // TODO: Figure out what should be returned here, because JLabels don't
+ // allow selection. I guess -1 for now.
+ return -1;
+ }
+
+ /**
+ * Returns an {@link AttributeSet} that reflects the text attributes of
+ * the specified character. We return an empty
+ * AttributeSet
here, because JLabels don't support text
+ * attributes (at least not yet).
+ *
+ * @param index the index of the character
+ *
+ * @return an {@link AttributeSet} that reflects the text attributes of
+ * the specified character
+ */
+ public AttributeSet getCharacterAttribute(int index)
+ {
+ return new SimpleAttributeSet();
+ }
+
+ /**
+ * Returns the character, word or sentence at the specified index. The
+ * part
parameter determines what is returned, the character,
+ * word or sentence after the index.
+ *
+ * @param part one of {@link AccessibleText#CHARACTER},
+ * {@link AccessibleText#WORD} or
+ * {@link AccessibleText#SENTENCE}, specifying what is returned
+ * @param index the index
+ *
+ * @return the character, word or sentence after index
+ */
+ public String getAtIndex(int part, int index)
+ {
+ String result = "";
+ int startIndex = -1;
+ int endIndex = -1;
+ switch(part)
+ {
+ case AccessibleText.CHARACTER:
+ result = String.valueOf(text.charAt(index));
+ break;
+ case AccessibleText.WORD:
+ startIndex = text.lastIndexOf(' ', index);
+ endIndex = text.indexOf(' ', startIndex + 1);
+ if (endIndex == -1)
+ endIndex = startIndex + 1;
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ case AccessibleText.SENTENCE:
+ default:
+ startIndex = text.lastIndexOf('.', index);
+ endIndex = text.indexOf('.', startIndex + 1);
+ if (endIndex == -1)
+ endIndex = startIndex + 1;
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the character, word or sentence after the specified index. The
+ * part
parameter determines what is returned, the character,
+ * word or sentence after the index.
+ *
+ * @param part one of {@link AccessibleText#CHARACTER},
+ * {@link AccessibleText#WORD} or
+ * {@link AccessibleText#SENTENCE}, specifying what is returned
+ * @param index the index
+ *
+ * @return the character, word or sentence after index
+ */
+ public String getAfterIndex(int part, int index)
+ {
+ String result = "";
+ int startIndex = -1;
+ int endIndex = -1;
+ switch(part)
+ {
+ case AccessibleText.CHARACTER:
+ result = String.valueOf(text.charAt(index + 1));
+ break;
+ case AccessibleText.WORD:
+ startIndex = text.indexOf(' ', index);
+ endIndex = text.indexOf(' ', startIndex + 1);
+ if (endIndex == -1)
+ endIndex = startIndex + 1;
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ case AccessibleText.SENTENCE:
+ default:
+ startIndex = text.indexOf('.', index);
+ endIndex = text.indexOf('.', startIndex + 1);
+ if (endIndex == -1)
+ endIndex = startIndex + 1;
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the character, word or sentence before the specified index. The
+ * part
parameter determines what is returned, the character,
+ * word or sentence before the index.
+ *
+ * @param part one of {@link AccessibleText#CHARACTER},
+ * {@link AccessibleText#WORD} or
+ * {@link AccessibleText#SENTENCE}, specifying what is returned
+ * @param index the index
+ *
+ * @return the character, word or sentence before index
+ */
+ public String getBeforeIndex(int part, int index)
+ {
+ String result = "";
+ int startIndex = -1;
+ int endIndex = -1;
+ switch(part)
+ {
+ case AccessibleText.CHARACTER:
+ result = String.valueOf(text.charAt(index - 1));
+ break;
+ case AccessibleText.WORD:
+ endIndex = text.lastIndexOf(' ', index);
+ if (endIndex == -1)
+ endIndex = 0;
+ startIndex = text.lastIndexOf(' ', endIndex - 1);
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ case AccessibleText.SENTENCE:
+ default:
+ endIndex = text.lastIndexOf('.', index);
+ if (endIndex == -1)
+ endIndex = 0;
+ startIndex = text.lastIndexOf('.', endIndex - 1);
+ result = text.substring(startIndex + 1, endIndex);
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the caret position. This method returns -1 because JLabel don't
+ * have a caret.
+ *
+ * @return the caret position
+ */
+ public int getCaretPosition()
+ {
+ return -1;
+ }
+
+ /**
+ * Returns the number of characters that are displayed by the JLabel.
+ *
+ * @return the number of characters that are displayed by the JLabel
+ */
+ public int getCharCount()
+ {
+ return text.length();
+ }
+
+ /**
+ * Returns the bounding box of the character at the specified index.
+ *
+ * @param index the index of the character that we return the
+ * bounds for
+ *
+ * @return the bounding box of the character at the specified index
+ */
+ public Rectangle getCharacterBounds(int index)
+ {
+ // FIXME: Implement this correctly.
+ return new Rectangle();
+ }
+
+ /**
+ * Returns the index of the character that is located at the specified
+ * point.
+ *
+ * @param point the location that we lookup the character for
+ *
+ * @return the index of the character that is located at the specified
+ * point
+ */
+ public int getIndexAtPoint(Point point)
+ {
+ // FIXME: Implement this correctly.
+ return 0;
+ }
+ }
+
/** DOCUMENT ME! */
private static final long serialVersionUID = 5496508283662221534L;
@@ -62,7 +302,7 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
protected Component labelFor;
/** The label's text. */
- private transient String text;
+ transient String text;
/** Where the label will be positioned horizontally. */
private transient int horizontalAlignment = LEADING;
@@ -91,6 +331,9 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
/** The gap between the icon and the text. */
private transient int iconTextGap = 4;
+ /** The accessible context for this JLabel. */
+ private AccessibleJLabel accessibleContext;
+
/**
* Creates a new vertically centered, horizontally on the leading edge
* JLabel object with text and no icon.
@@ -638,10 +881,12 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
/**
* DOCUMENT ME!
*
- * @return
+ * @return The accessible context.
*/
public AccessibleContext getAccessibleContext()
{
- return null;
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJLabel();
+ return accessibleContext;
}
}
diff --git a/libjava/classpath/javax/swing/JLayeredPane.java b/libjava/classpath/javax/swing/JLayeredPane.java
index c9a4fd4..1ea39dc 100644
--- a/libjava/classpath/javax/swing/JLayeredPane.java
+++ b/libjava/classpath/javax/swing/JLayeredPane.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
+import java.awt.Container;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
@@ -47,21 +48,43 @@ import java.util.TreeMap;
import javax.accessibility.Accessible;
/**
- * The "Layered Pane" is a container which divides its children into 6 (or - * more) disjoint sets. the pre-defined sets are:
+ * A container that adds depth to the usualContainer
semantics.
+ * Each child component of a Layered Pane
is placed within one
+ * of several layers. JLayeredPane
defines a set of standard
+ * layers. The pre-defined sets are (in the order from button to top):
*
- * A child is in exactly one of these layers at any time, though there may * be other layers if someone creates them.
* + *You can add a component to a specific layer using the
+ * {@link Container#add(Component, Object)} method. I.e.
+ * layeredPane.add(comp, JLayeredPane.MODAL_LAYER)
will add the
+ * component comp
to the modal layer of layeredPane
.
+ *
To change the layer of a component that is already a child of
+ * a JLayeredPane
, use the {@link #setLayer(Component, int)}
+ * method.
The purpose of this class is to translate this view of "layers" into a * contiguous array of components: the one held in our ancestor, * {@link java.awt.Container}.
@@ -283,7 +306,7 @@ public class JLayeredPane extends JComponent implements Accessible * @param c the component to move to the front of its layer. * @throws IllegalArgumentException if the component is not a child of * this container. - * @see #moveToBack() + * @see #moveToBack */ public void moveToFront(Component c) { @@ -302,7 +325,7 @@ public class JLayeredPane extends JComponent implements Accessible * @param c the component to move to the back of its layer. * @throws IllegalArgumentException if the component is not a child of * this container. - * @see #moveToFront() + * @see #moveToFront */ public void moveToBack(Component c) { @@ -317,7 +340,7 @@ public class JLayeredPane extends JComponent implements Accessible * @param c the component to get the position of. * @throws IllegalArgumentException if the component is not a child of * this container. - * @see #setPosition() + * @see #setPosition */ public int getPosition(Component c) { @@ -344,7 +367,7 @@ public class JLayeredPane extends JComponent implements Accessible * @param position the position to assign the component to. * @throws IllegalArgumentException if the component is not a child of * this container. - * @see #getPosition() + * @see #getPosition */ public void setPosition(Component c, int position) { diff --git a/libjava/classpath/javax/swing/JList.java b/libjava/classpath/javax/swing/JList.java index fb8d18b..92fe1cc 100644 --- a/libjava/classpath/javax/swing/JList.java +++ b/libjava/classpath/javax/swing/JList.java @@ -574,7 +574,7 @@ public class JList extends JComponent implements Accessible, Scrollable ComponentOrientation or = getComponentOrientation(); Rectangle r = getVisibleRect(); if (or == ComponentOrientation.RIGHT_TO_LEFT) - r.translate((int) r.getWidth(), 0); + r.translate((int) r.getWidth() - 1, 0); return getUI().locationToIndex(this, r.getLocation()); } @@ -596,8 +596,7 @@ public class JList extends JComponent implements Accessible, Scrollable * @return location of the cell located at the specified index in the list. */ public Point indexToLocation(int index){ - //FIXME: Need to implement. - return null; + return getCellBounds(index, index).getLocation(); } /** @@ -605,17 +604,20 @@ public class JList extends JComponent implements Accessible, Scrollable * {@link #visibleRect} property, depending on the {@link * #componentOrientation} property. * - * @return The index of the first visible list cell, or-1
+ * @return The index of the last visible list cell, or -1
* if none is visible.
*/
public int getLastVisibleIndex()
{
ComponentOrientation or = getComponentOrientation();
Rectangle r = getVisibleRect();
- r.translate(0, (int) r.getHeight());
+ r.translate(0, (int) r.getHeight() - 1);
if (or == ComponentOrientation.LEFT_TO_RIGHT)
- r.translate((int) r.getWidth(), 0);
- return getUI().locationToIndex(this, r.getLocation());
+ r.translate((int) r.getWidth() - 1, 0);
+ if (getUI().locationToIndex(this, r.getLocation()) == -1
+ && indexToLocation(getModel().getSize() - 1).y < r.y)
+ return getModel().getSize() - 1;
+ return getUI().locationToIndex(this, r.getLocation());
}
/**
@@ -1030,20 +1032,41 @@ public class JList extends JComponent implements Accessible, Scrollable
*/
public Dimension getPreferredScrollableViewportSize()
{
+ //If the layout orientation is not VERTICAL, then this will
+ //return the value from getPreferredSize. The current ListUI is
+ //expected to override getPreferredSize to return an appropriate value.
+ if (getLayoutOrientation() != VERTICAL)
+ return getPreferredSize();
+
+ if (fixedCellHeight != -1 && fixedCellWidth != -1)
+ return new Dimension(fixedCellWidth, getModel().getSize() *
+ fixedCellHeight);
- Dimension retVal = getPreferredSize();
- if (getLayoutOrientation() == VERTICAL)
+ int prefWidth, prefHeight;
+ if (fixedCellWidth != -1)
+ prefWidth = fixedCellWidth;
+ else
{
- if (fixedCellHeight != -1)
- {
- if (fixedCellWidth != -1)
- {
- int size = getModel().getSize();
- retVal = new Dimension(fixedCellWidth, size * fixedCellHeight);
- } // TODO: add else clause (preferredSize is ok for now)
- } // TODO: add else clause (preferredSize is ok for now)
+ prefWidth = 0;
+ int size = getModel().getSize();
+ for (int i = 0; i < size; i++)
+ if (getCellBounds(i, i).width > prefWidth)
+ prefWidth = getCellBounds(i, i).width;
}
- return retVal;
+
+ if (getModel().getSize() == 0 && fixedCellWidth == -1)
+ return new Dimension(256, 16 * getVisibleRowCount());
+ else if (getModel().getSize() == 0)
+ return new Dimension (fixedCellWidth, 16 * getVisibleRowCount());
+
+ if (fixedCellHeight != -1)
+ prefHeight = fixedCellHeight;
+ else
+ {
+ prefHeight = getVisibleRowCount() * getCellBounds
+ (getFirstVisibleIndex(), getFirstVisibleIndex()).height;
+ }
+ return new Dimension (prefWidth, prefHeight);
}
/**
diff --git a/libjava/classpath/javax/swing/JMenuBar.java b/libjava/classpath/javax/swing/JMenuBar.java
index a464fff..eebb1a0 100644
--- a/libjava/classpath/javax/swing/JMenuBar.java
+++ b/libjava/classpath/javax/swing/JMenuBar.java
@@ -326,7 +326,7 @@ public class JMenuBar extends JComponent implements Accessible, MenuElement
* Process key events forwarded from MenuSelectionManager. This method
* doesn't do anything. It is here to conform to the MenuElement interface.
*
- * @param event event forwarded from MenuSelectionManager
+ * @param e event forwarded from MenuSelectionManager
* @param path path to the menu element from which event was generated
* @param manager MenuSelectionManager for the current menu hierarchy
*
diff --git a/libjava/classpath/javax/swing/JOptionPane.java b/libjava/classpath/javax/swing/JOptionPane.java
index 88fa993..ad0772a 100644
--- a/libjava/classpath/javax/swing/JOptionPane.java
+++ b/libjava/classpath/javax/swing/JOptionPane.java
@@ -384,8 +384,8 @@ public class JOptionPane extends JComponent implements Accessible
}
/**
- * This method creates a new JInternalFrame that is in the JDesktopPane
- * which contains the parentComponent given. If no suitable JDesktopPane
+ * This method creates a new JInternalFrame that is in the JLayeredPane
+ * which contains the parentComponent given. If no suitable JLayeredPane
* can be found from the parentComponent given, a RuntimeException will be
* thrown.
*
@@ -395,25 +395,42 @@ public class JOptionPane extends JComponent implements Accessible
* @return A new JInternalFrame based on the JOptionPane configuration.
*
* @throws RuntimeException If no suitable JDesktopPane is found.
+ *
+ * @specnote The specification says that the internal frame is placed
+ * in the nearest JDesktopPane
that is found in
+ * parent
's ancestors. The behaviour of the JDK
+ * is that it actually looks up the nearest
+ * JLayeredPane
in parent
's ancestors.
+ * So do we.
*/
public JInternalFrame createInternalFrame(Component parentComponent,
String title)
throws RuntimeException
{
- JDesktopPane toUse = getDesktopPaneForComponent(parentComponent);
+ // Try to find a JDesktopPane.
+ JLayeredPane toUse = getDesktopPaneForComponent(parentComponent);
+ // If we don't have a JDesktopPane, we try to find a JLayeredPane.
+ if (toUse == null)
+ toUse = JLayeredPane.getLayeredPaneAbove(parentComponent);
+ // If this still fails, we throw a RuntimeException.
if (toUse == null)
- throw new RuntimeException("parentComponent does not have a valid parent");
+ throw new RuntimeException
+ ("parentComponent does not have a valid parent");
JInternalFrame frame = new JInternalFrame(title);
inputValue = UNINITIALIZED_VALUE;
value = UNINITIALIZED_VALUE;
+ frame.setContentPane(this);
frame.setClosable(true);
+
toUse.add(frame);
+ frame.setLayer(JLayeredPane.MODAL_LAYER);
+
+ frame.pack();
+ frame.setVisible(true);
- // FIXME: JLayeredPane broken? See bug # 16576
- // frame.setLayer(JLayeredPane.MODAL_LAYER);
return frame;
}
@@ -1102,7 +1119,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message);
JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
- startModal(frame, pane);
+ startModal(frame);
return ((Integer) pane.getValue()).intValue();
}
@@ -1127,7 +1144,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return ((Integer) pane.getValue()).intValue();
}
@@ -1153,7 +1170,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message, messageType, optionType);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return ((Integer) pane.getValue()).intValue();
}
@@ -1181,7 +1198,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return ((Integer) pane.getValue()).intValue();
}
@@ -1204,7 +1221,7 @@ public class JOptionPane extends JComponent implements Accessible
pane.setWantsInput(true);
JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
- startModal(frame, pane);
+ startModal(frame);
return (String) pane.getInputValue();
}
@@ -1230,7 +1247,7 @@ public class JOptionPane extends JComponent implements Accessible
pane.setWantsInput(true);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return (String) pane.getInputValue();
}
@@ -1265,7 +1282,7 @@ public class JOptionPane extends JComponent implements Accessible
pane.setInitialSelectionValue(initialSelectionValue);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return (String) pane.getInputValue();
}
@@ -1284,7 +1301,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message);
JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
- startModal(frame, pane);
+ startModal(frame);
}
/**
@@ -1304,7 +1321,7 @@ public class JOptionPane extends JComponent implements Accessible
JOptionPane pane = new JOptionPane(message, messageType);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
}
/**
@@ -1326,7 +1343,7 @@ public class JOptionPane extends JComponent implements Accessible
pane.setIcon(icon);
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
}
/**
@@ -1358,7 +1375,7 @@ public class JOptionPane extends JComponent implements Accessible
JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
- startModal(frame, pane);
+ startModal(frame);
return ((Integer) pane.getValue()).intValue();
}
@@ -1509,15 +1526,8 @@ public class JOptionPane extends JComponent implements Accessible
* @param f The JInternalFrame to make modal.
* @param pane The JOptionPane to add to the JInternalFrame.
*/
- private static void startModal(JInternalFrame f, JOptionPane pane)
+ private static void startModal(JInternalFrame f)
{
- f.getContentPane().add(pane);
- f.pack();
- f.show();
-
- Dimension pref = f.getPreferredSize();
- f.setBounds(0, 0, pref.width, pref.height);
-
synchronized (f)
{
final JInternalFrame tmp = f;
diff --git a/libjava/classpath/javax/swing/JPasswordField.java b/libjava/classpath/javax/swing/JPasswordField.java
index f9df102..151d248 100644
--- a/libjava/classpath/javax/swing/JPasswordField.java
+++ b/libjava/classpath/javax/swing/JPasswordField.java
@@ -50,6 +50,7 @@ import javax.swing.text.Document;
* class JPasswordField
*
* @author Andrew Selkirk
+ * @author Lillian Angel
* @version 1.0
*/
public class JPasswordField extends JTextField
@@ -178,14 +179,15 @@ public class JPasswordField extends JTextField
}
/**
- * echoCharIsSet
+ * Returns true if this JPasswordField has a character set for echoing.
+ * A character is considered to be set if the echo character is not 0.
*
* @return true
if the echo char is set,
* false
otherwise.
*/
public boolean echoCharIsSet()
{
- return echoChar == 0;
+ return echoChar != 0;
}
/**
@@ -207,7 +209,8 @@ public class JPasswordField extends JTextField
}
/**
- * getText
+ * Returns the text contained in this TextComponent. If the
+ * underlying document is null, will give a NullPointerException.
*
* @return String
*
@@ -215,11 +218,21 @@ public class JPasswordField extends JTextField
*/
public String getText()
{
- return null; // TODO
+ try
+ {
+ return getDocument().getText(0, getDocument().getLength());
+ }
+ catch (BadLocationException ble)
+ {
+ // This should never happen.
+ throw new AssertionError(ble);
+ }
}
/**
- * getText
+ * Fetches a portion of the text represented by the component.
+ * Returns an empty string if length is 0. If the
+ * underlying document is null, will give a NullPointerException.
*
* @param offset TODO
* @param length TODO
@@ -232,27 +245,40 @@ public class JPasswordField extends JTextField
*/
public String getText(int offset, int length) throws BadLocationException
{
- return null; // TODO
+ return getDocument().getText(offset, length);
}
/**
- * getPassword
+ * Returns the text contained in this TextComponent. If the underlying
+ * document is null, will give a NullPointerException.
+ * For stronger security, it is recommended that the returned character
+ * array be cleared after use by setting each character to zero.
*
* @return char[]
*/
public char[] getPassword()
{
- return new char[0]; // TODO
+ return getText().toCharArray();
}
/**
- * paramString
+ * Returns a string representation of this JPasswordField. 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 null.
*
* @return String
*/
protected String paramString()
{
- return null; // TODO
+ try
+ {
+ return getText();
+ }
+ catch (NullPointerException npe)
+ {
+ return "";
+ }
}
/**
diff --git a/libjava/classpath/javax/swing/JPopupMenu.java b/libjava/classpath/javax/swing/JPopupMenu.java
index a0a7359..c4ee5fe 100644
--- a/libjava/classpath/javax/swing/JPopupMenu.java
+++ b/libjava/classpath/javax/swing/JPopupMenu.java
@@ -232,6 +232,7 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
constraints.gridy = i;
super.add(items[i], constraints, i);
}
+ this.setSize(this.getPreferredSize());
}
/**
@@ -276,6 +277,7 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
super.add(items[i], constraints, i);
}
}
+ this.setSize(this.getPreferredSize());
}
/**
@@ -908,13 +910,13 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
*/
private class LightWeightPopup extends Container implements Popup
{
+ private Component c;
+
/**
* Creates a new LightWeightPopup menu
*
* @param c Container containing menu items
*/
- private Component c;
-
public LightWeightPopup(Container c)
{
this.c = c;
diff --git a/libjava/classpath/javax/swing/JScrollBar.java b/libjava/classpath/javax/swing/JScrollBar.java
index caed92c..a2cc76c 100644
--- a/libjava/classpath/javax/swing/JScrollBar.java
+++ b/libjava/classpath/javax/swing/JScrollBar.java
@@ -69,8 +69,6 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
/**
* Creates a new AccessibleJSlider object.
- *
- * @param value0 DOCUMENT ME!
*/
protected AccessibleJScrollBar()
{
diff --git a/libjava/classpath/javax/swing/JScrollPane.java b/libjava/classpath/javax/swing/JScrollPane.java
index 377f05a..e83513f 100644
--- a/libjava/classpath/javax/swing/JScrollPane.java
+++ b/libjava/classpath/javax/swing/JScrollPane.java
@@ -571,8 +571,6 @@ public class JScrollPane
* Creates a new JScrollPane
without a view. The scrollbar
* policy is set to {@link #VERTICAL_SCROLLBAR_AS_NEEDED} and
* {@link #HORIZONTAL_SCROLLBAR_AS_NEEDED}.
- *
- * @param view the component that is embedded inside the JScrollPane
*/
public JScrollPane()
{
@@ -600,12 +598,12 @@ public class JScrollPane
* @param vsbPolicy the vertical scrollbar policy to set
* @param hsbPolicy the vertical scrollbar policy to set
*
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS}
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED}
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER}
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
*/
public JScrollPane(int vsbPolicy, int hsbPolicy)
{
@@ -620,12 +618,12 @@ public class JScrollPane
* @param vsbPolicy the vertical scrollbar policy to set
* @param hsbPolicy the vertical scrollbar policy to set
*
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS}
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED}
- * @see {@link ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED}
- * @see {@link ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER}
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
+ * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
+ * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
*/
public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
{
diff --git a/libjava/classpath/javax/swing/JSeparator.java b/libjava/classpath/javax/swing/JSeparator.java
index 064c465..6a3b97d 100644
--- a/libjava/classpath/javax/swing/JSeparator.java
+++ b/libjava/classpath/javax/swing/JSeparator.java
@@ -59,8 +59,6 @@ public class JSeparator extends JComponent implements SwingConstants,
/**
* Constructor AccessibleJSeparator
- *
- * @param component TODO
*/
protected AccessibleJSeparator()
{
diff --git a/libjava/classpath/javax/swing/JSlider.java b/libjava/classpath/javax/swing/JSlider.java
index 7f99511..2caf509 100644
--- a/libjava/classpath/javax/swing/JSlider.java
+++ b/libjava/classpath/javax/swing/JSlider.java
@@ -41,6 +41,7 @@ package javax.swing;
import java.awt.Dimension;
import java.awt.MenuContainer;
import java.awt.image.ImageObserver;
+import java.beans.PropertyChangeEvent;
import java.io.Serializable;
import java.util.Dictionary;
import java.util.Enumeration;
@@ -124,8 +125,6 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
/**
* Creates a new AccessibleJSlider object.
- *
- * @param value0 DOCUMENT ME!
*/
protected AccessibleJSlider()
{
@@ -229,7 +228,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
protected int minorTickSpacing;
/** Whether the slider snaps its values to ticks. */
- protected boolean snapToTicks = true;
+ protected boolean snapToTicks = false;
/** The orientation of the slider. */
protected int orientation = HORIZONTAL;
@@ -256,7 +255,11 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
* Creates a new JSlider object with the given orientation and a minimum of
* 0, a maximum of 100, and a value of 50.
*
- * @param orientation The orientation of the slider.
+ * @param orientation The orientation of the slider ({@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if orientation
is not one of
+ * the specified values.
*/
public JSlider(int orientation)
{
@@ -293,10 +296,14 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
* Creates a new JSlider object with the given orientation, minimum,
* maximum, and value.
*
- * @param orientation The orientation of the JSlider.
+ * @param orientation The orientation of the slider ({@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
* @param minimum The minimum value of the JSlider.
* @param maximum The maximum value of the JSlider.
* @param value The initial value of the JSlider.
+ *
+ * @throws IllegalArgumentException if orientation
is not one of
+ * the specified values.
*/
public JSlider(int orientation, int minimum, int maximum, int value)
{
@@ -312,14 +319,13 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
/**
* Creates a new horizontal JSlider object with the given model.
*
- * @param model The model the slider will be created with.
+ * @param model The model (null
not permitted).
+ *
+ * @throws NullPointerException if model
is null
.
*/
public JSlider(BoundedRangeModel model)
{
- if (model == null)
- sliderModel = new DefaultBoundedRangeModel(50, 0, 0, 100);
- else
- sliderModel = model;
+ sliderModel = model;
changeListener = createChangeListener();
sliderModel.addChangeListener(changeListener);
updateUI();
@@ -504,7 +510,10 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
public void setMinimum(int minimum)
{
+ int old = sliderModel.getMinimum();
sliderModel.setMinimum(minimum);
+ if (minimum != old)
+ firePropertyChange("minimum", old, minimum);
}
/**
@@ -524,7 +533,10 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
public void setMaximum(int maximum)
{
+ int old = sliderModel.getMaximum();
sliderModel.setMaximum(maximum);
+ if (maximum != old)
+ firePropertyChange("maximum", old, maximum);
}
/**
@@ -643,9 +655,12 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
* minimum and increase by the increment. Each label will have a text
* string indicating their integer value.
*
- * @param increment The increment to between labels.
+ * @param increment The increment between labels (must be > 0).
*
* @return A hashtable with the labels and their keys.
+ *
+ * @throws IllegalArgumentException if increment
is not greater
+ * than zero.
*/
public Hashtable createStandardLabels(int increment)
{
@@ -656,15 +671,23 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
* Creates a hashtable of (Integer, JLabel) pairs that can be used as a
* label table for this slider. The labels will start from the given start
* value and increase by the increment. Each label will have a text string
- * indicating their integer value.
+ * indicating its integer value.
*
- * @param increment The increment to between labels.
+ * @param increment The increment between labels (must be > 0).
* @param start The value to start from.
*
* @return A hashtable with the labels and their keys.
+ *
+ * @throws IllegalArgumentException if increment
is not greater
+ * than zero, or start
is not within the range of the
+ * model.
*/
public Hashtable createStandardLabels(int increment, int start)
{
+ if (increment <= 0)
+ throw new IllegalArgumentException("Requires 'increment' > 0.");
+ if (start < getMinimum() || start > getMaximum())
+ throw new IllegalArgumentException("The 'start' value is out of range.");
Hashtable table = new Hashtable();
JLabel label;
Dimension dim;
@@ -801,7 +824,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
if (snap != snapToTicks)
{
snapToTicks = snap;
- fireStateChanged();
+ firePropertyChange("snapToTicks", !snap, snap);
}
}
@@ -847,13 +870,19 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
}
/**
- * This method sets whether the track will be painted.
+ * Sets the flag that controls whether or not the track is painted, and
+ * sends a {@link PropertyChangeEvent} (for the "paintTrack" property) to all
+ * registered listeners.
*
* @param paint Whether the track will be painted.
*/
public void setPaintTrack(boolean paint)
{
- paintTrack = paint;
+ if (paintTrack != paint)
+ {
+ paintTrack = paint;
+ firePropertyChange("paintTrack", !paint, paint);
+ }
}
/**
@@ -875,9 +904,10 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
{
if (paint != paintLabels)
{
- boolean oldPaintLabels = paintLabels;
paintLabels = paint;
- firePropertyChange("paintLabels", oldPaintLabels, paintLabels);
+ if (paint && majorTickSpacing > 0)
+ labelTable = createStandardLabels(majorTickSpacing);
+ firePropertyChange("paintLabels", !paint, paint);
}
}
diff --git a/libjava/classpath/javax/swing/JSpinner.java b/libjava/classpath/javax/swing/JSpinner.java
index 96fe10f..fc2b13e 100644
--- a/libjava/classpath/javax/swing/JSpinner.java
+++ b/libjava/classpath/javax/swing/JSpinner.java
@@ -49,7 +49,6 @@ import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.SpinnerUI;
@@ -297,7 +296,7 @@ public class JSpinner extends JComponent
* create a DateEditor
instance
* @param dateFormatPattern the date format to use
*
- * @see SimpleDateFormat(String)
+ * @see SimpleDateFormat#SimpleDateFormat(String)
*/
public DateEditor(JSpinner spinner, String dateFormatPattern)
{
diff --git a/libjava/classpath/javax/swing/JSplitPane.java b/libjava/classpath/javax/swing/JSplitPane.java
index d7abce9..cea5afe 100644
--- a/libjava/classpath/javax/swing/JSplitPane.java
+++ b/libjava/classpath/javax/swing/JSplitPane.java
@@ -66,8 +66,6 @@ public class JSplitPane extends JComponent implements Accessible
/**
* Creates a new AccessibleJSplitPane object.
- *
- * @param value0 DOCUMENT ME!
*/
protected AccessibleJSplitPane()
{
diff --git a/libjava/classpath/javax/swing/JTable.java b/libjava/classpath/javax/swing/JTable.java
index 505a460..21680d5 100644
--- a/libjava/classpath/javax/swing/JTable.java
+++ b/libjava/classpath/javax/swing/JTable.java
@@ -43,9 +43,14 @@ import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Date;
+import java.util.EventObject;
import java.util.Hashtable;
import java.util.Vector;
@@ -69,6 +74,7 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
+import javax.swing.text.Caret;
public class JTable extends JComponent
implements TableModelListener, Scrollable, TableColumnModelListener,
@@ -351,6 +357,7 @@ public class JTable extends JComponent
*/
protected transient Component editorComp;
+
/**
* Whether or not the table should automatically compute a matching
* {@link TableColumnModel} and assign it to the {@link #columnModel}
@@ -555,7 +562,27 @@ public class JTable extends JComponent
*/
protected JTableHeader tableHeader;
-
+ /**
+ * The row of the cell being edited.
+ */
+ int rowBeingEdited = -1;
+
+ /**
+ * The column of the cell being edited.
+ */
+ int columnBeingEdited = -1;
+
+ /**
+ * The action listener for the editor's Timer.
+ */
+ Timer editorTimer = new EditorUpdateTimer();
+
+ /**
+ * Stores the old value of a cell before it was edited, in case
+ * editing is cancelled
+ */
+ Object oldCellValue;
+
/**
* Creates a new JTable
instance.
*/
@@ -618,9 +645,14 @@ public class JTable extends JComponent
{
setModel(dm == null ? createDefaultDataModel() : dm);
setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
-
+
this.columnModel = cm;
initializeLocalVars();
+ // The next two lines are for compliance with the JDK which starts
+ // the JLists associated with a JTable with both lead selection
+ // indices at 0, rather than -1 as in regular JLists
+ selectionModel.setLeadSelectionIndex(0);
+ columnModel.getSelectionModel().setLeadSelectionIndex(0);
updateUI();
}
@@ -641,7 +673,7 @@ public class JTable extends JComponent
this.defaultEditorsByColumnClass = new Hashtable();
createDefaultEditors();
- this.autoResizeMode = AUTO_RESIZE_ALL_COLUMNS;
+ this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
this.rowHeight = 16;
this.rowMargin = 1;
this.rowSelectionAllowed = true;
@@ -668,6 +700,51 @@ public class JTable extends JComponent
this(new DefaultTableModel(data, columnNames));
}
+ /**
+ * The timer that updates the editor component.
+ */
+ private class EditorUpdateTimer
+ extends Timer
+ implements ActionListener
+ {
+ /**
+ * Creates a new EditorUpdateTimer object with a default delay of 0.5 seconds.
+ */
+ public EditorUpdateTimer()
+ {
+ super(500, null);
+ addActionListener(this);
+ }
+
+ /**
+ * Lets the caret blink and repaints the table.
+ */
+ public void actionPerformed(ActionEvent ev)
+ {
+ Caret c = ((JTextField)JTable.this.editorComp).getCaret();
+ if (c != null)
+ c.setVisible(!c.isVisible());
+ JTable.this.repaint();
+ }
+
+ /**
+ * Updates the blink delay according to the current caret.
+ */
+ public void update()
+ {
+ stop();
+ Caret c = ((JTextField)JTable.this.editorComp).getCaret();
+ if (c != null)
+ {
+ setDelay(c.getBlinkRate());
+ if (((JTextField)JTable.this.editorComp).isEditable())
+ start();
+ else
+ c.setVisible(false);
+ }
+ }
+ }
+
public void addColumn(TableColumn column)
{
if (column.getHeaderValue() == null)
@@ -769,11 +846,40 @@ public class JTable extends JComponent
public void editingCanceled (ChangeEvent event)
{
+ if (rowBeingEdited > -1 && columnBeingEdited > -1)
+ {
+ if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField)
+ {
+ remove ((Component)getValueAt(rowBeingEdited, columnBeingEdited));
+ setValueAt(oldCellValue, rowBeingEdited, columnBeingEdited);
+ }
+ rowBeingEdited = -1;
+ columnBeingEdited = -1;
+ }
+ editorTimer.stop();
+ editorComp = null;
+ cellEditor = null;
+ requestFocusInWindow(false);
repaint();
}
public void editingStopped (ChangeEvent event)
{
+ if (rowBeingEdited > -1 && columnBeingEdited > -1)
+ {
+ if (getValueAt(rowBeingEdited, columnBeingEdited) instanceof JTextField)
+ {
+ remove((Component)getValueAt(rowBeingEdited, columnBeingEdited));
+ setValueAt(((JTextField)editorComp).getText(),
+ rowBeingEdited, columnBeingEdited);
+ }
+ rowBeingEdited = -1;
+ columnBeingEdited = -1;
+ }
+ editorTimer.stop();
+ editorComp = null;
+ cellEditor = null;
+ requestFocusInWindow(false);
repaint();
}
@@ -804,20 +910,23 @@ public class JTable extends JComponent
*/
public int columnAtPoint(Point point)
{
- int x0 = getLocation().x;
- int ncols = getColumnCount();
- Dimension gap = getIntercellSpacing();
- TableColumnModel cols = getColumnModel();
- int x = point.x;
-
- for (int i = 0; i < ncols; ++i)
+ if (point != null)
{
- int width = cols.getColumn(i).getWidth() + (gap == null ? 0 : gap.width);
- if (0 <= x && x < width)
- return i;
- x -= width;
+ int x0 = getLocation().x;
+ int ncols = getColumnCount();
+ Dimension gap = getIntercellSpacing();
+ TableColumnModel cols = getColumnModel();
+ int x = point.x;
+
+ for (int i = 0; i < ncols; ++i)
+ {
+ int width = cols.getColumn(i).getWidth()
+ + (gap == null ? 0 : gap.width);
+ if (0 <= x && x < width)
+ return i;
+ x -= width;
+ }
}
-
return -1;
}
@@ -831,19 +940,21 @@ public class JTable extends JComponent
*/
public int rowAtPoint(Point point)
{
- int y0 = getLocation().y;
- int nrows = getRowCount();
- Dimension gap = getIntercellSpacing();
- int height = getRowHeight() + (gap == null ? 0 : gap.height);
- int y = point.y;
-
- for (int i = 0; i < nrows; ++i)
+ if (point != null)
{
- if (0 <= y && y < height)
- return i;
- y -= height;
+ int y0 = getLocation().y;
+ int nrows = getRowCount();
+ Dimension gap = getIntercellSpacing();
+ int height = getRowHeight() + (gap == null ? 0 : gap.height);
+ int y = point.y;
+
+ for (int i = 0; i < nrows; ++i)
+ {
+ if (0 <= y && y < height)
+ return i;
+ y -= height;
+ }
}
-
return -1;
}
@@ -867,7 +978,7 @@ public class JTable extends JComponent
int column,
boolean includeSpacing)
{
- int height = getHeight();
+ int height = getRowHeight(row);
int width = columnModel.getColumn(column).getWidth();
int x_gap = columnModel.getColumnMargin();
int y_gap = rowMargin;
@@ -975,7 +1086,7 @@ public class JTable extends JComponent
if (editor == null)
editor = getDefaultEditor(dataModel.getColumnClass(column));
-
+
return editor;
}
@@ -1095,6 +1206,19 @@ public class JTable extends JComponent
}
/**
+ * Get the height of the specified row.
+ *
+ * @param row the row whose height to return
+ */
+ public int getRowHeight(int row)
+ {
+ // FIXME: return the height of the specified row
+ // which may be different from the general rowHeight
+ return rowHeight;
+ }
+
+
+ /**
* Get the value of the {@link #rowMargin} property.
*
* @return The current value of the property
@@ -1457,14 +1581,27 @@ public class JTable extends JComponent
*/
public void setRowHeight(int r)
{
- if (rowHeight < 1)
+ if (r < 1)
throw new IllegalArgumentException();
rowHeight = r;
revalidate();
repaint();
}
-
+
+ /**
+ * Sets the value of the rowHeight property for the specified
+ * row.
+ *
+ * @param rh is the new rowHeight
+ * @param row is the row to change the rowHeight of
+ */
+ public void setRowHeight(int row, int rh)
+ {
+ setRowHeight(rh);
+ // FIXME: not implemented
+ }
+
/**
* Set the value of the {@link #rowMargin} property.
*
@@ -2065,8 +2202,17 @@ public class JTable extends JComponent
public void selectAll()
{
+ // rowLead and colLead store the current lead selection indices
+ int rowLead = selectionModel.getLeadSelectionIndex();
+ int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex();
+ // the following calls to setSelectionInterval change the lead selection
+ // indices
setColumnSelectionInterval(0, getColumnCount() - 1);
setRowSelectionInterval(0, getRowCount() - 1);
+ // the following addSelectionInterval calls restore the lead selection
+ // indices to their previous values
+ addColumnSelectionInterval(colLead,colLead);
+ addRowSelectionInterval(rowLead, rowLead);
}
public Object getValueAt(int row, int column)
@@ -2076,6 +2222,11 @@ public class JTable extends JComponent
public void setValueAt(Object value, int row, int column)
{
+ if (!isCellEditable(row, column))
+ return;
+
+ if (value instanceof Component)
+ add((Component)value);
dataModel.setValueAt(value, row, convertColumnIndexToModel(column));
}
@@ -2167,4 +2318,58 @@ public class JTable extends JComponent
}
}
+
+ /**
+ * Programmatically starts editing the specified cell.
+ *
+ * @param row the row of the cell to edit.
+ * @param column the column of the cell to edit.
+ */
+ public boolean editCellAt (int row, int column)
+ {
+ oldCellValue = getValueAt(row, column);
+ setCellEditor(getCellEditor(row, column));
+ editorComp = prepareEditor(cellEditor, row, column);
+ cellEditor.addCellEditorListener(this);
+ rowBeingEdited = row;
+ columnBeingEdited = column;
+ setValueAt(editorComp, row, column);
+ ((JTextField)editorComp).requestFocusInWindow(false);
+ editorTimer.start();
+ return true;
+ }
+
+ /**
+ * Programmatically starts editing the specified cell.
+ *
+ * @param row the row of the cell to edit.
+ * @param column the column of the cell to edit.
+ */
+ public boolean editCellAt (int row, int column, EventObject e)
+ {
+ return editCellAt(row, column);
+ }
+
+ /**
+ * Discards the editor object.
+ */
+ public void removeEditor()
+ {
+ editingStopped(new ChangeEvent(this));
+ }
+
+ /**
+ * Prepares the editor by querying for the value and selection state of the
+ * cell at (row, column).
+ *
+ * @param editor the TableCellEditor to set up
+ * @param row the row of the cell to edit
+ * @param column the column of the cell to edit
+ * @return the Component being edited
+ */
+ public Component prepareEditor (TableCellEditor editor, int row, int column)
+ {
+ return editor.getTableCellEditorComponent
+ (this, getValueAt(row, column), isCellSelected(row, column), row, column);
+ }
}
diff --git a/libjava/classpath/javax/swing/JTextArea.java b/libjava/classpath/javax/swing/JTextArea.java
index fb35eb3..53591ff 100644
--- a/libjava/classpath/javax/swing/JTextArea.java
+++ b/libjava/classpath/javax/swing/JTextArea.java
@@ -80,13 +80,13 @@ import javax.swing.text.View;
* @author Michael Koch (konqueror@gmx.de)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @see java.awt.TextArea
- * @see javax.swing.JTextComponent
+ * @see javax.swing.text.JTextComponent
* @see javax.swing.JTextField
* @see javax.swing.JTextPane
* @see javax.swing.JEditorPane
* @see javax.swing.text.Document
- * @see javax.swing.text.DocumentEvent
- * @see javax.swing.text.DocumentListener
+ * @see javax.swing.event.DocumentEvent
+ * @see javax.swing.event.DocumentListener
*/
public class JTextArea extends JTextComponent
@@ -166,7 +166,7 @@ public class JTextArea extends JTextComponent
/**
* Creates a new JTextArea
object.
*
- * @param the document model to use
+ * @param doc the document model to use
*/
public JTextArea(Document doc)
{
@@ -176,7 +176,7 @@ public class JTextArea extends JTextComponent
/**
* Creates a new JTextArea
object.
*
- * @param the document model to use
+ * @param doc the document model to use
* @param text the initial text
* @param rows the number of rows
* @param columns the number of cols
@@ -235,12 +235,12 @@ public class JTextArea extends JTextComponent
/**
* Returns the increment that is needed to expose exactly one new line
* of text. This is implemented here to return the values of
- * {@link #getRowHeight} and {@link getColumnWidth}, depending on
+ * {@link #getRowHeight} and {@link #getColumnWidth}, depending on
* the value of the argument direction
.
*
* @param visibleRect the view area that is visible in the viewport
- * @param orientation either {@link SwingConstants.VERTICAL} or
- * {@link SwingConstants.HORIZONTAL}
+ * @param orientation either {@link SwingConstants#VERTICAL} or
+ * {@link SwingConstants#HORIZONTAL}
* @param direction less than zero for up/left scrolling, greater
* than zero for down/right scrolling
*
@@ -329,7 +329,7 @@ public class JTextArea extends JTextComponent
/**
* Sets the number of rows.
*
- * @param columns number of columns
+ * @param rows number of rows
*
* @exception IllegalArgumentException if rows is negative
*/
@@ -355,7 +355,7 @@ public class JTextArea extends JTextComponent
/**
* Enables/disables line wrapping.
*
- * @param wrapping true
to enable line wrapping,
+ * @param flag true
to enable line wrapping,
* false
otherwise
*/
public void setLineWrap(boolean flag)
diff --git a/libjava/classpath/javax/swing/JTextField.java b/libjava/classpath/javax/swing/JTextField.java
index 7d8407f..5ae9c9f 100644
--- a/libjava/classpath/javax/swing/JTextField.java
+++ b/libjava/classpath/javax/swing/JTextField.java
@@ -197,7 +197,7 @@ public class JTextField extends JTextComponent
public void insertString(int offset, String str, AttributeSet a)
throws BadLocationException
{
- if (str.indexOf('\n') == -1)
+ if (str != null && str.indexOf('\n') == -1)
super.insertString(offset, str, a);
}
};
diff --git a/libjava/classpath/javax/swing/JTextPane.java b/libjava/classpath/javax/swing/JTextPane.java
index 5321812..80632ff 100644
--- a/libjava/classpath/javax/swing/JTextPane.java
+++ b/libjava/classpath/javax/swing/JTextPane.java
@@ -1,5 +1,5 @@
-/* JTextPane.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* JTextPane.java -- A powerful text widget supporting styled text
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,228 +43,373 @@ import java.io.IOException;
import java.io.ObjectOutputStream;
import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
+import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyledDocument;
import javax.swing.text.StyledEditorKit;
/**
- * JTextPane
- * @author Andrew Selkirk
- * @version 1.0
+ * A powerful text component that supports styled content as well as
+ * embedding images and components. It is entirely based on a
+ * {@link StyledDocument} content model and a {@link StyledEditorKit}.
+ *
+ * @author Roman Kennke (roman@kennke.org)
+ * @author Andrew Selkirk
*/
-public class JTextPane extends JEditorPane {
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * uiClassID
- */
- private static final String uiClassID = "TextPaneUI";
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor JTextPane
- */
- public JTextPane() {
- // TODO
- } // JTextPane()
-
- /**
- * Constructor JTextPane
- * @param document TODO
- */
- public JTextPane(StyledDocument document) {
- // TODO
- } // JTextPane()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * getUIClassID
- * @returns String
- */
- public String getUIClassID() {
- return uiClassID;
- } // getUIClassID()
-
- /**
- * setDocument
- * @param document TODO
- */
- public void setDocument(Document document) {
- super.setDocument(document); // TODO
- } // setDocument()
-
- /**
- * getStyledDocument
- * @returns StyledDocument
- */
- public StyledDocument getStyledDocument() {
- return null; // TODO
- } // getStyledDocument()
-
- /**
- * setStyledDocument
- * @param document TODO
- */
- public void setStyledDocument(StyledDocument document) {
- // TODO
- } // setStyledDocument()
-
- /**
- * replaceSelection
- * @param content TODO
- */
- public void replaceSelection(String content) {
- super.replaceSelection(content); // TODO
- } // replaceSelection()
-
- /**
- * insertComponent
- * @param component TODO
- */
- public void insertComponent(Component component) {
- // TODO
- } // insertComponent()
-
- /**
- * insertIcon
- * @param icon TODO
- */
- public void insertIcon(Icon icon) {
- // TODO
- } // insertIcon()
-
- /**
- * addStyle
- * @param nm TODO
- * @param parent TODO
- * @returns Style
- */
- public Style addStyle(String nm, Style parent) {
- return null; // TODO
- } // addStyle()
-
- /**
- * removeStyle
- * @param nm TODO
- */
- public void removeStyle(String nm) {
- // TODO
- } // removeStyle()
-
- /**
- * getStyle
- * @param nm TODO
- * @returns Style
- */
- public Style getStyle(String nm) {
- return null; // TODO
- } // getStyle()
-
- /**
- * getLogicalStyle
- * @returns Style
- */
- public Style getLogicalStyle() {
- return null; // TODO
- } // getLogicalStyle()
-
- /**
- * setLogicalStyle
- * @param style TODO
- */
- public void setLogicalStyle(Style style) {
- // TODO
- } // setLogicalStyle()
-
- /**
- * getCharacterAttributes
- * @returns AttributeSet
- */
- public AttributeSet getCharacterAttributes() {
- return null; // TODO
- } // getCharacterAttributes()
-
- /**
- * setCharacterAttributes
- * @param attribute TODO
- * @param replace TODO
- */
- public void setCharacterAttributes(AttributeSet attribute,
- boolean replace) {
- // TODO
- } // setCharacterAttributes()
-
- /**
- * getParagraphAttributes
- * @returns AttributeSet
- */
- public AttributeSet getParagraphAttributes() {
- return null; // TODO
- } // getParagraphAttributes()
-
- /**
- * setParagraphAttributes
- * @param attribute TODO
- * @param replace TODO
- */
- public void setParagraphAttributes(AttributeSet attribute,
- boolean replace) {
- // TODO
- } // setParagraphAttributes()
-
- /**
- * getInputAttributes
- * @returns MutableAttributeSet
- */
- public MutableAttributeSet getInputAttributes() {
- return null; // TODO
- } // getInputAttributes()
-
- /**
- * getStyledEditorKit
- * @returns StyledEditorKit
- */
- protected final StyledEditorKit getStyledEditorKit() {
- return null; // TODO
- } // getStyledEditorKit()
-
- /**
- * createDefaultEditorKit
- * @returns EditorKit
- */
- protected EditorKit createDefaultEditorKit() {
- return super.createDefaultEditorKit(); // TODO
- } // createDefaultEditorKit()
-
- /**
- * setEditorKit
- * @param editor TODO
- */
- public final void setEditorKit(EditorKit editor) {
- super.setEditorKit(editor); // TODO
- } // setEditorKit()
-
- /**
- * paramString
- * @returns String
- */
- protected String paramString() {
- return super.paramString(); // TODO
- } // paramString()
-
-
-} // JTextPane
+public class JTextPane
+ extends JEditorPane
+{
+ /**
+ * Creates a new JTextPane
with a null
document.
+ */
+ public JTextPane()
+ {
+ super();
+ }
+
+ /**
+ * Creates a new JTextPane
and sets the specified
+ * document
.
+ *
+ * @param document the content model to use
+ */
+ public JTextPane(StyledDocument document)
+ {
+ this();
+ setStyledDocument(document);
+ }
+
+ /**
+ * Returns the UI class ID. This is TextPaneUI
.
+ *
+ * @return TextPaneUI
+ */
+ public String getUIClassID()
+ {
+ return "TextPaneUI";
+ }
+
+ /**
+ * Sets the content model for this JTextPane
.
+ * JTextPane
can only be used with {@link StyledDocument}s,
+ * if you try to set a different type of Document
, an
+ * IllegalArgumentException
is thrown.
+ *
+ * @param document the content model to set
+ *
+ * @throws IllegalArgumentException if document
is not an
+ * instance of StyledDocument
+ *
+ * @see {@link #setStyledDocument}
+ */
+ public void setDocument(Document document)
+ {
+ if (document != null && !(document instanceof StyledDocument))
+ throw new IllegalArgumentException
+ ("JTextPane can only handle StyledDocuments");
+
+ setStyledDocument((StyledDocument) document);
+ }
+
+ /**
+ * Returns the {@link StyledDocument} that is the content model for
+ * this JTextPane
. This is a typed wrapper for
+ * {@link #getDocument}.
+ *
+ * @return the content model of this JTextPane
+ */
+ public StyledDocument getStyledDocument()
+ {
+ return (StyledDocument) super.getDocument();
+ }
+
+ /**
+ * Sets the content model for this JTextPane
.
+ *
+ * @param document the content model to set
+ */
+ public void setStyledDocument(StyledDocument document)
+ {
+ super.setDocument(document);
+ }
+
+ /**
+ * Replaces the currently selected text with the specified
+ * content
. If there is no selected text, this results
+ * in a simple insertion at the current caret position. If there is
+ * no content
specified, this results in the selection
+ * beeing deleted.
+ *
+ * @param content the text with which the selection is replaced
+ */
+ public void replaceSelection(String content)
+ {
+ Caret caret = getCaret();
+ StyledDocument doc = getStyledDocument();
+
+ int dot = caret.getDot();
+ int mark = caret.getMark();
+
+ // If content is empty delete selection.
+ if (content == null)
+ {
+ caret.setDot(dot);
+ return;
+ }
+
+ try
+ {
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+ int contentLength = content.length();
+
+ // Remove selected text.
+ if (dot != mark)
+ doc.remove(start, end - start);
+
+ // Insert new text.
+ doc.insertString(start, content, null);
+ // Set attributes for inserted text
+ doc.setCharacterAttributes(start, contentLength, getInputAttributes(),
+ true);
+
+ // Set dot to new position.
+ setCaretPosition(start + contentLength);
+ }
+ catch (BadLocationException e)
+ {
+ throw new AssertionError
+ ("No BadLocationException should be thrown here");
+ }
+ }
+
+ /**
+ * Inserts an AWT or Swing component into the text at the current caret
+ * position.
+ *
+ * @param component the component to be inserted
+ */
+ public void insertComponent(Component component)
+ {
+ // TODO: One space must be inserted here with attributes set to indicate
+ // that the component must be displayed here. Have to figure out the
+ // attributes.
+ }
+
+ /**
+ * Inserts an Icon
into the text at the current caret position.
+ *
+ * @param icon the Icon
to be inserted
+ */
+ public void insertIcon(Icon icon)
+ {
+ // TODO: One space must be inserted here with attributes set to indicate
+ // that the icon must be displayed here. Have to figure out the
+ // attributes.
+ }
+
+ /**
+ * Adds a style into the style hierarchy. Unspecified style attributes
+ * can be resolved in the parent
style, if one is specified.
+ *
+ * While it is legal to add nameless styles (nm == null
null if the style should
+ * be unnamed
+ * @param parent the parent in which unspecified style attributes are
+ * resolved, or null
if that is not necessary
+ *
+ * @return the newly created Style
+ */
+ public Style addStyle(String nm, Style parent)
+ {
+ return getStyledDocument().addStyle(nm, parent);
+ }
+
+ /**
+ * Removes a named Style
from the style hierarchy.
+ *
+ * @param nm the name of the Style
to be removed
+ */
+ public void removeStyle(String nm)
+ {
+ getStyledDocument().removeStyle(nm);
+ }
+
+ /**
+ * Looks up and returns a named Style
.
+ *
+ * @param nm the name of the Style
+ *
+ * @return the found Style
of null
if no such
+ * Style
exists
+ */
+ public Style getStyle(String nm)
+ {
+ return getStyledDocument().getStyle(nm);
+ }
+
+ /**
+ * Returns the logical style of the paragraph at the current caret position.
+ *
+ * @return the logical style of the paragraph at the current caret position
+ */
+ public Style getLogicalStyle()
+ {
+ return getStyledDocument().getLogicalStyle(getCaretPosition());
+ }
+
+ /**
+ * Sets the logical style for the paragraph at the current caret position.
+ *
+ * @param style the style to set for the current paragraph
+ */
+ public void setLogicalStyle(Style style)
+ {
+ getStyledDocument().setLogicalStyle(getCaretPosition(), style);
+ }
+
+ /**
+ * Returns the text attributes for the character at the current caret
+ * position.
+ *
+ * @return the text attributes for the character at the current caret
+ * position
+ */
+ public AttributeSet getCharacterAttributes()
+ {
+ StyledDocument doc = getStyledDocument();
+ Element el = doc.getCharacterElement(getCaretPosition());
+ return el.getAttributes();
+ }
+
+ /**
+ * Sets text attributes for the current selection. If there is no selection
+ * the text attributes are applied to newly inserted text
+ *
+ * @param attribute the text attributes to set
+ * @param replace if true
, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ *
+ * @see {@link #getInputAttributes}
+ */
+ public void setCharacterAttributes(AttributeSet attribute,
+ boolean replace)
+ {
+ int dot = getCaret().getDot();
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+ if (start == dot && end == dot)
+ // There is no selection, update insertAttributes instead
+ {
+ MutableAttributeSet inputAttributes =
+ getStyledEditorKit().getInputAttributes();
+ inputAttributes.addAttributes(attribute);
+ }
+ else
+ getStyledDocument().setCharacterAttributes(start, end - start, attribute,
+ replace);
+ }
+
+ /**
+ * Returns the text attributes of the paragraph at the current caret
+ * position.
+ *
+ * @return the attributes of the paragraph at the current caret position
+ */
+ public AttributeSet getParagraphAttributes()
+ {
+ StyledDocument doc = getStyledDocument();
+ Element el = doc.getParagraphElement(getCaretPosition());
+ return el.getAttributes();
+ }
+
+ /**
+ * Sets text attributes for the paragraph at the current selection.
+ * If there is no selection the text attributes are applied to
+ * the paragraph at the current caret position.
+ *
+ * @param attribute the text attributes to set
+ * @param replace if true
, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ */
+ public void setParagraphAttributes(AttributeSet attribute,
+ boolean replace)
+ {
+ // TODO
+ }
+
+ /**
+ * Returns the attributes that are applied to newly inserted text.
+ * This is a {@link MutableAttributeSet}, so you can easily modify these
+ * attributes.
+ *
+ * @return the attributes that are applied to newly inserted text
+ */
+ public MutableAttributeSet getInputAttributes()
+ {
+ return getStyledEditorKit().getInputAttributes();
+ }
+
+ /**
+ * Returns the {@link StyledEditorKit} that is currently used by this
+ * JTextPane
.
+ *
+ * @return the current StyledEditorKit
of this
+ * JTextPane
+ */
+ protected final StyledEditorKit getStyledEditorKit()
+ {
+ return (StyledEditorKit) getEditorKit();
+ }
+
+ /**
+ * Creates the default {@link EditorKit} that is used in
+ * JTextPane
s. This is an instance of {@link StyledEditorKit}.
+ *
+ * @return the default {@link EditorKit} that is used in
+ * JTextPane
s
+ */
+ protected EditorKit createDefaultEditorKit()
+ {
+ return new StyledEditorKit();
+ }
+
+ /**
+ * Sets the {@link EditorKit} to use for this JTextPane
.
+ * JTextPane
s can only handle {@link StyledEditorKit}s,
+ * if client programs try to set a different type of EditorKit
+ * then an IllegalArgumentException is thrown
+ *
+ * @param editor the EditorKit
to set
+ *
+ * @throws IllegalArgumentException if editor
is no
+ * StyledEditorKit
+ */
+ public final void setEditorKit(EditorKit editor)
+ {
+ if (!(editor instanceof StyledEditorKit))
+ throw new IllegalArgumentException
+ ("JTextPanes can only handle StyledEditorKits");
+ super.setEditorKit(editor);
+ }
+
+ /**
+ * Returns a param string that can be used for debugging.
+ *
+ * @return a param string that can be used for debugging.
+ */
+ protected String paramString()
+ {
+ return super.paramString(); // TODO
+ }
+}
diff --git a/libjava/classpath/javax/swing/JToggleButton.java b/libjava/classpath/javax/swing/JToggleButton.java
index 0e1b9e6..25d67f5 100644
--- a/libjava/classpath/javax/swing/JToggleButton.java
+++ b/libjava/classpath/javax/swing/JToggleButton.java
@@ -134,7 +134,7 @@ public class JToggleButton extends AbstractButton implements Accessible
* Sets the pressed state of the button. The selected state
* of the button also changes follwing the button being pressed.
*
- * @param b true if the button is pressed down.
+ * @param p true if the button is pressed down.
*/
public void setPressed(boolean p)
{
@@ -145,7 +145,20 @@ public class JToggleButton extends AbstractButton implements Accessible
// if this call does not represent a CHANGE in state, then return
if ((p && isPressed()) || (!p && !isPressed()))
return;
-
+
+ // The JDK first fires events in the following order:
+ // 1. ChangeEvent for selected
+ // 2. ChangeEvent for pressed
+ // 3. ActionEvent
+ // So do we.
+
+ // setPressed(false) == mouse release on us,
+ // if we were armed, we flip the selected state.
+ if (!p && isArmed())
+ {
+ setSelected(! isSelected());
+ }
+
// make the change
if (p)
stateMask = stateMask | PRESSED;
@@ -154,16 +167,14 @@ public class JToggleButton extends AbstractButton implements Accessible
// notify interested ChangeListeners
fireStateChanged();
-
- // setPressed(false) == mouse release on us,
- // if we were armed, we flip the selected state.
+
if (!p && isArmed())
{
fireActionPerformed(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
actionCommand));
- setSelected(! isSelected());
}
+
}
}
diff --git a/libjava/classpath/javax/swing/JTree.java b/libjava/classpath/javax/swing/JTree.java
index bccd983..bb24c7a 100644
--- a/libjava/classpath/javax/swing/JTree.java
+++ b/libjava/classpath/javax/swing/JTree.java
@@ -339,7 +339,6 @@ public class JTree
{
setModel(model);
setSelectionModel(EmptySelectionModel.sharedInstance());
- selectionModel.addTreeSelectionListener(selectionRedirector);
setCellRenderer(new DefaultTreeCellRenderer());
updateUI();
}
@@ -564,13 +563,13 @@ public class JTree
}
/**
- * Returns the preferred viewport size..
+ * Returns the preferred viewport size.
*
* @return the preferred size
*/
public Dimension getPreferredScrollableViewportSize()
{
- return null;
+ return new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight());
}
public int getScrollableUnitIncrement(Rectangle visibleRect,
@@ -585,15 +584,19 @@ public class JTree
return 1;
}
- public boolean getScrollableTracksViewportWidth()
- {
- return false;
- }
-
- public boolean getScrollableTracksViewportHeight()
- {
- return false;
- }
+ public boolean getScrollableTracksViewportWidth()
+ {
+ if (getParent() instanceof JViewport)
+ return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
+ return false;
+ }
+
+ public boolean getScrollableTracksViewportHeight()
+ {
+ if (getParent() instanceof JViewport)
+ return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
+ return false;
+ }
/**
* Adds a TreeExpansionListener
object to the tree.
@@ -660,7 +663,7 @@ public class JTree
*/
public void addTreeSelectionListener(TreeSelectionListener listener)
{
- listenerList.add(TreeSelectionListener.class, listener);
+ listenerList.add(TreeSelectionListener.class, listener);
}
/**
@@ -692,7 +695,7 @@ public class JTree
protected void fireValueChanged(TreeSelectionEvent event)
{
TreeSelectionListener[] listeners = getTreeSelectionListeners();
-
+
for (int index = 0; index < listeners.length; ++index)
listeners[index].valueChanged(event);
}
@@ -775,16 +778,17 @@ public class JTree
{
if (treeModel == model)
return;
-
- TreeModel oldValue = treeModel;
- treeModel = model;
-
- firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
-
+
// add treeModelListener to the new model
if (treeModelListener == null)
treeModelListener = createTreeModelListener();
- model.addTreeModelListener(treeModelListener);
+ if (model != null) // as setModel(null) is allowed
+ model.addTreeModelListener(treeModelListener);
+
+ TreeModel oldValue = treeModel;
+ treeModel = model;
+
+ firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
}
/**
@@ -1276,9 +1280,17 @@ public class JTree
}
public void collapsePath(TreePath path)
- {
- setExpandedState(path, false);
- }
+ {
+ try
+ {
+ fireTreeWillCollapse(path);
+ }
+ catch (ExpandVetoException ev)
+ {
+ }
+ setExpandedState(path, false);
+ fireTreeCollapsed(path);
+ }
public void collapseRow(int row)
{
@@ -1292,13 +1304,22 @@ public class JTree
}
public void expandPath(TreePath path)
- {
- // Don't expand if last path component is a leaf node.
- if ((path == null) || (treeModel.isLeaf(path.getLastPathComponent())))
- return;
-
- setExpandedState(path, true);
- }
+ {
+ // Don't expand if last path component is a leaf node.
+ if ((path == null) || (treeModel.isLeaf(path.getLastPathComponent())))
+ return;
+
+ try
+ {
+ fireTreeWillExpand(path);
+ }
+ catch (ExpandVetoException ev)
+ {
+ }
+
+ setExpandedState(path, true);
+ fireTreeExpanded(path);
+ }
public void expandRow(int row)
{
@@ -1502,28 +1523,11 @@ public class JTree
return null;
}
- private void checkExpandParents(TreePath path) throws ExpandVetoException
- {
-
- TreePath parent = path.getParentPath();
-
- if (parent != null)
- checkExpandParents(parent);
-
- fireTreeWillExpand(path);
- }
-
private void doExpandParents(TreePath path, boolean state)
{
- TreePath parent = path.getParentPath();
-
- if (isExpanded(parent))
- {
- nodeStates.put(path, state ? EXPANDED : COLLAPSED);
- return;
- }
-
- if (parent != null)
+ TreePath parent = path.getParentPath();
+
+ if (!isExpanded(parent) && parent != null)
doExpandParents(parent, false);
nodeStates.put(path, state ? EXPANDED : COLLAPSED);
@@ -1533,20 +1537,8 @@ public class JTree
{
if (path == null)
return;
-
TreePath parent = path.getParentPath();
- try
- {
- if (parent != null)
- checkExpandParents(parent);
- }
- catch (ExpandVetoException e)
- {
- // Expansion vetoed.
- return;
- }
-
doExpandParents(path, state);
}
@@ -1729,8 +1721,8 @@ public class JTree
*
* @param prefix the prefix to search for in the cell values
* @param startingRow the index of the row where to start searching from
- * @param bias the search direction, either {@link Position.Bias.Forward} or
- * {@link Position.Bias.Backward}
+ * @param bias the search direction, either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward}
*
* @return the path to the found element or -1 if no such element has been
* found
@@ -1802,7 +1794,7 @@ public class JTree
* it will be removed too.
*
* @param path the path from which selected descendants are to be removed
- * @param includePath if true
then path
itself
+ * @param includeSelected if true
then path
itself
* will also be remove if it's selected
*
* @return true
if something has been removed,
diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java
index 397cb31..d750bad 100644
--- a/libjava/classpath/javax/swing/JViewport.java
+++ b/libjava/classpath/javax/swing/JViewport.java
@@ -89,7 +89,7 @@ import javax.swing.plaf.ViewportUI;
*
* But in terms of drawing its child, the viewport thinks of itself as
* covering a particular position of the view's coordinate space.
- * For example, the {@link javax.JViewPort.getViewPosition} method returns
+ * For example, the {@link #getViewPosition} method returns
* the position (VX,VY)
shown above, which is an position in
* "view space", even though this is implemented by positioning
* the underlying child at position (-VX,-VY)
When the {@link RepaintWorker} comes to the head of the system
* event queue, its {@link RepaintWorker#run} method is executed by the
@@ -235,7 +236,7 @@ public class RepaintManager
*
* @param manager The new value of the shared instance
*
- * @see #currentManager
+ * @see #currentManager(JComponent)
*/
public static void setCurrentManager(RepaintManager manager)
{
@@ -501,7 +502,7 @@ public class RepaintManager
*
* @since 1.4
*
- * @see {@link VolatileImage}
+ * @see VolatileImage
*/
public Image getVolatileOffscreenBuffer(Component comp, int proposedWidth,
int proposedHeight)
@@ -542,7 +543,7 @@ public class RepaintManager
*
* @param buffer The new value of the property
*
- * @see #getDoubleBufferingEnabled
+ * @see #isDoubleBufferingEnabled
*/
public void setDoubleBufferingEnabled(boolean buffer)
{
diff --git a/libjava/classpath/javax/swing/SizeRequirements.java b/libjava/classpath/javax/swing/SizeRequirements.java
index 430aeed..77b42db 100644
--- a/libjava/classpath/javax/swing/SizeRequirements.java
+++ b/libjava/classpath/javax/swing/SizeRequirements.java
@@ -295,7 +295,6 @@ public class SizeRequirements implements Serializable
* @param allocated the amount of allocated space
* @param total the total size requirements of the components
* @param children the size requirement of each component
- * @param offsets will hold the offset values for each component
* @param spans will hold the span values for each component
* @param forward whether the components should be placed in the forward
* direction (left-right or top-bottom) or reverse direction
diff --git a/libjava/classpath/javax/swing/SortingFocusTraversalPolicy.java b/libjava/classpath/javax/swing/SortingFocusTraversalPolicy.java
index 48f864b..fada17c 100644
--- a/libjava/classpath/javax/swing/SortingFocusTraversalPolicy.java
+++ b/libjava/classpath/javax/swing/SortingFocusTraversalPolicy.java
@@ -89,7 +89,7 @@ public class SortingFocusTraversalPolicy
* Creates a new
+ * Note that if
+ * Note that if the event's
* If you need more information about SGML DTD documents,
* the author suggests to read SGML tutorial on
- * {@link http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html}.
+ * http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html.
* We also recommend Goldfarb C.F (1991) The SGML Handbook,
* Oxford University Press, 688 p, ISBN: 0198537379.
* This class defines the SGML basic types, used for describing HTML 4.01
- * at {@link http://www.w3.org/TR/html4/types.html }. Not all constants,
+ * at http://www.w3.org/TR/html4/types.html. Not all constants,
* defined here, are actually used in HTML 4.01 SGML specification. Some others
* are defined just as part of the required implementation.
*
* If you need more information about SGML DTD documents,
* the author suggests to read SGML tutorial on
- * {@link http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html}.
+ * http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html.
* We also recommend Goldfarb C.F (1991) The SGML Handbook,
* Oxford University Press, 688 p, ISBN: 0198537379.
* SortingFocusTraversalPolicy
with the given
* comparator set.
*
- * @param the comparator to set
+ * @param comparator the comparator to set
*/
public SortingFocusTraversalPolicy(Comparator comparator)
{
@@ -306,12 +306,12 @@ public class SortingFocusTraversalPolicy
}
/**
- * Return the current value of the {@link implicitDownCycleTraversal}
+ * Return the current value of the {@link #implicitDownCycleTraversal}
* property.
*
* @return the current value of the property
*
- * @see setImplicitDownCycleTraversal
+ * @see #setImplicitDownCycleTraversal
*/
public boolean getImplicitDownCycleTraversal()
{
@@ -319,12 +319,12 @@ public class SortingFocusTraversalPolicy
}
/**
- * Set the current value of the {@link implicitDownCycleTraversal}
+ * Set the current value of the {@link #implicitDownCycleTraversal}
* property.
*
* @param down the new value of the property
*
- * @see getImplicitDownCycleTraversal
+ * @see #getImplicitDownCycleTraversal
*/
public void setImplicitDownCycleTraversal(boolean down)
{
diff --git a/libjava/classpath/javax/swing/SpinnerListModel.java b/libjava/classpath/javax/swing/SpinnerListModel.java
index a0dc4d1..85dc4ef 100644
--- a/libjava/classpath/javax/swing/SpinnerListModel.java
+++ b/libjava/classpath/javax/swing/SpinnerListModel.java
@@ -42,6 +42,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import javax.swing.event.ChangeEvent;
+
/**
* An implementation of SpinnerModel
which uses the values
* contained within a list or an array. The backing list or array is
diff --git a/libjava/classpath/javax/swing/Spring.java b/libjava/classpath/javax/swing/Spring.java
index 4255e86..69c88c7 100644
--- a/libjava/classpath/javax/swing/Spring.java
+++ b/libjava/classpath/javax/swing/Spring.java
@@ -189,9 +189,9 @@ public abstract class Spring
/**
* Creates a new SimpleSpring object.
*
- * @param min the constant minimum value.
- * @param pref the constant preferred value.
- * @param max the constant maximum value.
+ * @param newMin the constant minimum value.
+ * @param newPref the constant preferred value.
+ * @param newMax the constant maximum value.
*/
public SimpleSpring(int newMin, int newPref, int newMax)
{
diff --git a/libjava/classpath/javax/swing/SpringLayout.java b/libjava/classpath/javax/swing/SpringLayout.java
index b45edba..df9ddff 100644
--- a/libjava/classpath/javax/swing/SpringLayout.java
+++ b/libjava/classpath/javax/swing/SpringLayout.java
@@ -152,7 +152,7 @@ public class SpringLayout implements LayoutManager2
/**
* Returns the constraint for the edge with the edgeName
.
* This is expected to be one of
- * {@link #EAST}, {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+ * {@link #EAST}, {@link #WEST}, {@link #NORTH} or {@link #SOUTH}.
*
* @param edgeName the name of the edge.
* @return the constraint for the specified edge.
@@ -246,7 +246,7 @@ public class SpringLayout implements LayoutManager2
* the mathematics still hold true.
*
* @param edgeName the name of the edge, one of {@link #EAST},
- * {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+ * {@link #WEST}, {@link #NORTH} or {@link #SOUTH}.
* @param s the constraint to be set.
*/
public void setConstraint(String edgeName, Spring s)
@@ -361,8 +361,8 @@ public class SpringLayout implements LayoutManager2
* Method. This method does nothing, since SpringLayout does not manage
* String-indexed components.
*
- * @param component the component to be added.
- * @param constraint the constraint to be set.
+ * @param name the name.
+ * @param c the component to be added.
*/
public void addLayoutComponent(String name, Component c)
{
@@ -374,7 +374,7 @@ public class SpringLayout implements LayoutManager2
*
* @param c the component from which to get the constraint.
* @param edgeName the name of the edge, one of {@link #EAST},
- * {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+ * {@link #WEST}, {@link #NORTH} or {@link #SOUTH}.
* @return the constraint of the edge edgeName
of the
* component c.
*/
diff --git a/libjava/classpath/javax/swing/SwingUtilities.java b/libjava/classpath/javax/swing/SwingUtilities.java
index 69b6345..ee5fa74 100644
--- a/libjava/classpath/javax/swing/SwingUtilities.java
+++ b/libjava/classpath/javax/swing/SwingUtilities.java
@@ -63,7 +63,7 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.InputMapUIResource;
/**
- * This class contains a number of static utility functions which are
+ * A number of static utility functions which are
* useful when drawing swing components, dispatching events, or calculating
* regions which need painting.
*
@@ -449,7 +449,7 @@ public class SwingUtilities
* @return A component containing (x,y)
, or
* null
*
- * @see java.awt.Container#findComponentAt
+ * @see java.awt.Container#findComponentAt(int, int)
*/
public static Component getDeepestComponentAt(Component parent, int x, int y)
{
@@ -473,7 +473,7 @@ public class SwingUtilities
* @param p The point to convert
* @param c The component which the point is expressed in terms of
*
- * @see convertPointFromScreen
+ * @see #convertPointFromScreen
*/
public static void convertPointToScreen(Point p, Component c)
{
@@ -568,7 +568,7 @@ public class SwingUtilities
*
* @see #convertPointToScreen
* @see #convertPointFromScreen
- * @see #convertPoint
+ * @see #convertPoint(Component, int, int, Component)
* @see #getRoot
*/
public static Rectangle convertRectangle(Component source,
@@ -596,7 +596,7 @@ public class SwingUtilities
* component's coordinate space, and with the destination component as
* its source
*
- * @see #convertPoint
+ * @see #convertPoint(Component, int, int, Component)
*/
public static MouseEvent convertMouseEvent(Component source,
MouseEvent sourceEvent,
@@ -938,7 +938,7 @@ public class SwingUtilities
}
/**
- * Calls {@link java.awt.EventQueue.invokeLater} with the
+ * Calls {@link java.awt.EventQueue#invokeLater} with the
* specified {@link Runnable}.
*/
public static void invokeLater(Runnable doRun)
@@ -947,7 +947,7 @@ public class SwingUtilities
}
/**
- * Calls {@link java.awt.EventQueue.invokeAndWait} with the
+ * Calls {@link java.awt.EventQueue#invokeAndWait} with the
* specified {@link Runnable}.
*/
public static void invokeAndWait(Runnable doRun)
@@ -958,7 +958,10 @@ public class SwingUtilities
}
/**
- * Calls {@link java.awt.EventQueue.isEventDispatchThread}.
+ * Calls {@link java.awt.EventQueue#isDispatchThread()}.
+ *
+ * @return true
if the current thread is the current AWT event
+ * dispatch thread.
*/
public static boolean isEventDispatchThread()
{
@@ -1262,11 +1265,11 @@ public class SwingUtilities
* Calculates the intersection of two rectangles.
*
* @param x upper-left x coodinate of first rectangle
- * @param x upper-left y coodinate of first rectangle
+ * @param y upper-left y coodinate of first rectangle
* @param w width of first rectangle
* @param h height of first rectangle
* @param rect a Rectangle object of the second rectangle
- * @throws a NullPointerException if rect is null.
+ * @throws NullPointerException if rect is null.
*
* @return a rectangle corresponding to the intersection of the
* two rectangles. A zero rectangle is returned if the rectangles
@@ -1308,11 +1311,11 @@ public class SwingUtilities
* Calculates the union of two rectangles.
*
* @param x upper-left x coodinate of first rectangle
- * @param x upper-left y coodinate of first rectangle
+ * @param y upper-left y coodinate of first rectangle
* @param w width of first rectangle
* @param h height of first rectangle
* @param rect a Rectangle object of the second rectangle
- * @throws a NullPointerException if rect is null.
+ * @throws NullPointerException if rect is null.
*
* @return a rectangle corresponding to the union of the
* two rectangles. A rectangle encompassing both is returned if the
@@ -1361,9 +1364,9 @@ public class SwingUtilities
* maps should be returned, may be
* {@link JComponent#WHEN_IN_FOCUSED_WINDOW},
* {@link JComponent#WHEN_FOCUSED} or
- * {@link JComponent#WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
+ * {@link JComponent#WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}
*
- * @return
+ * @return The input map.
*/
public static InputMap getUIInputMap(JComponent component, int cond)
{
diff --git a/libjava/classpath/javax/swing/UIDefaults.java b/libjava/classpath/javax/swing/UIDefaults.java
index 06fee05..ab78ca6 100644
--- a/libjava/classpath/javax/swing/UIDefaults.java
+++ b/libjava/classpath/javax/swing/UIDefaults.java
@@ -421,9 +421,9 @@ public class UIDefaults extends Hashtable
* @return the font entry for key
or null if no such entry
* exists
*/
- public Font getFont(Object key, Locale l)
+ public Font getFont(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Font ? (Font) o : null;
}
@@ -450,9 +450,9 @@ public class UIDefaults extends Hashtable
* @return the color entry for key
or null if no such entry
* exists
*/
- public Color getColor(Object key, Locale l)
+ public Color getColor(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Color ? (Color) o : null;
}
@@ -479,9 +479,9 @@ public class UIDefaults extends Hashtable
* @return the icon entry for key
or null if no such entry
* exists
*/
- public Icon getIcon(Object key, Locale l)
+ public Icon getIcon(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Icon ? (Icon) o : null;
}
@@ -508,9 +508,9 @@ public class UIDefaults extends Hashtable
* @return the border entry for key
or null if no such entry
* exists
*/
- public Border getBorder(Object key, Locale l)
+ public Border getBorder(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Border ? (Border) o : null;
}
@@ -537,9 +537,9 @@ public class UIDefaults extends Hashtable
* @return the string entry for key
or null if no such entry
* exists
*/
- public String getString(Object key, Locale l)
+ public String getString(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof String ? (String) o : null;
}
@@ -566,9 +566,9 @@ public class UIDefaults extends Hashtable
* @return the integer entry for key
or null if no such entry
* exists
*/
- public int getInt(Object key, Locale l)
+ public int getInt(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Integer ? ((Integer) o).intValue() : 0;
}
@@ -594,9 +594,9 @@ public class UIDefaults extends Hashtable
* @return the boolean entry for key
or null if no such entry
* exists
*/
- public boolean getBoolean(Object key, Locale l)
+ public boolean getBoolean(Object key, Locale locale)
{
- return Boolean.TRUE.equals(get(key, l));
+ return Boolean.TRUE.equals(get(key, locale));
}
/**
@@ -622,9 +622,9 @@ public class UIDefaults extends Hashtable
* @return the boolean entry for key
or null if no such entry
* exists
*/
- public Insets getInsets(Object key, Locale l)
+ public Insets getInsets(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Insets ? (Insets) o : null;
}
@@ -651,9 +651,9 @@ public class UIDefaults extends Hashtable
* @return the boolean entry for key
or null if no such entry
* exists
*/
- public Dimension getDimension(Object key, Locale l)
+ public Dimension getDimension(Object key, Locale locale)
{
- Object o = get(key, l);
+ Object o = get(key, locale);
return o instanceof Dimension ? (Dimension) o : null;
}
diff --git a/libjava/classpath/javax/swing/UIManager.java b/libjava/classpath/javax/swing/UIManager.java
index 7f6d65e..f4648f1 100644
--- a/libjava/classpath/javax/swing/UIManager.java
+++ b/libjava/classpath/javax/swing/UIManager.java
@@ -47,15 +47,31 @@ import java.io.Serializable;
import java.util.Locale;
import javax.swing.border.Border;
+import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalLookAndFeel;
+/**
+ * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel}
+ * instances.
+ */
public class UIManager implements Serializable
{
+ /**
+ * Represents the basic information about a {@link LookAndFeel} (LAF), so
+ * that a list of installed LAFs can be presented without actually loading
+ * the LAF class(es).
+ */
public static class LookAndFeelInfo
{
String name, clazz;
+ /**
+ * Creates a new instance.
+ *
+ * @param name the look and feel name.
+ * @param clazz the look and feel class name.
+ */
public LookAndFeelInfo(String name,
String clazz)
{
@@ -63,11 +79,21 @@ public class UIManager implements Serializable
this.clazz = clazz;
}
+ /**
+ * Returns the name of the look and feel.
+ *
+ * @return The name of the look and feel.
+ */
public String getName()
{
return name;
}
+ /**
+ * Returns the fully qualified class name for the {@link LookAndFeel}.
+ *
+ * @return The fully qualified class name for the {@link LookAndFeel}.
+ */
public String getClassName()
{
return clazz;
@@ -93,13 +119,22 @@ public class UIManager implements Serializable
private static final long serialVersionUID = -5547433830339189365L;
+ /** The installed look and feel(s). */
static LookAndFeelInfo [] installed = {
- new LookAndFeelInfo ("Metal", "javax.swing.plaf.metal.MetalLookAndFeel")
+ new LookAndFeelInfo("Metal", "javax.swing.plaf.metal.MetalLookAndFeel")
};
- static LookAndFeel[] aux_installed;
+ /** The installed auxiliary look and feels. */
+ static LookAndFeel[] auxLookAndFeels;
+
+ /** The current look and feel. */
+ static LookAndFeel currentLookAndFeel;
- static LookAndFeel look_and_feel = new MetalLookAndFeel();
+ static UIDefaults currentUIDefaults;
+
+ /** Property change listener mechanism. */
+ static SwingPropertyChangeSupport listeners
+ = new SwingPropertyChangeSupport(UIManager.class);
static
{
@@ -115,11 +150,19 @@ public class UIManager implements Serializable
catch (Exception ex)
{
System.err.println("cannot initialize Look and Feel: " + defaultlaf);
- System.err.println("errot: " + ex.getMessage());
+ System.err.println("error: " + ex.getMessage());
System.err.println("falling back to Metal Look and Feel");
}
- }
+ currentLookAndFeel = new MetalLookAndFeel();
+ currentLookAndFeel.initialize();
+ currentUIDefaults = currentLookAndFeel.getDefaults();
+ }
+
+ /**
+ * Creates a new instance of the UIManager
. There is no need
+ * to construct an instance of this class, since all methods are static.
+ */
public UIManager()
{
// Do nothing here.
@@ -132,7 +175,7 @@ public class UIManager implements Serializable
*/
public static void addPropertyChangeListener(PropertyChangeListener listener)
{
- // FIXME
+ listeners.addPropertyChangeListener(listener);
}
/**
@@ -140,9 +183,10 @@ public class UIManager implements Serializable
*
* @param listener the listener to remove
*/
- public static void removePropertyChangeListener(PropertyChangeListener listener)
+ public static void removePropertyChangeListener(PropertyChangeListener
+ listener)
{
- // FIXME
+ listeners.removePropertyChangeListener(listener);
}
/**
@@ -154,60 +198,117 @@ public class UIManager implements Serializable
*/
public static PropertyChangeListener[] getPropertyChangeListeners()
{
- // FIXME
- throw new Error ("Not implemented");
+ return listeners.getPropertyChangeListeners();
}
/**
- * Add a LookAndFeel to the list of auxiliary look and feels.
+ * Add a {@link LookAndFeel} to the list of auxiliary look and feels.
+ *
+ * @param laf the auxiliary look and feel (null
not permitted).
+ *
+ * @throws NullPointerException if laf
is null
.
+ *
+ * @see #getAuxiliaryLookAndFeels()
*/
- public static void addAuxiliaryLookAndFeel (LookAndFeel l)
+ public static void addAuxiliaryLookAndFeel(LookAndFeel laf)
{
- if (aux_installed == null)
+ if (laf == null)
+ throw new NullPointerException("Null 'laf' argument.");
+ if (auxLookAndFeels == null)
{
- aux_installed = new LookAndFeel[1];
- aux_installed[0] = l;
+ auxLookAndFeels = new LookAndFeel[1];
+ auxLookAndFeels[0] = laf;
return;
}
- LookAndFeel[] T = new LookAndFeel[ aux_installed.length+1 ];
- System.arraycopy(aux_installed, 0, T, 0, aux_installed.length);
- aux_installed = T;
- aux_installed[aux_installed.length-1] = l;
+ LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length + 1];
+ System.arraycopy(auxLookAndFeels, 0, temp, 0, auxLookAndFeels.length);
+ auxLookAndFeels = temp;
+ auxLookAndFeels[auxLookAndFeels.length - 1] = laf;
}
+ /**
+ * Removes a {@link LookAndFeel} (LAF) from the list of auxiliary LAFs.
+ *
+ * @param laf the LAF to remove.
+ *
+ * @return true
if the LAF was removed, and false
+ * otherwise.
+ */
public static boolean removeAuxiliaryLookAndFeel(LookAndFeel laf)
{
- if (aux_installed == null)
+ if (auxLookAndFeels == null)
return false;
-
- for (int i=0;inull
).
+ *
+ * @see #addAuxiliaryLookAndFeel(LookAndFeel)
+ */
+ public static LookAndFeel[] getAuxiliaryLookAndFeels()
{
- return aux_installed;
+ return auxLookAndFeels;
}
- public static Object get(Object key)
+ /**
+ * Returns an object from the {@link UIDefaults} table for the current
+ * {@link LookAndFeel}.
+ *
+ * @param key the key.
+ *
+ * @return The object.
+ */
+ public static Object get(Object key)
{
- return getLookAndFeel().getDefaults().get(key);
+ return getLookAndFeelDefaults().get(key);
}
- public static Object get(Object key, Locale locale)
+ /**
+ * Returns an object from the {@link UIDefaults} table for the current
+ * {@link LookAndFeel}.
+ *
+ * @param key the key.
+ *
+ * @return The object.
+ */
+ public static Object get(Object key, Locale locale)
{
- return getLookAndFeel().getDefaults().get(key ,locale);
+ return getLookAndFeelDefaults().get(key ,locale);
}
/**
@@ -218,7 +319,7 @@ public class UIManager implements Serializable
*/
public static boolean getBoolean(Object key)
{
- Boolean value = (Boolean) getLookAndFeel().getDefaults().get(key);
+ Boolean value = (Boolean) getLookAndFeelDefaults().get(key);
return value != null ? value.booleanValue() : false;
}
@@ -230,7 +331,7 @@ public class UIManager implements Serializable
*/
public static boolean getBoolean(Object key, Locale locale)
{
- Boolean value = (Boolean) getLookAndFeel().getDefaults().get(key, locale);
+ Boolean value = (Boolean) getLookAndFeelDefaults().get(key, locale);
return value != null ? value.booleanValue() : false;
}
@@ -239,7 +340,7 @@ public class UIManager implements Serializable
*/
public static Border getBorder(Object key)
{
- return (Border) getLookAndFeel().getDefaults().get(key);
+ return (Border) getLookAndFeelDefaults().get(key);
}
/**
@@ -249,39 +350,44 @@ public class UIManager implements Serializable
*/
public static Border getBorder(Object key, Locale locale)
{
- return (Border) getLookAndFeel().getDefaults().get(key, locale);
+ return (Border) getLookAndFeelDefaults().get(key, locale);
}
/**
* Returns a drawing color from the defaults table.
*/
- public static Color getColor(Object key)
+ public static Color getColor(Object key)
{
- return (Color) getLookAndFeel().getDefaults().get(key);
+ return (Color) getLookAndFeelDefaults().get(key);
}
/**
* Returns a drawing color from the defaults table.
*/
- public static Color getColor(Object key, Locale locale)
+ public static Color getColor(Object key, Locale locale)
{
- return (Color) getLookAndFeel().getDefaults().get(key);
+ return (Color) getLookAndFeelDefaults().get(key);
}
/**
- * this string can be passed to Class.forName()
+ * The fully qualified class name of the cross platform (Metal) look and feel.
+ * This string can be passed to Class.forName()
+ *
+ * @return "javax.swing.plaf.metal.MetalLookAndFeel"
*/
- public static String getCrossPlatformLookAndFeelClassName()
+ public static String getCrossPlatformLookAndFeelClassName()
{
return "javax.swing.plaf.metal.MetalLookAndFeel";
}
/**
* Returns the default values for this look and feel.
+ *
+ * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
*/
public static UIDefaults getDefaults()
{
- return getLookAndFeel().getDefaults();
+ return currentUIDefaults;
}
/**
@@ -289,7 +395,7 @@ public class UIManager implements Serializable
*/
public static Dimension getDimension(Object key)
{
- return (Dimension) getLookAndFeel().getDefaults().get(key);
+ return (Dimension) getLookAndFeelDefaults().get(key);
}
/**
@@ -297,7 +403,7 @@ public class UIManager implements Serializable
*/
public static Dimension getDimension(Object key, Locale locale)
{
- return (Dimension) getLookAndFeel().getDefaults().get(key, locale);
+ return (Dimension) getLookAndFeelDefaults().get(key, locale);
}
/**
@@ -310,7 +416,7 @@ public class UIManager implements Serializable
*/
public static Font getFont(Object key)
{
- return (Font) getLookAndFeel().getDefaults().get(key);
+ return (Font) getLookAndFeelDefaults().get(key);
}
/**
@@ -323,7 +429,7 @@ public class UIManager implements Serializable
*/
public static Font getFont(Object key, Locale locale)
{
- return (Font) getLookAndFeel().getDefaults().get(key ,locale);
+ return (Font) getLookAndFeelDefaults().get(key ,locale);
}
/**
@@ -331,7 +437,7 @@ public class UIManager implements Serializable
*/
public static Icon getIcon(Object key)
{
- return (Icon) getLookAndFeel().getDefaults().get(key);
+ return (Icon) getLookAndFeelDefaults().get(key);
}
/**
@@ -339,7 +445,7 @@ public class UIManager implements Serializable
*/
public static Icon getIcon(Object key, Locale locale)
{
- return (Icon) getLookAndFeel().getDefaults().get(key, locale);
+ return (Icon) getLookAndFeelDefaults().get(key, locale);
}
/**
@@ -347,7 +453,7 @@ public class UIManager implements Serializable
*/
public static Insets getInsets(Object key)
{
- return (Insets) getLookAndFeel().getDefaults().getInsets(key);
+ return getLookAndFeelDefaults().getInsets(key);
}
/**
@@ -355,9 +461,15 @@ public class UIManager implements Serializable
*/
public static Insets getInsets(Object key, Locale locale)
{
- return (Insets) getLookAndFeel().getDefaults().getInsets(key, locale);
+ return getLookAndFeelDefaults().getInsets(key, locale);
}
+ /**
+ * Returns an array containing information about the {@link LookAndFeel}s
+ * that are installed.
+ *
+ * @return A list of the look and feels that are available (installed).
+ */
public static LookAndFeelInfo[] getInstalledLookAndFeels()
{
return installed;
@@ -365,7 +477,7 @@ public class UIManager implements Serializable
public static int getInt(Object key)
{
- Integer x = (Integer) getLookAndFeel().getDefaults().get(key);
+ Integer x = (Integer) getLookAndFeelDefaults().get(key);
if (x == null)
return 0;
return x.intValue();
@@ -373,24 +485,33 @@ public class UIManager implements Serializable
public static int getInt(Object key, Locale locale)
{
- Integer x = (Integer) getLookAndFeel().getDefaults().get(key, locale);
+ Integer x = (Integer) getLookAndFeelDefaults().get(key, locale);
if (x == null)
return 0;
return x.intValue();
}
+ /**
+ * Returns the current look and feel (which may be null
).
+ *
+ * @return The current look and feel.
+ *
+ * @see #setLookAndFeel(LookAndFeel)
+ */
public static LookAndFeel getLookAndFeel()
{
- return look_and_feel;
+ return currentLookAndFeel;
}
/**
* Returns the UIDefaults
table of the currently active
* look and feel.
+ *
+ * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
*/
public static UIDefaults getLookAndFeelDefaults()
{
- return getLookAndFeel().getDefaults();
+ return currentUIDefaults;
}
/**
@@ -398,7 +519,7 @@ public class UIManager implements Serializable
*/
public static String getString(Object key)
{
- return (String) getLookAndFeel().getDefaults().get(key);
+ return (String) getLookAndFeelDefaults().get(key);
}
/**
@@ -406,13 +527,17 @@ public class UIManager implements Serializable
*/
public static String getString(Object key, Locale locale)
{
- return (String) getLookAndFeel().getDefaults().get(key, locale);
+ return (String) getLookAndFeelDefaults().get(key, locale);
}
/**
- * Returns the name of the LookAndFeel class that implements the
+ * Returns the name of the {@link LookAndFeel} class that implements the
* native systems look and feel if there is one, otherwise the name
* of the default cross platform LookAndFeel class.
+ *
+ * @return The fully qualified class name for the system look and feel.
+ *
+ * @see #getCrossPlatformLookAndFeelClassName()
*/
public static String getSystemLookAndFeelClassName()
{
@@ -420,18 +545,26 @@ public class UIManager implements Serializable
}
/**
- * Returns the Look and Feel object that renders the target component.
+ * Returns UI delegate from the current {@link LookAndFeel} that renders the
+ * target component.
+ *
+ * @param target the target component.
*/
public static ComponentUI getUI(JComponent target)
{
- return getDefaults().getUI(target);
+ return getLookAndFeelDefaults().getUI(target);
}
/**
* Creates a new look and feel and adds it to the current array.
+ *
+ * @param name the look and feel name.
+ * @param className the fully qualified name of the class that implements the
+ * look and feel.
*/
public static void installLookAndFeel(String name, String className)
{
+ installLookAndFeel(new LookAndFeelInfo(name, className));
}
/**
@@ -440,6 +573,7 @@ public class UIManager implements Serializable
*/
public static void installLookAndFeel(LookAndFeelInfo info)
{
+ // FIXME: not yet implemented
}
/**
@@ -447,7 +581,7 @@ public class UIManager implements Serializable
*/
public static Object put(Object key, Object value)
{
- return getLookAndFeel().getDefaults().put(key,value);
+ return getLookAndFeelDefaults().put(key,value);
}
/**
@@ -455,32 +589,56 @@ public class UIManager implements Serializable
*/
public static void setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
{
+ // FIXME: not yet implemented.
}
/**
- * Set the current default look.
+ * Sets the current {@link LookAndFeel}.
+ *
+ * @param newLookAndFeel the new look and feel (null
permitted).
+ *
+ * @throws UnsupportedLookAndFeelException if the look and feel is not
+ * supported on the current platform.
+ *
+ * @see LookAndFeel#isSupportedLookAndFeel()
*/
public static void setLookAndFeel(LookAndFeel newLookAndFeel)
throws UnsupportedLookAndFeelException
{
- if (! newLookAndFeel.isSupportedLookAndFeel())
+ if (newLookAndFeel != null && ! newLookAndFeel.isSupportedLookAndFeel())
throw new UnsupportedLookAndFeelException(newLookAndFeel.getName());
- if (look_and_feel != null)
- look_and_feel.uninitialize();
+ LookAndFeel oldLookAndFeel = currentLookAndFeel;
+ if (oldLookAndFeel != null)
+ oldLookAndFeel.uninitialize();
// Set the current default look and feel using a LookAndFeel object.
- look_and_feel = newLookAndFeel;
- look_and_feel.initialize();
-
+ currentLookAndFeel = newLookAndFeel;
+ if (newLookAndFeel != null)
+ {
+ newLookAndFeel.initialize();
+ currentUIDefaults = newLookAndFeel.getDefaults();
+ }
+ else
+ {
+ currentUIDefaults = null;
+ }
+ listeners.firePropertyChange("lookAndFeel", oldLookAndFeel, newLookAndFeel);
//revalidate();
//repaint();
}
/**
* Set the current default look and feel using a class name.
+ *
+ * @param className the look and feel class name.
+ *
+ * @throws UnsupportedLookAndFeelException if the look and feel is not
+ * supported on the current platform.
+ *
+ * @see LookAndFeel#isSupportedLookAndFeel()
*/
- public static void setLookAndFeel (String className)
+ public static void setLookAndFeel(String className)
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException
{
diff --git a/libjava/classpath/javax/swing/ViewportLayout.java b/libjava/classpath/javax/swing/ViewportLayout.java
index 18b4912..1973583 100644
--- a/libjava/classpath/javax/swing/ViewportLayout.java
+++ b/libjava/classpath/javax/swing/ViewportLayout.java
@@ -69,7 +69,11 @@ public class ViewportLayout implements LayoutManager, Serializable
JViewport vp = (JViewport)parent;
Component view = vp.getView();
if (view != null)
- return view.getPreferredSize();
+ {
+ if (view instanceof Scrollable)
+ return ((Scrollable)view).getPreferredScrollableViewportSize();
+ return view.getPreferredSize();
+ }
else
return new Dimension();
}
@@ -120,7 +124,7 @@ public class ViewportLayout implements LayoutManager, Serializable
JViewport port = (JViewport) parent;
Component view = port.getView();
-
+
if (view == null)
return;
@@ -139,7 +143,8 @@ public class ViewportLayout implements LayoutManager, Serializable
if (portBounds.height >= viewMinimum.height)
{
portBounds.y = 0;
- viewPref.height = portBounds.height;
+ if ( !(view instanceof Scrollable) || ((Scrollable)view).getScrollableTracksViewportHeight())
+ viewPref.height = portBounds.height;
}
else
{
@@ -153,7 +158,8 @@ public class ViewportLayout implements LayoutManager, Serializable
if (portBounds.width >= viewMinimum.width)
{
portBounds.x = 0;
- viewPref.width = portBounds.width;
+ if ( !(view instanceof Scrollable) || ((Scrollable)view).getScrollableTracksViewportWidth())
+ viewPref.width = portBounds.width;
}
else
{
diff --git a/libjava/classpath/javax/swing/border/AbstractBorder.java b/libjava/classpath/javax/swing/border/AbstractBorder.java
index d755b67..951debd 100644
--- a/libjava/classpath/javax/swing/border/AbstractBorder.java
+++ b/libjava/classpath/javax/swing/border/AbstractBorder.java
@@ -118,7 +118,7 @@ public abstract class AbstractBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets (Component c, Insets insets)
{
diff --git a/libjava/classpath/javax/swing/border/BevelBorder.java b/libjava/classpath/javax/swing/border/BevelBorder.java
index e755fdc..fcdc1c6 100644
--- a/libjava/classpath/javax/swing/border/BevelBorder.java
+++ b/libjava/classpath/javax/swing/border/BevelBorder.java
@@ -172,7 +172,7 @@ public class BevelBorder
* @throws NullPointerException if highlight
or
* shadow
is null
.
*
- * @see java.awt.Color.brighter()
+ * @see java.awt.Color#brighter()
*/
public BevelBorder(int bevelType, Color highlight, Color shadow)
{
@@ -289,7 +289,7 @@ public class BevelBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c, Insets insets)
{
diff --git a/libjava/classpath/javax/swing/border/EtchedBorder.java b/libjava/classpath/javax/swing/border/EtchedBorder.java
index ea2a61d..0bd76ff 100644
--- a/libjava/classpath/javax/swing/border/EtchedBorder.java
+++ b/libjava/classpath/javax/swing/border/EtchedBorder.java
@@ -246,7 +246,7 @@ public class EtchedBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c, Insets insets)
{
diff --git a/libjava/classpath/javax/swing/border/LineBorder.java b/libjava/classpath/javax/swing/border/LineBorder.java
index 00c1634..c34e38c 100644
--- a/libjava/classpath/javax/swing/border/LineBorder.java
+++ b/libjava/classpath/javax/swing/border/LineBorder.java
@@ -287,7 +287,7 @@ public class LineBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c, Insets insets)
{
diff --git a/libjava/classpath/javax/swing/border/SoftBevelBorder.java b/libjava/classpath/javax/swing/border/SoftBevelBorder.java
index fa718e3..379ecb6 100644
--- a/libjava/classpath/javax/swing/border/SoftBevelBorder.java
+++ b/libjava/classpath/javax/swing/border/SoftBevelBorder.java
@@ -120,7 +120,7 @@ public class SoftBevelBorder
* @throws NullPointerException if highlight
or
* shadow
is null
.
*
- * @see java.awt.Color.brighter()
+ * @see java.awt.Color#brighter()
*/
public SoftBevelBorder(int bevelType, Color highlight, Color shadow)
{
@@ -235,7 +235,7 @@ public class SoftBevelBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c, Insets insets)
{
diff --git a/libjava/classpath/javax/swing/border/TitledBorder.java b/libjava/classpath/javax/swing/border/TitledBorder.java
index 30e4bcd..ceae2b1 100644
--- a/libjava/classpath/javax/swing/border/TitledBorder.java
+++ b/libjava/classpath/javax/swing/border/TitledBorder.java
@@ -675,7 +675,7 @@ public class TitledBorder
*
* @return the same object that was passed for insets
.
*
- * @see #getBorderInsets()
+ * @see #getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c, Insets insets)
{
@@ -1117,7 +1117,7 @@ public class TitledBorder
/**
* Determines the insets of the nested component when it has a
* TitledBorder as its border. Used by {@link
- * TitledBorder#getBorderInsets()}.
+ * TitledBorder#getBorderInsets(Component, Insets)}.
*
* @param i an Insets object for storing the results into, or
* null
to cause the creation of a
@@ -1140,7 +1140,7 @@ public class TitledBorder
/**
* Calculates the minimum size needed for displaying the border
- * and its title. Used by {@link TitledBorder#getMiminumSize()}.
+ * and its title. Used by {@link TitledBorder#getMinimumSize(Component)}.
*/
public Dimension getMinimumSize()
{
diff --git a/libjava/classpath/javax/swing/event/DocumentEvent.java b/libjava/classpath/javax/swing/event/DocumentEvent.java
index 6a005ea..6cd8e61 100644
--- a/libjava/classpath/javax/swing/event/DocumentEvent.java
+++ b/libjava/classpath/javax/swing/event/DocumentEvent.java
@@ -1,5 +1,5 @@
/* DocumentEvent.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,47 +45,38 @@ import javax.swing.text.Element;
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public interface DocumentEvent {
-
- //-------------------------------------------------------------
- // Classes ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * ElementChange public interface
- */
- public interface ElementChange {
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * getIndex
- * @returns int
- */
- int getIndex();
-
- /**
- * getElement
- * @returns Element
- */
- Element getElement();
-
- /**
- * getChildrenRemoved
- * @returns Element[]
- */
- Element[] getChildrenRemoved();
+public interface DocumentEvent
+{
+ /**
+ * ElementChange public interface
+ */
+ public static interface ElementChange
+ {
+ /**
+ * getIndex
+ * @returns int
+ */
+ int getIndex();
- /**
- * getChildrenAdded
- * @returns Element[]
- */
- Element[] getChildrenAdded();
+ /**
+ * getElement
+ * @returns Element
+ */
+ Element getElement();
+ /**
+ * getChildrenRemoved
+ * @returns Element[]
+ */
+ Element[] getChildrenRemoved();
- } // ElementChange
+ /**
+ * getChildrenAdded
+ * @returns Element[]
+ */
+ Element[] getChildrenAdded();
+
+ }
/**
* EventType
@@ -131,36 +122,35 @@ public interface DocumentEvent {
}
}
- /**
- * getType
- * @returns EventType
- */
- EventType getType();
-
- /**
- * getOffset
- * @returns int
- */
- int getOffset();
-
- /**
- * getLength
- * @returns int
- */
- int getLength();
-
- /**
- * getDocument
- * @returns Document
- */
- Document getDocument();
-
- /**
- * getChange
- * @param element TODO
- * @returns ElementChange
- */
- ElementChange getChange(Element element);
-
-
-} // DocumentEvent
+ /**
+ * getType
+ * @returns EventType
+ */
+ EventType getType();
+
+ /**
+ * getOffset
+ * @returns int
+ */
+ int getOffset();
+
+ /**
+ * getLength
+ * @returns int
+ */
+ int getLength();
+
+ /**
+ * getDocument
+ * @returns Document
+ */
+ Document getDocument();
+
+ /**
+ * getChange
+ * @param element TODO
+ * @returns ElementChange
+ */
+ ElementChange getChange(Element element);
+
+}
diff --git a/libjava/classpath/javax/swing/event/EventListenerList.java b/libjava/classpath/javax/swing/event/EventListenerList.java
index ea14d4d..3b9f4c8 100644
--- a/libjava/classpath/javax/swing/event/EventListenerList.java
+++ b/libjava/classpath/javax/swing/event/EventListenerList.java
@@ -133,7 +133,7 @@ public class EventListenerList
* @throws IllegalArgumentException if listener
is not
* an instance of t
(or a subclass thereof).
*
- * @throws Exception if t
is null
.
+ * @throws NullPointerException if t
is null
.
*/
public void add(Class t, EventListener listener)
{
@@ -246,7 +246,7 @@ public class EventListenerList
* @throws IllegalArgumentException if listener
is not
* an instance of t
(or a subclass thereof).
*
- * @throws Exception if t
is null
.
+ * @throws NullPointerException if t
is null
.
*/
public void remove(Class t, EventListener listener)
{
diff --git a/libjava/classpath/javax/swing/event/MenuKeyEvent.java b/libjava/classpath/javax/swing/event/MenuKeyEvent.java
index 48fcb45..511cb22 100644
--- a/libjava/classpath/javax/swing/event/MenuKeyEvent.java
+++ b/libjava/classpath/javax/swing/event/MenuKeyEvent.java
@@ -76,7 +76,7 @@ public class MenuKeyEvent extends KeyEvent {
* @param when Time
* @param modifiers Modifier keys
* @param keyCode Key code
- * @param keyhar Key char
+ * @param keyChar Key char
* @param path Path
* @param manager MenuSelectionManager
*/
diff --git a/libjava/classpath/javax/swing/event/SwingPropertyChangeSupport.java b/libjava/classpath/javax/swing/event/SwingPropertyChangeSupport.java
index ddbb486..408ca95 100644
--- a/libjava/classpath/javax/swing/event/SwingPropertyChangeSupport.java
+++ b/libjava/classpath/javax/swing/event/SwingPropertyChangeSupport.java
@@ -1,5 +1,5 @@
/* SwingPropertyChangeSupport.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,217 +39,299 @@ package javax.swing.event;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeListenerProxy;
import java.beans.PropertyChangeSupport;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
+import java.util.ArrayList;
import java.util.EventListener;
import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
- * SwingPropertyChangeSupport
+ * Provides a mechanism for registering {@link PropertyChangeListener}s and
+ * forwarding {@link PropertyChangeEvent}s to those listeners.
+ *
* @author Andrew Selkirk
-*/
-public final class SwingPropertyChangeSupport
- extends PropertyChangeSupport {
+ */
+public final class SwingPropertyChangeSupport
+ extends PropertyChangeSupport
+{
private static final long serialVersionUID = 7162625831330845068L;
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * listeners
- */
- private transient EventListenerList listeners;
-
- /**
- * propertyListeners
- */
- private Hashtable propertyListeners;
-
- /**
- * source
- */
- private Object source;
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor SwingPropertyChangeSupport
- * @param source TODO
- */
- public SwingPropertyChangeSupport(Object source) {
- super(source);
- this.source = source;
- this.listeners = new EventListenerList();
- this.propertyListeners = new Hashtable();
- } // SwingPropertyChangeSupport()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * writeObject
- * @param stream TODO
- * @exception IOException TODO
- */
- private void writeObject(ObjectOutputStream stream) throws IOException {
- // TODO
- } // writeObject()
-
- /**
- * readObject
- * @param stream TODO
- * @exception ClassNotFoundException TODO
- * @exception IOException TODO
- */
- private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
- // TODO
- } // readObject()
-
- /**
- * addPropertyChangeListener
- * @param listener TODO
- */
- public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
- listeners.add(PropertyChangeListener.class, listener);
- } // addPropertyChangeListener()
-
- /**
- * addPropertyChangeListener
- * @param propertyName TODO
- * @param listener TODO
- */
- public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-
- // Variables
- EventListenerList list;
-
- // Get Listener list
- list = (EventListenerList) propertyListeners.get(propertyName);
- if (list == null) {
- list = new EventListenerList();
- propertyListeners.put(propertyName, list);
- } // if
-
- // Add Listeners
- list.add(PropertyChangeListener.class, listener);
-
- } // addPropertyChangeListener()
-
- /**
- * removePropertyChangeListener
- * @param listener TODO
- */
- public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
- listeners.remove(PropertyChangeListener.class, listener);
- } // removePropertyChangeListener()
-
- /**
- * removePropertyChangeListener
- * @param propertyName TODO
- * @param listener TODO
- */
- public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-
- // Variables
- EventListenerList list;
-
- // Get Listener list
- list = (EventListenerList) propertyListeners.get(propertyName);
- if (list == null) {
- return;
- } // if
-
- // Remove Listeners
- list.remove(PropertyChangeListener.class, listener);
-
- // Clean up propertyListeners
- if (list.getListenerCount() == 0) {
- propertyListeners.remove(propertyName);
- } // if
-
- } // removePropertyChangeListener()
-
- /**
- * firePropertyChange
- * @param propertyName TODO
- * @param oldValue TODO
- * @param newValue TODO
- */
- public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
-
- // Variables
- PropertyChangeEvent event;
-
- // Create Property Change Event
- event = new PropertyChangeEvent(source, propertyName, oldValue, newValue);
-
- // Fire Event
- firePropertyChange(event);
-
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- * @param event TODO
- */
- public void firePropertyChange(PropertyChangeEvent event) {
-
- // Variables
- EventListenerList list;
- EventListener[] listenerList;
- int index;
- PropertyChangeListener listener;
-
- // Check Values if they are equal
- if (event.getOldValue() == null && event.getNewValue() == null ||
- (event.getOldValue() != null && event.getNewValue() != null &&
- event.getOldValue().equals(event.getNewValue()))) {
- return;
- } // if
-
- // Process Main Listener List
- listenerList = listeners.getListeners(PropertyChangeListener.class);
- for (index = 0; index < listenerList.length; index++) {
- listener = (PropertyChangeListener) listenerList[index];
- listener.propertyChange(event);
- } // for
-
- // Process Property Listener List
- list = (EventListenerList) propertyListeners.get(event.getPropertyName());
- if (list != null) {
- listenerList = list.getListeners(PropertyChangeListener.class);
- for (index = 0; index < listenerList.length; index++) {
- listener = (PropertyChangeListener) listenerList[index];
- listener.propertyChange(event);
- } // for
- } // if
-
- } // firePropertyChange()
-
- /**
- * hasListeners
- * @param propertyName TODO
- * @returns boolean
- */
- public synchronized boolean hasListeners(String propertyName) {
-
- // Get Listener list
- if (propertyListeners.get(propertyName) == null) {
- return false;
- } // if
-
- return true;
-
- } // hasListeners()
-
-
-} // SwingPropertyChangeSupport
+ /**
+ * Storage for the listeners that are not linked to a specific property.
+ */
+ private transient EventListenerList listeners;
+
+ /**
+ * Storage for the listeners that are linked (by name) to a specific property.
+ * The hash table maps String
objects (the property names) to
+ * {@link EventListenerList} instances (which record the listener(s) for the
+ * given property).
+ */
+ private Hashtable propertyListeners;
+
+ /**
+ * The object that is used as the default source for the
+ * {@link PropertyChangeEvent}s generated by this class.
+ */
+ private Object source;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param source the source (null
not permitted).
+ *
+ * @throws NullPointerException if source
is null
.
+ */
+ public SwingPropertyChangeSupport(Object source)
+ {
+ super(source);
+ this.source = source;
+ this.listeners = new EventListenerList();
+ this.propertyListeners = new Hashtable();
+ }
+
+ /**
+ * Registers listener
to receive notification of any future
+ * {@link PropertyChangeEvent}s generated by this instance.
+ *
+ * @param listener the listener (null
is ignored).
+ *
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener
+ listener)
+ {
+ listeners.add(PropertyChangeListener.class, listener);
+ }
+
+ /**
+ * Registers listener
to receive notification of any future
+ * {@link PropertyChangeEvent}s generated by this instance for the named
+ * property.
+ *
+ * @param propertyName the property name.
+ * @param listener the listener.
+ *
+ * @see #removePropertyChangeListener(String, PropertyChangeListener)
+ */
+ public synchronized void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
+ EventListenerList list;
+ list = (EventListenerList) propertyListeners.get(propertyName);
+ if (list == null)
+ {
+ list = new EventListenerList();
+ propertyListeners.put(propertyName, list);
+ }
+ list.add(PropertyChangeListener.class, listener);
+ }
+
+ /**
+ * Removes listener
from the list of registered listeners, so
+ * that it will no longer receive notification of property change events.
+ *
+ * @param listener the listener to remove.
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener
+ listener)
+ {
+ listeners.remove(PropertyChangeListener.class, listener);
+ }
+
+ /**
+ * Removes listener
from the list of registered listeners for
+ * the named property, so that it will no longer receive notification of
+ * property change events.
+ *
+ * @param propertyName the property name.
+ * @param listener the listener to remove.
+ */
+ public synchronized void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
+ EventListenerList list;
+ list = (EventListenerList) propertyListeners.get(propertyName);
+ if (list == null)
+ return;
+ list.remove(PropertyChangeListener.class, listener);
+ if (list.getListenerCount() == 0)
+ {
+ propertyListeners.remove(propertyName);
+ }
+ }
+
+ /**
+ * Returns an array of the {@link PropertyChangeListener}s registered with
+ * this SwingPropertyChangeSupport
instance.
+ *
+ * @return The array of listeners.
+ *
+ * @since 1.4
+ */
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners()
+ {
+ // fetch the named listeners first so we know how many there are
+ List namedListeners = new ArrayList();
+ Set namedListenerEntries = propertyListeners.entrySet();
+ Iterator iterator = namedListenerEntries.iterator();
+ while (iterator.hasNext())
+ {
+ Map.Entry e = (Map.Entry) iterator.next();
+ String propertyName = (String) e.getKey();
+ EventListenerList ell = (EventListenerList) e.getValue();
+ if (ell != null)
+ {
+ Object[] list = ell.getListenerList();
+ for (int i = 0; i < list.length; i += 2)
+ {
+ namedListeners.add(new PropertyChangeListenerProxy(propertyName,
+ (PropertyChangeListener) list[i + 1]));
+ }
+ }
+ }
+
+ // create an array that can hold everything
+ int size = listeners.getListenerCount() + namedListeners.size();
+ PropertyChangeListener[] result = new PropertyChangeListener[size];
+
+ // copy in the general listeners
+ Object[] list = listeners.getListenerList();
+ int index = 0;
+ for (int i = 0; i < list.length; i += 2)
+ result[index++] = (PropertyChangeListener) list[i + 1];
+
+ // ...and the named listeners
+ Iterator iterator2 = namedListeners.iterator();
+ while (iterator2.hasNext())
+ result[index++] = (PropertyChangeListenerProxy) iterator2.next();
+
+ return result;
+ }
+
+ /**
+ * Returns an array of all listeners that are registered to receive
+ * notification of changes to the named property. This includes the general
+ * listeners as well as those registered specifically for the named
+ * property.
+ *
+ * @param propertyName the property name.
+ *
+ * @return An array of all listeners for the named property.
+ */
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+ String propertyName)
+ {
+ EventListenerList list
+ = (EventListenerList) propertyListeners.get(propertyName);
+ if (list == null)
+ return getPropertyChangeListeners();
+ int size = listeners.getListenerCount() + list.getListenerCount();
+ PropertyChangeListener[] result = new PropertyChangeListener[size];
+
+ // copy in the general listeners
+ int index = 0;
+ for (int i = 0; i < listeners.listenerList.length; i += 2)
+ {
+ result[index++]
+ = (PropertyChangeListener) listeners.listenerList[i + 1];
+ }
+
+ // copy in the specific listeners
+ Object[] specificListeners = list.getListenerList();
+ for (int i = 0; i < specificListeners.length; i += 2)
+ {
+ result[index++] = (PropertyChangeListener) specificListeners[i + 1];
+ }
+ return result;
+ }
+
+ /**
+ * Creates a new {@link PropertyChangeEvent} using the given arguments (and
+ * the default source
for this
+ * SwingPropertyChangeSupport
instance) and forwards it to all
+ * registered listeners via the
+ * {@link PropertyChangeListener#propertyChange(PropertyChangeEvent)} method.
+ * oldValue
and newValue
are non-null
+ * and equal, no listeners will be notified.
+ *
+ * @param propertyName the property name.
+ * @param oldValue the old value
+ * @param newValue the new value.
+ */
+ public void firePropertyChange(String propertyName, Object oldValue,
+ Object newValue)
+ {
+ PropertyChangeEvent event;
+ event = new PropertyChangeEvent(source, propertyName, oldValue, newValue);
+ firePropertyChange(event);
+ }
+
+ /**
+ * Forwards event
to registered listeners.
+ * getOldValue()
and
+ * getNewValue()
methods return non-null and equal values, no
+ * listeners will be notified.
+ *
+ * @param event the event.
+ */
+ public void firePropertyChange(PropertyChangeEvent event)
+ {
+ EventListenerList list;
+ EventListener[] listenerList;
+ int index;
+ PropertyChangeListener listener;
+
+ // Check Values if they are equal
+ if (event.getOldValue() == null && event.getNewValue() == null ||
+ (event.getOldValue() != null && event.getNewValue() != null &&
+ event.getOldValue().equals(event.getNewValue())))
+ return;
+
+ // Process Main Listener List
+ listenerList = listeners.getListeners(PropertyChangeListener.class);
+ for (index = 0; index < listenerList.length; index++)
+ {
+ listener = (PropertyChangeListener) listenerList[index];
+ listener.propertyChange(event);
+ }
+
+ // Process Property Listener List
+ list = (EventListenerList) propertyListeners.get(event.getPropertyName());
+ if (list != null)
+ {
+ listenerList = list.getListeners(PropertyChangeListener.class);
+ for (index = 0; index < listenerList.length; index++)
+ {
+ listener = (PropertyChangeListener) listenerList[index];
+ listener.propertyChange(event);
+ }
+ }
+
+ }
+
+ /**
+ * Tell whether the specified property is being listened on or not. This
+ * will only return true
if there are listeners on all
+ * properties or if there is a listener specifically on this property.
+ *
+ * @param propertyName the property that may be listened on
+ * @return whether the property is being listened on
+ * @throws NullPointerException if propertyName is null
+ */
+ public synchronized boolean hasListeners(String propertyName)
+ {
+ if (listeners.getListenerCount() > 0)
+ return true;
+ else
+ return (propertyListeners.get(propertyName) != null);
+ }
+
+}
diff --git a/libjava/classpath/javax/swing/event/TreeSelectionEvent.java b/libjava/classpath/javax/swing/event/TreeSelectionEvent.java
index df4e0ff..9b87667 100644
--- a/libjava/classpath/javax/swing/event/TreeSelectionEvent.java
+++ b/libjava/classpath/javax/swing/event/TreeSelectionEvent.java
@@ -100,8 +100,8 @@ public class TreeSelectionEvent extends EventObject {
/**
* Constructor TreeSelectionEvent
* @param source TODO
- * @param paths TODO
- * @param areNew TODO
+ * @param path TODO
+ * @param isNew TODO
* @param oldLeadSelectionPath TODO
* @param newLeadSelectionPath TODO
*/
diff --git a/libjava/classpath/javax/swing/plaf/BorderUIResource.java b/libjava/classpath/javax/swing/plaf/BorderUIResource.java
index 1bf8540..4402bbb 100644
--- a/libjava/classpath/javax/swing/plaf/BorderUIResource.java
+++ b/libjava/classpath/javax/swing/plaf/BorderUIResource.java
@@ -556,7 +556,7 @@ public class BorderUIResource
* @param shadow the color that will be used for painting
* the shadow part of the border.
*
- * @see #EtchedBorderUIResource(int, Color, Color)
+ * @see EtchedBorderUIResource#EtchedBorderUIResource(int, Color, Color)
*/
public EtchedBorderUIResource(Color highlight, Color shadow)
{
@@ -684,7 +684,7 @@ public class BorderUIResource
* @param left the width of the border at its left edge.
* @param bottom the width of the border at its bottom edge.
* @param right the width of the border at its right edge.
- * @param matteColor the color for filling the border.
+ * @param color the color for filling the border.
*/
public MatteBorderUIResource(int top, int left,
int bottom, int right,
diff --git a/libjava/classpath/javax/swing/plaf/FileChooserUI.java b/libjava/classpath/javax/swing/plaf/FileChooserUI.java
index 87847c4..8b661e3 100644
--- a/libjava/classpath/javax/swing/plaf/FileChooserUI.java
+++ b/libjava/classpath/javax/swing/plaf/FileChooserUI.java
@@ -98,7 +98,7 @@ public abstract class FileChooserUI
* @param chooser the JFileChooser
whose
* button text is requested.
*
- * @see javax.swing.JFileChoose#getApproveButtonText
+ * @see javax.swing.JFileChooser#getApproveButtonText
*/
public abstract String getApproveButtonText(JFileChooser chooser);
@@ -111,7 +111,7 @@ public abstract class FileChooserUI
* @param chooser the JFileChooser
whose
* dialog title is requested.
*
- * @see javax.swing.JFileChoose#getDialogtitle
+ * @see javax.swing.JFileChooser#getDialogTitle
*/
public abstract String getDialogTitle(JFileChooser chooser);
diff --git a/libjava/classpath/javax/swing/plaf/TextUI.java b/libjava/classpath/javax/swing/plaf/TextUI.java
index 86d1f1f..dcabdfc 100644
--- a/libjava/classpath/javax/swing/plaf/TextUI.java
+++ b/libjava/classpath/javax/swing/plaf/TextUI.java
@@ -40,6 +40,7 @@ package javax.swing.plaf;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.Shape;
import javax.swing.text.BadLocationException;
import javax.swing.text.EditorKit;
@@ -83,9 +84,7 @@ public abstract class TextUI
* @throws BadLocationException if pos
does not
* designate a valid position in the document model.
*
- * @see javax.swing.text.View#modelToView(int,
- * javax.swing.text.Position.Bias, int,
- * javax.swing.text.position.Bias, java.awt.Shape)
+ * @see javax.swing.text.ComponentView#modelToView(int, Shape, Position.Bias)
*/
public abstract Rectangle modelToView(JTextComponent tc, int pos)
throws BadLocationException;
@@ -113,9 +112,7 @@ public abstract class TextUI
* @throws BadLocationException if pos
does not
* designate a valid position in the document model.
*
- * @see javax.swing.text.View#modelToView(int,
- * javax.swing.text.Position.Bias, int,
- * javax.swing.text.position.Bias, java.awt.Shape)
+ * @see javax.swing.text.ComponentView#modelToView(int, Shape, Position.Bias)
*/
public abstract Rectangle modelToView(JTextComponent tc, int pos,
Position.Bias bias)
@@ -126,10 +123,10 @@ public abstract class TextUI
* Finds the caret position which is closest to the specified visual
* location.
*
- * @param tc the JTextComponent
for which this
+ * @param t the JTextComponent
for which this
* delegate object provides the user interface.
*
- * @param loc the position in view coordinates.
+ * @param pt the position in view coordinates.
*
* @return the caret position which is closest to loc
.
*
@@ -191,7 +188,7 @@ public abstract class TextUI
*
* @throws IllegalArgumentException if direction
* is not one of Position.Bias.Forward
- * or Position.Biad.Backward
.
+ * or Position.Bias.Backward
.
*/
public abstract int getNextVisualPositionFrom(JTextComponent tc,
int pos,
diff --git a/libjava/classpath/javax/swing/plaf/UIResource.java b/libjava/classpath/javax/swing/plaf/UIResource.java
index 1e28280..59edf56 100644
--- a/libjava/classpath/javax/swing/plaf/UIResource.java
+++ b/libjava/classpath/javax/swing/plaf/UIResource.java
@@ -40,7 +40,7 @@ package javax.swing.plaf;
/**
* This public interface is used to designate which objects were created by
- * ComponentUI
delegates. When uninstalling the user public interface
+ * {@link ComponentUI} delegates. When uninstalling the user public interface
* renderer with ComponentUI.uninstallUI()
the renderer
* property is set to null
.
*
@@ -50,6 +50,6 @@ package javax.swing.plaf;
* they are initialized or set to null
.
*
* @author Brian Jones
- * @see java.lang.ComponentUI
+ * @see ComponentUI
*/
public interface UIResource { }
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java
index 4da4691..836ef22 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java
@@ -56,7 +56,7 @@ import javax.swing.border.Border;
public class BasicArrowButton extends JButton implements SwingConstants
{
/** The default size of the Arrow buttons. */
- private static int defaultSize = 10;
+ private static int defaultSize = 12;
/** The Polygon that points up. */
private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
index d893c5d..6c80f14 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
@@ -115,21 +115,21 @@ public class BasicButtonUI extends ButtonUI
*/
protected String getPropertyPrefix()
{
- return "Button";
+ return "Button.";
}
protected void installDefaults(AbstractButton b)
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
String prefix = getPropertyPrefix();
- focusColor = defaults.getColor(prefix + ".focus");
- b.setForeground(defaults.getColor(prefix + ".foreground"));
- b.setBackground(defaults.getColor(prefix + ".background"));
- b.setMargin(defaults.getInsets(prefix + ".margin"));
- b.setBorder(defaults.getBorder(prefix + ".border"));
- b.setIconTextGap(defaults.getInt(prefix + ".textIconGap"));
+ focusColor = defaults.getColor(prefix + "focus");
+ b.setForeground(defaults.getColor(prefix + "foreground"));
+ b.setBackground(defaults.getColor(prefix + "background"));
+ b.setMargin(defaults.getInsets(prefix + "margin"));
+ b.setBorder(defaults.getBorder(prefix + "border"));
+ b.setIconTextGap(defaults.getInt(prefix + "textIconGap"));
b.setInputMap(JComponent.WHEN_FOCUSED,
- (InputMap) defaults.get(prefix + ".focusInputMap"));
+ (InputMap) defaults.get(prefix + "focusInputMap"));
b.setOpaque(true);
}
@@ -285,7 +285,8 @@ public class BasicButtonUI extends ButtonUI
paintIcon(g, c, ir);
if (text != null)
paintText(g, b, tr, text);
- paintFocus(g, b, vr, tr, ir);
+ if (b.isFocusOwner())
+ paintFocus(g, b, vr, tr, ir);
}
/**
@@ -306,15 +307,8 @@ public class BasicButtonUI extends ButtonUI
protected void paintFocus(Graphics g, AbstractButton b, Rectangle vr,
Rectangle tr, Rectangle ir)
{
- if (b.hasFocus() && b.isFocusPainted())
- {
- Color saved_color = g.getColor();
- g.setColor(focusColor);
- Rectangle focusRect = ir.union(tr);
- g.drawRect(focusRect.x, focusRect.y,
- focusRect.width, focusRect.height);
- g.setColor(saved_color);
- }
+ // In the BasicLookAndFeel no focus border is drawn. This can be
+ // overridden in subclasses to implement such behaviour.
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
index da11898..945aea5 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
@@ -67,13 +67,13 @@ public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
}
/**
- * DOCUMENT ME!
+ * Returns the prefix for entries in the {@link UIDefaults} table.
*
- * @return $returnType$ DOCUMENT ME!
+ * @return "CheckBoxMenuItem"
*/
protected String getPropertyPrefix()
{
- return null;
+ return "CheckBoxMenuItem";
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java
index e316732..3cf02a0 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java
@@ -57,14 +57,14 @@ public class BasicCheckBoxUI extends BasicRadioButtonUI
return defaults.getIcon("CheckBox.icon");
}
- public void installUI(final JComponent c) {
- super.installUI(c);
- }
-
- // Overridden to change method access.
+ /**
+ * Returns the prefix for entries in the {@link UIDefaults} table.
+ *
+ * @return "CheckBox."
+ */
public String getPropertyPrefix()
{
- return super.getPropertyPrefix();
+ return "CheckBox.";
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxEditor.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxEditor.java
index 04296df..dd867f0 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxEditor.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxEditor.java
@@ -91,7 +91,10 @@ public class BasicComboBoxEditor extends Object implements ComboBoxEditor,
*/
public void setItem(Object item)
{
- editor.setText(item.toString());
+ if (item == null)
+ editor.setText("");
+ else
+ editor.setText(item.toString());
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java
index b15700d..b59261b 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java
@@ -363,7 +363,7 @@ public class BasicDesktopPaneUI extends DesktopPaneUI
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- desktop.setBackground(defaults.getColor("Desktop.background"));
+ desktop.setBackground(defaults.getColor("desktop"));
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java
index 6dd15a8..d5b34d9 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java
@@ -39,30 +39,69 @@ exception statement from your version. */
package javax.swing.plaf.basic;
import javax.swing.JComponent;
+import javax.swing.JEditorPane;
import javax.swing.plaf.ComponentUI;
+import javax.swing.text.EditorKit;
import javax.swing.text.Element;
+import javax.swing.text.JTextComponent;
import javax.swing.text.PlainView;
import javax.swing.text.View;
+/**
+ * The UI class for {@link JEditorPane}s.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class BasicEditorPaneUI extends BasicTextUI
{
+ /**
+ * Creates an instance of BasicEditorPaneUI
for the text
+ * component comp
.
+ *
+ * @param comp the component for which to create an UI
+ *
+ * @return the UI for comp
+ */
public static ComponentUI createUI(JComponent comp)
{
return new BasicEditorPaneUI();
}
+ /**
+ * Creates a new BasicEditorPaneUI
+ */
public BasicEditorPaneUI()
{
// Do nothing here.
}
+ // FIXME: Should not be overridden here but instead be handled by the
+ // JEditorPane's EditorKit. However, as long as we don't have styles in
+ // place this doesn't make much sense.
public View create(Element elem)
{
return new PlainView(elem);
}
+ /**
+ * Returns the property prefix to be used by this UI class. This is
+ * EditorPane
in this case.
+ *
+ * @return EditorPane
+ */
protected String getPropertyPrefix()
{
return "EditorPane";
}
+
+ /**
+ * Gets the EditorKit for the text component.
+ *
+ * @param textComponent the text component for which to fetch the editor kit
+ */
+ public EditorKit getEditorKit(JTextComponent textComponent)
+ {
+ return ((JEditorPane) textComponent).getEditorKit();
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
index fd34fbd..f74e922 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
@@ -1090,7 +1090,9 @@ public class BasicFileChooserUI extends FileChooserUI
}
// FIXME: Indent the entries in the combobox
- private void boxEntries()
+ // Made this method package private to access it from within inner classes
+ // with better performance
+ void boxEntries()
{
ArrayList parentFiles = new ArrayList();
File parent = filechooser.getCurrentDirectory();
@@ -1098,12 +1100,12 @@ public class BasicFileChooserUI extends FileChooserUI
parent = filechooser.getFileSystemView().getDefaultDirectory();
while (parent != null)
{
- String name = parent.getName();
- if (name.equals(""))
- name = parent.getAbsolutePath();
+ String name = parent.getName();
+ if (name.equals(""))
+ name = parent.getAbsolutePath();
- parentFiles.add(parentFiles.size(), name);
- parent = parent.getParentFile();
+ parentFiles.add(parentFiles.size(), name);
+ parent = parent.getParentFile();
}
if (parentFiles.size() == 0)
@@ -1509,12 +1511,12 @@ public class BasicFileChooserUI extends FileChooserUI
}
else if (e.getPropertyName().equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
{
- //boxEntries();
filelist.clearSelection();
filelist.revalidate();
filelist.repaint();
setDirectorySelected(false);
setDirectory(filechooser.getCurrentDirectory());
+ boxEntries();
}
else if (e.getPropertyName().equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)
|| e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java b/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
index 78ee62f..757ac47 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
@@ -609,7 +609,7 @@ public class BasicGraphicsUtils
* LineMetrics, not a FontMetrics argument. But fixing this that
* would change the public API.
*/
- SwingUtilities.layoutCompoundLabel(
+ SwingUtilities.layoutCompoundLabel(
b, // for the component orientation
b.getToolkit().getFontMetrics(b.getFont()), // see comment above
b.getText(),
@@ -630,10 +630,10 @@ public class BasicGraphicsUtils
*/
contentRect = textRect.union(iconRect);
-
+
return new Dimension(insets.left
+ contentRect.width
- + insets.right,
+ + insets.right + b.getHorizontalAlignment(),
insets.top
+ contentRect.height
+ insets.bottom);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java
index e7aad89..56a67b0 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java
@@ -1,5 +1,5 @@
/* BasicIconFactory.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,13 +44,11 @@ import java.awt.Graphics;
import java.awt.Polygon;
import java.io.Serializable;
-import javax.swing.AbstractButton;
import javax.swing.Icon;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
+import javax.swing.JCheckBoxMenuItem;
/**
- * STUBBED
+ * Creates icons for the {@link BasicLookAndFeel}.
*/
public class BasicIconFactory implements Serializable
{
@@ -70,13 +68,174 @@ public class BasicIconFactory implements Serializable
}
}
+ /**
+ * The icon used for CheckBoxes in the BasicLookAndFeel. This is an empty
+ * icon with a size of 13x13 pixels.
+ */
+ static class CheckBoxIcon
+ implements Icon
+ {
+ /**
+ * Returns the height of the icon. The BasicLookAndFeel CheckBox icon
+ * has a height of 13 pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconHeight()
+ {
+ return 13;
+ }
- public BasicIconFactory()
+ /**
+ * Returns the width of the icon. The BasicLookAndFeel CheckBox icon
+ * has a width of 13 pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconWidth()
+ {
+ return 13;
+ }
+
+ /**
+ * Paints the icon. The BasicLookAndFeel CheckBox icon is empty and does
+ * not need to be painted.
+ *
+ * @param c the component to be painted
+ * @param g the Graphics context to be painted with
+ * @param x the x position of the icon
+ * @param y the y position of the icon
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ // The icon is empty and needs no painting.
+ }
+ }
+
+ /**
+ * The icon used for {@link JCheckBoxMenuItem}s in the
+ * {@link BasicLookAndFeel}. This icon has a size of 9x9 pixels.
+ */
+ static class CheckBoxMenuItemIcon
+ implements Icon
{
+ /**
+ * Returns the height of the icon in pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconHeight()
+ {
+ return 9;
+ }
+
+ /**
+ * Returns the width of the icon in pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconWidth()
+ {
+ return 9;
+ }
+
+ /**
+ * Paints the icon.
+ *
+ * @param c the component to be painted
+ * @param g the Graphics context to be painted with
+ * @param x the x position of the icon
+ * @param y the y position of the icon
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) c;
+ if (item.isSelected())
+ {
+ // paint the check...
+ g.setColor(Color.black);
+ g.drawLine(x + 1, y + 3, x + 1, y + 4);
+ g.drawLine(x + 2, y + 4, x + 2, y + 5);
+ for (int i = 0; i < 5; i++)
+ g.drawLine(x + 3 + i, y + 5 - i, x + 3 + i, y + 6 - i);
+ }
+ }
}
+
+ /**
+ * The icon used for RadioButtons in the BasicLookAndFeel. This is an empty
+ * icon with a size of 13x13 pixels.
+ */
+ static class RadioButtonIcon
+ implements Icon
+ {
+ /**
+ * Returns the height of the icon. The BasicLookAndFeel RadioButton icon
+ * has a height of 13 pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconHeight()
+ {
+ return 13;
+ }
+
+ /**
+ * Returns the width of the icon. The BasicLookAndFeel RadioButton icon
+ * has a width of 13 pixels.
+ *
+ * @return the height of the icon
+ */
+ public int getIconWidth()
+ {
+ return 13;
+ }
+
+ /**
+ * Paints the icon. The BasicLookAndFeel RadioButton icon is empty and does
+ * not need to be painted.
+ *
+ * @param c the component to be painted
+ * @param g the Graphics context to be painted with
+ * @param x the x position of the icon
+ * @param y the y position of the icon
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ // The icon is empty and needs no painting.
+ }
+ }
+ /** The cached CheckBoxIcon instance. */
+ private static CheckBoxIcon checkBoxIcon;
+
+ /** The cached RadioButtonIcon instance. */
+ private static RadioButtonIcon radioButtonIcon;
+
public static Icon getMenuItemCheckIcon()
{
- return new DummyIcon();
+ return new Icon()
+ {
+ public int getIconHeight()
+ {
+ return 13;
+ }
+
+ public int getIconWidth()
+ {
+ return 13;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color saved = g.getColor();
+ g.setColor(Color.BLACK);
+ g.drawLine(3 + x, 5 + y, 3 + x, 9 + y);
+ g.drawLine(4 + x, 5 + y, 4 + x, 9 + y);
+ g.drawLine(5 + x, 7 + y, 9 + x, 3 + y);
+ g.drawLine(5 + x, 8 + y, 9 + x, 4 + y);
+ g.setColor(saved);
+ }
+ };
}
public static Icon getMenuItemArrowIcon()
{
@@ -114,123 +273,50 @@ public class BasicIconFactory implements Serializable
};
}
+ /**
+ * Returns an icon for CheckBoxes in the BasicLookAndFeel. CheckBox icons
+ * in the Basic L&F are empty and have a size of 13x13 pixels.
+ * This method returns a shared single instance of this icon.
+ *
+ * @return an icon for CheckBoxes in the BasicLookAndFeel
+ */
public static Icon getCheckBoxIcon()
{
- return new Icon()
- {
- public int getIconHeight()
- {
- return 10;
- }
- public int getIconWidth()
- {
- return 10;
- }
- public void paintIcon(Component c, Graphics g, int x, int y)
- {
- if (c instanceof AbstractButton)
- {
- UIDefaults defaults;
- defaults = UIManager.getLookAndFeelDefaults();
- Color hi = defaults.getColor("CheckBox.highlight");
- Color low = defaults.getColor("CheckBox.darkShadow");
- Color sel = defaults.getColor("CheckBox.foreground");
- Color dim = defaults.getColor("CheckBox.shadow");
- Polygon check = new Polygon(new int[] {x+3, x+3, x+8},
- new int[] {y+5, y+9, y+3}, 3);
- AbstractButton b = (AbstractButton) c;
- Color saved = g.getColor();
- if (b.isEnabled())
- {
- g.setColor(low);
- g.drawRect(x, y, 10, 10);
- g.setColor(hi);
- g.drawRect(x+1, y+1, 10, 10);
- if (b.isSelected())
- {
- g.setColor(sel);
- if (b.isSelected())
- {
- g.drawLine(x+3, y+5, x+3, y+8);
- g.drawLine(x+4, y+5, x+4, y+8);
- g.drawLine(x+3, y+8, x+8, y+3);
- g.drawLine(x+4, y+8, x+8, y+3);
- }
- }
- }
- else
- {
- g.setColor(hi);
- g.drawRect(x, y, 10, 10);
- if (b.isSelected())
- {
- g.drawLine(x+3, y+5, x+3, y+9);
- g.drawLine(x+3, y+9, x+8, y+3);
- }
- }
- g.setColor(saved);
- }
- }
- };
+ if (checkBoxIcon == null)
+ checkBoxIcon = new CheckBoxIcon();
+ return checkBoxIcon;
}
+ /**
+ * Returns an icon for RadioButtons in the BasicLookAndFeel. RadioButton
+ * icons in the Basic L&F are empty and have a size of 13x13 pixels.
+ * This method returns a shared single instance of this icon.
+ *
+ * @return an icon for RadioButtons in the BasicLookAndFeel
+ */
public static Icon getRadioButtonIcon()
{
- return new Icon()
- {
- public int getIconHeight()
- {
- return 12;
- }
- public int getIconWidth()
- {
- return 12;
- }
- public void paintIcon(Component c, Graphics g, int x, int y)
- {
- UIDefaults defaults;
- defaults = UIManager.getLookAndFeelDefaults();
- Color hi = defaults.getColor("RadioButton.highlight");
- Color low = defaults.getColor("RadioButton.darkShadow");
- Color sel = defaults.getColor("RadioButton.foreground");
- Color dim = defaults.getColor("RadioButton.shadow");
-
- if (c instanceof AbstractButton)
- {
- AbstractButton b = (AbstractButton) c;
- Color saved = g.getColor();
- if (b.isEnabled())
- {
- g.setColor(low);
- g.drawOval(x, y, 12, 12);
- g.setColor(hi);
- g.drawOval(x+1, y+1, 12, 12);
- if (b.isSelected())
- {
- g.setColor(sel);
- g.fillOval(x+4, y+4, 6, 6);
- }
- }
- else
- {
- g.setColor(hi);
- g.drawOval(x, y, 12, 12);
- if (b.isSelected())
- g.fillOval(x+4, y+4, 6, 6);
- }
- g.setColor(saved);
- }
- }
- };
+ if (radioButtonIcon == null)
+ radioButtonIcon = new RadioButtonIcon();
+ return radioButtonIcon;
}
+
+ /**
+ * Creates and returns an icon used when rendering {@link JCheckBoxMenuItem}
+ * components.
+ *
+ * @return An icon.
+ */
public static Icon getCheckBoxMenuItemIcon()
{
- return getCheckBoxIcon();
+ return new CheckBoxMenuItemIcon();
}
+
public static Icon getRadioButtonMenuItemIcon()
{
return getRadioButtonIcon();
}
+
public static Icon createEmptyFrameIcon()
{
return new DummyIcon();
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
index 91db0cb..cc26294 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
@@ -47,7 +47,6 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
-import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -514,18 +513,6 @@ public class BasicInternalFrameTitlePane extends JComponent
/** The button that maximizes the JInternalFrame. */
protected JButton maxButton;
- /** Active background color. */
- protected Color activeBGColor;
-
- /** Active foreground color. */
- protected Color activeFGColor;
-
- /** Inactive background color. */
- protected Color inactiveBGColor;
-
- /** Inactive foreground color. */
- protected Color inactiveFGColor;
-
/** The icon displayed in the restore button. */
protected Icon minIcon = BasicIconFactory.createEmptyFrameIcon();
@@ -592,6 +579,7 @@ public class BasicInternalFrameTitlePane extends JComponent
setOpaque(true);
setBackground(Color.LIGHT_GRAY);
+ setOpaque(true);
installTitlePane();
}
@@ -679,10 +667,10 @@ public class BasicInternalFrameTitlePane extends JComponent
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
setFont(defaults.getFont("InternalFrame.titleFont"));
- activeFGColor = defaults.getColor("InternalFrame.activeTitleForeground");
- activeBGColor = defaults.getColor("InternalFrame.activeTitleBackground");
- inactiveFGColor = defaults.getColor("InternalFrame.inactiveTitleForeground");
- inactiveBGColor = defaults.getColor("InternalFrame.inactiveTitleBackground");
+ selectedTextColor = defaults.getColor("InternalFrame.activeTitleForeground");
+ selectedTitleColor = defaults.getColor("InternalFrame.activeTitleBackground");
+ notSelectedTextColor = defaults.getColor("InternalFrame.inactiveTitleForeground");
+ notSelectedTitleColor = defaults.getColor("InternalFrame.inactiveTitleBackground");
}
/**
@@ -691,10 +679,10 @@ public class BasicInternalFrameTitlePane extends JComponent
protected void uninstallDefaults()
{
setFont(null);
- activeFGColor = null;
- activeBGColor = null;
- inactiveFGColor = null;
- inactiveBGColor = null;
+ selectedTextColor = null;
+ selectedTitleColor = null;
+ notSelectedTextColor = null;
+ notSelectedTitleColor = null;
}
/**
@@ -714,12 +702,19 @@ public class BasicInternalFrameTitlePane extends JComponent
}
/**
- * This method sets the icons in the buttons. This is a no-op method here, it
- * can be overridden by subclasses to set icons for the minimize-, maximize-
- * and close-buttons.
+ * Set icons for the minimize-, maximize- and close-buttons.
*/
protected void setButtonIcons()
{
+ Icon icon = UIManager.getIcon("InternalFrame.closeIcon");
+ if (icon != null)
+ closeButton.setIcon(icon);
+ icon = UIManager.getIcon("InternalFrame.iconifyIcon");
+ if (icon != null)
+ iconButton.setIcon(icon);
+ icon = UIManager.getIcon("InternalFrame.maximizeIcon");
+ if (icon != null)
+ maxButton.setIcon(icon);
}
/**
@@ -827,9 +822,9 @@ public class BasicInternalFrameTitlePane extends JComponent
{
Color saved = g.getColor();
if (frame.isSelected())
- g.setColor(activeFGColor);
+ g.setColor(selectedTextColor);
else
- g.setColor(inactiveFGColor);
+ g.setColor(notSelectedTextColor);
title.setText(getTitle(frame.getTitle(), fm, title.getBounds().width));
SwingUtilities.paintComponent(g, title, null, title.getBounds());
g.setColor(saved);
@@ -848,9 +843,9 @@ public class BasicInternalFrameTitlePane extends JComponent
Color bg = getBackground();
if (frame.isSelected())
- bg = activeBGColor;
+ bg = selectedTitleColor;
else
- bg = inactiveBGColor;
+ bg = notSelectedTitleColor;
g.setColor(bg);
g.fillRect(0, 0, dims.width, dims.height);
g.setColor(saved);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 1637966..8f76ea0 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -74,7 +74,6 @@ import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
-import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InternalFrameUI;
import javax.swing.plaf.UIResource;
@@ -1150,7 +1149,6 @@ public class BasicInternalFrameUI extends InternalFrameUI
installKeyboardActions();
frame.setOpaque(true);
- titlePane.setOpaque(true);
frame.invalidate();
}
}
@@ -1179,28 +1177,10 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
protected void installDefaults()
{
- // This is the border of InternalFrames in the BasicLookAndFeel.
- // Note that there exist entries for various border colors in
- // BasicLookAndFeel's defaults, but obviously they differ
- // from the colors that are actually used by the JDK.
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- Color borderColor = defaults.getColor("InternalFrame.borderColor");
- Border inner = BorderFactory.createLineBorder(borderColor, 1);
- Color borderDarkShadow = defaults.getColor
- ("InternalFrame.borderDarkShadow");
- Color borderHighlight = defaults.getColor
- ("InternalFrame.borderHighlight");
- Color borderShadow = defaults.getColor("InternalFrame.borderShadow");
- Color borderLight = defaults.getColor("InternalFrame.borderLight");
- Border outer = BorderFactory.createBevelBorder(BevelBorder.RAISED,
- borderShadow,
- borderHighlight,
- borderDarkShadow,
- borderShadow);
- Border border = new BorderUIResource.CompoundBorderUIResource(outer,
- inner);
+ Border border = defaults.getBorder("InternalFrame.border");
frame.setBorder(border);
-
+ frame.setFrameIcon(defaults.getIcon("InternalFrame.icon"));
// InternalFrames are invisible by default.
frame.setVisible(false);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
index e71e82f..bb9ce6c 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
@@ -1,39 +1,39 @@
/* BasicLabelUI.java
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
package javax.swing.plaf.basic;
@@ -56,12 +56,13 @@ import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.LabelUI;
-
/**
* This is the Basic Look and Feel class for the JLabel. One BasicLabelUI
* object is used to paint all JLabels that utilize the Basic Look and Feel.
*/
-public class BasicLabelUI extends LabelUI implements PropertyChangeListener
+public class BasicLabelUI
+ extends LabelUI
+ implements PropertyChangeListener
{
/** The labelUI that is shared by all labels. */
protected static BasicLabelUI labelUI;
@@ -99,20 +100,20 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
*
* @return The preferred size.
*/
- public Dimension getPreferredSize(JComponent c)
+ public Dimension getPreferredSize(JComponent c)
{
- JLabel lab = (JLabel)c;
+ JLabel lab = (JLabel) c;
Rectangle vr = new Rectangle();
Rectangle ir = new Rectangle();
Rectangle tr = new Rectangle();
- Insets insets = lab.getInsets();
+ Insets insets = lab.getInsets();
FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont());
layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
Rectangle cr = tr.union(ir);
- return new Dimension(insets.left + cr.width + insets.right,
- insets.top + cr.height + insets.bottom);
-
- }
+ return new Dimension(insets.left + cr.width + insets.right, insets.top
+ + cr.height + insets.bottom);
+
+ }
/**
* This method returns the minimum size of the {@link JComponent} given. If
@@ -144,7 +145,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
/**
* The method that paints the label according to its current state.
- *
+ *
* @param g The {@link Graphics} object to paint with.
* @param c The {@link JComponent} to paint.
*/
@@ -169,26 +170,28 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
vr.width = 0;
if (vr.height < 0)
vr.height = 0;
-
+
Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
-
+
if (icon != null)
- icon.paintIcon(b, g, ir.x, ir.y);
- if (text != null && ! text.equals(""))
- {
- if (b.isEnabled())
- paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
- else
- paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
- }
+ icon.paintIcon(b, g, ir.x, ir.y);
+
+ if (text != null && !text.equals(""))
+ {
+ if (b.isEnabled())
+ paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
+ else
+ paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
+ }
+
g.setFont(saved_font);
}
/**
* This method is simply calls SwingUtilities's layoutCompoundLabel.
- *
+ *
* @param label The label to lay out.
* @param fontMetrics The FontMetrics for the font used.
* @param text The text to paint.
@@ -196,20 +199,16 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param viewR The entire viewable rectangle.
* @param iconR The icon bounds rectangle.
* @param textR The text bounds rectangle.
- *
+ *
* @return A possibly clipped version of the text.
*/
- protected String layoutCL(JLabel label, FontMetrics fontMetrics,
- String text, Icon icon, Rectangle viewR,
- Rectangle iconR, Rectangle textR)
+ protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text,
+ Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR)
{
return SwingUtilities.layoutCompoundLabel(label, fontMetrics, text, icon,
- label.getVerticalAlignment(),
- label.getHorizontalAlignment(),
- label.getVerticalTextPosition(),
- label.getHorizontalTextPosition(),
- viewR, iconR, textR,
- label.getIconTextGap());
+ label.getVerticalAlignment(), label.getHorizontalAlignment(), label
+ .getVerticalTextPosition(), label.getHorizontalTextPosition(),
+ viewR, iconR, textR, label.getIconTextGap());
}
/**
@@ -225,7 +224,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param textY The y coordinate of the start of the baseline.
*/
protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
- int textY)
+ int textY)
{
Color saved_color = g.getColor();
@@ -235,14 +234,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
- textY);
+ textY);
else
g.drawString(s, textX, textY);
g.setColor(l.getBackground().darker());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX + 1,
- textY + 1);
+ textY + 1);
else
g.drawString(s, textX + 1, textY + 1);
@@ -260,7 +259,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param textY The y coordinate of the start of the baseline.
*/
protected void paintEnabledText(JLabel l, Graphics g, String s, int textX,
- int textY)
+ int textY)
{
Color saved_color = g.getColor();
g.setColor(l.getForeground());
@@ -269,7 +268,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
- textY);
+ textY);
else
g.drawString(s, textX, textY);
@@ -287,14 +286,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
super.installUI(c);
if (c instanceof JLabel)
- {
- JLabel l = (JLabel) c;
-
- installComponents(l);
- installDefaults(l);
- installListeners(l);
- installKeyboardActions(l);
- }
+ {
+ JLabel l = (JLabel) c;
+
+ installComponents(l);
+ installDefaults(l);
+ installListeners(l);
+ installKeyboardActions(l);
+ }
}
/**
@@ -308,14 +307,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
super.uninstallUI(c);
if (c instanceof JLabel)
- {
- JLabel l = (JLabel) c;
-
- uninstallKeyboardActions(l);
- uninstallListeners(l);
- uninstallDefaults(l);
- uninstallComponents(l);
- }
+ {
+ JLabel l = (JLabel) c;
+
+ uninstallKeyboardActions(l);
+ uninstallListeners(l);
+ uninstallDefaults(l);
+ uninstallComponents(l);
+ }
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
index 24c6cd2..841bd67 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
@@ -49,6 +49,7 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
@@ -208,12 +209,12 @@ public class BasicListUI extends ListUI
if ((evt.getKeyCode() == KeyEvent.VK_DOWN)
|| (evt.getKeyCode() == KeyEvent.VK_KP_DOWN))
{
- if (!evt.isShiftDown())
+ if (evt.getModifiers() == 0)
{
BasicListUI.this.list.clearSelection();
BasicListUI.this.list.setSelectedIndex(Math.min(lead+1,max));
}
- else
+ else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
{
BasicListUI.this.list.getSelectionModel().
setLeadSelectionIndex(Math.min(lead+1,max));
@@ -222,12 +223,12 @@ public class BasicListUI extends ListUI
else if ((evt.getKeyCode() == KeyEvent.VK_UP)
|| (evt.getKeyCode() == KeyEvent.VK_KP_UP))
{
- if (!evt.isShiftDown())
+ if (evt.getModifiers() == 0)
{
BasicListUI.this.list.clearSelection();
BasicListUI.this.list.setSelectedIndex(Math.max(lead-1,0));
}
- else
+ else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
{
BasicListUI.this.list.getSelectionModel().
setLeadSelectionIndex(Math.max(lead-1,0));
@@ -235,20 +236,53 @@ public class BasicListUI extends ListUI
}
else if (evt.getKeyCode() == KeyEvent.VK_PAGE_UP)
{
- // FIXME: implement, need JList.ensureIndexIsVisible to work
+ int target;
+ if (lead == BasicListUI.this.list.getFirstVisibleIndex())
+ {
+ target = Math.max
+ (0, lead - (BasicListUI.this.list.getLastVisibleIndex() -
+ BasicListUI.this.list.getFirstVisibleIndex() + 1));
+ }
+ else
+ {
+ target = BasicListUI.this.list.getFirstVisibleIndex();
+ }
+ if (evt.getModifiers() == 0)
+ BasicListUI.this.list.setSelectedIndex(target);
+ else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
+ BasicListUI.this.list.getSelectionModel().
+ setLeadSelectionIndex(target);
}
else if (evt.getKeyCode() == KeyEvent.VK_PAGE_DOWN)
{
- // FIXME: implement, need JList.ensureIndexIsVisible to work
+ int target;
+ if (lead == BasicListUI.this.list.getLastVisibleIndex())
+ {
+ target = Math.min
+ (max, lead + (BasicListUI.this.list.getLastVisibleIndex() -
+ BasicListUI.this.list.getFirstVisibleIndex() + 1));
+ }
+ else
+ {
+ target = BasicListUI.this.list.getLastVisibleIndex();
+ }
+ if (evt.getModifiers() == 0)
+ BasicListUI.this.list.setSelectedIndex(target);
+ else if (evt.getModifiers() == InputEvent.SHIFT_MASK)
+ BasicListUI.this.list.getSelectionModel().
+ setLeadSelectionIndex(target);
}
else if (evt.getKeyCode() == KeyEvent.VK_BACK_SLASH
- && evt.isControlDown())
+ && (evt.getModifiers() == InputEvent.CTRL_MASK))
{
BasicListUI.this.list.clearSelection();
}
else if ((evt.getKeyCode() == KeyEvent.VK_HOME)
|| evt.getKeyCode() == KeyEvent.VK_END)
{
+ if (evt.getModifiers() != 0 &&
+ evt.getModifiers() != InputEvent.SHIFT_MASK)
+ return;
// index is either 0 for HOME, or last cell for END
int index = (evt.getKeyCode() == KeyEvent.VK_HOME) ? 0 : max;
@@ -264,16 +298,23 @@ public class BasicListUI extends ListUI
setLeadSelectionIndex(index);
}
else if ((evt.getKeyCode() == KeyEvent.VK_A || evt.getKeyCode()
- == KeyEvent.VK_SLASH) && evt.isControlDown())
+ == KeyEvent.VK_SLASH) && (evt.getModifiers() ==
+ InputEvent.CTRL_MASK))
{
BasicListUI.this.list.setSelectionInterval(0, max);
+ // this next line is to restore the lead selection index to the old
+ // position, because select-all should not change the lead index
+ BasicListUI.this.list.addSelectionInterval(lead, lead);
}
- else if (evt.getKeyCode() == KeyEvent.VK_SPACE && evt.isControlDown())
+ else if (evt.getKeyCode() == KeyEvent.VK_SPACE &&
+ (evt.getModifiers() == InputEvent.CTRL_MASK))
{
BasicListUI.this.list.getSelectionModel().
setLeadSelectionIndex(Math.min(lead+1,max));
}
-
+
+ BasicListUI.this.list.ensureIndexIsVisible
+ (BasicListUI.this.list.getLeadSelectionIndex());
}
}
@@ -295,17 +336,7 @@ public class BasicListUI extends ListUI
int index = BasicListUI.this.locationToIndex(list, click);
if (index == -1)
return;
- if (event.isControlDown())
- {
- if (BasicListUI.this.list.getSelectionMode() ==
- ListSelectionModel.SINGLE_SELECTION)
- BasicListUI.this.list.setSelectedIndex(index);
- else if (BasicListUI.this.list.isSelectedIndex(index))
- BasicListUI.this.list.removeSelectionInterval(index,index);
- else
- BasicListUI.this.list.addSelectionInterval(index,index);
- }
- else if (event.isShiftDown())
+ if (event.isShiftDown())
{
if (BasicListUI.this.list.getSelectionMode() ==
ListSelectionModel.SINGLE_SELECTION)
@@ -329,8 +360,21 @@ public class BasicListUI extends ListUI
BasicListUI.this.list.getSelectionModel().
setLeadSelectionIndex(index);
}
+ else if (event.isControlDown())
+ {
+ if (BasicListUI.this.list.getSelectionMode() ==
+ ListSelectionModel.SINGLE_SELECTION)
+ BasicListUI.this.list.setSelectedIndex(index);
+ else if (BasicListUI.this.list.isSelectedIndex(index))
+ BasicListUI.this.list.removeSelectionInterval(index,index);
+ else
+ BasicListUI.this.list.addSelectionInterval(index,index);
+ }
else
BasicListUI.this.list.setSelectedIndex(index);
+
+ BasicListUI.this.list.ensureIndexIsVisible
+ (BasicListUI.this.list.getLeadSelectionIndex());
}
/**
@@ -843,11 +887,11 @@ public class BasicListUI extends ListUI
ListCellRenderer rend, ListModel data,
ListSelectionModel sel, int lead)
{
- boolean is_sel = list.isSelectedIndex(row);
- boolean has_focus = false;
+ boolean isSel = list.isSelectedIndex(row);
+ boolean hasFocus = (list.getLeadSelectionIndex() == row) && BasicListUI.this.list.hasFocus();
Component comp = rend.getListCellRendererComponent(list,
data.getElementAt(row),
- 0, is_sel, has_focus);
+ 0, isSel, hasFocus);
//comp.setBounds(new Rectangle(0, 0, bounds.width, bounds.height));
//comp.paint(g);
rendererPane.paintComponent(g, comp, list, bounds);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
index 14fe28f..d35ac9e 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -57,6 +57,7 @@ import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.DimensionUIResource;
import javax.swing.plaf.FontUIResource;
+import javax.swing.plaf.IconUIResource;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.text.JTextComponent;
@@ -276,7 +277,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Button.shadow", new ColorUIResource(Color.GRAY),
"Button.textIconGap", new Integer(4),
"Button.textShiftOffset", new Integer(0),
- "CheckBox.background", new ColorUIResource(light),
+ "CheckBox.background", new ColorUIResource(new Color(204, 204, 204)),
"CheckBox.border", new BorderUIResource.CompoundBorderUIResource(null,
null),
"CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
@@ -285,21 +286,43 @@ public abstract class BasicLookAndFeel extends LookAndFeel
}),
"CheckBox.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"CheckBox.foreground", new ColorUIResource(darkShadow),
- "CheckBox.icon", BasicIconFactory.getCheckBoxIcon(),
+ "CheckBox.icon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return BasicIconFactory.getCheckBoxIcon();
+ }
+ },
+ "CheckBox.checkIcon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return BasicIconFactory.getMenuItemCheckIcon();
+ }
+ },
"CheckBox.margin",new InsetsUIResource(2, 2, 2, 2),
"CheckBox.textIconGap", new Integer(4),
"CheckBox.textShiftOffset", new Integer(0),
"CheckBoxMenuItem.acceleratorFont", new FontUIResource("Dialog",
Font.PLAIN, 12),
"CheckBoxMenuItem.acceleratorForeground",
- new ColorUIResource(darkShadow),
+ new ColorUIResource(new Color(16, 16, 16)),
"CheckBoxMenuItem.acceleratorSelectionForeground",
new ColorUIResource(Color.white),
"CheckBoxMenuItem.arrowIcon", BasicIconFactory.getMenuItemArrowIcon(),
"CheckBoxMenuItem.background", new ColorUIResource(light),
"CheckBoxMenuItem.border", new BasicBorders.MarginBorder(),
"CheckBoxMenuItem.borderPainted", Boolean.FALSE,
- "CheckBoxMenuItem.checkIcon", BasicIconFactory.getCheckBoxMenuItemIcon(),
+ "CheckBoxMenuItem.checkIcon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return BasicIconFactory.getCheckBoxMenuItemIcon();
+ }
+ },
"CheckBoxMenuItem.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"CheckBoxMenuItem.foreground", new ColorUIResource(darkShadow),
"CheckBoxMenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
@@ -371,7 +394,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"ctrl F10", "maximize",
"ctrl alt shift F6","selectPreviousFrame"
}),
- "Desktop.background", new ColorUIResource(0, 92, 92),
"DesktopIcon.border", new BorderUIResource.CompoundBorderUIResource(null,
null),
"EditorPane.background", new ColorUIResource(Color.white),
@@ -480,15 +502,22 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"InternalFrame.borderLight", new ColorUIResource(Color.LIGHT_GRAY),
"InternalFrame.borderShadow", new ColorUIResource(Color.GRAY),
"InternalFrame.closeIcon", BasicIconFactory.createEmptyFrameIcon(),
- // XXX Don't use gif
-// "InternalFrame.icon", new IconUIResource(new ImageIcon("icons/JavaCup.gif")),
+ // FIXME: Set a nice icon for InternalFrames here.
+ "InternalFrame.icon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return new IconUIResource(BasicIconFactory.createEmptyFrameIcon());
+ }
+ },
"InternalFrame.iconifyIcon", BasicIconFactory.createEmptyFrameIcon(),
"InternalFrame.inactiveTitleBackground", new ColorUIResource(Color.gray),
"InternalFrame.inactiveTitleForeground",
new ColorUIResource(Color.lightGray),
"InternalFrame.maximizeIcon", BasicIconFactory.createEmptyFrameIcon(),
"InternalFrame.minimizeIcon", BasicIconFactory.createEmptyFrameIcon(),
- "InternalFrame.titleFont", new FontUIResource("Dialog", Font.PLAIN, 12),
+ "InternalFrame.titleFont", new FontUIResource("Dialog", Font.BOLD, 12),
"InternalFrame.windowBindings", new Object[] {
"shift ESCAPE", "showSystemMenu",
"ctrl SPACE", "showSystemMenu",
@@ -524,6 +553,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"List.foreground", new ColorUIResource(darkShadow),
"List.selectionBackground", new ColorUIResource(Color.black),
"List.selectionForeground", new ColorUIResource(Color.white),
+ "List.focusCellHighlightBorder",
+ new BorderUIResource.
+ LineBorderUIResource(new ColorUIResource(Color.yellow)),
"Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12),
"Menu.acceleratorForeground", new ColorUIResource(darkShadow),
"Menu.acceleratorSelectionForeground", new ColorUIResource(Color.white),
@@ -613,7 +645,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
null, null),
"PasswordField.caretBlinkRate", new Integer(500),
"PasswordField.caretForeground", new ColorUIResource(Color.black),
- "PasswordField.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12),
+ "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"PasswordField.foreground", new ColorUIResource(Color.black),
"PasswordField.inactiveBackground", new ColorUIResource(light),
"PasswordField.inactiveForeground", new ColorUIResource(Color.gray),
@@ -649,7 +681,14 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"RadioButton.font", new FontUIResource("Dialog", Font.PLAIN, 12),
"RadioButton.foreground", new ColorUIResource(darkShadow),
"RadioButton.highlight", new ColorUIResource(highLight),
- "RadioButton.icon", BasicIconFactory.getRadioButtonIcon(),
+ "RadioButton.icon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return BasicIconFactory.getRadioButtonIcon();
+ }
+ },
"RadioButton.light", new ColorUIResource(highLight),
"RadioButton.margin", new InsetsUIResource(2, 2, 2, 2),
"RadioButton.shadow", new ColorUIResource(shadow),
@@ -748,7 +787,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Slider.highlight", new ColorUIResource(highLight),
"Slider.shadow", new ColorUIResource(shadow),
"Slider.thumbHeight", new Integer(20),
- "Slider.thumbWidth", new Integer(10),
+ "Slider.thumbWidth", new Integer(11),
"Slider.tickHeight", new Integer(12),
"Spinner.background", new ColorUIResource(light),
"Spinner.foreground", new ColorUIResource(light),
@@ -838,13 +877,24 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"shift KP_DOWN", "selectNextRowExtendSelection",
"shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ESCAPE", "cancel",
- "ctrl shift PAGE_UP", "scrollRightExtendSelection",
- "shift KP_RIGHT", " selectNextColumnExtendSelection",
+ "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl PAGE_UP", "scrollLeftChangeSelection",
"shift PAGE_UP", "scrollUpExtendSelection",
- "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
"ctrl PAGE_DOWN", "scrollRightChangeSelection",
- "PAGE_UP", "scrollUpChangeSelection"
+ "PAGE_UP", "scrollUpChangeSelection",
+ "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift UP", "selectPreviousRowExtendSelection",
+ "ctrl shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift DOWN", "selectNextRowExtendSelection",
+ "ctrl BACK_SLASH", "clearSelection",
+ "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl SLASH", "selectAll",
+ "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
}),
"Table.background", new ColorUIResource(light),
"Table.focusCellBackground", new ColorUIResource(light),
@@ -1000,7 +1050,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"shift END", "selectLastExtendSelection",
"HOME", "selectFirst",
"ctrl END", "selectLastChangeLead",
- "ctrl /", "selectAll",
+ "ctrl SLASH", "selectAll",
"LEFT", "selectParent",
"shift HOME", "selectFirstExtendSelection",
"UP", "selectPrevious",
@@ -1027,7 +1077,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"shift KP_DOWN","selectNextExtendSelection",
"ctrl SPACE", "toggleSelectionPreserveAnchor",
"ctrl shift PAGE_UP", "scrollUpExtendSelection",
- "ctrl \\", "clearSelection",
+ "ctrl BACK_SLASH", "clearSelection",
"shift SPACE", "extendSelection",
"ctrl PAGE_UP", "scrollUpChangeLead",
"shift PAGE_UP","scrollUpExtendSelection",
@@ -1046,6 +1096,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Tree.selectionBackground", new ColorUIResource(Color.black),
"Tree.nonSelectionBackground", new ColorUIResource(new Color(239, 235, 231)),
"Tree.selectionBorderColor", new ColorUIResource(Color.black),
+ "Tree.selectionBorder", new BorderUIResource.LineBorderUIResource(Color.black),
"Tree.selectionForeground", new ColorUIResource(new Color(255, 255, 255)),
"Tree.textBackground", new ColorUIResource(new Color(255, 255, 255)),
"Tree.textForeground", new ColorUIResource(Color.black),
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
index a5bf082..8aa1193 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -295,7 +295,7 @@ public class BasicMenuItemUI extends MenuItemUI
* Returns preferred size for the given menu item.
*
* @param c menu item for which to get preferred size
- * @param checkIcon chech icon displayed in the given menu item
+ * @param checkIcon check icon displayed in the given menu item
* @param arrowIcon arrow icon displayed in the given menu item
* @param defaultTextIconGap space between icon and text in the given menuItem
*
@@ -355,12 +355,18 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public Dimension getPreferredSize(JComponent c)
{
- return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap);
+ return getPreferredMenuItemSize(c, checkIcon, arrowIcon,
+ defaultTextIconGap);
}
+ /**
+ * Returns the prefix for entries in the {@link UIDefaults} table.
+ *
+ * @return "MenuItem"
+ */
protected String getPropertyPrefix()
{
- return null;
+ return "MenuItem";
}
/**
@@ -507,7 +513,8 @@ public class BasicMenuItemUI extends MenuItemUI
br.height += insets.top + insets.bottom;
// Menu item is considered to be highlighted when it is selected.
- if (m.isSelected() || m.getModel().isArmed() &&
+ // But we don't want to paint the background of JCheckBoxMenuItems
+ if ((m.isSelected() && checkIcon == null) || m.getModel().isArmed() &&
(m.getParent() instanceof MenuElement))
{
if (m.isContentAreaFilled())
@@ -531,8 +538,7 @@ public class BasicMenuItemUI extends MenuItemUI
SwingUtilities.layoutCompoundLabel(m, fm, null, checkIcon, vertAlign,
horAlign, vertTextPos, horTextPos,
vr, cr, tr, defaultTextIconGap);
- checkIcon.paintIcon(m, g, cr.x, cr.y);
-
+ checkIcon.paintIcon(m, g, cr.x, cr.y);
// We need to calculate position of the menu text and position of
// user menu icon if there exists one relative to the check icon.
// So we need to adjust view rectangle s.t. its starting point is at
@@ -561,7 +567,6 @@ public class BasicMenuItemUI extends MenuItemUI
defaultTextIconGap);
if (i != null)
i.paintIcon(c, g, ir.x, ir.y);
-
paintText(g, m, tr, m.getText());
// paint accelerator
@@ -605,7 +610,8 @@ public class BasicMenuItemUI extends MenuItemUI
if (menuItem.isEnabled())
{
// Menu item is considered to be highlighted when it is selected.
- if (menuItem.isSelected() || menuItem.getModel().isArmed() &&
+ // But not if it's a JCheckBoxMenuItem
+ if ((menuItem.isSelected() && checkIcon == null) || menuItem.getModel().isArmed() &&
(menuItem.getParent() instanceof MenuElement))
g.setColor(selectionForeground);
else
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
index 6bd15ed..30be592 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
@@ -46,6 +46,7 @@ import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.MenuSelectionManager;
import javax.swing.UIDefaults;
@@ -179,12 +180,23 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public Dimension getMaximumSize(JComponent c)
{
+ // If this menu is in a popup menu, treat it like a regular JMenuItem
+ if (!((JMenu)c).isTopLevelMenu())
+ {
+ JMenuItem menuItem = new JMenuItem(((JMenu)c).getText(), ((JMenu)c).getIcon());
+ return menuItem.getMaximumSize();
+ }
return c.getPreferredSize();
}
+ /**
+ * Returns the prefix for entries in the {@link UIDefaults} table.
+ *
+ * @return "Menu"
+ */
protected String getPropertyPrefix()
{
- return null;
+ return "Menu";
}
/**
@@ -294,14 +306,17 @@ public class BasicMenuUI extends BasicMenuItemUI
private boolean popupVisible()
{
- JMenuBar mb = (JMenuBar) ((JMenu)menuItem).getParent();
+ JMenuBar mb = (JMenuBar) ((JMenu) menuItem).getParent();
// check if mb.isSelected because if no menus are selected
// we don't have to look through the list for popup menus
if (!mb.isSelected())
return false;
- for (int i=0;iBasicRadioButtonUI
+ */
public static ComponentUI createUI(final JComponent c) {
return new BasicRadioButtonUI();
}
+ /**
+ * Creates a new instance of BasicButtonUI
.
+ */
public BasicRadioButtonUI()
{
icon = getDefaultIcon();
}
- public void installUI(final JComponent c) {
- super.installUI(c);
- if (c instanceof AbstractButton)
- {
- AbstractButton b = (AbstractButton) c;
- b.setIcon(icon);
- }
+ /**
+ * Installs defaults from the Look & Feel table on the specified
+ * button.
+ *
+ * @param b the button on which to install the defaults
+ */
+ protected void installDefaults(AbstractButton b)
+ {
+ super.installDefaults(b);
+ if (b.getIcon() == null)
+ b.setIcon(icon);
+ if (b.getSelectedIcon() == null)
+ b.setSelectedIcon(icon);
}
+ /**
+ * Returns the prefix used for UIDefaults properties. This is
+ * RadioButton
in this case.
+ *
+ * @return the prefix used for UIDefaults properties
+ */
+ protected String getPropertyPrefix()
+ {
+ return "RadioButton.";
+ }
+
+ /**
+ * Returns the default icon for JRadioButtons.
+ * The default icon displays the usual
+ * RadioButton and is sensible to the selection state of the button,
+ * and can be used both as normal icon as well as selectedIcon.
+ *
+ * @return the default icon for JRadioButtons
+ */
public Icon getDefaultIcon()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- return defaults.getIcon("RadioButton.icon");
+ return defaults.getIcon(getPropertyPrefix() + "icon");
}
-
-}
-
-
-
-
+ /**
+ * Paints the RadioButton.
+ *
+ * @param g the Graphics context to paint with
+ * @param c the button to paint
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ AbstractButton b = (AbstractButton) c;
+ Rectangle tr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle vr = new Rectangle();
+ Font f = c.getFont();
+ g.setFont(f);
+ Icon currentIcon = null;
+ if (b.isSelected())
+ currentIcon = b.getSelectedIcon();
+ else
+ currentIcon = b.getIcon();
+ SwingUtilities.calculateInnerArea(b, vr);
+ String text = SwingUtilities.layoutCompoundLabel
+ (c, g.getFontMetrics(f), b.getText(), currentIcon,
+ b.getVerticalAlignment(), b.getHorizontalAlignment(),
+ b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
+ vr, ir, tr, b.getIconTextGap() + defaultTextShiftOffset);
+
+ if (currentIcon != null)
+ {
+ currentIcon.paintIcon(c, g, ir.x, ir.y);
+ }
+ if (text != null)
+ paintText(g, b, tr, text);
+ paintFocus(g, b, vr, tr, ir);
+ }
+}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
index 892db2b..22242af 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -659,7 +659,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
height = Math.max(incrButton.getPreferredSize().height,
decrButton.getPreferredSize().height);
height = Math.max(getMinimumThumbSize().height, height);
- height = Math.max(20, height);
height = Math.min(getMaximumThumbSize().height, height);
}
else
@@ -672,7 +671,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
width = Math.max(incrButton.getPreferredSize().width,
decrButton.getPreferredSize().width);
width = Math.max(getMinimumThumbSize().width, width);
- width = Math.max(20, width);
width = Math.min(getMaximumThumbSize().width, width);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 7bb7acf..bd1576f 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -102,14 +102,6 @@ public class BasicScrollPaneUI extends ScrollPaneUI
return sl.minimumLayoutSize(c);
}
- public Dimension getPreferredSize(JComponent c)
- {
- JScrollPane p = (JScrollPane ) c;
- ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
- return sl.preferredLayoutSize(c);
- }
-
-
public void paint(Graphics g, JComponent c)
{
// do nothing; the normal painting-of-children algorithm, along with
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
index 0a72a62..0b40584 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
@@ -470,15 +470,6 @@ public class BasicSliderUI extends SliderUI
}
}
- /** The preferred height of the thumb. */
- private transient int thumbHeight;
-
- /** The preferred width of the thumb. */
- private transient int thumbWidth;
-
- /** The preferred height of the tick rectangle. */
- private transient int tickHeight;
-
/** Listener for changes from the model. */
protected ChangeListener changeListener;
@@ -698,11 +689,6 @@ public class BasicSliderUI extends SliderUI
focusColor = defaults.getColor("Slider.focus");
slider.setBorder(defaults.getBorder("Slider.border"));
slider.setOpaque(true);
-
- thumbHeight = defaults.getInt("Slider.thumbHeight");
- thumbWidth = defaults.getInt("Slider.thumbWidth");
- tickHeight = defaults.getInt("Slider.tickHeight");
-
focusInsets = defaults.getInsets("Slider.focusInsets");
}
@@ -899,11 +885,11 @@ public class BasicSliderUI extends SliderUI
width += insets.left + insets.right + focusInsets.left + focusInsets.right;
// Height is determined by the thumb, the ticks and the labels.
- int height = thumbHeight;
+ int height = getThumbSize().height;
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
|| slider.getMinorTickSpacing() > 0)
- height += tickHeight;
+ height += getTickLength();
if (slider.getPaintLabels())
height += getHeightOfTallestLabel();
@@ -934,11 +920,11 @@ public class BasicSliderUI extends SliderUI
height += insets.top + insets.bottom + focusInsets.top
+ focusInsets.bottom;
- int width = thumbHeight;
+ int width = getThumbSize().width;
if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
|| slider.getMinorTickSpacing() > 0)
- width += tickHeight;
+ width += getTickLength();
if (slider.getPaintLabels())
width += getWidthOfWidestLabel();
@@ -956,7 +942,21 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMinimumHorizontalSize()
{
- return getPreferredHorizontalSize();
+ Insets insets = slider.getInsets();
+ // Height is determined by the thumb, the ticks and the labels.
+ int height = getThumbSize().height;
+
+ if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0)
+ height += getTickLength();
+
+ if (slider.getPaintLabels())
+ height += getHeightOfTallestLabel();
+
+ height += insets.top + insets.bottom + focusInsets.top
+ + focusInsets.bottom;
+
+ return new Dimension(36, height);
}
/**
@@ -967,7 +967,19 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMinimumVerticalSize()
{
- return getPreferredVerticalSize();
+ Insets insets = slider.getInsets();
+ int width = getThumbSize().width;
+
+ if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0)
+ width += getTickLength();
+
+ if (slider.getPaintLabels())
+ width += getWidthOfWidestLabel();
+
+ width += insets.left + insets.right + focusInsets.left + focusInsets.right;
+
+ return new Dimension(width, 36);
}
/**
@@ -999,15 +1011,14 @@ public class BasicSliderUI extends SliderUI
public Dimension getMinimumSize(JComponent c)
{
if (slider.getOrientation() == JSlider.HORIZONTAL)
- return getPreferredHorizontalSize();
+ return getMinimumHorizontalSize();
else
- return getPreferredVerticalSize();
+ return getMinimumVerticalSize();
}
/**
* This method returns the maximum size for this {@link JSlider} for this
- * look and feel. If it returns null, then it is up to the Layout Manager
- * to give the {@link JComponent} a size.
+ * look and feel.
*
* @param c The {@link JComponent} to find a maximum size for.
*
@@ -1015,10 +1026,40 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMaximumSize(JComponent c)
{
+ Insets insets = slider.getInsets();
if (slider.getOrientation() == JSlider.HORIZONTAL)
- return getPreferredHorizontalSize();
+ {
+ // Height is determined by the thumb, the ticks and the labels.
+ int height = getThumbSize().height;
+
+ if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0)
+ height += getTickLength();
+
+ if (slider.getPaintLabels())
+ height += getHeightOfTallestLabel();
+
+ height += insets.top + insets.bottom + focusInsets.top
+ + focusInsets.bottom;
+
+ return new Dimension(32767, height);
+ }
else
- return getPreferredVerticalSize();
+ {
+ int width = getThumbSize().width;
+
+ if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0)
+ width += getTickLength();
+
+ if (slider.getPaintLabels())
+ width += getWidthOfWidestLabel();
+
+ width += insets.left + insets.right + focusInsets.left
+ + focusInsets.right;
+
+ return new Dimension(width, 32767);
+ }
}
/**
@@ -1045,7 +1086,6 @@ public class BasicSliderUI extends SliderUI
{
insetCache = slider.getInsets();
focusRect = SwingUtilities.calculateInnerArea(slider, focusRect);
-
if (focusRect.width < 0)
focusRect.width = 0;
if (focusRect.height < 0)
@@ -1058,30 +1098,13 @@ public class BasicSliderUI extends SliderUI
*/
protected void calculateThumbSize()
{
+ Dimension d = getThumbSize();
+ thumbRect.width = d.width;
+ thumbRect.height = d.height;
if (slider.getOrientation() == JSlider.HORIZONTAL)
- {
- if (thumbWidth > contentRect.width)
- thumbRect.width = contentRect.width / 4;
- else
- thumbRect.width = thumbWidth;
- if (thumbHeight > contentRect.height)
- thumbRect.height = contentRect.height;
- else
- thumbRect.height = thumbHeight;
- }
+ thumbRect.y = trackRect.y;
else
- {
- // The thumb gets flipped when inverted, so thumbWidth
- // actually is the height and vice versa.
- if (thumbWidth > contentRect.height)
- thumbRect.height = contentRect.height / 4;
- else
- thumbRect.height = thumbWidth;
- if (thumbHeight > contentRect.width)
- thumbRect.width = contentRect.width;
- else
- thumbRect.width = thumbHeight;
- }
+ thumbRect.x = trackRect.x;
}
/**
@@ -1092,9 +1115,10 @@ public class BasicSliderUI extends SliderUI
{
contentRect.x = focusRect.x + focusInsets.left;
contentRect.y = focusRect.y + focusInsets.top;
+
contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
- contentRect.height = focusRect.height - focusInsets.top
- - focusInsets.bottom;
+ contentRect.height = focusRect.height - focusInsets.top
+ - focusInsets.bottom;
if (contentRect.width < 0)
contentRect.width = 0;
@@ -1113,11 +1137,11 @@ public class BasicSliderUI extends SliderUI
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
thumbRect.x = xPositionForValue(value) - thumbRect.width / 2;
- thumbRect.y = contentRect.y;
+ thumbRect.y = trackRect.y;
}
else
{
- thumbRect.x = contentRect.x;
+ thumbRect.x = trackRect.x;
thumbRect.y = yPositionForValue(value) - thumbRect.height / 2;
}
}
@@ -1129,9 +1153,9 @@ public class BasicSliderUI extends SliderUI
protected void calculateTrackBuffer()
{
if (slider.getOrientation() == JSlider.HORIZONTAL)
- trackBuffer = thumbRect.width;
+ trackBuffer = thumbRect.width / 2;
else
- trackBuffer = thumbRect.height;
+ trackBuffer = thumbRect.height / 2;
}
/**
@@ -1141,9 +1165,11 @@ public class BasicSliderUI extends SliderUI
*/
protected Dimension getThumbSize()
{
- // This is really just the bounds box for the thumb.
- // The thumb will actually be pointed (like a rectangle + triangle at bottom)
- return thumbRect.getSize();
+ // TODO: shouldn't create new objects every time
+ if (slider.getOrientation() == JSlider.HORIZONTAL)
+ return new Dimension(11, 20);
+ else
+ return new Dimension(20, 11);
}
/**
@@ -1155,13 +1181,21 @@ public class BasicSliderUI extends SliderUI
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
trackRect.x = contentRect.x + trackBuffer;
- trackRect.y = contentRect.y;
+ int h = getThumbSize().height;
+ if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0))
+ h += getTickLength();
+ trackRect.y = contentRect.y + (contentRect.height - h) / 2 - 1;
trackRect.width = contentRect.width - 2 * trackBuffer;
trackRect.height = thumbRect.height;
}
else
{
- trackRect.x = contentRect.x;
+ int w = getThumbSize().width;
+ if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
+ || slider.getMinorTickSpacing() > 0))
+ w += getTickLength();
+ trackRect.x = contentRect.x + (contentRect.width - w) / 2 - 1;
trackRect.y = contentRect.y + trackBuffer;
trackRect.width = thumbRect.width;
trackRect.height = contentRect.height - 2 * trackBuffer;
@@ -1180,7 +1214,7 @@ public class BasicSliderUI extends SliderUI
*/
protected int getTickLength()
{
- return tickHeight;
+ return 8;
}
/**
@@ -1536,9 +1570,6 @@ public class BasicSliderUI extends SliderUI
Point c = new Point(a);
Point d = new Point(a);
- Polygon high;
- Polygon shadow;
-
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
width = trackRect.width;
@@ -1591,74 +1622,78 @@ public class BasicSliderUI extends SliderUI
{
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
- double loc = tickRect.x;
+ double loc = tickRect.x + 0.5;
double increment = (max == min) ? 0
- : majorSpace * (double) tickRect.width / (max
- - min);
- if (drawInverted())
+ : majorSpace * (double) (tickRect.width - 1) / (max - min);
+ if (drawInverted())
{
loc += tickRect.width;
increment *= -1;
}
+ g.translate(0, tickRect.y);
for (int i = min; i <= max; i += majorSpace)
{
paintMajorTickForHorizSlider(g, tickRect, (int) loc);
loc += increment;
}
+ g.translate(0, -tickRect.y);
}
else
{
- double loc = tickRect.height + tickRect.y;
+ double loc = tickRect.height + tickRect.y + 0.5;
double increment = (max == min) ? 0
- : -majorSpace * (double) tickRect.height / (max
- - min);
+ : -majorSpace * (double) (tickRect.height - 1) / (max - min);
if (drawInverted())
{
- loc = tickRect.y;
+ loc = tickRect.y + 0.5;
increment *= -1;
}
+ g.translate(tickRect.x, 0);
for (int i = min; i <= max; i += majorSpace)
{
paintMajorTickForVertSlider(g, tickRect, (int) loc);
loc += increment;
}
+ g.translate(-tickRect.x, 0);
}
}
if (minorSpace > 0)
{
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
- double loc = tickRect.x;
+ double loc = tickRect.x + 0.5;
double increment = (max == min) ? 0
- : minorSpace * (double) tickRect.width / (max
- - min);
+ : minorSpace * (double) (tickRect.width - 1) / (max - min);
if (drawInverted())
{
loc += tickRect.width;
increment *= -1;
}
+ g.translate(0, tickRect.y);
for (int i = min; i <= max; i += minorSpace)
{
paintMinorTickForHorizSlider(g, tickRect, (int) loc);
loc += increment;
}
+ g.translate(0, -tickRect.y);
}
else
{
- double loc = tickRect.height + tickRect.y;
+ double loc = tickRect.height + tickRect.y + 0.5;
double increment = (max == min) ? 0
- : -minorSpace * (double) tickRect.height / (max
- - min);
+ : -minorSpace * (double) (tickRect.height - 1) / (max - min);
if (drawInverted())
{
- loc = tickRect.y;
+ loc = tickRect.y + 0.5;
increment *= -1;
}
+ g.translate(tickRect.x, 0);
for (int i = min; i <= max; i += minorSpace)
{
paintMinorTickForVertSlider(g, tickRect, (int) loc);
loc += increment;
}
+ g.translate(-tickRect.x, 0);
}
}
}
@@ -1680,7 +1715,7 @@ public class BasicSliderUI extends SliderUI
protected void paintMinorTickForHorizSlider(Graphics g,
Rectangle tickBounds, int x)
{
- int y = tickRect.y + tickRect.height / 4;
+ int y = tickRect.height / 4;
Color saved = g.getColor();
g.setColor(Color.BLACK);
@@ -1699,7 +1734,7 @@ public class BasicSliderUI extends SliderUI
protected void paintMajorTickForHorizSlider(Graphics g,
Rectangle tickBounds, int x)
{
- int y = tickRect.y + tickRect.height / 4;
+ int y = tickRect.height / 4;
Color saved = g.getColor();
g.setColor(Color.BLACK);
@@ -1718,7 +1753,7 @@ public class BasicSliderUI extends SliderUI
protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
int y)
{
- int x = tickRect.x + tickRect.width / 4;
+ int x = tickRect.width / 4;
Color saved = g.getColor();
g.setColor(Color.BLACK);
@@ -1737,7 +1772,7 @@ public class BasicSliderUI extends SliderUI
protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
int y)
{
- int x = tickRect.x + tickRect.width / 4;
+ int x = tickRect.width / 4;
Color saved = g.getColor();
g.setColor(Color.BLACK);
@@ -1924,8 +1959,6 @@ public class BasicSliderUI extends SliderUI
{
Color saved_color = g.getColor();
- Polygon thumb = new Polygon();
-
Point a = new Point(thumbRect.x, thumbRect.y);
Point b = new Point(a);
Point c = new Point(a);
@@ -1933,7 +1966,8 @@ public class BasicSliderUI extends SliderUI
Point e = new Point(a);
Polygon bright;
- Polygon dark;
+ Polygon light; // light shadow
+ Polygon dark; // dark shadow
Polygon all;
// This will be in X-dimension if the slider is inverted and y if it isn't.
@@ -1943,36 +1977,42 @@ public class BasicSliderUI extends SliderUI
{
turnPoint = thumbRect.height * 3 / 4;
- b.translate(thumbRect.width, 0);
- c.translate(thumbRect.width, turnPoint);
- d.translate(thumbRect.width / 2, thumbRect.height);
+ b.translate(thumbRect.width - 1, 0);
+ c.translate(thumbRect.width - 1, turnPoint);
+ d.translate(thumbRect.width / 2 - 1, thumbRect.height - 1);
e.translate(0, turnPoint);
- bright = new Polygon(new int[] { b.x, a.x, e.x, d.x },
+ bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x },
new int[] { b.y, a.y, e.y, d.y }, 4);
- dark = new Polygon(new int[] { b.x, c.x, d.x },
- new int[] { b.y, c.y, d.y }, 3);
- all = new Polygon(new int[] { a.x + 1, b.x, c.x, d.x, e.x + 1 },
- new int[] { a.y + 1, b.y + 1, c.y, d.y + 1, e.y }, 5);
+ dark = new Polygon(new int[] { b.x, c.x, d.x + 1 },
+ new int[] { b.y, c.y - 1, d.y }, 3);
+
+ light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
+ new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
+
+ all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
+ new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y }, 5);
}
else
{
- turnPoint = thumbRect.width * 3 / 4;
+ turnPoint = thumbRect.width * 3 / 4 - 1;
b.translate(turnPoint, 0);
- c.translate(thumbRect.width, thumbRect.height / 2);
- d.translate(turnPoint, thumbRect.height);
- e.translate(0, thumbRect.height);
+ c.translate(thumbRect.width - 1, thumbRect.height / 2);
+ d.translate(turnPoint, thumbRect.height - 1);
+ e.translate(0, thumbRect.height - 1);
- bright = new Polygon(new int[] { c.x, b.x, a.x, e.x },
- new int[] { c.y, b.y, a.y, e.y }, 4);
+ bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x },
+ new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4);
- dark = new Polygon(new int[] { c.x, d.x, e.x + 1 },
+ dark = new Polygon(new int[] { c.x, d.x, e.x },
new int[] { c.y, d.y, e.y }, 3);
- all = new Polygon(new int[] { a.x + 1, b.x, c.x - 1, d.x, e.x + 1 },
- new int[] { a.y + 1, b.y + 1, c.y, d.y, e.y }, 5);
+ light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1},
+ new int[] { c.y, d.y - 1, e.y - 1}, 3);
+ all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, e.x + 1 },
+ new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2, e.y - 2 }, 6);
}
g.setColor(Color.WHITE);
@@ -1982,6 +2022,10 @@ public class BasicSliderUI extends SliderUI
g.drawPolyline(dark.xpoints, dark.ypoints, dark.npoints);
g.setColor(Color.GRAY);
+ g.drawPolyline(light.xpoints, light.ypoints, light.npoints);
+
+ g.setColor(Color.LIGHT_GRAY);
+ g.drawPolyline(all.xpoints, all.ypoints, all.npoints);
g.fillPolygon(all);
g.setColor(saved_color);
@@ -2065,8 +2109,7 @@ public class BasicSliderUI extends SliderUI
{
int min = slider.getMinimum();
int max = slider.getMaximum();
- int extent = slider.getExtent();
- int len = trackRect.width;
+ int len = trackRect.width - 1;
int xPos = (max == min) ? 0 : (value - min) * len / (max - min);
@@ -2074,7 +2117,7 @@ public class BasicSliderUI extends SliderUI
xPos += trackRect.x;
else
{
- xPos = trackRect.width - xPos;
+ xPos = len - xPos;
xPos += trackRect.x;
}
return xPos;
@@ -2091,14 +2134,13 @@ public class BasicSliderUI extends SliderUI
{
int min = slider.getMinimum();
int max = slider.getMaximum();
- int extent = slider.getExtent();
- int len = trackRect.height;
+ int len = trackRect.height - 1;
int yPos = (max == min) ? 0 : (value - min) * len / (max - min);
if (! drawInverted())
{
- yPos = trackRect.height - yPos;
+ yPos = len - yPos;
yPos += trackRect.y;
}
else
@@ -2123,8 +2165,9 @@ public class BasicSliderUI extends SliderUI
int value;
- // If the length is 0, you shouldn't be able to even see where the slider is.
- // This really shouldn't ever happen, but just in case, we'll return the middle.
+ // If the length is 0, you shouldn't be able to even see where the slider
+ // is. This really shouldn't ever happen, but just in case, we'll return
+ // the middle.
if (len == 0)
return ((max - min) / 2);
@@ -2158,8 +2201,9 @@ public class BasicSliderUI extends SliderUI
int value;
- // If the length is 0, you shouldn't be able to even see where the slider is.
- // This really shouldn't ever happen, but just in case, we'll return the middle.
+ // If the length is 0, you shouldn't be able to even see where the slider
+ // is. This really shouldn't ever happen, but just in case, we'll return
+ // the middle.
if (len == 0)
return ((max - min) / 2);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
index ff7e8ac..ef8e228 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -870,7 +870,8 @@ public class BasicSplitPaneUI extends SplitPaneUI
transient int lastDragLocation = -1;
/** The distance the divider is moved when moved by keyboard actions. */
- protected static int KEYBOARD_DIVIDER_MOVE_OFFSET;
+ // Sun defines this as 3
+ protected static int KEYBOARD_DIVIDER_MOVE_OFFSET = 3;
/** The divider that divides this JSplitPane. */
protected BasicSplitPaneDivider divider;
@@ -1337,9 +1338,11 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public int getMinimumDividerLocation(JSplitPane jc)
{
- int value = layoutManager.getInitialLocation(jc.getInsets());
- if (layoutManager.components[0] != null)
- value += layoutManager.minimumSizeOfComponent(0);
+ int value = layoutManager.getInitialLocation(jc.getInsets())
+ - layoutManager.getAvailableSize(jc.getSize(), jc.getInsets())
+ + splitPane.getDividerSize();
+ if (layoutManager.components[1] != null)
+ value += layoutManager.minimumSizeOfComponent(1);
return value;
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 8a27f98..7e9d9b9 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -1680,18 +1680,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
/**
- * This method returns the preferred size of the JTabbedPane.
- *
- * @param c The JComponent to find a size for.
- *
- * @return The preferred size.
- */
- public Dimension getPreferredSize(JComponent c)
- {
- return layoutManager.preferredLayoutSize(tabPane);
- }
-
- /**
* This method returns the minimum size of the JTabbedPane.
*
* @param c The JComponent to find a size for.
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
index 7787436..4559937 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
@@ -40,26 +40,37 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
+import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TableUI;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
@@ -85,6 +96,9 @@ public class BasicTableUI
/** The cell border for selected/highlighted cells. */
Border highlightCellBorder;
+ /** The action bound to KeyStrokes. */
+ TableAction action;
+
class FocusHandler implements FocusListener
{
public void focusGained(FocusEvent e)
@@ -95,54 +109,37 @@ public class BasicTableUI
}
}
- class KeyHandler implements KeyListener
- {
- public void keyPressed(KeyEvent e)
- {
- }
- public void keyReleased(KeyEvent e)
- {
- }
- public void keyTyped(KeyEvent e)
- {
- }
- }
-
class MouseInputHandler implements MouseInputListener
{
Point begin, curr;
private void updateSelection(boolean controlPressed)
{
- if (table.getRowSelectionAllowed())
+ // Update the rows
+ int lo_row = table.rowAtPoint(begin);
+ int hi_row = table.rowAtPoint(curr);
+ ListSelectionModel rowModel = table.getSelectionModel();
+ if (lo_row != -1 && hi_row != -1)
{
- int lo_row = table.rowAtPoint(begin);
- int hi_row = table.rowAtPoint(curr);
- ListSelectionModel rowModel = table.getSelectionModel();
- if (lo_row != -1 && hi_row != -1)
- {
- if (controlPressed && rowModel.getSelectionMode()
- != ListSelectionModel.SINGLE_SELECTION)
- rowModel.addSelectionInterval(lo_row, hi_row);
- else
- rowModel.setSelectionInterval(lo_row, hi_row);
- }
+ if (controlPressed && rowModel.getSelectionMode()
+ != ListSelectionModel.SINGLE_SELECTION)
+ rowModel.addSelectionInterval(lo_row, hi_row);
+ else
+ rowModel.setSelectionInterval(lo_row, hi_row);
}
-
- if (table.getColumnSelectionAllowed())
+
+ // Update the columns
+ int lo_col = table.columnAtPoint(begin);
+ int hi_col = table.columnAtPoint(curr);
+ ListSelectionModel colModel = table.getColumnModel().
+ getSelectionModel();
+ if (lo_col != -1 && hi_col != -1)
{
- int lo_col = table.columnAtPoint(begin);
- int hi_col = table.columnAtPoint(curr);
- ListSelectionModel colModel = table.getColumnModel().
- getSelectionModel();
- if (lo_col != -1 && hi_col != -1)
- {
- if (controlPressed && colModel.getSelectionMode() !=
- ListSelectionModel.SINGLE_SELECTION)
- colModel.addSelectionInterval(lo_col, hi_col);
- else
- colModel.setSelectionInterval(lo_col, hi_col);
- }
+ if (controlPressed && colModel.getSelectionMode() !=
+ ListSelectionModel.SINGLE_SELECTION)
+ colModel.addSelectionInterval(lo_col, hi_col);
+ else
+ colModel.setSelectionInterval(lo_col, hi_col);
}
}
@@ -165,6 +162,11 @@ public class BasicTableUI
}
public void mousePressed(MouseEvent e)
{
+ ListSelectionModel rowModel = table.getSelectionModel();
+ ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+ int rowLead = rowModel.getLeadSelectionIndex();
+ int colLead = colModel.getLeadSelectionIndex();
+
begin = new Point(e.getX(), e.getY());
curr = new Point(e.getX(), e.getY());
//if control is pressed and the cell is already selected, deselect it
@@ -180,7 +182,12 @@ public class BasicTableUI
}
else
updateSelection(e.isControlDown());
-
+
+ // If we were editing, but the moved to another cell, stop editing
+ if (rowLead != rowModel.getLeadSelectionIndex() ||
+ colLead != colModel.getLeadSelectionIndex())
+ if (table.isEditing())
+ table.editingStopped(new ChangeEvent(e));
}
public void mouseReleased(MouseEvent e)
{
@@ -193,23 +200,50 @@ public class BasicTableUI
{
return new FocusHandler();
}
- protected KeyListener createKeyListener()
- {
- return new KeyHandler();
- }
+
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
+ /**
+ * Return the maximum size of the table. The maximum height is the row
+ * height times the number of rows. The maximum width is the sum of
+ * the maximum widths of each column.
+ *
+ * @param comp the component whose maximum size is being queried,
+ * this is ignored.
+ * @return a Dimension object representing the maximum size of the table,
+ * or null if the table has no elements.
+ */
public Dimension getMaximumSize(JComponent comp)
{
- return getPreferredSize(comp);
+ int maxTotalColumnWidth = 0;
+ for (int i = 0; i < table.getColumnCount(); i++)
+ maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth();
+ if (maxTotalColumnWidth == 0 || table.getRowCount() == 0)
+ return null;
+ return new Dimension(maxTotalColumnWidth, table.getRowCount()*table.getRowHeight());
}
+ /**
+ * Return the minimum size of the table. The minimum height is the row
+ * height times the number of rows. The minimum width is the sum of
+ * the minimum widths of each column.
+ *
+ * @param comp the component whose minimum size is being queried,
+ * this is ignored.
+ * @return a Dimension object representing the minimum size of the table,
+ * or null if the table has no elements.
+ */
public Dimension getMinimumSize(JComponent comp)
{
- return getPreferredSize(comp);
+ int minTotalColumnWidth = 0;
+ for (int i = 0; i < table.getColumnCount(); i++)
+ minTotalColumnWidth += table.getColumnModel().getColumn(i).getMinWidth();
+ if (minTotalColumnWidth == 0 || table.getRowCount() == 0)
+ return null;
+ return new Dimension(minTotalColumnWidth, table.getRowCount()*table.getRowHeight());
}
public Dimension getPreferredSize(JComponent comp)
@@ -233,8 +267,657 @@ public class BasicTableUI
highlightCellBorder = defaults.getBorder("Table.focusCellHighlightBorder");
cellBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
}
+
+ private int convertModifiers(int mod)
+ {
+ if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.SHIFT_MASK;
+ mod &= ~KeyEvent.SHIFT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.CTRL_MASK;
+ mod &= ~KeyEvent.CTRL_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.META_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.META_MASK;
+ mod &= ~KeyEvent.META_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_MASK;
+ mod &= ~KeyEvent.ALT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_GRAPH_MASK;
+ mod &= ~KeyEvent.ALT_GRAPH_DOWN_MASK;
+ }
+ return mod;
+ }
+
protected void installKeyboardActions()
{
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ InputMap ancestorMap = (InputMap)defaults.get("Table.ancestorInputMap");
+ InputMapUIResource parentInputMap = new InputMapUIResource();
+ // FIXME: The JDK uses a LazyActionMap for parentActionMap
+ ActionMap parentActionMap = new ActionMap();
+ action = new TableAction();
+ Object keys[] = ancestorMap.allKeys();
+ // Register key bindings in the UI InputMap-ActionMap pair
+ // Note that we register key bindings with both the old and new modifier
+ // masks: InputEvent.SHIFT_MASK and InputEvent.SHIFT_DOWN_MASK and so on.
+ for (int i = 0; i < keys.length; i++)
+ {
+ parentInputMap.put(KeyStroke.getKeyStroke
+ (((KeyStroke)keys[i]).getKeyCode(), convertModifiers
+ (((KeyStroke)keys[i]).getModifiers())),
+ (String)ancestorMap.get((KeyStroke)keys[i]));
+
+ parentInputMap.put(KeyStroke.getKeyStroke
+ (((KeyStroke)keys[i]).getKeyCode(),
+ ((KeyStroke)keys[i]).getModifiers()),
+ (String)ancestorMap.get((KeyStroke)keys[i]));
+
+ parentActionMap.put
+ ((String)ancestorMap.get((KeyStroke)keys[i]), new ActionListenerProxy
+ (action, (String)ancestorMap.get((KeyStroke)keys[i])));
+
+ }
+ // Set the UI InputMap-ActionMap pair to be the parents of the
+ // JTable's InputMap-ActionMap pair
+ parentInputMap.setParent
+ (table.getInputMap
+ (JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent());
+ parentActionMap.setParent(table.getActionMap().getParent());
+ table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
+ setParent(parentInputMap);
+ table.getActionMap().setParent(parentActionMap);
+ }
+
+ /**
+ * This class is used to mimmic the behaviour of the JDK when registering
+ * keyboard actions. It is the same as the private class used in JComponent
+ * for the same reason. This class receives an action event and dispatches
+ * it to the true receiver after altering the actionCommand property of the
+ * event.
+ */
+ private static class ActionListenerProxy
+ extends AbstractAction
+ {
+ ActionListener target;
+ String bindingCommandName;
+
+ public ActionListenerProxy(ActionListener li,
+ String cmd)
+ {
+ target = li;
+ bindingCommandName = cmd;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ ActionEvent derivedEvent = new ActionEvent(e.getSource(),
+ e.getID(),
+ bindingCommandName,
+ e.getModifiers());
+ target.actionPerformed(derivedEvent);
+ }
+ }
+
+ /**
+ * This class implements the actions that we want to happen
+ * when specific keys are pressed for the JTable. The actionPerformed
+ * method is called when a key that has been registered for the JTable
+ * is received.
+ */
+ class TableAction extends AbstractAction
+ {
+ /**
+ * What to do when this action is called.
+ *
+ * @param e the ActionEvent that caused this action.
+ */
+ public void actionPerformed (ActionEvent e)
+ {
+ ListSelectionModel rowModel = table.getSelectionModel();
+ ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+
+ int rowLead = rowModel.getLeadSelectionIndex();
+ int rowMax = table.getModel().getRowCount() - 1;
+
+ int colLead = colModel.getLeadSelectionIndex();
+ int colMax = table.getModel().getColumnCount() - 1;
+
+ if (e.getActionCommand().equals("selectPreviousRowExtendSelection"))
+ {
+ rowModel.setLeadSelectionIndex(Math.max(rowLead - 1, 0));
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("selectLastColumn"))
+ {
+ table.clearSelection();
+ rowModel.setSelectionInterval(rowLead, rowLead);
+ colModel.setSelectionInterval(colMax, colMax);
+ }
+ else if (e.getActionCommand().equals("startEditing"))
+ {
+ if (table.isCellEditable(rowLead, colLead))
+ table.editCellAt(rowLead,colLead);
+ }
+ else if (e.getActionCommand().equals("selectFirstRowExtendSelection"))
+ {
+ rowModel.setLeadSelectionIndex(0);
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("selectFirstColumn"))
+ {
+ rowModel.setSelectionInterval(rowLead, rowLead);
+ colModel.setSelectionInterval(0, 0);
+ }
+ else if (e.getActionCommand().equals("selectFirstColumnExtendSelection"))
+ {
+ colModel.setLeadSelectionIndex(0);
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("selectLastRow"))
+ {
+ rowModel.setSelectionInterval(rowMax,rowMax);
+ colModel.setSelectionInterval(colLead, colLead);
+ }
+ else if (e.getActionCommand().equals("selectNextRowExtendSelection"))
+ {
+ rowModel.setLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("selectFirstRow"))
+ {
+ rowModel.setSelectionInterval(0,0);
+ colModel.setSelectionInterval(colLead, colLead);
+ }
+ else if (e.getActionCommand().equals("selectNextColumnExtendSelection"))
+ {
+ colModel.setLeadSelectionIndex(Math.min(colLead + 1, colMax));
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("selectLastColumnExtendSelection"))
+ {
+ colModel.setLeadSelectionIndex(colMax);
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("selectPreviousColumnExtendSelection"))
+ {
+ colModel.setLeadSelectionIndex(Math.max(colLead - 1, 0));
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("selectNextRow"))
+ {
+ rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
+ Math.min(rowLead + 1, rowMax));
+ colModel.setSelectionInterval(colLead,colLead);
+ }
+ else if (e.getActionCommand().equals("scrollUpExtendSelection"))
+ {
+ int target;
+ if (rowLead == getFirstVisibleRowIndex())
+ target = Math.max
+ (0, rowLead - (getLastVisibleRowIndex() -
+ getFirstVisibleRowIndex() + 1));
+ else
+ target = getFirstVisibleRowIndex();
+
+ rowModel.setLeadSelectionIndex(target);
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("selectPreviousRow"))
+ {
+ rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
+ Math.max(rowLead - 1, 0));
+ colModel.setSelectionInterval(colLead,colLead);
+ }
+ else if (e.getActionCommand().equals("scrollRightChangeSelection"))
+ {
+ int target;
+ if (colLead == getLastVisibleColumnIndex())
+ target = Math.min
+ (colMax, colLead + (getLastVisibleColumnIndex() -
+ getFirstVisibleColumnIndex() + 1));
+ else
+ target = getLastVisibleColumnIndex();
+
+ colModel.setSelectionInterval(target, target);
+ rowModel.setSelectionInterval(rowLead, rowLead);
+ }
+ else if (e.getActionCommand().equals("selectPreviousColumn"))
+ {
+ rowModel.setSelectionInterval(rowLead,rowLead);
+ colModel.setSelectionInterval(Math.max(colLead - 1, 0),
+ Math.max(colLead - 1, 0));
+ }
+ else if (e.getActionCommand().equals("scrollLeftChangeSelection"))
+ {
+ int target;
+ if (colLead == getFirstVisibleColumnIndex())
+ target = Math.max
+ (0, colLead - (getLastVisibleColumnIndex() -
+ getFirstVisibleColumnIndex() + 1));
+ else
+ target = getFirstVisibleColumnIndex();
+
+ colModel.setSelectionInterval(target, target);
+ rowModel.setSelectionInterval(rowLead, rowLead);
+ }
+ else if (e.getActionCommand().equals("clearSelection"))
+ {
+ table.clearSelection();
+ }
+ else if (e.getActionCommand().equals("cancel"))
+ {
+ // FIXME: implement other parts of "cancel" like undo-ing last
+ // selection. Right now it just calls editingCancelled if
+ // we're currently editing.
+ if (table.isEditing())
+ table.editingCanceled(new ChangeEvent("cancel"));
+ }
+ else if (e.getActionCommand().equals("selectNextRowCell")
+ || e.getActionCommand().equals("selectPreviousRowCell")
+ || e.getActionCommand().equals("selectNextColumnCell")
+ || e.getActionCommand().equals("selectPreviousColumnCell"))
+ {
+ // If nothing is selected, select the first cell in the table
+ if (table.getSelectedRowCount() == 0 &&
+ table.getSelectedColumnCount() == 0)
+ {
+ rowModel.setSelectionInterval(0, 0);
+ colModel.setSelectionInterval(0, 0);
+ return;
+ }
+
+ // If the lead selection index isn't selected (ie a remove operation
+ // happened, then set the lead to the first selected cell in the
+ // table
+ if (!table.isCellSelected(rowLead, colLead))
+ {
+ rowModel.addSelectionInterval(rowModel.getMinSelectionIndex(),
+ rowModel.getMinSelectionIndex());
+ colModel.addSelectionInterval(colModel.getMinSelectionIndex(),
+ colModel.getMinSelectionIndex());
+ return;
+ }
+
+ // multRowsSelected and multColsSelected tell us if multiple rows or
+ // columns are selected, respectively
+ boolean multRowsSelected, multColsSelected;
+ multRowsSelected = table.getSelectedRowCount() > 1 &&
+ table.getRowSelectionAllowed();
+
+ multColsSelected = table.getSelectedColumnCount() > 1 &&
+ table.getColumnSelectionAllowed();
+
+ // If there is just one selection, select the next cell, and wrap
+ // when you get to the edges of the table.
+ if (!multColsSelected && !multRowsSelected)
+ {
+ if (e.getActionCommand().indexOf("Column") != -1)
+ advanceSingleSelection(colModel, colMax, rowModel, rowMax,
+ (e.getActionCommand().equals
+ ("selectPreviousColumnCell")));
+ else
+ advanceSingleSelection(rowModel, rowMax, colModel, colMax,
+ (e.getActionCommand().equals
+ ("selectPreviousRowCell")));
+ return;
+ }
+
+
+ // rowMinSelected and rowMaxSelected are the minimum and maximum
+ // values respectively of selected cells in the row selection model
+ // Similarly for colMinSelected and colMaxSelected.
+ int rowMaxSelected = table.getRowSelectionAllowed() ?
+ rowModel.getMaxSelectionIndex() : table.getModel().getRowCount() - 1;
+ int rowMinSelected = table.getRowSelectionAllowed() ?
+ rowModel.getMinSelectionIndex() : 0;
+ int colMaxSelected = table.getColumnSelectionAllowed() ?
+ colModel.getMaxSelectionIndex() :
+ table.getModel().getColumnCount() - 1;
+ int colMinSelected = table.getColumnSelectionAllowed() ?
+ colModel.getMinSelectionIndex() : 0;
+
+ // If there are multiple rows and columns selected, select the next
+ // cell and wrap at the edges of the selection.
+ if (e.getActionCommand().indexOf("Column") != -1)
+ advanceMultipleSelection(colModel, colMinSelected, colMaxSelected,
+ rowModel, rowMinSelected, rowMaxSelected,
+ (e.getActionCommand().equals
+ ("selectPreviousColumnCell")), true);
+
+ else
+ advanceMultipleSelection(rowModel, rowMinSelected, rowMaxSelected,
+ colModel, colMinSelected, colMaxSelected,
+ (e.getActionCommand().equals
+ ("selectPreviousRowCell")), false);
+ }
+ else if (e.getActionCommand().equals("selectNextColumn"))
+ {
+ rowModel.setSelectionInterval(rowLead,rowLead);
+ colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
+ Math.min(colLead + 1, colMax));
+ }
+ else if (e.getActionCommand().equals("scrollLeftExtendSelection"))
+ {
+ int target;
+ if (colLead == getFirstVisibleColumnIndex())
+ target = Math.max
+ (0, colLead - (getLastVisibleColumnIndex() -
+ getFirstVisibleColumnIndex() + 1));
+ else
+ target = getFirstVisibleColumnIndex();
+
+ colModel.setLeadSelectionIndex(target);
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("scrollDownChangeSelection"))
+ {
+ int target;
+ if (rowLead == getLastVisibleRowIndex())
+ target = Math.min
+ (rowMax, rowLead + (getLastVisibleRowIndex() -
+ getFirstVisibleRowIndex() + 1));
+ else
+ target = getLastVisibleRowIndex();
+
+ rowModel.setSelectionInterval(target, target);
+ colModel.setSelectionInterval(colLead, colLead);
+ }
+ else if (e.getActionCommand().equals("scrollRightExtendSelection"))
+ {
+ int target;
+ if (colLead == getLastVisibleColumnIndex())
+ target = Math.min
+ (colMax, colLead + (getLastVisibleColumnIndex() -
+ getFirstVisibleColumnIndex() + 1));
+ else
+ target = getLastVisibleColumnIndex();
+
+ colModel.setLeadSelectionIndex(target);
+ rowModel.setLeadSelectionIndex(rowLead);
+ }
+ else if (e.getActionCommand().equals("selectAll"))
+ {
+ table.selectAll();
+ }
+ else if (e.getActionCommand().equals("selectLastRowExtendSelection"))
+ {
+ rowModel.setLeadSelectionIndex(rowMax);
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("scrollDownExtendSelection"))
+ {
+ int target;
+ if (rowLead == getLastVisibleRowIndex())
+ target = Math.min
+ (rowMax, rowLead + (getLastVisibleRowIndex() -
+ getFirstVisibleRowIndex() + 1));
+ else
+ target = getLastVisibleRowIndex();
+
+ rowModel.setLeadSelectionIndex(target);
+ colModel.setLeadSelectionIndex(colLead);
+ }
+ else if (e.getActionCommand().equals("scrollUpChangeSelection"))
+ {
+ int target;
+ if (rowLead == getFirstVisibleRowIndex())
+ target = Math.max
+ (0, rowLead - (getLastVisibleRowIndex() -
+ getFirstVisibleRowIndex() + 1));
+ else
+ target = getFirstVisibleRowIndex();
+
+ rowModel.setSelectionInterval(target, target);
+ colModel.setSelectionInterval(colLead, colLead);
+ }
+ else
+ {
+ // If we're here that means we bound this TableAction class
+ // to a keyboard input but we either want to ignore that input
+ // or we just haven't implemented its action yet.
+ }
+
+ if (table.isEditing() && e.getActionCommand() != "startEditing")
+ table.editingCanceled(new ChangeEvent("update"));
+ table.repaint();
+
+ table.scrollRectToVisible
+ (table.getCellRect(rowModel.getLeadSelectionIndex(),
+ colModel.getLeadSelectionIndex(), false));
+ }
+
+ int getFirstVisibleColumnIndex()
+ {
+ ComponentOrientation or = table.getComponentOrientation();
+ Rectangle r = table.getVisibleRect();
+ if (!or.isLeftToRight())
+ r.translate((int) r.getWidth() - 1, 0);
+ return table.columnAtPoint(r.getLocation());
+ }
+
+ /**
+ * Returns the column index of the last visible column.
+ *
+ */
+ int getLastVisibleColumnIndex()
+ {
+ ComponentOrientation or = table.getComponentOrientation();
+ Rectangle r = table.getVisibleRect();
+ if (or.isLeftToRight())
+ r.translate((int) r.getWidth() - 1, 0);
+ return table.columnAtPoint(r.getLocation());
+ }
+
+ /**
+ * Returns the row index of the first visible row.
+ *
+ */
+ int getFirstVisibleRowIndex()
+ {
+ ComponentOrientation or = table.getComponentOrientation();
+ Rectangle r = table.getVisibleRect();
+ if (!or.isLeftToRight())
+ r.translate((int) r.getWidth() - 1, 0);
+ return table.rowAtPoint(r.getLocation());
+ }
+
+ /**
+ * Returns the row index of the last visible row.
+ *
+ */
+ int getLastVisibleRowIndex()
+ {
+ ComponentOrientation or = table.getComponentOrientation();
+ Rectangle r = table.getVisibleRect();
+ r.translate(0, (int) r.getHeight() - 1);
+ if (or.isLeftToRight())
+ r.translate((int) r.getWidth() - 1, 0);
+ // The next if makes sure that we don't return -1 simply because
+ // there is white space at the bottom of the table (ie, the display
+ // area is larger than the table)
+ if (table.rowAtPoint(r.getLocation()) == -1)
+ {
+ if (getFirstVisibleRowIndex() == -1)
+ return -1;
+ else
+ return table.getModel().getRowCount() - 1;
+ }
+ return table.rowAtPoint(r.getLocation());
+ }
+
+ /**
+ * A helper method for the key bindings. Used because the actions
+ * for TAB, SHIFT-TAB, ENTER, and SHIFT-ENTER are very similar.
+ *
+ * Selects the next (previous if SHIFT pressed) column for TAB, or row for
+ * ENTER from within the currently selected cells.
+ *
+ * @param firstModel the ListSelectionModel for columns (TAB) or
+ * rows (ENTER)
+ * @param firstMin the first selected index in firstModel
+ * @param firstMax the last selected index in firstModel
+ * @param secondModel the ListSelectionModel for rows (TAB) or
+ * columns (ENTER)
+ * @param secondMin the first selected index in secondModel
+ * @param secondMax the last selected index in secondModel
+ * @param reverse true if shift was held for the event
+ * @param eventIsTab true if TAB was pressed, false if ENTER pressed
+ */
+ void advanceMultipleSelection (ListSelectionModel firstModel, int firstMin,
+ int firstMax, ListSelectionModel secondModel,
+ int secondMin, int secondMax, boolean reverse,
+ boolean eventIsTab)
+ {
+ // If eventIsTab, all the "firsts" correspond to columns, otherwise, to rows
+ // "seconds" correspond to the opposite
+ int firstLead = firstModel.getLeadSelectionIndex();
+ int secondLead = secondModel.getLeadSelectionIndex();
+ int numFirsts = eventIsTab ?
+ table.getModel().getColumnCount() : table.getModel().getRowCount();
+ int numSeconds = eventIsTab ?
+ table.getModel().getRowCount() : table.getModel().getColumnCount();
+
+ // check if we have to wrap the "firsts" around, going to the other side
+ if ((firstLead == firstMax && !reverse) ||
+ (reverse && firstLead == firstMin))
+ {
+ firstModel.addSelectionInterval(reverse ? firstMax : firstMin,
+ reverse ? firstMax : firstMin);
+
+ // check if we have to wrap the "seconds"
+ if ((secondLead == secondMax && !reverse) ||
+ (reverse && secondLead == secondMin))
+ secondModel.addSelectionInterval(reverse ? secondMax : secondMin,
+ reverse ? secondMax : secondMin);
+
+ // if we're not wrapping the seconds, we have to find out where we
+ // are within the secondModel and advance to the next cell (or
+ // go back to the previous cell if reverse == true)
+ else
+ {
+ int[] secondsSelected;
+ if (eventIsTab && table.getRowSelectionAllowed() ||
+ !eventIsTab && table.getColumnSelectionAllowed())
+ secondsSelected = eventIsTab ?
+ table.getSelectedRows() : table.getSelectedColumns();
+ else
+ {
+ // if row selection is not allowed, then the entire column gets
+ // selected when you click on it, so consider ALL rows selected
+ secondsSelected = new int[numSeconds];
+ for (int i = 0; i < numSeconds; i++)
+ secondsSelected[i] = i;
+ }
+
+ // and now find the "next" index within the model
+ int secondIndex = reverse ? secondsSelected.length - 1 : 0;
+ if (!reverse)
+ while (secondsSelected[secondIndex] <= secondLead)
+ secondIndex++;
+ else
+ while (secondsSelected[secondIndex] >= secondLead)
+ secondIndex--;
+
+ // and select it - updating the lead selection index
+ secondModel.addSelectionInterval(secondsSelected[secondIndex],
+ secondsSelected[secondIndex]);
+ }
+ }
+ // We didn't have to wrap the firsts, so just find the "next" first
+ // and select it, we don't have to change "seconds"
+ else
+ {
+ int[] firstsSelected;
+ if (eventIsTab && table.getColumnSelectionAllowed() ||
+ !eventIsTab && table.getRowSelectionAllowed())
+ firstsSelected = eventIsTab ?
+ table.getSelectedColumns() : table.getSelectedRows();
+ else
+ {
+ // if selection not allowed, consider ALL firsts to be selected
+ firstsSelected = new int[numFirsts];
+ for (int i = 0; i < numFirsts; i++)
+ firstsSelected[i] = i;
+ }
+ int firstIndex = reverse ? firstsSelected.length - 1 : 0;
+ if (!reverse)
+ while (firstsSelected[firstIndex] <= firstLead)
+ firstIndex++;
+ else
+ while (firstsSelected[firstIndex] >= firstLead)
+ firstIndex--;
+ firstModel.addSelectionInterval(firstsSelected[firstIndex],
+ firstsSelected[firstIndex]);
+ secondModel.addSelectionInterval(secondLead, secondLead);
+ }
+ }
+
+ /**
+ * A helper method for the key bindings. Used because the actions
+ * for TAB, SHIFT-TAB, ENTER, and SHIFT-ENTER are very similar.
+ *
+ * Selects the next (previous if SHIFT pressed) column (TAB) or row (ENTER)
+ * in the table, changing the current selection. All cells in the table
+ * are eligible, not just the ones that are currently selected.
+ * @param firstModel the ListSelectionModel for columns (TAB) or rows
+ * (ENTER)
+ * @param firstMax the last index in firstModel
+ * @param secondModel the ListSelectionModel for rows (TAB) or columns
+ * (ENTER)
+ * @param secondMax the last index in secondModel
+ * @param reverse true if SHIFT was pressed for the event
+ */
+
+ void advanceSingleSelection (ListSelectionModel firstModel, int firstMax,
+ ListSelectionModel secondModel, int secondMax,
+ boolean reverse)
+ {
+ // for TABs, "first" corresponds to columns and "seconds" to rows.
+ // the opposite is true for ENTERs
+ int firstLead = firstModel.getLeadSelectionIndex();
+ int secondLead = secondModel.getLeadSelectionIndex();
+
+ // if we are going backwards subtract 2 because we later add 1
+ // for a net change of -1
+ if (reverse && (firstLead == 0))
+ {
+ // check if we have to wrap around
+ if (secondLead == 0)
+ secondLead += secondMax + 1;
+ secondLead -= 2;
+ }
+
+ // do we have to wrap the "seconds"?
+ if (reverse && (firstLead == 0) || !reverse && (firstLead == firstMax))
+ secondModel.setSelectionInterval((secondLead + 1)%(secondMax + 1),
+ (secondLead + 1)%(secondMax + 1));
+ // if not, just reselect the current lead
+ else
+ secondModel.setSelectionInterval(secondLead, secondLead);
+
+ // if we are going backwards, subtract 2 because we add 1 later
+ // for net change of -1
+ if (reverse)
+ {
+ // check for wraparound
+ if (firstLead == 0)
+ firstLead += firstMax + 1;
+ firstLead -= 2;
+ }
+ // select the next "first"
+ firstModel.setSelectionInterval ((firstLead + 1)%(firstMax + 1),
+ (firstLead + 1)%(firstMax + 1));
+ }
}
protected void installListeners()
@@ -281,7 +964,6 @@ public class BasicTableUI
{
table = (JTable)comp;
focusListener = createFocusListener();
- keyListener = createKeyListener();
mouseInputListener = createMouseInputListener();
installDefaults();
installKeyboardActions();
@@ -332,14 +1014,19 @@ public class BasicTableUI
gfx.translate(x, y);
comp.setBounds(new Rectangle(0, 0, width, height));
// Set correct border on cell renderer.
+ // Only the lead selection cell gets a border
if (comp instanceof JComponent)
{
- if (table.isCellSelected(r, c))
+ if (table.getSelectionModel().getLeadSelectionIndex() == r
+ && table.getColumnModel().getSelectionModel().
+ getLeadSelectionIndex() == c)
((JComponent) comp).setBorder(highlightCellBorder);
else
((JComponent) comp).setBorder(cellBorder);
}
comp.paint(gfx);
+ if (comp instanceof JTextField)
+ ((JTextField)comp).getCaret().paint(gfx);
gfx.translate(-x, -y);
}
y += height;
@@ -392,7 +1079,5 @@ public class BasicTableUI
}
gfx.setColor(save);
}
-
}
-
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
index dd0828e..91ccb00 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
@@ -78,10 +78,20 @@ import javax.swing.text.Position;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
-
+/**
+ * The abstract base class from which the UI classes for Swings text
+ * components are derived. This provides most of the functionality for
+ * the UI classes.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public abstract class BasicTextUI extends TextUI
implements ViewFactory
{
+ /**
+ * A {@link DefaultCaret} that implements {@link UIResource}.
+ */
public static class BasicCaret extends DefaultCaret
implements UIResource
{
@@ -90,6 +100,9 @@ public abstract class BasicTextUI extends TextUI
}
}
+ /**
+ * A {@link DefaultHighlighter} that implements {@link UIResource}.
+ */
public static class BasicHighlighter extends DefaultHighlighter
implements UIResource
{
@@ -97,40 +110,120 @@ public abstract class BasicTextUI extends TextUI
{
}
}
-
+
+ /**
+ * This view forms the root of the View hierarchy. However, it delegates
+ * most calls to another View which is the real root of the hierarchy.
+ * The purpose is to make sure that all Views in the hierarchy, including
+ * the (real) root have a well-defined parent to which they can delegate
+ * calls like {@link #preferenceChanged}, {@link #getViewFactory} and
+ * {@link #getContainer}.
+ */
private class RootView extends View
{
+ /** The real root view. */
private View view;
-
+
+ /**
+ * Creates a new RootView.
+ */
public RootView()
{
super(null);
}
- // View methods.
-
+ /**
+ * Returns the ViewFactory for this RootView. If the current EditorKit
+ * provides a ViewFactory, this is used. Otherwise the TextUI itself
+ * is returned as a ViewFactory.
+ *
+ * @return the ViewFactory for this RootView
+ */
public ViewFactory getViewFactory()
{
- // FIXME: Handle EditorKit somehow.
- return BasicTextUI.this;
+ ViewFactory factory = null;
+ EditorKit editorKit = BasicTextUI.this.getEditorKit(getComponent());
+ factory = editorKit.getViewFactory();
+ if (factory == null)
+ factory = BasicTextUI.this;
+ return factory;
+ }
+
+ /**
+ * Indicates that the preferences of one of the child view has changed.
+ * This calls revalidate on the text component.
+ *
+ * @param view the child view which's preference has changed
+ * @param width true
if the width preference has changed
+ * @param height true
if the height preference has changed
+ */
+ public void preferenceChanged(View view, boolean width, boolean height)
+ {
+ textComponent.revalidate();
}
+ /**
+ * Sets the real root view.
+ *
+ * @param v the root view to set
+ */
public void setView(View v)
{
if (view != null)
- view.setParent(null);
+ view.setParent(null);
if (v != null)
- v.setParent(null);
+ v.setParent(null);
view = v;
}
+ /**
+ * Returns the real root view, regardless of the index.
+ *
+ * @param index not used here
+ *
+ * @return the real root view, regardless of the index.
+ */
+ public View getView(int index)
+ {
+ return view;
+ }
+
+ /**
+ * Returns 1
since the RootView always contains one
+ * child, that is the real root of the View hierarchy.
+ *
+ * @return 1
since the RootView always contains one
+ * child, that is the real root of the View hierarchy
+ */
+ public int getViewCount()
+ {
+ if (view != null)
+ return 1;
+ else
+ return 0;
+ }
+
+ /**
+ * Returns the Container
that contains this view. This
+ * normally will be the text component that is managed by this TextUI.
+ *
+ * @return the Container
that contains this view
+ */
public Container getContainer()
{
return textComponent;
}
-
+
+ /**
+ * Returns the preferred span along the specified axis
.
+ * This is delegated to the real root view.
+ *
+ * @param axis the axis for which the preferred span is queried
+ *
+ * @return the preferred span along the axis
+ */
public float getPreferredSpan(int axis)
{
if (view != null)
@@ -139,19 +232,61 @@ public abstract class BasicTextUI extends TextUI
return Integer.MAX_VALUE;
}
+ /**
+ * Paints the view. This is delegated to the real root view.
+ *
+ * @param g the Graphics
context to paint to
+ * @param s the allocation for the View
+ */
public void paint(Graphics g, Shape s)
{
if (view != null)
view.paint(g, s);
}
+
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * This is delegated to the real root view.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ * @param bias either {@link Position.Bias.Forward} or
+ * {@link Position.Bias.Backward} depending on the preferred
+ * direction bias. If null
this defaults to
+ * Position.Bias.Forward
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if pos
is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
public Shape modelToView(int position, Shape a, Position.Bias bias)
throws BadLocationException
{
- if (view == null)
- return null;
-
- return ((PlainView) view).modelToView(position, a, bias).getBounds();
+ return ((View) view).modelToView(position, a, bias);
+ }
+
+ /**
+ * Maps coordinates from the View
's space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this View
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates x, y
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
+ {
+ return view.viewToModel(x, y, a, b);
}
/**
@@ -194,8 +329,16 @@ public abstract class BasicTextUI extends TextUI
}
}
+ /**
+ * Receives notifications when properties of the text component change.
+ */
class UpdateHandler implements PropertyChangeListener
{
+ /**
+ * Notifies when a property of the text component changes.
+ *
+ * @param event the PropertyChangeEvent describing the change
+ */
public void propertyChange(PropertyChangeEvent event)
{
if (event.getPropertyName().equals("document"))
@@ -223,7 +366,7 @@ public abstract class BasicTextUI extends TextUI
{
Dimension size = textComponent.getSize();
rootView.changedUpdate(ev, new Rectangle(0, 0, size.width, size.height),
- BasicTextUI.this);
+ rootView.getViewFactory());
}
/**
@@ -235,7 +378,7 @@ public abstract class BasicTextUI extends TextUI
{
Dimension size = textComponent.getSize();
rootView.insertUpdate(ev, new Rectangle(0, 0, size.width, size.height),
- BasicTextUI.this);
+ rootView.getViewFactory());
int caretPos = textComponent.getCaretPosition();
if (caretPos >= ev.getOffset())
textComponent.setCaretPosition(caretPos + ev.getLength());
@@ -250,41 +393,80 @@ public abstract class BasicTextUI extends TextUI
{
Dimension size = textComponent.getSize();
rootView.removeUpdate(ev, new Rectangle(0, 0, size.width, size.height),
- BasicTextUI.this);
+ rootView.getViewFactory());
int caretPos = textComponent.getCaretPosition();
if (caretPos >= ev.getOffset())
textComponent.setCaretPosition(ev.getOffset());
}
}
+ /**
+ * The EditorKit used by this TextUI.
+ */
+ // FIXME: should probably be non-static.
static EditorKit kit = new DefaultEditorKit();
+ /**
+ * The root view.
+ */
RootView rootView = new RootView();
+
+ /**
+ * The text component that we handle.
+ */
JTextComponent textComponent;
+
+ /**
+ * Receives notification when the model changes.
+ */
UpdateHandler updateHandler = new UpdateHandler();
/** The DocumentEvent handler. */
DocumentHandler documentHandler = new DocumentHandler();
+ /**
+ * Creates a new BasicTextUI
instance.
+ */
public BasicTextUI()
{
}
+ /**
+ * Creates a {@link Caret} that should be installed into the text component.
+ *
+ * @return a caret that should be installed into the text component
+ */
protected Caret createCaret()
{
return new BasicCaret();
}
+ /**
+ * Creates a {@link Highlighter} that should be installed into the text
+ * component.
+ *
+ * @return a Highlighter
for the text component
+ */
protected Highlighter createHighlighter()
{
return new BasicHighlighter();
}
-
+
+ /**
+ * The text component that is managed by this UI.
+ *
+ * @return the text component that is managed by this UI
+ */
protected final JTextComponent getComponent()
{
return textComponent;
}
-
+
+ /**
+ * Installs this UI on the text component.
+ *
+ * @param c the text component on which to install the UI
+ */
public void installUI(final JComponent c)
{
super.installUI(c);
@@ -307,6 +489,9 @@ public abstract class BasicTextUI extends TextUI
installKeyboardActions();
}
+ /**
+ * Installs UI defaults on the text components.
+ */
protected void installDefaults()
{
Caret caret = textComponent.getCaret();
@@ -331,6 +516,9 @@ public abstract class BasicTextUI extends TextUI
caret.setBlinkRate(defaults.getInt(prefix + ".caretBlinkRate"));
}
+ /**
+ * This FocusListener triggers repaints on focus shift.
+ */
private FocusListener focuslistener = new FocusListener() {
public void focusGained(FocusEvent e)
{
@@ -342,6 +530,9 @@ public abstract class BasicTextUI extends TextUI
}
};
+ /**
+ * Install all listeners on the text component.
+ */
protected void installListeners()
{
textComponent.addFocusListener(focuslistener);
@@ -375,6 +566,11 @@ public abstract class BasicTextUI extends TextUI
return className;
}
+ /**
+ * Creates the {@link Keymap} that is installed on the text component.
+ *
+ * @return the {@link Keymap} that is installed on the text component
+ */
protected Keymap createKeymap()
{
String prefix = getPropertyPrefix();
@@ -393,6 +589,9 @@ public abstract class BasicTextUI extends TextUI
return km;
}
+ /**
+ * Installs the keyboard actions on the text components.
+ */
protected void installKeyboardActions()
{
// load any bindings for the older Keymap interface
@@ -408,6 +607,13 @@ public abstract class BasicTextUI extends TextUI
SwingUtilities.replaceUIActionMap(textComponent, getActionMap());
}
+ /**
+ * Gets the input map for the specified condition
.
+ *
+ * @param condition the condition for the InputMap
+ *
+ * @return the InputMap for the specified condition
+ */
InputMap getInputMap(int condition)
{
String prefix = getPropertyPrefix();
@@ -425,6 +631,13 @@ public abstract class BasicTextUI extends TextUI
}
}
+ /**
+ * Returns the ActionMap to be installed on the text component.
+ *
+ * @return the ActionMap to be installed on the text component
+ */
+ // FIXME: The UIDefaults have no entries for .actionMap, so this should
+ // be handled somehow different.
ActionMap getActionMap()
{
String prefix = getPropertyPrefix();
@@ -438,6 +651,11 @@ public abstract class BasicTextUI extends TextUI
return am;
}
+ /**
+ * Creates an ActionMap to be installed on the text component.
+ *
+ * @return an ActionMap to be installed on the text component
+ */
ActionMap createActionMap()
{
Action[] actions = textComponent.getActions();
@@ -450,7 +668,12 @@ public abstract class BasicTextUI extends TextUI
}
return am;
}
-
+
+ /**
+ * Uninstalls this TextUI from the text component.
+ *
+ * @param component the text component to uninstall the UI from
+ */
public void uninstallUI(final JComponent component)
{
super.uninstallUI(component);
@@ -465,23 +688,49 @@ public abstract class BasicTextUI extends TextUI
textComponent = null;
}
+ /**
+ * Uninstalls all default properties that have previously been installed by
+ * this UI.
+ */
protected void uninstallDefaults()
{
// Do nothing here.
}
+ /**
+ * Uninstalls all listeners that have previously been installed by
+ * this UI.
+ */
protected void uninstallListeners()
{
textComponent.removeFocusListener(focuslistener);
}
+ /**
+ * Uninstalls all keyboard actions that have previously been installed by
+ * this UI.
+ */
protected void uninstallKeyboardActions()
{
- // Do nothing here.
+ // FIXME: Uninstall keyboard actions here.
}
-
+
+ /**
+ * Returns the property prefix by which the text component's UIDefaults
+ * are looked up.
+ *
+ * @return the property prefix by which the text component's UIDefaults
+ * are looked up
+ */
protected abstract String getPropertyPrefix();
+ /**
+ * Returns the preferred size of the text component.
+ *
+ * @param c not used here
+ *
+ * @return the preferred size of the text component
+ */
public Dimension getPreferredSize(JComponent c)
{
View v = getRootView(textComponent);
@@ -497,6 +746,8 @@ public abstract class BasicTextUI extends TextUI
*
* This returns (Integer.MAX_VALUE, Integer.MAX_VALUE).
*
+ * @param c not used here
+ *
* @return the maximum size for text components that use this UI
*/
public Dimension getMaximumSize(JComponent c)
@@ -505,11 +756,22 @@ public abstract class BasicTextUI extends TextUI
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
+ /**
+ * Paints the text component.
+ *
+ * @param g the Graphics
context to paint to
+ * @param c not used here
+ */
public final void paint(Graphics g, JComponent c)
{
paintSafely(g);
}
+ /**
+ * Actually performs the painting.
+ *
+ * @param g the Graphics
context to paint to
+ */
protected void paintSafely(Graphics g)
{
Caret caret = textComponent.getCaret();
@@ -528,74 +790,213 @@ public abstract class BasicTextUI extends TextUI
caret.paint(g);
}
+ /**
+ * Paints the background of the text component.
+ *
+ * @param g the Graphics
context to paint to
+ */
protected void paintBackground(Graphics g)
{
g.setColor(textComponent.getBackground());
g.fillRect(0, 0, textComponent.getWidth(), textComponent.getHeight());
}
+ /**
+ * Marks the specified range inside the text component's model as
+ * damaged and queues a repaint request.
+ *
+ * @param t the text component
+ * @param p0 the start location inside the document model of the range that
+ * is damaged
+ * @param p1 the end location inside the document model of the range that
+ * is damaged
+ */
public void damageRange(JTextComponent t, int p0, int p1)
{
damageRange(t, p0, p1, null, null);
}
+ /**
+ * Marks the specified range inside the text component's model as
+ * damaged and queues a repaint request. This variant of this method
+ * allows a {@link Position.Bias} object to be specified for the start
+ * and end location of the range.
+ *
+ * @param t the text component
+ * @param p0 the start location inside the document model of the range that
+ * is damaged
+ * @param p1 the end location inside the document model of the range that
+ * is damaged
+ * @param firstBias the bias for the start location
+ * @param secondBias the bias for the end location
+ */
public void damageRange(JTextComponent t, int p0, int p1,
Position.Bias firstBias, Position.Bias secondBias)
{
+ // TODO: Implement me.
}
+ /**
+ * Returns the {@link EditorKit} used for the text component that is managed
+ * by this UI.
+ *
+ * @param t the text component
+ *
+ * @return the {@link EditorKit} used for the text component that is managed
+ * by this UI
+ */
public EditorKit getEditorKit(JTextComponent t)
{
return kit;
}
+ /**
+ * Gets the next position inside the document model that is visible on
+ * screen, starting from pos
.
+ *
+ * @param t the text component
+ * @param pos the start positionn
+ * @param b the bias for pos
+ * @param direction the search direction
+ * @param biasRet filled by the method to indicate the bias of the return
+ * value
+ *
+ * @return the next position inside the document model that is visible on
+ * screen
+ */
public int getNextVisualPositionFrom(JTextComponent t, int pos,
Position.Bias b, int direction,
Position.Bias[] biasRet)
throws BadLocationException
{
- return 0;
+ return 0; // TODO: Implement me.
}
+ /**
+ * Returns the root {@link View} of a text component.
+ *
+ * @return the root {@link View} of a text component
+ */
public View getRootView(JTextComponent t)
{
return rootView;
}
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero. A bias of {@link Position.Bias.Forward} is used in this method.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if pos
is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
public Rectangle modelToView(JTextComponent t, int pos)
throws BadLocationException
{
return modelToView(t, pos, Position.Bias.Forward);
}
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ * @param bias either {@link Position.Bias.Forward} or
+ * {@link Position.Bias.Backward} depending on the preferred
+ * direction bias. If null
this defaults to
+ * Position.Bias.Forward
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if pos
is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
public Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias)
throws BadLocationException
{
return rootView.modelToView(pos, getVisibleEditorRect(), bias).getBounds();
}
+ /**
+ * Maps a point in the View
coordinate space to a position
+ * inside a document model.
+ *
+ * @param t the text component
+ * @param pt the point to be mapped
+ *
+ * @return the position inside the document model that corresponds to
+ * pt
+ */
public int viewToModel(JTextComponent t, Point pt)
{
return viewToModel(t, pt, null);
}
+ /**
+ * Maps a point in the View
coordinate space to a position
+ * inside a document model.
+ *
+ * @param t the text component
+ * @param pt the point to be mapped
+ * @param biasReturn filled in by the method to indicate the bias of the
+ * return value
+ *
+ * @return the position inside the document model that corresponds to
+ * pt
+ */
public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn)
{
- return 0;
+ return 0; // FIXME: Implement me.
}
+ /**
+ * Creates a {@link View} for the specified {@link Element}.
+ *
+ * @param elem the Element
to create a View
for
+ *
+ * @see ViewFactory
+ */
public View create(Element elem)
{
// Subclasses have to implement this to get this functionality.
return null;
}
+ /**
+ * Creates a {@link View} for the specified {@link Element}.
+ *
+ * @param elem the Element
to create a View
for
+ * @param p0 the start offset
+ * @param p1 the end offset
+ *
+ * @see ViewFactory
+ */
public View create(Element elem, int p0, int p1)
{
// Subclasses have to implement this to get this functionality.
return null;
}
-
+
+ /**
+ * Returns the allocation to give the root view.
+ *
+ * @return the allocation to give the root view
+ *
+ * @specnote The allocation has nothing to do with visibility. According
+ * to the specs the naming of this method is unfortunate and
+ * has historical reasons
+ */
protected Rectangle getVisibleEditorRect()
{
int width = textComponent.getWidth();
@@ -610,12 +1011,21 @@ public abstract class BasicTextUI extends TextUI
height - insets.top + insets.bottom);
}
+ /**
+ * Sets the root view for the text component.
+ *
+ * @param view the View
to be set as root view
+ */
protected final void setView(View view)
{
rootView.setView(view);
view.setParent(rootView);
}
+ /**
+ * Indicates that the model of a text component has changed. This
+ * triggers a rebuild of the view hierarchy.
+ */
protected void modelChanged()
{
if (textComponent == null || rootView == null)
@@ -630,6 +1040,7 @@ public abstract class BasicTextUI extends TextUI
Element elem = doc.getDefaultRootElement();
if (elem == null)
return;
- setView(factory.create(elem));
+ View view = factory.create(elem);
+ setView(view);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java
index 84509ad..9106b0b 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java
@@ -56,7 +56,7 @@ public class BasicToggleButtonUI extends BasicButtonUI
*/
protected String getPropertyPrefix()
{
- return "ToggleButton";
+ return "ToggleButton.";
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
index bc655a2..8be89ef 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -542,19 +542,6 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
}
/**
- * This method returns the preferred size of the given JComponent for this
- * UI.
- *
- * @param c The JComponent to find a preferred size for.
- *
- * @return The preferred size for this UI.
- */
- public Dimension getPreferredSize(JComponent c)
- {
- return toolBar.getLayout().preferredLayoutSize(c);
- }
-
- /**
* This method installs the needed components for the JToolBar.
*/
protected void installComponents()
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
index b9d3b62..6f714a3 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
@@ -1,39 +1,39 @@
/* BasicTreeUI.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
package javax.swing.plaf.basic;
@@ -60,18 +60,22 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.util.Hashtable;
import javax.swing.AbstractAction;
import javax.swing.Action;
+import javax.swing.ActionMap;
import javax.swing.CellRendererPane;
import javax.swing.Icon;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
+import javax.swing.JTextField;
import javax.swing.JTree;
+import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
@@ -86,21 +90,20 @@ import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TreeUI;
+import javax.swing.text.Caret;
import javax.swing.tree.AbstractLayoutCache;
-import javax.swing.tree.FixedHeightLayoutCache;
-import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.ExpandVetoException;
+import javax.swing.tree.FixedHeightLayoutCache;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
-import javax.swing.tree.TreeSelectionModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
+import javax.swing.tree.TreeSelectionModel;
/**
* A delegate providing the user interface for JTree
according to
@@ -111,2703 +114,3482 @@ import java.util.Hashtable;
* @author Lillian Angel (langel@redhat.com)
*/
public class BasicTreeUI
- extends TreeUI
+ extends TreeUI
{
+ /** Collapse Icon for the tree. */
+ protected transient Icon collapsedIcon;
- /** Collapse Icon for the tree. */
- protected transient Icon collapsedIcon;
-
- /** Expanded Icon for the tree. */
- protected transient Icon expandedIcon;
-
- /** Distance between left margin and where vertical dashes will be drawn. */
- protected int leftChildIndent;
-
- /**
- * Distance between leftChildIndent and where cell contents will be drawn.
- */
- protected int rightChildIndent;
-
- /**
- * Total fistance that will be indented. The sum of leftChildIndent and
- * rightChildIndent .
- */
- protected int totalChildIndent;
-
- /** Minimum preferred size. */
- protected Dimension preferredMinsize;
-
- /** Index of the row that was last selected. */
- protected int lastSelectedRow;
-
- /** Component that we're going to be drawing onto. */
- protected JTree tree;
-
- /** Renderer that is being used to do the actual cell drawing. */
- protected transient TreeCellRenderer currentCellRenderer;
-
- /**
- * Set to true if the renderer that is currently in the tree was created by
- * this instance.
- */
- protected boolean createdRenderer;
-
- /** Editor for the tree. */
- protected transient TreeCellEditor cellEditor;
-
- /**
- * Set to true if editor that is currently in the tree was created by this
- * instance.
- */
- protected boolean createdCellEditor;
+ /** Expanded Icon for the tree. */
+ protected transient Icon expandedIcon;
- /**
- * Set to false when editing and shouldSelectCall() returns true meaning the
- * node should be selected before editing, used in completeEditing.
- */
- protected boolean stopEditingInCompleteEditing;
+ /** Distance between left margin and where vertical dashes will be drawn. */
+ protected int leftChildIndent;
- /** Used to paint the TreeCellRenderer. */
- protected CellRendererPane rendererPane;
+ /**
+ * Distance between leftChildIndent and where cell contents will be drawn.
+ */
+ protected int rightChildIndent;
- /** Size needed to completely display all the nodes. */
- protected Dimension preferredSize;
+ /**
+ * Total fistance that will be indented. The sum of leftChildIndent and
+ * rightChildIndent .
+ */
+ protected int totalChildIndent;
- /** Is the preferredSize valid? */
- protected boolean validCachedPreferredSize;
+ /** Minimum preferred size. */
+ protected Dimension preferredMinsize;
- /** Object responsible for handling sizing and expanded issues. */
- protected AbstractLayoutCache treeState;
+ /** Index of the row that was last selected. */
+ protected int lastSelectedRow;
- /** Used for minimizing the drawing of vertical lines. */
- protected Hashtable drawingCache;
+ /** Component that we're going to be drawing onto. */
+ protected JTree tree;
- /**
- * True if doing optimizations for a largeModel. Subclasses that don't
- * support this may wish to override createLayoutCache to not return a
- * FixedHeightLayoutCache instance.
- */
- protected boolean largeModel;
+ /** Renderer that is being used to do the actual cell drawing. */
+ protected transient TreeCellRenderer currentCellRenderer;
- /** Responsible for telling the TreeState the size needed for a node. */
- protected AbstractLayoutCache.NodeDimensions nodeDimensions;
+ /**
+ * Set to true if the renderer that is currently in the tree was created by
+ * this instance.
+ */
+ protected boolean createdRenderer;
- /** Used to determine what to display. */
- protected TreeModel treeModel;
+ /** Editor for the tree. */
+ protected transient TreeCellEditor cellEditor;
- /** Model maintaining the selection. */
- protected TreeSelectionModel treeSelectionModel;
+ /**
+ * Set to true if editor that is currently in the tree was created by this
+ * instance.
+ */
+ protected boolean createdCellEditor;
- /**
- * How much the depth should be offset to properly calculate x locations.
- * This is based on whether or not the root is visible, and if the root
- * handles are visible.
- */
- protected int depthOffset;
+ /**
+ * Set to false when editing and shouldSelectCall() returns true meaning the
+ * node should be selected before editing, used in completeEditing.
+ */
+ protected boolean stopEditingInCompleteEditing;
- /**
- * When editing, this will be the Component that is doing the actual editing.
- */
- protected Component editingComponent;
+ /** Used to paint the TreeCellRenderer. */
+ protected CellRendererPane rendererPane;
- /** Path that is being edited. */
- protected TreePath editingPath;
+ /** Size needed to completely display all the nodes. */
+ protected Dimension preferredSize;
- /**
- * Row that is being edited. Should only be referenced if editingComponent is
- * null.
- */
- protected int editingRow;
+ /** Is the preferredSize valid? */
+ protected boolean validCachedPreferredSize;
- /** Set to true if the editor has a different size than the renderer. */
- protected boolean editorHasDifferentSize;
+ /** Object responsible for handling sizing and expanded issues. */
+ protected AbstractLayoutCache treeState;
- /** Listeners */
- private PropertyChangeListener propertyChangeListener;
+ /** Used for minimizing the drawing of vertical lines. */
+ protected Hashtable drawingCache;
- private FocusListener focusListener;
+ /**
+ * True if doing optimizations for a largeModel. Subclasses that don't support
+ * this may wish to override createLayoutCache to not return a
+ * FixedHeightLayoutCache instance.
+ */
+ protected boolean largeModel;
- private TreeSelectionListener treeSelectionListener;
+ /** Responsible for telling the TreeState the size needed for a node. */
+ protected AbstractLayoutCache.NodeDimensions nodeDimensions;
- private MouseInputListener mouseInputListener;
-
- private KeyListener keyListener;
-
- private PropertyChangeListener selectionModelPropertyChangeListener;
-
- private ComponentListener componentListener;
-
- private CellEditorListener cellEditorListener;
-
- private TreeExpansionListener treeExpansionListener;
-
- private TreeModelListener treeModelListener;
-
- /**
- * Creates a new BasicTreeUI object.
- */
- public BasicTreeUI()
- {
- drawingCache = new Hashtable();
- cellEditor = createDefaultCellEditor();
- currentCellRenderer = createDefaultCellRenderer();
- nodeDimensions = createNodeDimensions();
- rendererPane = createCellRendererPane();
- configureLayoutCache();
-
- propertyChangeListener = createPropertyChangeListener();
- focusListener = createFocusListener();
- treeSelectionListener = createTreeSelectionListener();
- mouseInputListener = new MouseInputHandler(null, null, null);
- keyListener = createKeyListener();
- selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
- componentListener = createComponentListener();
- cellEditorListener = createCellEditorListener();
- treeExpansionListener = createTreeExpansionListener();
- treeModelListener = createTreeModelListener();
+ /** Used to determine what to display. */
+ protected TreeModel treeModel;
+
+ /** Model maintaining the selection. */
+ protected TreeSelectionModel treeSelectionModel;
+
+ /**
+ * How much the depth should be offset to properly calculate x locations. This
+ * is based on whether or not the root is visible, and if the root handles are
+ * visible.
+ */
+ protected int depthOffset;
+
+ /**
+ * When editing, this will be the Component that is doing the actual editing.
+ */
+ protected Component editingComponent;
+
+ /** Path that is being edited. */
+ protected TreePath editingPath;
+
+ /**
+ * Row that is being edited. Should only be referenced if editingComponent is
+ * null.
+ */
+ protected int editingRow;
+
+ /** Set to true if the editor has a different size than the renderer. */
+ protected boolean editorHasDifferentSize;
+
+ /** The action listener for the editor's Timer. */
+ private Timer editorTimer = new EditorUpdateTimer();
+
+ /** The new value of the node after editing. */
+ private Object newVal;
+
+ /** The action bound to KeyStrokes. */
+ private TreeAction action;
+
+ /** Boolean to keep track of editing. */
+ private boolean isEditing;
+
+ /** Listeners */
+ private PropertyChangeListener propertyChangeListener;
+
+ private FocusListener focusListener;
+
+ private TreeSelectionListener treeSelectionListener;
+
+ private MouseInputListener mouseInputListener;
+
+ private KeyListener keyListener;
+
+ private PropertyChangeListener selectionModelPropertyChangeListener;
+
+ private ComponentListener componentListener;
+
+ private CellEditorListener cellEditorListener;
+
+ private TreeExpansionListener treeExpansionListener;
+
+ private TreeModelListener treeModelListener;
+
+ /**
+ * Creates a new BasicTreeUI object.
+ */
+ public BasicTreeUI()
+ {
+ drawingCache = new Hashtable();
+ nodeDimensions = createNodeDimensions();
+ configureLayoutCache();
+
+ propertyChangeListener = createPropertyChangeListener();
+ focusListener = createFocusListener();
+ treeSelectionListener = createTreeSelectionListener();
+ mouseInputListener = new MouseInputHandler(null, null, null);
+ keyListener = createKeyListener();
+ selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener();
+ componentListener = createComponentListener();
+ cellEditorListener = createCellEditorListener();
+ treeExpansionListener = createTreeExpansionListener();
+ treeModelListener = createTreeModelListener();
+
+ editingRow = -1;
+ lastSelectedRow = -1;
+ }
+
+ /**
+ * Returns an instance of the UI delegate for the specified component.
+ *
+ * @param c
+ * the JComponent
for which we need a UI delegate for.
+ * @return the ComponentUI
for c.
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new BasicTreeUI();
+ }
+
+ /**
+ * Returns the Hash color.
+ *
+ * @return the Color
of the Hash.
+ */
+ protected Color getHashColor()
+ {
+ return UIManager.getLookAndFeelDefaults().getColor("Tree.hash");
+ }
+
+ /**
+ * Sets the Hash color.
+ *
+ * @param color
+ * the Color
to set the Hash to.
+ */
+ protected void setHashColor(Color color)
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ defaults.put("Tree.hash", color);
+ }
+
+ /**
+ * Sets the left child's indent value.
+ *
+ * @param newAmount
+ * is the new indent value for the left child.
+ */
+ public void setLeftChildIndent(int newAmount)
+ {
+ leftChildIndent = newAmount;
+ }
+
+ /**
+ * Returns the indent value for the left child.
+ *
+ * @return the indent value for the left child.
+ */
+ public int getLeftChildIndent(int newAmount)
+ {
+ return leftChildIndent;
+ }
+
+ /**
+ * Sets the right child's indent value.
+ *
+ * @param newAmount
+ * is the new indent value for the right child.
+ */
+ public void setRightChildIndent(int newAmount)
+ {
+ rightChildIndent = newAmount;
+ }
+
+ /**
+ * Returns the indent value for the right child.
+ *
+ * @return the indent value for the right child.
+ */
+ public int getRightChildIndent()
+ {
+ return rightChildIndent;
+ }
+
+ /**
+ * Sets the expanded icon.
+ *
+ * @param newG
+ * is the new expanded icon.
+ */
+ public void setExpandedIcon(Icon newG)
+ {
+ expandedIcon = newG;
+ }
+
+ /**
+ * Returns the current expanded icon.
+ *
+ * @return the current expanded icon.
+ */
+ public Icon getExpandedIcon()
+ {
+ return expandedIcon;
+ }
+
+ /**
+ * Sets the collapsed icon.
+ *
+ * @param newG
+ * is the new collapsed icon.
+ */
+ public void setCollapsedIcon(Icon newG)
+ {
+ collapsedIcon = newG;
+ }
+
+ /**
+ * Returns the current collapsed icon.
+ *
+ * @return the current collapsed icon.
+ */
+ public Icon getCollapsedIcon()
+ {
+ return collapsedIcon;
+ }
+
+ /**
+ * Updates the componentListener, if necessary.
+ *
+ * @param largeModel
+ * sets this.largeModel to it.
+ */
+ protected void setLargeModel(boolean largeModel)
+ {
+ if (largeModel != this.largeModel)
+ {
+ tree.removeComponentListener(componentListener);
+ this.largeModel = largeModel;
+ tree.addComponentListener(componentListener);
+ }
+ }
+
+ /**
+ * Returns true if largeModel is set
+ *
+ * @return true if largeModel is set, otherwise false.
+ */
+ protected boolean isLargeModel()
+ {
+ return largeModel;
+ }
+
+ /**
+ * Sets the row height.
+ *
+ * @param rowHeight
+ * is the height to set this.rowHeight to.
+ */
+ protected void setRowHeight(int rowHeight)
+ {
+ treeState.setRowHeight(rowHeight);
+ }
+
+ /**
+ * Returns the current row height.
+ *
+ * @return current row height.
+ */
+ protected int getRowHeight()
+ {
+ return treeState.getRowHeight();
+ }
+
+ /**
+ * Sets the TreeCellRenderer to tcr
. This invokes
+ * updateRenderer
.
+ *
+ * @param tcr
+ * is the new TreeCellRenderer.
+ */
+ protected void setCellRenderer(TreeCellRenderer tcr)
+ {
+ currentCellRenderer = tcr;
+ tree.setCellRenderer(tcr);
+ updateRenderer();
+ }
+
+ /**
+ * Return currentCellRenderer, which will either be the trees renderer, or
+ * defaultCellRenderer, which ever was not null.
+ *
+ * @return the current Cell Renderer
+ */
+ protected TreeCellRenderer getCellRenderer()
+ {
+ if (currentCellRenderer != null)
+ return currentCellRenderer;
+
+ return createDefaultCellRenderer();
+ }
+
+ /**
+ * Sets the tree's model.
+ *
+ * @param model
+ * to set the treeModel to.
+ */
+ protected void setModel(TreeModel model)
+ {
+ tree.setModel(model);
+ treeModel = tree.getModel();
+ }
+
+ /**
+ * Returns the tree's model
+ *
+ * @return treeModel
+ */
+ protected TreeModel getModel()
+ {
+ return treeModel;
+ }
+
+ /**
+ * Sets the root to being visible.
+ *
+ * @param newValue
+ * sets the visibility of the root
+ */
+ protected void setRootVisible(boolean newValue)
+ {
+ tree.setRootVisible(newValue);
+ }
+
+ /**
+ * Returns true if the root is visible.
+ *
+ * @return true if the root is visible.
+ */
+ protected boolean isRootVisible()
+ {
+ return tree.isRootVisible();
+ }
+
+ /**
+ * Determines whether the node handles are to be displayed.
+ *
+ * @param newValue
+ * sets whether or not node handles should be displayed.
+ */
+ protected void setShowsRootHandles(boolean newValue)
+ {
+ tree.setShowsRootHandles(newValue);
+ }
+
+ /**
+ * Returns true if the node handles are to be displayed.
+ *
+ * @return true if the node handles are to be displayed.
+ */
+ protected boolean getShowsRootHandles()
+ {
+ return tree.getShowsRootHandles();
+ }
+
+ /**
+ * Sets the cell editor.
+ *
+ * @param editor
+ * to set the cellEditor to.
+ */
+ protected void setCellEditor(TreeCellEditor editor)
+ {
+ cellEditor = editor;
+ createdCellEditor = true;
+ }
+
+ /**
+ * Returns the TreeCellEditor
for this tree.
+ *
+ * @return the cellEditor for this tree.
+ */
+ protected TreeCellEditor getCellEditor()
+ {
+ return cellEditor;
+ }
+
+ /**
+ * Configures the receiver to allow, or not allow, editing.
+ *
+ * @param newValue
+ * sets the receiver to allow editing if true.
+ */
+ protected void setEditable(boolean newValue)
+ {
+ tree.setEditable(newValue);
+ }
+
+ /**
+ * Returns true if the receiver allows editing.
+ *
+ * @return true if the receiver allows editing.
+ */
+ protected boolean isEditable()
+ {
+ return tree.isEditable();
+ }
+
+ /**
+ * Resets the selection model. The appropriate listeners are installed on the
+ * model.
+ *
+ * @param newLSM
+ * resets the selection model.
+ */
+ protected void setSelectionModel(TreeSelectionModel newLSM)
+ {
+ if (newLSM != null)
+ {
+ treeSelectionModel = newLSM;
+ tree.setSelectionModel(treeSelectionModel);
+ }
+ }
+
+ /**
+ * Returns the current selection model.
+ *
+ * @return the current selection model.
+ */
+ protected TreeSelectionModel getSelectionModel()
+ {
+ return treeSelectionModel;
+ }
+
+ /**
+ * Returns the Rectangle enclosing the label portion that the last item in
+ * path will be drawn to. Will return null if any component in path is
+ * currently valid.
+ *
+ * @param tree
+ * is the current tree the path will be drawn to.
+ * @param path
+ * is the current path the tree to draw to.
+ * @return the Rectangle enclosing the label portion that the last item in the
+ * path will be drawn to.
+ */
+ public Rectangle getPathBounds(JTree tree, TreePath path)
+ {
+ if (path != null)
+ {
+ Object cell = path.getLastPathComponent();
+
+ TreeModel mod = tree.getModel();
+ if (mod != null)
+ {
+ Object root = mod.getRoot();
+ if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root)))
+ root = getNextNode(root);
+
+ Point loc = getCellLocation(0, 0, tree, mod, cell, root);
+ return getCellBounds(loc.x, loc.y, cell);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the path for passed in row. If row is not visible null is returned.
+ *
+ * @param tree
+ * is the current tree to return path for.
+ * @param row
+ * is the row number of the row to return.
+ * @return the path for passed in row. If row is not visible null is returned.
+ */
+ public TreePath getPathForRow(JTree tree, int row)
+ {
+ TreeModel mod = tree.getModel();
+ if (mod != null)
+ {
+ Object node = mod.getRoot();
+ if (!tree.isRootVisible()
+ && tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
+ node = getNextNode(node);
+
+ for (int i = 0; i < row; i++)
+ node = getNextVisibleNode(node);
+
+ if (node == null)
+ return null;
+
+ return new TreePath(getPathToRoot(node, 0));
+ }
+ return null;
+ }
+
+ /**
+ * Returns the row that the last item identified in path is visible at. Will
+ * return -1 if any of the elments in the path are not currently visible.
+ *
+ * @param tree
+ * is the current tree to return the row for.
+ * @param path
+ * is the path used to find the row.
+ * @return the row that the last item identified in path is visible at. Will
+ * return -1 if any of the elments in the path are not currently
+ * visible.
+ */
+ public int getRowForPath(JTree tree, TreePath path)
+ {
+ int row = path.getPathCount();
+ if (tree.isVisible(path))
+ return row;
+
+ path = path.getParentPath();
+ while (row > 0 && !tree.isVisible(path))
+ {
+ path = path.getParentPath();
+ row--;
+ }
+ return row;
+ }
+
+ /**
+ * Returns the number of rows that are being displayed.
+ *
+ * @param tree
+ * is the current tree to return the number of rows for.
+ * @return the number of rows being displayed.
+ */
+ public int getRowCount(JTree tree)
+ {
+ TreeModel mod = tree.getModel();
+ int count = 0;
+ if (mod != null)
+ {
+ Object node = mod.getRoot();
+ if (!tree.isRootVisible()
+ && tree.isExpanded(new TreePath((getPathToRoot(node, 0)))))
+ node = getNextNode(node);
+
+ while (node != null)
+ {
+ count++;
+ node = getNextVisibleNode(node);
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Returns the path to the node that is closest to x,y. If there is nothing
+ * currently visible this will return null, otherwise it'll always return a
+ * valid path. If you need to test if the returned object is exactly at x,y
+ * you should get the bounds for the returned path and test x,y against that.
+ *
+ * @param tree
+ * the tree to search for the closest path
+ * @param x
+ * is the x coordinate of the location to search
+ * @param y
+ * is the y coordinate of the location to search
+ * @return the tree path closes to x,y.
+ */
+ public TreePath getClosestPathForLocation(JTree tree, int x, int y)
+ {
+ // FIXME: what if root is hidden? should not depend on (0,0)
+ // should start counting rows from where root is.
+
+ int row = Math.round(y / getRowHeight());
+ TreePath path = getPathForRow(tree, row);
+
+ // no row is visible at this node
+ while (row > 0 && path == null)
+ {
+ --row;
+ path = getPathForRow(tree, row);
+ }
+
+ return path;
+ }
+
+ /**
+ * Returns true if the tree is being edited. The item that is being edited can
+ * be returned by getEditingPath().
+ *
+ * @param tree
+ * is the tree to check for editing.
+ * @return true if the tree is being edited.
+ */
+ public boolean isEditing(JTree tree)
+ {
+ return isEditing;
+ }
+
+ /**
+ * Stops the current editing session. This has no effect if the tree is not
+ * being edited. Returns true if the editor allows the editing session to
+ * stop.
+ *
+ * @param tree
+ * is the tree to stop the editing on
+ * @return true if the editor allows the editing session to stop.
+ */
+ public boolean stopEditing(JTree tree)
+ {
+ if (isEditing(tree))
+ completeEditing(true, false, false);
+ return !isEditing(tree);
+ }
+
+ /**
+ * Cancels the current editing session.
+ *
+ * @param tree
+ * is the tree to cancel the editing session on.
+ */
+ public void cancelEditing(JTree tree)
+ {
+ if (isEditing(tree))
+ completeEditing(false, true, false);
+ }
+
+ /**
+ * Selects the last item in path and tries to edit it. Editing will fail if
+ * the CellEditor won't allow it for the selected item.
+ *
+ * @param tree
+ * is the tree to edit on.
+ * @param path
+ * is the path in tree to edit on.
+ */
+ public void startEditingAtPath(JTree tree, TreePath path)
+ {
+ startEditing(path, null);
+ }
+
+ /**
+ * Returns the path to the element that is being editted.
+ *
+ * @param tree
+ * is the tree to get the editing path from.
+ * @return the path that is being edited.
+ */
+ public TreePath getEditingPath(JTree tree)
+ {
+ return editingPath;
+ }
+
+ /**
+ * Invoked after the tree instance variable has been set, but before any
+ * default/listeners have been installed.
+ */
+ protected void prepareForUIInstall()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Invoked from installUI after all the defaults/listeners have been
+ * installed.
+ */
+ protected void completeUIInstall()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Invoked from uninstallUI after all the defaults/listeners have been
+ * uninstalled.
+ */
+ protected void completeUIUninstall()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Installs the subcomponents of the tree, which is the renderer pane.
+ */
+ protected void installComponents()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Creates an instance of NodeDimensions that is able to determine the size of
+ * a given node in the tree.
+ *
+ * @return the NodeDimensions of a given node in the tree
+ */
+ protected AbstractLayoutCache.NodeDimensions createNodeDimensions()
+ {
+ // FIXME: not implemented
+ return null;
+ }
+
+ /**
+ * Creates a listener that is reponsible for the updates the UI based on how
+ * the tree changes.
+ *
+ * @return the PropertyChangeListener that is reposnsible for the updates
+ */
+ protected PropertyChangeListener createPropertyChangeListener()
+ {
+ return new PropertyChangeHandler();
+ }
+
+ /**
+ * Creates the listener responsible for updating the selection based on mouse
+ * events.
+ *
+ * @return the MouseListener responsible for updating.
+ */
+ protected MouseListener createMouseListener()
+ {
+ return new MouseHandler();
+ }
+
+ /**
+ * Creates the listener that is responsible for updating the display when
+ * focus is lost/grained.
+ *
+ * @return the FocusListener responsible for updating.
+ */
+ protected FocusListener createFocusListener()
+ {
+ return new FocusHandler();
+ }
+
+ /**
+ * Creates the listener reponsible for getting key events from the tree.
+ *
+ * @return the KeyListener responsible for getting key events.
+ */
+ protected KeyListener createKeyListener()
+ {
+ return new KeyHandler();
+ }
+
+ /**
+ * Creates the listener responsible for getting property change events from
+ * the selection model.
+ *
+ * @returns the PropertyChangeListener reponsible for getting property change
+ * events from the selection model.
+ */
+ protected PropertyChangeListener createSelectionModelPropertyChangeListener()
+ {
+ return new SelectionModelPropertyChangeHandler();
+ }
+
+ /**
+ * Creates the listener that updates the display based on selection change
+ * methods.
+ *
+ * @return the TreeSelectionListener responsible for updating.
+ */
+ protected TreeSelectionListener createTreeSelectionListener()
+ {
+ return new TreeSelectionHandler();
+ }
+
+ /**
+ * Creates a listener to handle events from the current editor
+ *
+ * @return the CellEditorListener that handles events from the current editor
+ */
+ protected CellEditorListener createCellEditorListener()
+ {
+ return new CellEditorHandler();
+ }
+
+ /**
+ * Creates and returns a new ComponentHandler. This is used for the large
+ * model to mark the validCachedPreferredSize as invalid when the component
+ * moves.
+ *
+ * @return a new ComponentHandler.
+ */
+ protected ComponentListener createComponentListener()
+ {
+ return new ComponentHandler();
+ }
+
+ /**
+ * Creates and returns the object responsible for updating the treestate when
+ * a nodes expanded state changes.
+ *
+ * @return the TreeExpansionListener responsible for updating the treestate
+ */
+ protected TreeExpansionListener createTreeExpansionListener()
+ {
+ return new TreeExpansionHandler();
+ }
+
+ /**
+ * Creates the object responsible for managing what is expanded, as well as
+ * the size of nodes.
+ *
+ * @return the object responsible for managing what is expanded.
+ */
+ protected AbstractLayoutCache createLayoutCache()
+ {
+ return new FixedHeightLayoutCache();
+ }
+
+ /**
+ * Returns the renderer pane that renderer components are placed in.
+ *
+ * @return the rendererpane that render components are placed in.
+ */
+ protected CellRendererPane createCellRendererPane()
+ {
+ return new CellRendererPane();
+ }
+
+ /**
+ * Creates a default cell editor.
+ *
+ * @return the default cell editor.
+ */
+ protected TreeCellEditor createDefaultCellEditor()
+ {
+ if (currentCellRenderer != null)
+ return new DefaultTreeCellEditor(tree,
+ (DefaultTreeCellRenderer) currentCellRenderer,
+ cellEditor);
+ return new DefaultTreeCellEditor(tree,
+ (DefaultTreeCellRenderer) createDefaultCellRenderer(),
+ cellEditor);
+ }
+
+ /**
+ * Returns the default cell renderer that is used to do the stamping of each
+ * node.
+ *
+ * @return the default cell renderer that is used to do the stamping of each
+ * node.
+ */
+ protected TreeCellRenderer createDefaultCellRenderer()
+ {
+ return new DefaultTreeCellRenderer();
+ }
+
+ /**
+ * Returns a listener that can update the tree when the model changes.
+ *
+ * @return a listener that can update the tree when the model changes.
+ */
+ protected TreeModelListener createTreeModelListener()
+ {
+ return new TreeModelHandler();
+ }
+
+ /**
+ * Uninstall all registered listeners
+ */
+ protected void uninstallListeners()
+ {
+ tree.removePropertyChangeListener(propertyChangeListener);
+ tree.removeFocusListener(focusListener);
+ tree.removeTreeSelectionListener(treeSelectionListener);
+ tree.removeMouseListener(mouseInputListener);
+ tree.removeKeyListener(keyListener);
+ tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
+ tree.removeComponentListener(componentListener);
+ tree.removeTreeExpansionListener(treeExpansionListener);
+
+ TreeCellEditor tce = tree.getCellEditor();
+ if (tce != null)
+ tce.removeCellEditorListener(cellEditorListener);
+ TreeModel tm = tree.getModel();
+ if (tm != null)
+ tm.removeTreeModelListener(treeModelListener);
+ }
+
+ /**
+ * Uninstall all keyboard actions.
+ */
+ protected void uninstallKeyboardActions()
+ {
+ }
+
+ /**
+ * Uninstall the rendererPane.
+ */
+ protected void uninstallComponents()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * The vertical element of legs between nodes starts at the bottom of the
+ * parent node by default. This method makes the leg start below that.
+ *
+ * @return the vertical leg buffer
+ */
+ protected int getVerticalLegBuffer()
+ {
+ // FIXME: not implemented
+ return 0;
+ }
+
+ /**
+ * The horizontal element of legs between nodes starts at the right of the
+ * left-hand side of the child node by default. This method makes the leg end
+ * before that.
+ *
+ * @return the horizontal leg buffer
+ */
+ protected int getHorizontalLegBuffer()
+ {
+ // FIXME: not implemented
+ return 0;
+ }
+
+ /**
+ * Make all the nodes that are expanded in JTree expanded in LayoutCache. This
+ * invokes update ExpandedDescendants with the root path.
+ */
+ protected void updateLayoutCacheExpandedNodes()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Updates the expanded state of all the descendants of the path
+ * by getting the expanded descendants from the tree and forwarding to the
+ * tree state.
+ *
+ * @param path
+ * the path used to update the expanded states
+ */
+ protected void updateExpandedDescendants(TreePath path)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Returns a path to the last child of parent
+ *
+ * @param parent
+ * is the topmost path to specified
+ * @return a path to the last child of parent
+ */
+ protected TreePath getLastChildPath(TreePath parent)
+ {
+ return ((TreePath) parent.getLastPathComponent());
+ }
+
+ /**
+ * Updates how much each depth should be offset by.
+ */
+ protected void updateDepthOffset()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Updates the cellEditor based on editability of the JTree that we're
+ * contained in. If the tree is editable but doesn't have a cellEditor, a
+ * basic one will be used.
+ */
+ protected void updateCellEditor()
+ {
+ if (tree.isEditable() && cellEditor == null)
+ setCellEditor(createDefaultCellEditor());
+ createdCellEditor = true;
+ }
+
+ /**
+ * Messaged from the tree we're in when the renderer has changed.
+ */
+ protected void updateRenderer()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Resets the treeState instance based on the tree we're providing the look
+ * and feel for.
+ */
+ protected void configureLayoutCache()
+ {
+ treeState = createLayoutCache();
+ }
+
+ /**
+ * Marks the cached size as being invalid, and messages the tree with
+ * treeDidChange
.
+ */
+ protected void updateSize()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Updates the preferredSize
instance variable, which is
+ * returned from getPreferredSize()
. For left to right
+ * orientations, the size is determined from the current AbstractLayoutCache.
+ * For RTL orientations, the preferred size becomes the width minus the
+ * minimum x position.
+ */
+ protected void updateCachedPreferredSize()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Messaged from the VisibleTreeNode after it has been expanded.
+ *
+ * @param path
+ * is the path that has been expanded.
+ */
+ protected void pathWasExpanded(TreePath path)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Messaged from the VisibleTreeNode after it has collapsed
+ */
+ protected void pathWasCollapsed(TreePath path)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Install all defaults for the tree.
+ *
+ * @param tree
+ * is the JTree to install defaults for
+ */
+ protected void installDefaults(JTree tree)
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+ tree.setFont(defaults.getFont("Tree.font"));
+ tree.setForeground(defaults.getColor("Tree.foreground"));
+ tree.setBackground(defaults.getColor("Tree.background"));
+ tree.setOpaque(true);
+
+ rightChildIndent = defaults.getInt("Tree.rightChildIndent");
+ leftChildIndent = defaults.getInt("Tree.leftChildIndent");
+ setRowHeight(defaults.getInt("Tree.rowHeight"));
+ tree.requestFocusInWindow(false);
+ }
+
+ /**
+ * Install all keyboard actions for this
+ */
+ protected void installKeyboardActions()
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ InputMap focusInputMap = (InputMap) defaults.get("Tree.focusInputMap");
+ InputMapUIResource parentInputMap = new InputMapUIResource();
+ ActionMap parentActionMap = new ActionMap();
+ action = new TreeAction();
+ Object keys[] = focusInputMap.allKeys();
+
+ for (int i = 0; i < keys.length; i++)
+ {
+ parentInputMap.put(
+ KeyStroke.getKeyStroke(
+ ((KeyStroke) keys[i]).getKeyCode(),
+ convertModifiers(((KeyStroke) keys[i]).getModifiers())),
+ (String) focusInputMap.get((KeyStroke) keys[i]));
+
+ parentInputMap.put(
+ KeyStroke.getKeyStroke(
+ ((KeyStroke) keys[i]).getKeyCode(),
+ ((KeyStroke) keys[i]).getModifiers()),
+ (String) focusInputMap.get((KeyStroke) keys[i]));
+
+ parentActionMap.put(
+ (String) focusInputMap.get((KeyStroke) keys[i]),
+ new ActionListenerProxy(
+ action,
+ (String) focusInputMap.get((KeyStroke) keys[i])));
+
+ }
+
+ parentInputMap.setParent(tree.getInputMap(
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent());
+ parentActionMap.setParent(tree.getActionMap().getParent());
+ tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(
+ parentInputMap);
+ tree.getActionMap().setParent(parentActionMap);
+ }
+
+ /**
+ * Converts the modifiers.
+ *
+ * @param mod -
+ * modifier to convert
+ * @returns the new modifier
+ */
+ private int convertModifiers(int mod)
+ {
+ if ((mod & KeyEvent.SHIFT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.SHIFT_MASK;
+ mod &= ~KeyEvent.SHIFT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.CTRL_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.CTRL_MASK;
+ mod &= ~KeyEvent.CTRL_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.META_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.META_MASK;
+ mod &= ~KeyEvent.META_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_MASK;
+ mod &= ~KeyEvent.ALT_DOWN_MASK;
+ }
+ if ((mod & KeyEvent.ALT_GRAPH_DOWN_MASK) != 0)
+ {
+ mod |= KeyEvent.ALT_GRAPH_MASK;
+ mod &= ~KeyEvent.ALT_GRAPH_DOWN_MASK;
+ }
+ return mod;
+ }
+
+ /**
+ * Install all listeners for this
+ */
+ protected void installListeners()
+ {
+ tree.addPropertyChangeListener(propertyChangeListener);
+ tree.addFocusListener(focusListener);
+ tree.addTreeSelectionListener(treeSelectionListener);
+ tree.addMouseListener(mouseInputListener);
+ tree.addKeyListener(keyListener);
+ tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
+ tree.addComponentListener(componentListener);
+ tree.addTreeExpansionListener(treeExpansionListener);
+ if (treeModel != null)
+ treeModel.addTreeModelListener(treeModelListener);
+ }
+
+ /**
+ * Install the UI for the component
+ *
+ * @param c
+ * the component to install UI for
+ */
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ installDefaults((JTree) c);
+ tree = (JTree) c;
+
+ currentCellRenderer = createDefaultCellRenderer();
+ rendererPane = createCellRendererPane();
+ createdRenderer = true;
+
+ setCellEditor(createDefaultCellEditor());
+ createdCellEditor = true;
+ isEditing = false;
+
+ TreeModel mod = tree.getModel();
+ setModel(mod);
+ tree.setRootVisible(true);
+ if (mod != null)
+ tree.expandPath(new TreePath(mod.getRoot()));
+ treeSelectionModel = tree.getSelectionModel();
+
+ installKeyboardActions();
+ installListeners();
+ completeUIInstall();
+ }
+
+ /**
+ * Uninstall the defaults for the tree
+ *
+ * @param tree
+ * to uninstall defaults for
+ */
+ protected void uninstallDefaults(JTree tree)
+ {
+ tree.setFont(null);
+ tree.setForeground(null);
+ tree.setBackground(null);
+ }
+
+ /**
+ * Uninstall the UI for the component
+ *
+ * @param c
+ * the component to uninstall UI for
+ */
+ public void uninstallUI(JComponent c)
+ {
+ uninstallDefaults((JTree) c);
+ uninstallKeyboardActions();
+ uninstallListeners();
+ tree = null;
+ completeUIUninstall();
+ }
+
+ /**
+ * Paints the specified component appropriate for the look and feel. This
+ * method is invoked from the ComponentUI.update method when the specified
+ * component is being painted. Subclasses should override this method and use
+ * the specified Graphics object to render the content of the component.
+ *
+ * @param g
+ * the Graphics context in which to paint
+ * @param c
+ * the component being painted; this argument is often ignored, but
+ * might be used if the UI object is stateless and shared by multiple
+ * components
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ JTree tree = (JTree) c;
+
+ TreeModel mod = tree.getModel();
+
+ if (mod != null)
+ {
+ Object root = mod.getRoot();
+
+ if (!tree.isRootVisible())
+ tree.expandPath(new TreePath(root));
+
+ paintRecursive(g, 0, 0, 0, 0, tree, mod, root);
+
+ if (hasControlIcons())
+ paintControlIcons(g, 0, 0, 0, 0, tree, mod, root);
+ }
+ }
+
+ /**
+ * Ensures that the rows identified by beginRow through endRow are visible.
+ *
+ * @param beginRow
+ * is the first row
+ * @param endRow
+ * is the last row
+ */
+ protected void ensureRowsAreVisible(int beginRow, int endRow)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Sets the preferred minimum size.
+ *
+ * @param newSize
+ * is the new preferred minimum size.
+ */
+ public void setPreferredMinSize(Dimension newSize)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Gets the preferred minimum size.
+ *
+ * @returns the preferred minimum size.
+ */
+ public Dimension getPreferredMinSize()
+ {
+ // FIXME: not implemented
+ return null;
+ }
+
+ /**
+ * Returns the preferred size to properly display the tree, this is a cover
+ * method for getPreferredSize(c, false).
+ *
+ * @param c
+ * the component whose preferred size is being queried; this argument
+ * is often ignored but might be used if the UI object is stateless
+ * and shared by multiple components
+ * @return the preferred size
+ */
+ public Dimension getPreferredSize(JComponent c)
+ {
+ return getPreferredSize(c, false);
+ }
+
+ /**
+ * Returns the preferred size to represent the tree in c. If checkConsistancy
+ * is true, checkConsistancy is messaged first.
+ *
+ * @param c
+ * the component whose preferred size is being queried.
+ * @param checkConsistancy
+ * if true must check consistancy
+ * @return the preferred size
+ */
+ public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
+ {
+ // FIXME: checkConsistancy not implemented, c not used
+ TreeModel model = tree.getModel();
+ int maxWidth = 0;
+ int count = 0;
+ if (model != null)
+ {
+ Object node = model.getRoot();
+ if (node != null)
+ {
+ maxWidth = (int) (getCellBounds(0, 0, node).getWidth());
+ while (node != null)
+ {
+ count++;
+ Object nextNode = getNextVisibleNode(node);
+ if (nextNode != null)
+ maxWidth = Math.max(maxWidth,
+ (int) (getCellBounds(0, 0, nextNode).getWidth()));
+ node = nextNode;
+ }
+ }
+ }
+ return new Dimension(maxWidth, (getRowHeight() * count));
+ }
+
+ /**
+ * Returns the minimum size for this component. Which will be the min
+ * preferred size or (0,0).
+ *
+ * @param c
+ * the component whose min size is being queried.
+ * @returns the preferred size or null
+ */
+ public Dimension getMinimumSize(JComponent c)
+ {
+ // FIXME: not implemented
+ return getPreferredSize(c);
+ }
+
+ /**
+ * Returns the maximum size for the component, which will be the preferred
+ * size if the instance is currently in JTree or (0,0).
+ *
+ * @param c
+ * the component whose preferred size is being queried
+ * @return the max size or null
+ */
+ public Dimension getMaximumSize(JComponent c)
+ {
+ // FIXME: not implemented
+ return getPreferredSize(c);
+ }
+
+ /**
+ * Messages to stop the editing session. If the UI the receiver is providing
+ * the look and feel for returns true from
+ * getInvokesStopCellEditing
, stopCellEditing will be invoked
+ * on the current editor. Then completeEditing will be messaged with false,
+ * true, false to cancel any lingering editing.
+ */
+ protected void completeEditing()
+ {
+ completeEditing(false, true, false);
+ }
+
+ /**
+ * Stops the editing session. If messageStop is true, the editor is messaged
+ * with stopEditing, if messageCancel is true the editor is messaged with
+ * cancelEditing. If messageTree is true, the treeModel is messaged with
+ * valueForPathChanged.
+ *
+ * @param messageStop
+ * message to stop editing
+ * @param messageCancel
+ * message to cancel editing
+ * @param messageTree
+ * message to treeModel
+ */
+ protected void completeEditing(boolean messageStop, boolean messageCancel,
+ boolean messageTree)
+ {
+ if (messageStop)
+ {
+ getCellEditor().stopCellEditing();
+ stopEditingInCompleteEditing = true;
+ }
+
+ if (messageCancel)
+ {
+ getCellEditor().cancelCellEditing();
+ stopEditingInCompleteEditing = true;
+ }
+
+ if (messageTree)
+ tree.getModel().valueForPathChanged(tree.getLeadSelectionPath(), newVal);
+ }
+
+ /**
+ * Will start editing for node if there is a cellEditor and shouldSelectCall
+ * returns true. This assumes that path is valid and visible.
+ *
+ * @param path
+ * is the path to start editing
+ * @param event
+ * is the MouseEvent performed on the path
+ * @return true if successful
+ */
+ protected boolean startEditing(TreePath path, MouseEvent event)
+ {
+ int x;
+ int y;
+ if (event == null)
+ {
+ Rectangle bounds = getPathBounds(tree, path);
+ x = bounds.x;
+ y = bounds.y;
+ }
+ else
+ {
+ x = event.getX();
+ y = event.getY();
+ }
+
+ updateCellEditor();
+ TreeCellEditor ed = getCellEditor();
+ if (ed != null && ed.shouldSelectCell(event) && ed.isCellEditable(event))
+ {
+ editingPath = path;
+ editingRow = tree.getRowForPath(editingPath);
+ Object val = editingPath.getLastPathComponent();
+ cellEditor.addCellEditorListener(cellEditorListener);
+ stopEditingInCompleteEditing = false;
+ boolean expanded = tree.isExpanded(editingPath);
+ isEditing = true;
+ editingComponent = ed.getTreeCellEditorComponent(tree, val, true,
+ expanded,
+ isLeaf(editingRow),
+ editingRow);
+ editingComponent.getParent().setVisible(true);
+ editingComponent.getParent().validate();
+ tree.add(editingComponent.getParent());
+ editingComponent.getParent().validate();
+ ((JTextField) editingComponent).requestFocusInWindow(false);
+ editorTimer.start();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If the mouseX
and mouseY
are in the expand or
+ * collapse region of the row, this will toggle the row.
+ *
+ * @param path
+ * the path we are concerned with
+ * @param mouseX
+ * is the cursor's x position
+ * @param mouseY
+ * is the cursor's y position
+ */
+ protected void checkForClickInExpandControl(TreePath path, int mouseX,
+ int mouseY)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Returns true if the mouseX
and mouseY
fall in
+ * the area of row that is used to expand/collpse the node and the node at row
+ * does not represent a leaf.
+ *
+ * @param path
+ * the path we are concerned with
+ * @param mouseX
+ * is the cursor's x position
+ * @param mouseY
+ * is the cursor's y position
+ * @return true if the mouseX
and mouseY
fall in
+ * the area of row that is used to expand/collpse the node and the
+ * node at row does not represent a leaf.
+ */
+ protected boolean isLocationInExpandControl(TreePath path, int mouseX,
+ int mouseY)
+ {
+ // FIXME: not implemented
+ return false;
+ }
+
+ /**
+ * Messaged when the user clicks the particular row, this invokes
+ * toggleExpandState.
+ *
+ * @param path
+ * the path we are concerned with
+ * @param mouseX
+ * is the cursor's x position
+ * @param mouseY
+ * is the cursor's y position
+ */
+ protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Expands path if it is not expanded, or collapses row if it is expanded. If
+ * expanding a path and JTree scroll on expand, ensureRowsAreVisible is
+ * invoked to scroll as many of the children to visible as possible (tries to
+ * scroll to last visible descendant of path).
+ *
+ * @param path
+ * the path we are concerned with
+ */
+ protected void toggleExpandState(TreePath path)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Returning true signifies a mouse event on the node should toggle the
+ * selection of only the row under the mouse.
+ *
+ * @param event
+ * is the MouseEvent performed on the row.
+ * @return true signifies a mouse event on the node should toggle the
+ * selection of only the row under the mouse.
+ */
+ protected boolean isToggleSelectionEvent(MouseEvent event)
+ {
+ // FIXME: not implemented
+ return false;
+ }
+
+ /**
+ * Returning true signifies a mouse event on the node should select from the
+ * anchor point.
+ *
+ * @param event
+ * is the MouseEvent performed on the node.
+ * @return true signifies a mouse event on the node should select from the
+ * anchor point.
+ */
+ protected boolean isMultiSelectEvent(MouseEvent event)
+ {
+ // FIXME: not implemented
+ return false;
+ }
+
+ /**
+ * Returning true indicates the row under the mouse should be toggled based on
+ * the event. This is invoked after checkForClickInExpandControl, implying the
+ * location is not in the expand (toggle) control.
+ *
+ * @param event
+ * is the MouseEvent performed on the row.
+ * @return true indicates the row under the mouse should be toggled based on
+ * the event.
+ */
+ protected boolean isToggleEvent(MouseEvent event)
+ {
+ // FIXME: not implemented
+ return false;
+ }
+
+ /**
+ * Messaged to update the selection based on a MouseEvent over a particular
+ * row. If the even is a toggle selection event, the row is either selected,
+ * or deselected. If the event identifies a multi selection event, the
+ * selection is updated from the anchor point. Otherwise, the row is selected,
+ * and if the even specified a toggle event the row is expanded/collapsed.
+ *
+ * @param path
+ * is the path selected for an event
+ * @param event
+ * is the MouseEvent performed on the path.
+ */
+ protected void selectPathForEvent(TreePath path, MouseEvent event)
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Returns true if the node at row
is a leaf.
+ *
+ * @param row
+ * is the row we are concerned with.
+ * @return true if the node at row
is a leaf.
+ */
+ protected boolean isLeaf(int row)
+ {
+ TreePath pathForRow = getPathForRow(tree, row);
+ if (pathForRow == null)
+ return true;
+
+ Object node = pathForRow.getLastPathComponent();
+ return tree.getModel().isLeaf(node);
+ }
+
+ /**
+ * This class implements the actions that we want to happen when specific keys
+ * are pressed for the JTree. The actionPerformed method is called when a key
+ * that has been registered for the JTree is received.
+ */
+ class TreeAction
+ extends AbstractAction
+ {
+
+ /**
+ * What to do when this action is called.
+ *
+ * @param e
+ * the ActionEvent that caused this action.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ TreePath lead = tree.getLeadSelectionPath();
+
+ if (e.getActionCommand().equals("selectPreviousChangeLead")
+ || e.getActionCommand().equals("selectPreviousExtendSelection")
+ || e.getActionCommand().equals("selectPrevious")
+ || e.getActionCommand().equals("selectNext")
+ || e.getActionCommand().equals("selectNextExtendSelection")
+ || e.getActionCommand().equals("selectNextChangeLead"))
+ (new TreeIncrementAction(0, "")).actionPerformed(e);
+ else if (e.getActionCommand().equals("selectParent")
+ || e.getActionCommand().equals("selectChild"))
+ (new TreeTraverseAction(0, "")).actionPerformed(e);
+ else if (e.getActionCommand().equals("selectAll"))
+ {
+ TreePath[] paths = new TreePath[tree.getRowCount()];
+
+ Object curr = getNextVisibleNode(tree.getModel().getRoot());
+ int i = 0;
+ while (curr != null && i < paths.length)
+ {
+ paths[i] = new TreePath(getPathToRoot(curr, 0));
+ i++;
+ }
- createdRenderer = true;
- createdCellEditor = true;
+ tree.addSelectionPaths(paths);
+ }
+ else if (e.getActionCommand().equals("startEditing"))
+ tree.startEditingAtPath(lead);
+ else if (e.getActionCommand().equals("toggle"))
+ {
+ if (tree.isEditing())
+ tree.stopEditing();
+ else
+ {
+ Object last = lead.getLastPathComponent();
+ TreePath path = new TreePath(getPathToRoot(last, 0));
+ if (!tree.getModel().isLeaf(last))
+ {
+ if (tree.isExpanded(path))
+ tree.collapsePath(path);
+ else
+ tree.expandPath(path);
+ }
+ }
+ }
+ else if (e.getActionCommand().equals("clearSelection"))
+ tree.clearSelection();
+
+ if (tree.isEditing() && !e.getActionCommand().equals("startEditing"))
+ tree.cancelEditing();
+
+ tree.scrollPathToVisible(lead);
+ }
+ }
+
+ /**
+ * This class is used to mimic the behaviour of the JDK when registering
+ * keyboard actions. It is the same as the private class used in JComponent
+ * for the same reason. This class receives an action event and dispatches it
+ * to the true receiver after altering the actionCommand property of the
+ * event.
+ */
+ private static class ActionListenerProxy
+ extends AbstractAction
+ {
+ ActionListener target;
+
+ String bindingCommandName;
+
+ public ActionListenerProxy(ActionListener li, String cmd)
+ {
+ target = li;
+ bindingCommandName = cmd;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ ActionEvent derivedEvent = new ActionEvent(e.getSource(), e.getID(),
+ bindingCommandName,
+ e.getModifiers());
+
+ target.actionPerformed(derivedEvent);
+ }
+ }
+
+ /**
+ * The timer that updates the editor component.
+ */
+ private class EditorUpdateTimer
+ extends Timer
+ implements ActionListener
+ {
+ /**
+ * Creates a new EditorUpdateTimer object with a default delay of 0.3
+ * seconds.
+ */
+ public EditorUpdateTimer()
+ {
+ super(300, null);
+ addActionListener(this);
+ }
+
+ /**
+ * Lets the caret blink and repaints the table.
+ */
+ public void actionPerformed(ActionEvent ev)
+ {
+ Caret c = ((JTextField) editingComponent).getCaret();
+ if (c != null)
+ c.setVisible(!c.isVisible());
+ tree.repaint();
+ }
+
+ /**
+ * Updates the blink delay according to the current caret.
+ */
+ public void update()
+ {
+ stop();
+ Caret c = ((JTextField) editingComponent).getCaret();
+ if (c != null)
+ {
+ setDelay(c.getBlinkRate());
+ if (((JTextField) editingComponent).isEditable())
+ start();
+ else
+ c.setVisible(false);
+ }
+ }
+ }
+
+ /**
+ * Updates the preferred size when scrolling, if necessary.
+ */
+ public class ComponentHandler
+ extends ComponentAdapter
+ implements ActionListener
+ {
+ /**
+ * Timer used when inside a scrollpane and the scrollbar is adjusting
+ */
+ protected Timer timer;
+
+ /** ScrollBar that is being adjusted */
+ protected JScrollBar scrollBar;
+
+ /**
+ * Constructor
+ */
+ public ComponentHandler()
+ {
+ }
+
+ /**
+ * Invoked when the component's position changes.
+ *
+ * @param e
+ * the event that occurs when moving the component
+ */
+ public void componentMoved(ComponentEvent e)
+ {
+ }
+
+ /**
+ * Creats, if necessary, and starts a Timer to check if needed to resize the
+ * bounds
+ */
+ protected void startTimer()
+ {
+ }
+
+ /**
+ * Returns the JScrollPane housing the JTree, or null if one isn't found.
+ *
+ * @return JScrollPane housing the JTree, or null if one isn't found.
+ */
+ protected JScrollPane getScrollPane()
+ {
+ return null;
+ }
+
+ /**
+ * Public as a result of Timer. If the scrollBar is null, or not adjusting,
+ * this stops the timer and updates the sizing.
+ *
+ * @param ae
+ * is the action performed
+ */
+ public void actionPerformed(ActionEvent ae)
+ {
+ }
+ }// ComponentHandler
+
+ /**
+ * Listener responsible for getting cell editing events and updating the tree
+ * accordingly.
+ */
+ public class CellEditorHandler
+ implements CellEditorListener
+ {
+ /**
+ * Constructor
+ */
+ public CellEditorHandler()
+ {
+ }
+
+ /**
+ * Messaged when editing has stopped in the tree. Tells the listeners
+ * editing has stopped.
+ *
+ * @param e
+ * is the notification event
+ */
+ public void editingStopped(ChangeEvent e)
+ {
+ editingPath = null;
editingRow = -1;
- lastSelectedRow = -1;
- }
-
- /**
- * Returns an instance of the UI delegate for the specified component.
- *
- * @param c the JComponent
for which we need a UI delegate
- * for.
- * @return the ComponentUI
for c.
- */
- public static ComponentUI createUI(JComponent c)
- {
- return new BasicTreeUI();
- }
-
- /**
- * Returns the Hash color.
- *
- * @return the Color
of the Hash.
- */
- protected Color getHashColor()
- {
- return UIManager.getLookAndFeelDefaults().getColor("Tree.hash");
- }
-
- /**
- * Sets the Hash color.
- *
- * @param the Color
to set the Hash to.
- */
- protected void setHashColor(Color color)
- {
- // FIXME: not implemented
-
- }
-
- /**
- * Sets the left child's indent value.
- *
- * @param newAmount is the new indent value for the left child.
- */
- public void setLeftChildIndent(int newAmount)
- {
- leftChildIndent = newAmount;
- }
-
- /**
- * Returns the indent value for the left child.
- *
- * @return the indent value for the left child.
- */
- public int getLeftChildIndent(int newAmount)
- {
- return leftChildIndent;
- }
-
- /**
- * Sets the right child's indent value.
- *
- * @param newAmount is the new indent value for the right child.
- */
- public void setRightChildIndent(int newAmount)
- {
- rightChildIndent = newAmount;
- }
-
- /**
- * Returns the indent value for the right child.
- *
- * @return the indent value for the right child.
- */
- public int getRightChildIndent(int newAmount)
- {
- return rightChildIndent;
- }
-
- /**
- * Sets the expanded icon.
- *
- * @param newG is the new expanded icon.
- */
- public void setExpandedIcon(Icon newG)
- {
- expandedIcon = newG;
- }
-
- /**
- * Returns the current expanded icon.
- *
- * @return the current expanded icon.
- */
- public Icon getExpandedIcon()
- {
- return expandedIcon;
- }
-
- /**
- * Sets the collapsed icon.
- *
- * @param newG is the new collapsed icon.
- */
- public void setCollapsedIcon(Icon newG)
- {
- collapsedIcon = newG;
- }
-
- /**
- * Returns the current collapsed icon.
- *
- * @return the current collapsed icon.
- */
- public Icon getCollapsedIcon()
- {
- return collapsedIcon;
- }
-
- /**
- * Updates the componentListener, if necessary.
- *
- * @param largeModel sets this.largeModel to it.
- */
- protected void setLargeModel(boolean largeModel)
- {
- if (largeModel != this.largeModel)
- {
- tree.removeComponentListener(componentListener);
- this.largeModel = largeModel;
- tree.addComponentListener(componentListener);
- }
- }
-
- /**
- * Returns true if largeModel is set
- *
- * @return true if largeModel is set, otherwise false.
- */
- protected boolean isLargeModel()
- {
- return largeModel;
- }
-
- /**
- * Sets the row height.
- *
- * @param rowHeight is the height to set this.rowHeight to.
- */
- protected void setRowHeight(int rowHeight)
- {
- treeState.setRowHeight(rowHeight);
- }
-
- /**
- * Returns the current row height.
- *
- * @return current row height.
- */
- protected int getRowHeight()
- {
- return treeState.getRowHeight();
- }
-
- /**
- * Sets the TreeCellRenderer to tcr
. This invokes
- * updateRenderer
.
- *
- * @param tcr is the new TreeCellRenderer.
- */
- protected void setCellRenderer(TreeCellRenderer tcr)
- {
- currentCellRenderer = tcr;
- updateRenderer();
- }
-
- /**
- * Return currentCellRenderer, which will either be the trees renderer, or
- * defaultCellRenderer, which ever was not null.
- *
- * @return the current Cell Renderer
- */
- protected TreeCellRenderer getCellRenderer()
- {
- if (currentCellRenderer != null)
- return currentCellRenderer;
-
- return createDefaultCellRenderer();
- }
-
- /**
- * Sets the tree's model.
- *
- * @param model to set the treeModel to.
- */
- protected void setModel(TreeModel model)
- {
- treeState.setModel(model);
- treeModel = model;
- }
-
- /**
- * Returns the tree's model
- *
- * @return treeModel
- */
- protected TreeModel getModel()
- {
- return treeModel;
- }
-
- /**
- * Sets the root to being visible.
- *
- * @param newValue sets the visibility of the root
- */
- protected void setRootVisible(boolean newValue)
- {
- treeState.setRootVisible(newValue);
- }
-
- /**
- * Returns true if the root is visible.
- *
- * @return true if the root is visible.
- */
- protected boolean isRootVisible()
- {
- return treeState.isRootVisible();
- }
-
- /**
- * Determines whether the node handles are to be displayed.
- *
- * @param newValue sets whether or not node handles should be displayed.
- */
- protected void setShowsRootHandles(boolean newValue)
- {
- tree.setShowsRootHandles(newValue);
- }
-
- /**
- * Returns true if the node handles are to be displayed.
- *
- * @return true if the node handles are to be displayed.
- */
- protected boolean getShowsRootHandles()
- {
- return tree.getShowsRootHandles();
- }
-
- /**
- * Sets the cell editor.
- *
- * @param editor to set the cellEditor to.
- */
- protected void setCellEditor(TreeCellEditor editor)
- {
- cellEditor = editor;
- }
-
- /**
- * Returns the TreeCellEditor
for this tree.
- *
- * @return the cellEditor for this tree.
- */
- protected TreeCellEditor getCellEditor()
- {
- return cellEditor;
- }
-
- /**
- * Configures the receiver to allow, or not allow, editing.
- *
- * @param newValue sets the receiver to allow editing if true.
- */
- protected void setEditable(boolean newValue)
- {
- tree.setEditable(newValue);
- }
-
- /**
- * Returns true if the receiver allows editing.
- *
- * @return true if the receiver allows editing.
- */
- protected boolean isEditable()
- {
- return tree.isEditable();
- }
-
- /**
- * Resets the selection model. The appropriate listeners are installed on the
- * model.
- *
- * @param newLSM resets the selection model.
- */
- protected void setSelectionModel(TreeSelectionModel newLSM)
- {
- if (newLSM != null)
- {
- treeSelectionModel = newLSM;
- tree.setSelectionModel(treeSelectionModel);
- }
- }
-
- /**
- * Returns the current selection model.
- *
- * @return the current selection model.
- */
- protected TreeSelectionModel getSelectionModel()
- {
- return treeSelectionModel;
- }
-
- /**
- * Returns the Rectangle enclosing the label portion that the last item in
- * path will be drawn to. Will return null if any component in path is
- * currently valid.
- *
- * @param tree is the current tree the path will be drawn to.
- * @param path is the current path the tree to draw to.
- * @return the Rectangle enclosing the label portion that the last item in
- * the path will be drawn to.
- */
- public Rectangle getPathBounds(JTree tree, TreePath path)
- {
- Object cell = path.getLastPathComponent();
- TreeModel mod = tree.getModel();
- Point loc = getCellLocation(0, 0, tree, mod, cell, mod.getRoot());
- int x = (int) loc.getX();
- int y = (int) loc.getY();
- return getCellBounds(x, y, cell);
- }
-
- /**
- * Returns the path for passed in row. If row is not visible null is
- * returned.
- *
- * @param tree is the current tree to return path for.
- * @param row is the row number of the row to return.
- * @return the path for passed in row. If row is not visible null is
- * returned.
- */
- public TreePath getPathForRow(JTree tree, int row)
- {
- DefaultMutableTreeNode node = ((DefaultMutableTreeNode) (tree.getModel())
- .getRoot());
-
- for (int i = 0; i < row; i++)
- node = getNextVisibleNode(node);
-
- // in case nothing was found
- if (node == null)
- return null;
-
- // something was found
- return new TreePath(node.getPath());
- }
-
- /**
- * Get next visible node in the tree.
- * Package private for use in inner classes.
- * @param the current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
- */
- DefaultMutableTreeNode getNextVisibleNode(DefaultMutableTreeNode node)
- {
- DefaultMutableTreeNode next = null;
- TreePath current = null;
-
- if (node != null)
- next = node.getNextNode();
-
- if (next != null)
- {
- current = new TreePath(next.getPath());
- if (tree.isVisible(current))
- return next;
-
- while (next != null && !tree.isVisible(current))
- {
- next = next.getNextNode();
+ stopEditingInCompleteEditing = false;
+ if (editingComponent != null)
+ {
+ tree.remove(editingComponent.getParent());
+ editingComponent = null;
+ }
+ if (cellEditor != null)
+ {
+ newVal = ((JTextField) getCellEditor().getCellEditorValue()).getText();
+ completeEditing(false, false, true);
+ if (cellEditor instanceof DefaultTreeCellEditor)
+ tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
+ cellEditor.removeCellEditorListener(cellEditorListener);
+ setCellEditor(null);
+ createdCellEditor = false;
+ }
+ isEditing = false;
+ tree.requestFocusInWindow(false);
+ editorTimer.stop();
+ }
+
+ /**
+ * Messaged when editing has been canceled in the tree. This tells the
+ * listeners the editor has canceled editing.
+ *
+ * @param e
+ * is the notification event
+ */
+ public void editingCanceled(ChangeEvent e)
+ {
+ editingPath = null;
+ editingRow = -1;
+ stopEditingInCompleteEditing = false;
+ if (editingComponent != null)
+ tree.remove(editingComponent.getParent());
+ editingComponent = null;
+ if (cellEditor != null)
+ {
+ if (cellEditor instanceof DefaultTreeCellEditor)
+ tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
+ cellEditor.removeCellEditorListener(cellEditorListener);
+ setCellEditor(null);
+ createdCellEditor = false;
+ }
+ tree.requestFocusInWindow(false);
+ editorTimer.stop();
+ isEditing = false;
+ tree.repaint();
+ }
+ }// CellEditorHandler
+
+ /**
+ * Repaints the lead selection row when focus is lost/grained.
+ */
+ public class FocusHandler
+ implements FocusListener
+ {
+ /**
+ * Constructor
+ */
+ public FocusHandler()
+ {
+ }
+
+ /**
+ * Invoked when focus is activated on the tree we're in, redraws the lead
+ * row. Invoked when a component gains the keyboard focus.
+ *
+ * @param e
+ * is the focus event that is activated
+ */
+ public void focusGained(FocusEvent e)
+ {
+ }
+
+ /**
+ * Invoked when focus is deactivated on the tree we're in, redraws the lead
+ * row. Invoked when a component loses the keyboard focus.
+ *
+ * @param e
+ * is the focus event that is deactivated
+ */
+ public void focusLost(FocusEvent e)
+ {
+ }
+ }// FocusHandler
+
+ /**
+ * This is used to get multiple key down events to appropriately genereate
+ * events.
+ */
+ public class KeyHandler
+ extends KeyAdapter
+ {
+ /** Key code that is being generated for. */
+ protected Action repeatKeyAction;
+
+ /** Set to true while keyPressed is active */
+ protected boolean isKeyDown;
+
+ /**
+ * Constructor
+ */
+ public KeyHandler()
+ {
+ }
+
+ /**
+ * Invoked when a key has been typed. Moves the keyboard focus to the first
+ * element whose first letter matches the alphanumeric key pressed by the
+ * user. Subsequent same key presses move the keyboard focus to the next
+ * object that starts with the same letter.
+ *
+ * @param e
+ * the key typed
+ */
+ public void keyTyped(KeyEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a key has been pressed.
+ *
+ * @param e
+ * the key pressed
+ */
+ public void keyPressed(KeyEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a key has been released
+ *
+ * @param e
+ * the key released
+ */
+ public void keyReleased(KeyEvent e)
+ {
+ }
+ }// KeyHandler
+
+ /**
+ * MouseListener is responsible for updating the selection based on mouse
+ * events.
+ */
+ public class MouseHandler
+ extends MouseAdapter
+ implements MouseMotionListener
+ {
+ /**
+ * Constructor
+ */
+ public MouseHandler()
+ {
+ }
+
+ /**
+ * Invoked when a mouse button has been pressed on a component.
+ *
+ * @param e
+ * is the mouse event that occured
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a mouse button is pressed on a component and then dragged.
+ * MOUSE_DRAGGED events will continue to be delivered to the component where
+ * the drag originated until the mouse button is released (regardless of
+ * whether the mouse position is within the bounds of the component).
+ *
+ * @param e
+ * is the mouse event that occured
+ */
+ public void mouseDragged(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when the mouse button has been moved on a component (with no
+ * buttons no down).
+ *
+ * @param e
+ * the mouse event that occured
+ */
+ public void mouseMoved(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a mouse button has been released on a component.
+ *
+ * @param e
+ * is the mouse event that occured
+ */
+ public void mouseReleased(MouseEvent e)
+ {
+ }
+ }// MouseHandler
+
+ /**
+ * MouseInputHandler handles passing all mouse events, including mouse motion
+ * events, until the mouse is released to the destination it is constructed
+ * with.
+ */
+ public class MouseInputHandler
+ implements MouseInputListener
+ {
+ /** Source that events are coming from */
+ protected Component source;
+
+ /** Destination that receives all events. */
+ protected Component destination;
+
+ /**
+ * Constructor
+ *
+ * @param source
+ * that events are coming from
+ * @param destination
+ * that receives all events
+ * @param e
+ * is the event received
+ */
+ public MouseInputHandler(Component source, Component destination,
+ MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when the mouse button has been clicked (pressed and released) on
+ * a component.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a mouse button has been pressed on a component.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ Point click = e.getPoint();
+ int row = Math.round(click.y / getRowHeight());
+ TreePath path = getClosestPathForLocation(tree, click.x, click.y);
- if (next != null)
- current = new TreePath(next.getPath());
- }
- }
- return next;
- }
-
- /**
- * Get previous visible node in the tree.
- * Package private for use in inner classes.
- *
- * @param the current node
- * @return the next visible node in the JTree. Return null if there are no
- * more.
- */
- DefaultMutableTreeNode getPreviousVisibleNode
- (DefaultMutableTreeNode node)
- {
- DefaultMutableTreeNode prev = null;
- TreePath current = null;
-
- if (node != null)
- prev = node.getPreviousNode();
-
- if (prev != null)
- {
- current = new TreePath(prev.getPath());
- if (tree.isVisible(current))
- return prev;
+ if (path != null)
+ {
+ boolean inBounds = false;
+ boolean cntlClick = false;
+ Rectangle bounds = getPathBounds(tree, path);
+
+ bounds.x -= rightChildIndent - 4;
+ bounds.width += rightChildIndent + 4;
+
+ if (bounds.contains(click.x, click.y))
+ inBounds = true;
+ else if (hasControlIcons()
+ && (click.x < (bounds.x - rightChildIndent + 5) &&
+ click.x > (bounds.x - rightChildIndent - 5)))
+ cntlClick = true;
+
+ if ((inBounds || cntlClick) && tree.isVisible(path))
+ {
+ selectPath(tree, path);
- while (prev != null && !tree.isVisible(current))
- {
- prev = prev.getPreviousNode();
+ if ((e.getClickCount() == 2 || cntlClick) && !isLeaf(row))
+ {
+ if (tree.isExpanded(path))
+ tree.collapsePath(path);
+ else
+ tree.expandPath(path);
+ }
- if (prev != null)
- current = new TreePath(prev.getPath());
- }
- }
- return prev;
- }
-
- /**
- * Returns the row that the last item identified in path is visible at. Will
- * return -1 if any of the elments in the path are not currently visible.
- *
- * @param tree is the current tree to return the row for.
- * @param path is the path used to find the row.
- * @return the row that the last item identified in path is visible at. Will
- * return -1 if any of the elments in the path are not currently
- * visible.
- */
- public int getRowForPath(JTree tree, TreePath path)
- {
- // FIXME: check visibility
- // right now, just returns last element because
- // expand/collapse is not implemented
- return path.getPathCount() - 1;
- }
-
- /**
- * Returns the number of rows that are being displayed.
- *
- * @param tree is the current tree to return the number of rows for.
- * @return the number of rows being displayed.
- */
- public int getRowCount(JTree tree)
- {
- DefaultMutableTreeNode node = ((DefaultMutableTreeNode) (tree.getModel())
- .getRoot());
- int count = 0;
-
- while (node != null)
- {
- count++;
- node = getNextVisibleNode(node);
- }
-
- return count;
- }
-
- /**
- * Returns the path to the node that is closest to x,y. If there is nothing
- * currently visible this will return null, otherwise it'll always return a
- * valid path. If you need to test if the returned object is exactly at x,y
- * you should get the bounds for the returned path and test x,y against that.
- *
- * @param tree the tree to search for the closest path
- * @param x is the x coordinate of the location to search
- * @param y is the y coordinate of the location to search
- * @return the tree path closes to x,y.
- */
- public TreePath getClosestPathForLocation(JTree tree, int x, int y)
- {
- return treeState.getPathClosestTo(x, y);
- }
-
- /**
- * Returns true if the tree is being edited. The item that is being edited
- * can be returned by getEditingPath().
- *
- * @param tree is the tree to check for editing.
- * @return true if the tree is being edited.
- */
- public boolean isEditing(JTree tree)
- {
- // FIXME: not implemented
- return false;
- }
-
- /**
- * Stops the current editing session. This has no effect if the tree is not
- * being edited. Returns true if the editor allows the editing session to
- * stop.
- *
- * @param tree is the tree to stop the editing on
- * @return true if the editor allows the editing session to stop.
- */
- public boolean stopEditing(JTree tree)
- {
- // FIXME: not implemented
- return false;
- }
-
- /**
- * Cancels the current editing session.
- *
- * @param tree is the tree to cancel the editing session on.
- */
- public void cancelEditing(JTree tree)
- {
- // FIXME: not implemented
- }
-
- /**
- * Selects the last item in path and tries to edit it. Editing will fail if
- * the CellEditor won't allow it for the selected item.
- *
- * @param tree is the tree to edit on.
- * @param path is the path in tree to edit on.
- */
- public void startEditingAtPath(JTree tree, TreePath path)
- {
- // FIXME: not implemented
- }
-
- /**
- * Returns the path to the element that is being editted.
- *
- * @param tree is the tree to get the editing path from.
- * @return the path that is being edited.
- */
- public TreePath getEditingPath(JTree tree)
- {
- // FIXME: not implemented
- return null;
- }
-
- /**
- * Invoked after the tree instance variable has been set, but before any
- * default/listeners have been installed.
- */
- protected void prepareForUIInstall()
- {
- // FIXME: not implemented
- }
-
- /**
- * Invoked from installUI after all the defaults/listeners have been
- * installed.
- */
- protected void completeUIInstall()
- {
- // FIXME: not implemented
- }
-
- /**
- * Invoked from uninstallUI after all the defaults/listeners have been
- * uninstalled.
- */
- protected void completeUIUninstall()
- {
- // FIXME: not implemented
- }
-
- /**
- * Installs the subcomponents of the tree, which is the renderer pane.
- */
- protected void installComponents()
- {
- // FIXME: not implemented
- }
-
- /**
- * Creates an instance of NodeDimensions that is able to determine the size
- * of a given node in the tree.
- *
- * @return the NodeDimensions of a given node in the tree
- */
- protected AbstractLayoutCache.NodeDimensions createNodeDimensions()
- {
- // FIXME: not implemented
+ if (!cntlClick && tree.isEditable())
+ startEditing(path, e);
+ }
+ }
+ }
+
+ /**
+ * Invoked when a mouse button has been released on a component.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseReleased(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when the mouse enters a component.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseEntered(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when the mouse exits a component.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseExited(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when a mouse button is pressed on a component and then dragged.
+ * MOUSE_DRAGGED events will continue to be delivered to the component where
+ * the drag originated until the mouse button is released (regardless of
+ * whether the mouse position is within the bounds of the component).
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseDragged(MouseEvent e)
+ {
+ }
+
+ /**
+ * Invoked when the mouse cursor has been moved onto a component but no
+ * buttons have been pushed.
+ *
+ * @param e
+ * mouse event that occured
+ */
+ public void mouseMoved(MouseEvent e)
+ {
+ }
+
+ /**
+ * Removes event from the source
+ */
+ protected void removeFromSource()
+ {
+ }
+ }// MouseInputHandler
+
+ /**
+ * Class responsible for getting size of node, method is forwarded to
+ * BasicTreeUI method. X location does not include insets, that is handled in
+ * getPathBounds.
+ */
+ public class NodeDimensionsHandler
+ extends AbstractLayoutCache.NodeDimensions
+ {
+ /**
+ * Constructor
+ */
+ public NodeDimensionsHandler()
+ {
+ }
+
+ /**
+ * Responsible for getting the size of a particular node.
+ *
+ * @param value
+ * the value to be represented
+ * @param row
+ * row being queried
+ * @param depth
+ * the depth of the row
+ * @param expanded
+ * true if row is expanded
+ * @param size
+ * a Rectangle containing the size needed to represent value
+ * @return containing the node dimensions, or null if node has no dimension
+ */
+ public Rectangle getNodeDimensions(Object value, int row, int depth,
+ boolean expanded, Rectangle size)
+ {
return null;
- }
-
- /**
- * Creates a listener that is reponsible for the updates the UI based on how
- * the tree changes.
- *
- * @return the PropertyChangeListener that is reposnsible for the updates
- */
- protected PropertyChangeListener createPropertyChangeListener()
- {
- return new PropertyChangeHandler();
- }
-
- /**
- * Creates the listener responsible for updating the selection based on mouse
- * events.
- *
- * @return the MouseListener responsible for updating.
- */
- protected MouseListener createMouseListener()
- {
- return new MouseHandler();
- }
-
- /**
- * Creates the listener that is responsible for updating the display when
- * focus is lost/grained.
- *
- * @return the FocusListener responsible for updating.
- */
- protected FocusListener createFocusListener()
- {
- return new FocusHandler();
- }
-
- /**
- * Creates the listener reponsible for getting key events from the tree.
- *
- * @return the KeyListener responsible for getting key events.
- */
- protected KeyListener createKeyListener()
- {
- return new KeyHandler();
- }
-
- /**
- * Creates the listener responsible for getting property change events from
- * the selection model.
- *
- * @returns the PropertyChangeListener reponsible for getting property change
- * events from the selection model.
- */
- protected PropertyChangeListener createSelectionModelPropertyChangeListener()
- {
- return new SelectionModelPropertyChangeHandler();
- }
-
- /**
- * Creates the listener that updates the display based on selection change
- * methods.
- *
- * @return the TreeSelectionListener responsible for updating.
- */
- protected TreeSelectionListener createTreeSelectionListener()
- {
- return new TreeSelectionHandler();
- }
-
- /**
- * Creates a listener to handle events from the current editor
- *
- * @return the CellEditorListener that handles events from the current editor
- */
- protected CellEditorListener createCellEditorListener()
- {
- return new CellEditorHandler();
- }
-
- /**
- * Creates and returns a new ComponentHandler. This is used for the large
- * model to mark the validCachedPreferredSize as invalid when the component
- * moves.
- *
- * @return a new ComponentHandler.
- */
- protected ComponentListener createComponentListener()
- {
- return new ComponentHandler();
- }
-
- /**
- * Creates and returns the object responsible for updating the treestate when
- * a nodes expanded state changes.
- *
- * @return the TreeExpansionListener responsible for updating the treestate
- */
- protected TreeExpansionListener createTreeExpansionListener()
- {
- return new TreeExpansionHandler();
- }
-
- /**
- * Creates the object responsible for managing what is expanded, as well as
- * the size of nodes.
- *
- * @return the object responsible for managing what is expanded.
- */
- protected AbstractLayoutCache createLayoutCache()
- {
- return new FixedHeightLayoutCache();
- }
-
- /**
- * Returns the renderer pane that renderer components are placed in.
- *
- * @return the rendererpane that render components are placed in.
- */
- protected CellRendererPane createCellRendererPane()
- {
- return new CellRendererPane();
- }
-
- /**
- * Creates a default cell editor.
- *
- * @return the default cell editor.
- */
- protected TreeCellEditor createDefaultCellEditor()
- {
- return new DefaultTreeCellEditor(tree,
- (DefaultTreeCellRenderer) createDefaultCellRenderer(), cellEditor);
- }
-
- /**
- * Returns the default cell renderer that is used to do the stamping of each
- * node.
- *
- * @return the default cell renderer that is used to do the stamping of each
- * node.
- */
- protected TreeCellRenderer createDefaultCellRenderer()
- {
- return new DefaultTreeCellRenderer();
- }
-
- /**
- * Returns a listener that can update the tree when the model changes.
- *
- * @return a listener that can update the tree when the model changes.
- */
- protected TreeModelListener createTreeModelListener()
- {
- return new TreeModelHandler();
- }
-
- /**
- * Uninstall all registered listeners
- */
- protected void uninstallListeners()
- {
- tree.removePropertyChangeListener(propertyChangeListener);
- tree.removeFocusListener(focusListener);
- tree.removeTreeSelectionListener(treeSelectionListener);
- tree.removeMouseListener(mouseInputListener);
- tree.removeKeyListener(keyListener);
- tree.removePropertyChangeListener(selectionModelPropertyChangeListener);
- tree.removeComponentListener(componentListener);
- tree.getCellEditor().removeCellEditorListener(cellEditorListener);
- tree.removeTreeExpansionListener(treeExpansionListener);
- tree.getModel().removeTreeModelListener(treeModelListener);
- }
-
- /**
- * Uninstall all keyboard actions.
- */
- protected void uninstallKeyboardActions()
- {
- }
-
- /**
- * Uninstall the rendererPane.
- */
- protected void uninstallComponents()
- {
- // FIXME: not implemented
- }
-
- /**
- * The vertical element of legs between nodes starts at the bottom of the
- * parent node by default. This method makes the leg start below that.
- *
- * @return the vertical leg buffer
- */
- protected int getVerticalLegBuffer()
- {
- // FIXME: not implemented
- return 0;
- }
-
- /**
- * The horizontal element of legs between nodes starts at the right of the
- * left-hand side of the child node by default. This method makes the leg end
- * before that.
- *
- * @return the horizontal leg buffer
- */
- protected int getHorizontalLegBuffer()
- {
- // FIXME: not implemented
+ }
+
+ /**
+ * Returns the amount to indent the given row
+ *
+ * @return amount to indent the given row.
+ */
+ protected int getRowX(int row, int depth)
+ {
return 0;
- }
-
- /**
- * Make all the nodes that are expanded in JTree expanded in LayoutCache.
- * This invokes update ExpandedDescendants with the root path.
- */
- protected void updateLayoutCacheExpandedNodes()
- {
- // FIXME: not implemented
- }
-
- /**
- * Updates the expanded state of all the descendants of the path
- * by getting the expanded descendants from the tree and forwarding to the
- * tree state.
- *
- * @param path the path used to update the expanded states
- */
- protected void updateExpandedDescendants(TreePath path)
- {
- // FIXME: not implemented
- }
-
- /**
- * Returns a path to the last child of parent
- *
- * @param parent is the topmost path to specified
- * @return a path to the last child of parent
- */
- protected TreePath getLastChildPath(TreePath parent)
- {
- return ((TreePath) parent.getLastPathComponent());
- }
-
- /**
- * Updates how much each depth should be offset by.
- */
- protected void updateDepthOffset()
- {
- // FIXME: not implemented
- }
-
- /**
- * Updates the cellEditor based on editability of the JTree that we're
- * contained in. Ig the tree is editable but doesn't have a cellEditor, a
- * basic one will be used.
- */
- protected void updateCellEditor()
- {
- // FIXME: not implemented
- }
-
- /**
- * Messaged from the tree we're in when the renderer has changed.
- */
- protected void updateRenderer()
- {
- // FIXME: not implemented
- }
-
- /**
- * Resets the treeState instance based on the tree we're providing the look
- * and feel for.
- */
- protected void configureLayoutCache()
- {
- treeState = createLayoutCache();
- }
-
- /**
- * Marks the cached size as being invalid, and messages the tree with
- * treeDidChange
.
- */
- protected void updateSize()
- {
- // FIXME: not implemented
- }
-
- /**
- * Updates the preferredSize
instance variable, which is
- * returned from getPreferredSize()
. For left to right
- * orientations, the size is determined from the current AbstractLayoutCache.
- * For RTL orientations, the preferred size becomes the width minus the
- * minimum x position.
- */
- protected void updateCachedPreferredSize()
- {
- // FIXME: not implemented
- }
-
- /**
- * Messaged from the VisibleTreeNode after it has been expanded.
- *
- * @param path is the path that has been expanded.
- */
- protected void pathWasExpanded(TreePath path)
- {
- // FIXME: not implemented
- }
-
- /**
- * Messaged from the VisibleTreeNode after it has collapsed
- */
- protected void pathWasCollapsed(TreePath path)
- {
- // FIXME: not implemented
- }
-
- /**
- * Install all defaults for the tree.
- *
- * @param tree is the JTree to install defaults for
- */
- protected void installDefaults(JTree tree)
- {
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- tree.setFont(defaults.getFont("Tree.font"));
- tree.setForeground(defaults.getColor("Tree.foreground"));
- tree.setBackground(defaults.getColor("Tree.background"));
- tree.setOpaque(true);
-
- rightChildIndent = defaults.getInt("Tree.rightChildIndent");
- leftChildIndent = defaults.getInt("Tree.leftChildIndent");
- setRowHeight(defaults.getInt("Tree.rowHeight"));
- }
-
- /**
- * Install all keyboard actions for this
- */
- protected void installKeyboardActions()
- {
- }
-
- /**
- * Install all listeners for this
- */
- protected void installListeners()
- {
- tree.addPropertyChangeListener(propertyChangeListener);
- tree.addFocusListener(focusListener);
- tree.addTreeSelectionListener(treeSelectionListener);
- tree.addMouseListener(mouseInputListener);
- tree.addKeyListener(keyListener);
- tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
- tree.addComponentListener(componentListener);
- cellEditor.addCellEditorListener(cellEditorListener);
- tree.addTreeExpansionListener(treeExpansionListener);
- treeModel.addTreeModelListener(treeModelListener);
- }
-
- /**
- * Install the UI for the component
- *
- * @param c the component to install UI for
- */
- public void installUI(JComponent c)
- {
- super.installUI(c);
- installDefaults((JTree) c);
- tree = (JTree) c;
- setModel(tree.getModel());
- tree.setRootVisible(true);
- tree.expandPath(new TreePath(((DefaultMutableTreeNode)
- (tree.getModel()).getRoot()).getPath()));
- treeSelectionModel = tree.getSelectionModel();
- installListeners();
- installKeyboardActions();
- completeUIInstall();
- }
-
- /**
- * Uninstall the defaults for the tree
- *
- * @param tree to uninstall defaults for
- */
- protected void uninstallDefaults(JTree tree)
- {
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
- tree.setFont(null);
- tree.setForeground(null);
- tree.setBackground(null);
- tree.setCellRenderer(null);
- }
-
- /**
- * Uninstall the UI for the component
- *
- * @param c the component to uninstall UI for
- */
- public void uninstallUI(JComponent c)
- {
- uninstallDefaults((JTree) c);
- uninstallKeyboardActions();
- uninstallListeners();
- tree = null;
- completeUIUninstall();
- }
-
- /**
- * Paints the specified component appropriate for the look and feel. This
- * method is invoked from the ComponentUI.update method when the specified
- * component is being painted. Subclasses should override this method and use
- * the specified Graphics object to render the content of the component.
- *
- * @param g the Graphics context in which to paint
- * @param c the component being painted; this argument is often ignored, but
- * might be used if the UI object is stateless and shared by multiple
- * components
- */
- public void paint(Graphics g, JComponent c)
- {
- JTree tree = (JTree) c;
- TreeModel mod = tree.getModel();
- g.translate(10, 10);
- paintRecursive(g, 0, 0, 0, 0, tree, mod, mod.getRoot());
- paintControlIcons(g, 0, 0, 0, 0, tree, mod, mod.getRoot());
- g.translate(-10, -10);
- }
-
- /**
- * Ensures that the rows identified by beginRow through endRow are visible.
- *
- * @param beginRow is the first row
- * @param endRow is the last row
- */
- protected void ensureRowsAreVisible(int beginRow, int endRow)
- {
- // FIXME: not implemented
- }
-
- /**
- * Sets the preferred minimum size.
- *
- * @param newSize is the new preferred minimum size.
- */
- public void setPreferredMinSize(Dimension newSize)
- {
- // FIXME: not implemented
- }
-
- /**
- * Gets the preferred minimum size.
- *
- * @returns the preferred minimum size.
- */
- public Dimension getPreferredMinSize()
- {
- // FIXME: not implemented
- return null;
- }
-
- /**
- * Returns the preferred size to properly display the tree, this is a cover
- * method for getPreferredSize(c, false).
- *
- * @param c the component whose preferred size is being queried; this
- * argument is often ignored but might be used if the UI object is
- * stateless and shared by multiple components
- * @return the preferred size
- */
- public Dimension getPreferredSize(JComponent c)
- {
- return getPreferredSize(c, false);
- }
-
- /**
- * Returns the preferred size to represent the tree in c. If checkConsistancy
- * is true, checkConsistancy is messaged first.
- *
- * @param c the component whose preferred size is being queried.
- * @param checkConsistancy if true must check consistancy
- * @return the preferred size
- */
- public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)
- {
- // FIXME: checkConsistancy not implemented, c not used
- DefaultMutableTreeNode node = ((DefaultMutableTreeNode) (tree.getModel())
- .getRoot());
- int maxWidth = 0;
- int count = 0;
- if (node != null)
- {
- maxWidth = (int) (getCellBounds(0, 0, node).getWidth());
- while (node != null)
- {
- count++;
- DefaultMutableTreeNode nextNode = node.getNextNode();
- if (nextNode != null)
- maxWidth = Math.max(maxWidth, (int) (getCellBounds(0, 0, nextNode)
- .getWidth()));
- node = nextNode;
- }
- }
-
- return new Dimension(maxWidth, (getRowHeight() * count));
- }
-
- /**
- * Returns the minimum size for this component. Which will be the min
- * preferred size or (0,0).
- *
- * @param c the component whose min size is being queried.
- * @returns the preferred size or null
- */
- public Dimension getMinimumSize(JComponent c)
- {
- // FIXME: not implemented
- return getPreferredSize(c);
- }
-
- /**
- * Returns the maximum size for the component, which will be the preferred
- * size if the instance is currently in JTree or (0,0).
- *
- * @param c the component whose preferred size is being queried
- * @return the max size or null
- */
- public Dimension getMaximumSize(JComponent c)
- {
- // FIXME: not implemented
- return getPreferredSize(c);
- }
-
- /**
- * Messages to stop the editing session. If the UI the receiver is providing
- * the look and feel for returns true from
- * getInvokesStopCellEditing
, stopCellEditing will be invoked
- * on the current editor. Then completeEditing will be messaged with false,
- * true, false to cancel any lingering editing.
- */
- protected void completeEditing()
- {
- // FIXME: not implemented
- }
-
- /**
- * Stops the editing session. If messageStop is true, the editor is messaged
- * with stopEditing, if messageCancel is true the editor is messaged with
- * cancelEditing. If messageTree is true, the treeModel is messaged with
- * valueForPathChanged.
- *
- * @param messageStop message to stop editing
- * @param messageCancel message to cancel editing
- * @param messageTree message to treeModel
- */
- protected void completeEditing(boolean messageStop, boolean messageCancel,
- boolean messageTree)
- {
- // FIXME: not implemented
- }
-
- /**
- * Will start editing for node if there is a cellEditor and shouldSelectCall
- * returns true. This assumes that path is valid and visible.
- *
- * @param path is the path to start editing
- * @param event is the MouseEvent performed on the path
- * @return true if successful
- */
- protected boolean startEditing(TreePath path, MouseEvent event)
- {
- // FIXME: not implemented
+ }
+ }// NodeDimensionsHandler
+
+ /**
+ * PropertyChangeListener for the tree. Updates the appropriate varaible, or
+ * TreeState, based on what changes.
+ */
+ public class PropertyChangeHandler
+ implements PropertyChangeListener
+ {
+
+ /**
+ * Constructor
+ */
+ public PropertyChangeHandler()
+ {
+ }
+
+ /**
+ * This method gets called when a bound property is changed.
+ *
+ * @param event
+ * A PropertyChangeEvent object describing the event source and the
+ * property that has changed.
+ */
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ }
+ }// PropertyChangeHandler
+
+ /**
+ * Listener on the TreeSelectionModel, resets the row selection if any of the
+ * properties of the model change.
+ */
+ public class SelectionModelPropertyChangeHandler
+ implements PropertyChangeListener
+ {
+
+ /**
+ * Constructor
+ */
+ public SelectionModelPropertyChangeHandler()
+ {
+ }
+
+ /**
+ * This method gets called when a bound property is changed.
+ *
+ * @param event
+ * A PropertyChangeEvent object describing the event source and the
+ * property that has changed.
+ */
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ }
+ }// SelectionModelPropertyChangeHandler
+
+ /**
+ * ActionListener that invokes cancelEditing when action performed.
+ */
+ public class TreeCancelEditingAction
+ extends AbstractAction
+ {
+
+ /**
+ * Constructor
+ */
+ public TreeCancelEditingAction()
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled, false otherwise
+ */
+ public boolean isEnabled()
+ {
return false;
- }
-
- /**
- * If the mouseX
and mouseY
are in the expand
- * or collapse region of the row, this will toggle the row.
- *
- * @param path the path we are concerned with
- * @param mouseX is the cursor's x position
- * @param mouseY is the cursor's y position
- */
- protected void checkForClickInExpandControl(TreePath path, int mouseX,
- int mouseY)
- {
- // FIXME: not implemented
- }
-
- /**
- * Returns true if the mouseX
and mouseY
fall
- * in the area of row that is used to expand/collpse the node and the node at
- * row does not represent a leaf.
- *
- * @param path the path we are concerned with
- * @param mouseX is the cursor's x position
- * @param mouseY is the cursor's y position
- * @return true if the mouseX
and mouseY
fall
- * in the area of row that is used to expand/collpse the node and the
- * node at row does not represent a leaf.
- */
- protected boolean isLocationInExpandControl(TreePath path, int mouseX,
- int mouseY)
- {
- // FIXME: not implemented
+ }
+ }// TreeCancelEditingAction
+
+ /**
+ * Updates the TreeState in response to nodes expanding/collapsing.
+ */
+ public class TreeExpansionHandler
+ implements TreeExpansionListener
+ {
+
+ /**
+ * Constructor
+ */
+ public TreeExpansionHandler()
+ {
+ }
+
+ /**
+ * Called whenever an item in the tree has been expanded.
+ *
+ * @param event
+ * is the event that occured
+ */
+ public void treeExpanded(TreeExpansionEvent event)
+ {
+ tree.repaint();
+ }
+
+ /**
+ * Called whenever an item in the tree has been collapsed.
+ *
+ * @param event
+ * is the event that occured
+ */
+ public void treeCollapsed(TreeExpansionEvent event)
+ {
+ tree.repaint();
+ }
+ }// TreeExpansionHandler
+
+ /**
+ * TreeHomeAction is used to handle end/home actions. Scrolls either the first
+ * or last cell to be visible based on direction.
+ */
+ public class TreeHomeAction
+ extends AbstractAction
+ {
+
+ /** direction is either home or end */
+ protected int direction;
+
+ /**
+ * Constructor
+ *
+ * @param direction -
+ * it is home or end
+ * @param name
+ * is the name of the direction
+ */
+ public TreeHomeAction(int direction, String name)
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled.
+ */
+ public boolean isEnabled()
+ {
return false;
- }
-
- /**
- * Messaged when the user clicks the particular row, this invokes
- * toggleExpandState.
- *
- * @param path the path we are concerned with
- * @param mouseX is the cursor's x position
- * @param mouseY is the cursor's y position
- */
- protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)
- {
- // FIXME: not implemented
- }
-
- /**
- * Expands path if it is not expanded, or collapses row if it is expanded. If
- * expanding a path and JTree scroll on expand, ensureRowsAreVisible is
- * invoked to scroll as many of the children to visible as possible (tries to
- * scroll to last visible descendant of path).
- *
- * @param path the path we are concerned with
- */
- protected void toggleExpandState(TreePath path)
- {
- // FIXME: not implemented
- }
-
- /**
- * Returning true signifies a mouse event on the node should toggle the
- * selection of only the row under the mouse.
- *
- * @param event is the MouseEvent performed on the row.
- * @return true signifies a mouse event on the node should toggle the
- * selection of only the row under the mouse.
- */
- protected boolean isToggleSelectionEvent(MouseEvent event)
- {
- // FIXME: not implemented
- return false;
- }
-
- /**
- * Returning true signifies a mouse event on the node should select from the
- * anchor point.
- *
- * @param event is the MouseEvent performed on the node.
- * @return true signifies a mouse event on the node should select from the
- * anchor point.
- */
- protected boolean isMultiSelectEvent(MouseEvent event)
- {
- // FIXME: not implemented
- return false;
- }
-
- /**
- * Returning true indicates the row under the mouse should be toggled based
- * on the event. This is invoked after checkForClickInExpandControl, implying
- * the location is not in the expand (toggle) control.
- *
- * @param event is the MouseEvent performed on the row.
- * @return true indicates the row under the mouse should be toggled based on
- * the event.
- */
- protected boolean isToggleEvent(MouseEvent event)
- {
- // FIXME: not implemented
- return false;
- }
-
- /**
- * Messaged to update the selection based on a MouseEvent over a particular
- * row. If the even is a toggle selection event, the row is either selected,
- * or deselected. If the event identifies a multi selection event, the
- * selection is updated from the anchor point. Otherwise, the row is
- * selected, and if the even specified a toggle event the row is
- * expanded/collapsed.
- *
- * @param path is the path selected for an event
- * @param event is the MouseEvent performed on the path.
- */
- protected void selectPathForEvent(TreePath path, MouseEvent event)
- {
- // FIXME: not implemented
- }
-
- /**
- * Returns true if the node at row
is a leaf.
- *
- * @param row is the row we are concerned with.
- * @return true if the node at row
is a leaf.
- */
- protected boolean isLeaf(int row)
- {
- TreePath pathForRow = getPathForRow(tree, row);
- if (pathForRow == null)
- return true;
-
- Object node = pathForRow.getLastPathComponent();
-
- if (node instanceof TreeNode)
- return ((TreeNode) node).isLeaf();
- else
- return true;
- }
-
- /**
- * Selects the specified path in the tree depending on modes.
- * Package private for use in inner classes.
- *
- * @param tree is the tree we are selecting the path in
- * @param path is the path we are selecting
- */
- void selectPath(JTree tree, TreePath path)
- {
- if (path != null)
- {
- if (tree.isPathSelected(path))
- tree.removeSelectionPath(path);
- else if (tree.getSelectionModel().getSelectionMode()
- == TreeSelectionModel.SINGLE_TREE_SELECTION)
- {
- tree.getSelectionModel().clearSelection();
- tree.addSelectionPath(path);
- tree.setLeadSelectionPath(path);
- }
- else if (tree.getSelectionModel().getSelectionMode()
- == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
- {
- // TODO
- }
- else
- {
- tree.getSelectionModel().setSelectionMode(
- TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
- tree.addSelectionPath(path);
- tree.setLeadSelectionPath(path);
- }
- }
- }
-
- /* * INTERNAL CLASSES * */
-
- /**
- * Updates the preferred size when scrolling, if necessary.
- */
- public class ComponentHandler
- extends ComponentAdapter
- implements ActionListener
- {
- /**
- * Timer used when inside a scrollpane and the scrollbar is adjusting
- */
- protected Timer timer;
-
- /** ScrollBar that is being adjusted */
- protected JScrollBar scrollBar;
-
- /**
- * Constructor
- */
- public ComponentHandler()
- {
- }
-
- /**
- * Invoked when the component's position changes.
- *
- * @param e the event that occurs when moving the component
- */
- public void componentMoved(ComponentEvent e)
- {
- }
-
- /**
- * Creats, if necessary, and starts a Timer to check if needed to resize
- * the bounds
- */
- protected void startTimer()
- {
- }
-
- /**
- * Returns the JScrollPane housing the JTree, or null if one isn't found.
- *
- * @return JScrollPane housing the JTree, or null if one isn't found.
- */
- protected JScrollPane getScrollPane()
- {
- return null;
- }
-
- /**
- * Public as a result of Timer. If the scrollBar is null, or not
- * adjusting, this stops the timer and updates the sizing.
- *
- * @param ae is the action performed
- */
- public void actionPerformed(ActionEvent ae)
- {
- }
- }// ComponentHandler
-
- /**
- * Listener responsible for getting cell editing events and updating the tree
- * accordingly.
- */
- public class CellEditorHandler
- implements CellEditorListener
- {
- /**
- * Constructor
- */
- public CellEditorHandler()
- {
- }
-
- /**
- * Messaged when editing has stopped in the tree. Tells the listeners
- * editing has stopped.
- *
- * @param e is the notification event
- */
- public void editingStopped(ChangeEvent e)
- {
- }
-
- /**
- * Messaged when editing has been canceled in the tree. This tells the
- * listeners the editor has canceled editing.
- *
- * @param e is the notification event
- */
- public void editingCanceled(ChangeEvent e)
- {
- }
- }// CellEditorHandler
-
- /**
- * Repaints the lead selection row when focus is lost/grained.
- */
- public class FocusHandler
- implements FocusListener
- {
- /**
- * Constructor
- */
- public FocusHandler()
- {
- }
-
- /**
- * Invoked when focus is activated on the tree we're in, redraws the lead
- * row. Invoked when a component gains the keyboard focus.
- *
- * @param e is the focus event that is activated
- */
- public void focusGained(FocusEvent e)
- {
- }
-
- /**
- * Invoked when focus is deactivated on the tree we're in, redraws the
- * lead row. Invoked when a component loses the keyboard focus.
- *
- * @param e is the focus event that is deactivated
- */
- public void focusLost(FocusEvent e)
- {
- }
- }// FocusHandler
-
- /**
- * This is used to get multiple key down events to appropriately genereate
- * events.
- */
- public class KeyHandler
- extends KeyAdapter
- {
- /** Key code that is being generated for. */
- protected Action repeatKeyAction;
-
- /** Set to true while keyPressed is active */
- protected boolean isKeyDown;
-
- /**
- * Constructor
- */
- public KeyHandler()
- {
- }
-
- /**
- * Invoked when a key has been typed. Moves the keyboard focus to the
- * first element whose first letter matches the alphanumeric key pressed
- * by the user. Subsequent same key presses move the keyboard focus to the
- * next object that starts with the same letter.
- *
- * @param e the key typed
- */
- public void keyTyped(KeyEvent e)
- {
- }
-
- /**
- * Invoked when a key has been pressed.
- *
- * @param e the key pressed
- */
- public void keyPressed(KeyEvent e)
- {
- TreePath start = BasicTreeUI.this.tree.getLeadSelectionPath();
- DefaultMutableTreeNode last = null;
-
- if (start != null)
- last = (DefaultMutableTreeNode) start.getLastPathComponent();
- if (last != null)
- {
- if (e.getKeyCode() == KeyEvent.VK_DOWN)
+ }
+ }// TreeHomeAction
+
+ /**
+ * TreeIncrementAction is used to handle up/down actions. Selection is moved
+ * up or down based on direction.
+ */
+ public class TreeIncrementAction
+ extends AbstractAction
+ {
+
+ /** Specifies the direction to adjust the selection by. */
+ protected int direction;
+
+ /**
+ * Constructor
+ *
+ * @param direction
+ * up or down
+ * @param name
+ * is the name of the direction
+ */
+ public TreeIncrementAction(int direction, String name)
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ Object last = tree.getLeadSelectionPath().getLastPathComponent();
+
+ if (e.getActionCommand().equals("selectPreviousChangeLead"))
+ {
+ Object prev = getPreviousVisibleNode(last);
+
+ if (prev != null)
{
- DefaultMutableTreeNode next = (DefaultMutableTreeNode)
- BasicTreeUI.this.getNextVisibleNode(last);
-
- if (next != null)
- BasicTreeUI.this.selectPath(BasicTreeUI.this.tree,
- new TreePath(next.getPath()));
+ TreePath newPath = new TreePath(getPathToRoot(prev, 0));
+ selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
+ tree.setLeadSelectionPath(newPath);
}
- else if (e.getKeyCode() == KeyEvent.VK_UP)
+ }
+ else if (e.getActionCommand().equals("selectPreviousExtendSelection"))
+ {
+ Object prev = getPreviousVisibleNode(last);
+ if (prev != null)
{
- DefaultMutableTreeNode prev = (DefaultMutableTreeNode)
- BasicTreeUI.this.getPreviousVisibleNode(last);
-
- if (prev != null)
- BasicTreeUI.this.selectPath(BasicTreeUI.this.tree,
- new TreePath(prev.getPath()));
+ TreePath newPath = new TreePath(getPathToRoot(prev, 0));
+ tree.addSelectionPath(newPath);
+ tree.setLeadSelectionPath(newPath);
}
- else if (e.getKeyCode() == KeyEvent.VK_LEFT)
+ }
+ else if (e.getActionCommand().equals("selectPrevious"))
+ {
+ Object prev = getPreviousVisibleNode(last);
+ if (prev != null)
{
- TreePath path = new TreePath(last.getPath());
-
- if (!last.isLeaf() && BasicTreeUI.this.tree.isExpanded(path))
- {
- BasicTreeUI.this.tree.collapsePath(path);
- BasicTreeUI.this.tree.fireTreeCollapsed(path);
- }
+ TreePath newPath = new TreePath(getPathToRoot(prev, 0));
+ selectPath(tree, new TreePath(getPathToRoot(prev, 0)));
}
- else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
+ }
+ else if (e.getActionCommand().equals("selectNext"))
+ {
+ Object next = getNextVisibleNode(last);
+ if (next != null)
{
- TreePath path = new TreePath(last.getPath());
-
- if (!last.isLeaf() && BasicTreeUI.this.tree.isCollapsed(path))
- {
- BasicTreeUI.this.tree.expandPath(path);
- BasicTreeUI.this.tree.fireTreeExpanded(path);
- }
+ TreePath newPath = new TreePath(getPathToRoot(next, 0));
+ selectPath(tree, newPath);
}
- }
- }
-
- /**
- * Invoked when a key has been released
- *
- * @param e the key released
- */
- public void keyReleased(KeyEvent e)
- {
- }
- }// KeyHandler
-
- /**
- * MouseListener is responsible for updating the selevtion based on mouse
- * events.
- */
- public class MouseHandler
- extends MouseAdapter
- implements MouseMotionListener
- {
- /**
- * Constructor
- */
- public MouseHandler()
- {
- }
-
- /**
- * Invoked when a mouse button has been pressed on a component.
- *
- * @param e is the mouse event that occured
- */
- public void mousePressed(MouseEvent e)
- {
- }
-
- /**
- * Invoked when a mouse button is pressed on a component and then dragged.
- * MOUSE_DRAGGED events will continue to be delivered to the component
- * where the drag originated until the mouse button is released
- * (regardless of whether the mouse position is within the bounds of the
- * component).
- *
- * @param e is the mouse event that occured
- */
- public void mouseDragged(MouseEvent e)
- {
- }
-
- /**
- * Invoked when the mouse button has been moved on a component (with no
- * buttons no down).
- *
- * @param e the mouse event that occured
- */
- public void mouseMoved(MouseEvent e)
- {
- }
-
- /**
- * Invoked when a mouse button has been released on a component.
- *
- * @param e is the mouse event that occured
- */
- public void mouseReleased(MouseEvent e)
- {
- }
- }// MouseHandler
-
- /**
- * MouseInputHandler handles passing all mouse events, including mouse motion
- * events, until the mouse is released to the destination it is constructed
- * with.
- */
- public class MouseInputHandler
- implements MouseInputListener
- {
- /** Source that events are coming from */
- protected Component source;
-
- /** Destination that receives all events. */
- protected Component destination;
-
- /** Number of mouse clicks on a non-leaf */
- private int clickCount = 0;
-
- /**
- * Constructor
- *
- * @param source that events are coming from
- * @param destination that receives all events
- * @param event is the event received
- */
- public MouseInputHandler(Component source, Component destination,
- MouseEvent e)
- {
- }
-
- /**
- * Invoked when the mouse button has been clicked (pressed and released)
- * on a component.
- *
- * @param e mouse event that occured
- */
- public void mouseClicked(MouseEvent e)
- {
- Point click = e.getPoint();
- int clickX = (int) click.getX();
- int clickY = (int) click.getY();
- int row = (clickY / getRowHeight()) - 1;
- TreePath path = BasicTreeUI.this.tree.getPathForRow(row);
-
- boolean inBounds = false;
- boolean cntlClick = false;
- Rectangle bounds = BasicTreeUI.this.getPathBounds(
- BasicTreeUI.this.tree, path);
- int x = (int) bounds.getX();
- int y = (int) bounds.getY();
-
- if (clickY > y && clickY < (y + bounds.height + 10))
- {
- if (clickX > x && clickX < (x + bounds.width + 20))
- inBounds = true;
- else if (clickX < (x - rightChildIndent + 5) &&
- clickX > (x - rightChildIndent - 5))
- cntlClick = true;
- }
-
- if ((inBounds || cntlClick) && path != null &&
- BasicTreeUI.this.tree.isVisible(path))
- {
- if (!cntlClick && !BasicTreeUI.this.isLeaf(row))
- clickCount++;
-
- if (clickCount == 2 || cntlClick == true)
+ }
+ else if (e.getActionCommand().equals("selectNextExtendSelection"))
+ {
+ Object next = getNextVisibleNode(last);
+ if (next != null)
{
- clickCount = 0;
- BasicTreeUI.this.tree.getSelectionModel().clearSelection();
- if (BasicTreeUI.this.tree.isExpanded(path))
- {
- BasicTreeUI.this.tree.collapsePath(path);
- BasicTreeUI.this.tree.fireTreeCollapsed(path);
- }
- else
- {
- BasicTreeUI.this.tree.expandPath(path);
- BasicTreeUI.this.tree.fireTreeExpanded(path);
- }
+ TreePath newPath = new TreePath(getPathToRoot(next, 0));
+ tree.addSelectionPath(newPath);
+ tree.setLeadSelectionPath(newPath);
}
-
- BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, path);
- }
- }
-
- /**
- * Invoked when a mouse button has been pressed on a component.
- *
- * @param e mouse event that occured
- */
- public void mousePressed(MouseEvent e)
- {
- }
-
- /**
- * Invoked when a mouse button has been released on a component.
- *
- * @param e mouse event that occured
- */
- public void mouseReleased(MouseEvent e)
- {
- }
-
- /**
- * Invoked when the mouse enters a component.
- *
- * @param e mouse event that occured
- */
- public void mouseEntered(MouseEvent e)
- {
- }
-
- /**
- * Invoked when the mouse exits a component.
- *
- * @param e mouse event that occured
- */
- public void mouseExited(MouseEvent e)
- {
- }
-
- /**
- * Invoked when a mouse button is pressed on a component and then dragged.
- * MOUSE_DRAGGED events will continue to be delivered to the component
- * where the drag originated until the mouse button is released
- * (regardless of whether the mouse position is within the bounds of the
- * component).
- *
- * @param e mouse event that occured
- */
- public void mouseDragged(MouseEvent e)
- {
- }
-
- /**
- * Invoked when the mouse cursor has been moved onto a component but no
- * buttons have been pushed.
- *
- * @param e mouse event that occured
- */
- public void mouseMoved(MouseEvent e)
- {
- }
-
- /**
- * Removes event from the source
- */
- protected void removeFromSource()
- {
- }
- }// MouseInputHandler
-
- /**
- * Class responsible for getting size of node, method is forwarded to
- * BasicTreeUI method. X location does not include insets, that is handled in
- * getPathBounds.
- */
- public class NodeDimensionsHandler
- extends AbstractLayoutCache.NodeDimensions
- {
- /**
- * Constructor
- */
- public NodeDimensionsHandler()
- {
- }
-
- /**
- * Responsible for getting the size of a particular node.
- *
- * @param value the value to be represented
- * @param row row being queried
- * @param depth the depth of the row
- * @param expanded true if row is expanded
- * @param size a Rectangle containing the size needed to represent value
- * @return containing the node dimensions, or null if node has no
- * dimension
- */
- public Rectangle getNodeDimensions(Object value, int row, int depth,
- boolean expanded, Rectangle size)
- {
- return null;
- }
-
- /**
- * Returns the amount to indent the given row
- *
- * @return amount to indent the given row.
- */
- protected int getRowX(int row, int depth)
- {
- return 0;
- }
- }// NodeDimensionsHandler
-
- /**
- * PropertyChangeListener for the tree. Updates the appropriate varaible, or
- * TreeState, based on what changes.
- */
- public class PropertyChangeHandler
- implements PropertyChangeListener
- {
-
- /**
- * Constructor
- */
- public PropertyChangeHandler()
- {
- }
-
- /**
- * This method gets called when a bound property is changed.
- *
- * @param event A PropertyChangeEvent object describing the event source
- * and the property that has changed.
- */
- public void propertyChange(PropertyChangeEvent event)
- {
- }
- }// PropertyChangeHandler
-
- /**
- * Listener on the TreeSelectionModel, resets the row selection if any of the
- * properties of the model change.
- */
- public class SelectionModelPropertyChangeHandler
- implements PropertyChangeListener
- {
-
- /**
- * Constructor
- */
- public SelectionModelPropertyChangeHandler()
- {
- }
-
- /**
- * This method gets called when a bound property is changed.
- *
- * @param event A PropertyChangeEvent object describing the event source
- * and the property that has changed.
- */
- public void propertyChange(PropertyChangeEvent event)
- {
- }
- }// SelectionModelPropertyChangeHandler
-
- /**
- * ActionListener that invokes cancelEditing when action performed.
- */
- public class TreeCancelEditingAction
- extends AbstractAction
- {
-
- /**
- * Constructor
- */
- public TreeCancelEditingAction()
- {
- }
-
- /**
- * Invoked when an action occurs.
- *
- * @param e event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
-
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled, false otherwise
- */
- public boolean isEnabled()
- {
- return false;
- }
- }// TreeCancelEditingAction
-
- /**
- * Updates the TreeState in response to nodes expanding/collapsing.
- */
- public class TreeExpansionHandler
- implements TreeExpansionListener
- {
-
- /**
- * Constructor
- */
- public TreeExpansionHandler()
- {
- }
-
- /**
- * Called whenever an item in the tree has been expanded.
- *
- * @param event is the event that occured
- */
- public void treeExpanded(TreeExpansionEvent event)
- {
- BasicTreeUI.this.tree.repaint();
- }
-
- /**
- * Called whenever an item in the tree has been collapsed.
- *
- * @param event is the event that occured
- */
- public void treeCollapsed(TreeExpansionEvent event)
- {
- BasicTreeUI.this.tree.repaint();
- }
- }// TreeExpansionHandler
-
- /**
- * TreeHomeAction is used to handle end/home actions. Scrolls either the
- * first or last cell to be visible based on direction.
- */
- public class TreeHomeAction
- extends AbstractAction
- {
-
- /** direction is either home or end */
- protected int direction;
-
- /**
- * Constructor
- *
- * @param direction - it is home or end
- * @param name is the name of the direction
- */
- public TreeHomeAction(int direction, String name)
- {
- }
-
- /**
- * Invoked when an action occurs.
- *
- * @param e is the event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
+ }
+ else if (e.getActionCommand().equals("selectNextChangeLead"))
+ {
+ Object next = getNextVisibleNode(last);
+ if (next != null)
+ {
+ TreePath newPath = new TreePath(getPathToRoot(next, 0));
+ selectPath(tree, newPath);
+ tree.setLeadSelectionPath(newPath);
+ }
+ }
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled.
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+ }// TreeIncrementAction
+
+ /**
+ * Forwards all TreeModel events to the TreeState.
+ */
+ public class TreeModelHandler
+ implements TreeModelListener
+ {
+ /**
+ * Constructor
+ */
+ public TreeModelHandler()
+ {
+ }
+
+ /**
+ * Invoked after a node (or a set of siblings) has changed in some way. The
+ * node(s) have not changed locations in the tree or altered their children
+ * arrays, but other attributes have changed and may affect presentation.
+ * Example: the name of a file has changed, but it is in the same location
+ * in the file system. To indicate the root has changed, childIndices and
+ * children will be null. Use e.getPath() to get the parent of the changed
+ * node(s). e.getChildIndices() returns the index(es) of the changed
+ * node(s).
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void treeNodesChanged(TreeModelEvent e)
+ {
+ tree.repaint();
+ }
+
+ /**
+ * Invoked after nodes have been inserted into the tree. Use e.getPath() to
+ * get the parent of the new node(s). e.getChildIndices() returns the
+ * index(es) of the new node(s) in ascending order.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void treeNodesInserted(TreeModelEvent e)
+ {
+ tree.repaint();
+ }
+
+ /**
+ * Invoked after nodes have been removed from the tree. Note that if a
+ * subtree is removed from the tree, this method may only be invoked once
+ * for the root of the removed subtree, not once for each individual set of
+ * siblings removed. Use e.getPath() to get the former parent of the deleted
+ * node(s). e.getChildIndices() returns, in ascending order, the index(es)
+ * the node(s) had before being deleted.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void treeNodesRemoved(TreeModelEvent e)
+ {
+ tree.repaint();
+ }
+
+ /**
+ * Invoked after the tree has drastically changed structure from a given
+ * node down. If the path returned by e.getPath() is of length one and the
+ * first element does not identify the current root node the first element
+ * should become the new root of the tree. Use e.getPath() to get the path
+ * to the node. e.getChildIndices() returns null.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void treeStructureChanged(TreeModelEvent e)
+ {
+ tree.repaint();
+ }
+ }// TreeModelHandler
+
+ /**
+ * TreePageAction handles page up and page down events.
+ */
+ public class TreePageAction
+ extends AbstractAction
+ {
+ /** Specifies the direction to adjust the selection by. */
+ protected int direction;
+
+ /**
+ * Constructor
+ *
+ * @param direction
+ * up or down
+ * @param name
+ * is the name of the direction
+ */
+ public TreePageAction(int direction, String name)
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * is the event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled.
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+ }// TreePageAction
+
+ /**
+ * Listens for changes in the selection model and updates the display
+ * accordingly.
+ */
+ public class TreeSelectionHandler
+ implements TreeSelectionListener
+ {
+ /**
+ * Constructor
+ */
+ public TreeSelectionHandler()
+ {
+ }
+
+ /**
+ * Messaged when the selection changes in the tree we're displaying for.
+ * Stops editing, messages super and displays the changed paths.
+ *
+ * @param event
+ * the event that characterizes the change.
+ */
+ public void valueChanged(TreeSelectionEvent event)
+ {
+ if (tree.isEditing())
+ tree.cancelEditing();
+ }
+ }// TreeSelectionHandler
+
+ /**
+ * For the first selected row expandedness will be toggled.
+ */
+ public class TreeToggleAction
+ extends AbstractAction
+ {
+ /**
+ * Constructor
+ *
+ * @param name
+ * is the name of Action
field
+ */
+ public TreeToggleAction(String name)
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * the event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled, false otherwise
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+ } // TreeToggleAction
+
+ /**
+ * TreeTraverseAction is the action used for left/right keys. Will toggle the
+ * expandedness of a node, as well as potentially incrementing the selection.
+ */
+ public class TreeTraverseAction
+ extends AbstractAction
+ {
+ /**
+ * Determines direction to traverse, 1 means expand, -1 means collapse.
+ */
+ protected int direction;
+
+ /**
+ * Constructor
+ *
+ * @param direction
+ * to traverse
+ * @param name
+ * is the name of the direction
+ */
+ public TreeTraverseAction(int direction, String name)
+ {
+ }
+
+ /**
+ * Invoked when an action occurs.
+ *
+ * @param e
+ * the event that occured
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ TreeModel mod = tree.getModel();
+ Object last = tree.getLeadSelectionPath().getLastPathComponent();
+
+ if (e.getActionCommand().equals("selectParent"))
+ {
+ TreePath path = new TreePath(getPathToRoot(last, 0));
+ Object p = getParent(mod.getRoot(), last);
+
+ if (!mod.isLeaf(last) && tree.isExpanded(path))
+ tree.collapsePath(path);
+ else if (p != null)
+ selectPath(tree, new TreePath(getPathToRoot(p, 0)));
+ }
+ else if (e.getActionCommand().equals("selectChild"))
+ {
+ TreePath path = new TreePath(getPathToRoot(last, 0));
+
+ if (!mod.isLeaf(last) && tree.isCollapsed(path))
+ tree.expandPath(path);
+ else
+ {
+ Object next = getNextVisibleNode(last);
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled.
- */
- public boolean isEnabled()
- {
- return false;
- }
- }// TreeHomeAction
-
- /**
- * TreeIncrementAction is used to handle up/down actions. Selection is moved
- * up or down based on direction.
- */
- public class TreeIncrementAction
- extends AbstractAction
- {
-
- /** Specifies the direction to adjust the selection by. */
- protected int direction;
-
- /**
- * Constructor
- *
- * @param direction up or down
- * @param name is the name of the direction
- */
- public TreeIncrementAction(int direction, String name)
- {
- }
+ if (next != null)
+ selectPath(tree, new TreePath(getPathToRoot(next, 0)));
+ }
+ }
+ }
+
+ /**
+ * Returns true if the action is enabled.
+ *
+ * @return true if the action is enabled, false otherwise
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+ } // TreeTraverseAction
+
+ /**
+ * Returns the cell bounds for painting selected cells Package private for use
+ * in inner classes.
+ *
+ * @param x
+ * is the x location of the cell
+ * @param y
+ * is the y location of the cell
+ * @param cell
+ * is the Object to get the bounds for
+ * @returns Rectangle that represents the cell bounds
+ */
+ Rectangle getCellBounds(int x, int y, Object cell)
+ {
+ if (cell != null)
+ {
+ String s = cell.toString();
+ Font f = tree.getFont();
+ FontMetrics fm = tree.getToolkit().getFontMetrics(f);
+
+ if (s != null)
+ return new Rectangle(x, y,
+ SwingUtilities.computeStringWidth(fm, s) + 4,
+ fm.getHeight());
+ }
+ return new Rectangle(x, y, 0, 0);
+ }
+
+ /**
+ * Retrieves the location of some node, recursively starting at from some
+ * node. Package private for use in inner classes.
+ *
+ * @param x
+ * is the starting x position, offset
+ * @param y
+ * is the starting y position, offset
+ * @param tree
+ * is the tree to traverse
+ * @param mod
+ * is the TreeModel to use
+ * @param node
+ * is the node to get the location for
+ * @param startNode
+ * is the node to start searching from
+ * @return Point - the location of node
+ */
+ Point getCellLocation(int x, int y, JTree tree, TreeModel mod, Object node,
+ Object startNode)
+ {
+ int rowHeight = getRowHeight();
+ if (startNode == null || startNode.equals(node))
+ {
+ if (!tree.isRootVisible()
+ && tree.isExpanded(new TreePath(mod.getRoot())))
+ return new Point(x + ((getLevel(node)) * rightChildIndent), y);
+
+ return new Point(x + ((getLevel(node) + 1) * rightChildIndent), y);
+ }
+
+ if (!mod.isLeaf(startNode)
+ && tree.isExpanded(new TreePath(getPathToRoot(startNode, 0)))
+ && !mod.isLeaf(startNode) && mod.getChildCount(startNode) > 0)
+ {
+ Object child = mod.getChild(startNode, 0);
+ if (child != null)
+ return getCellLocation(x, y + rowHeight, tree, mod, node, child);
+ }
+
+ return getCellLocation(x, y + rowHeight, tree, mod, node,
+ getNextVisibleNode(startNode));
+ }
+
+ /**
+ * Paints a node in the tree Package private for use in inner classes.
+ *
+ * @param g
+ * the Graphics context in which to paint
+ * @param x
+ * the x location of the node
+ * @param y
+ * the y location of the node
+ * @param tree
+ * the tree to draw on
+ * @param node
+ * the object to draw
+ */
+ void paintNode(Graphics g, int x, int y, JTree tree, Object node,
+ boolean isLeaf)
+ {
+ TreePath curr = new TreePath(getPathToRoot(node, 0));
+ boolean selected = tree.isPathSelected(curr);
+ boolean expanded = false;
+ boolean hasIcons = false;
+
+ if (tree.isVisible(curr))
+ {
+ if (!isLeaf)
+ expanded = tree.isExpanded(curr);
+
+ if (editingComponent != null && editingPath != null && isEditing(tree)
+ && node.equals(editingPath.getLastPathComponent()))
+ {
+ Rectangle bounds = getPathBounds(tree, editingPath);
+ rendererPane.paintComponent(g, editingComponent.getParent(), null,
+ new Rectangle(0, 0, bounds.width,
+ bounds.height));
+ }
+ else
+ {
+ TreeCellRenderer dtcr = tree.getCellRenderer();
+ if (dtcr == null)
+ dtcr = createDefaultCellRenderer();
+
+ int row = getRowForPath(tree, curr);
+
+ Component c = dtcr.getTreeCellRendererComponent(tree, node,
+ selected, expanded,
+ isLeaf, row, false);
+
+ rendererPane.paintComponent(g, c, c.getParent(),
+ getCellBounds(x, y, node));
+ }
+ }
+ }
+
+ /**
+ * Recursively paints all elements of the tree Package private for use in
+ * inner classes.
+ *
+ * @param g
+ * the Graphics context in which to paint
+ * @param indentation
+ * of the current object
+ * @param descent
+ * is the number of elements drawn
+ * @param childNumber
+ * is the index of the current child in the tree
+ * @param depth
+ * is the depth of the current object in the tree
+ * @param tree
+ * is the tree to draw to
+ * @param mod
+ * is the TreeModel we are using to draw
+ * @param curr
+ * is the current object to draw
+ * @return int - current descent of the tree
+ */
+ int paintRecursive(Graphics g, int indentation, int descent, int childNumber,
+ int depth, JTree tree, TreeModel mod, Object curr)
+ {
+ Rectangle clip = g.getClipBounds();
+ if (indentation > clip.x + clip.width + rightChildIndent
+ || descent > clip.y + clip.height + getRowHeight())
+ return descent;
- /**
- * Invoked when an action occurs.
- *
- * @param e is the event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
+ int halfHeight = getRowHeight() / 2;
+ int halfWidth = rightChildIndent / 2;
+ int y0 = descent + halfHeight;
+ int heightOfLine = descent + halfHeight;
+ boolean isRootVisible = tree.isRootVisible();
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled.
- */
- public boolean isEnabled()
- {
- return false;
- }
- }// TreeIncrementAction
-
- /**
- * Forwards all TreeModel events to the TreeState.
- */
- public class TreeModelHandler
- implements TreeModelListener
- {
- /**
- * Constructor
- */
- public TreeModelHandler()
+ if (mod.isLeaf(curr))
{
+ paintNode(g, indentation + 4, descent, tree, curr, true);
+ descent += getRowHeight();
}
-
- /**
- * Invoked after a node (or a set of siblings) has changed in some way.
- * The node(s) have not changed locations in the tree or altered their
- * children arrays, but other attributes have changed and may affect
- * presentation. Example: the name of a file has changed, but it is in the
- * same location in the file system. To indicate the root has changed,
- * childIndices and children will be null. Use e.getPath() to get the
- * parent of the changed node(s). e.getChildIndices() returns the
- * index(es) of the changed node(s).
- *
- * @param e is the event that occured
- */
- public void treeNodesChanged(TreeModelEvent e)
+ else
{
- }
+ if (depth > 0 || isRootVisible)
+ {
+ paintNode(g, indentation + 4, descent, tree, curr, false);
+ descent += getRowHeight();
+ y0 += halfHeight;
+ }
+
+ int max = 0;
+ if (!mod.isLeaf(curr))
+ max = mod.getChildCount(curr);
+ if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
+ {
+ for (int i = 0; i < max; i++)
+ {
+ int indent = indentation + rightChildIndent;
+ if (!isRootVisible && depth == 0)
+ indent = 0;
+ else if ((!isRootVisible && !curr.equals(mod.getRoot()))
+ || isRootVisible)
+ {
+ g.setColor(getHashColor());
+ heightOfLine = descent + halfHeight;
+ g.drawLine(indentation + halfWidth, heightOfLine,
+ indentation + rightChildIndent, heightOfLine);
+ }
- /**
- * Invoked after nodes have been inserted into the tree. Use e.getPath()
- * to get the parent of the new node(s). e.getChildIndices() returns the
- * index(es) of the new node(s) in ascending order.
- *
- * @param e is the event that occured
- */
- public void treeNodesInserted(TreeModelEvent e)
- {
- }
+ descent = paintRecursive(g, indent, descent, i, depth + 1,
+ tree, mod, mod.getChild(curr, i));
+ }
+ }
+ }
+
+ if (tree.isExpanded(new TreePath(getPathToRoot(curr, 0))))
+ if (y0 != heightOfLine && !mod.isLeaf(curr)
+ && mod.getChildCount(curr) > 0)
+ {
+ g.setColor(getHashColor());
+ g.drawLine(indentation + halfWidth, y0, indentation + halfWidth,
+ heightOfLine);
+ }
+
+ return descent;
+ }
+
+ /**
+ * Recursively paints all the control icons on the tree. Package private for
+ * use in inner classes.
+ *
+ * @param g
+ * the Graphics context in which to paint
+ * @param indentation
+ * of the current object
+ * @param descent
+ * is the number of elements drawn
+ * @param childNumber
+ * is the index of the current child in the tree
+ * @param depth
+ * is the depth of the current object in the tree
+ * @param tree
+ * is the tree to draw to
+ * @param mod
+ * is the TreeModel we are using to draw
+ * @param curr
+ * is the current object to draw
+ * @return int - current descent of the tree
+ */
+ int paintControlIcons(Graphics g, int indentation, int descent,
+ int childNumber, int depth, JTree tree, TreeModel mod,
+ Object node)
+ {
+ int h = descent;
+ int rowHeight = getRowHeight();
+ Icon ei = UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon");
+ Icon ci = UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon");
+ Rectangle clip = g.getClipBounds();
+ if (indentation > clip.x + clip.width + rightChildIndent
+ || descent > clip.y + clip.height + getRowHeight())
+ return descent;
- /**
- * Invoked after nodes have been removed from the tree. Note that if a
- * subtree is removed from the tree, this method may only be invoked once
- * for the root of the removed subtree, not once for each individual set
- * of siblings removed. Use e.getPath() to get the former parent of the
- * deleted node(s). e.getChildIndices() returns, in ascending order, the
- * index(es) the node(s) had before being deleted.
- *
- * @param e is the event that occured
- */
- public void treeNodesRemoved(TreeModelEvent e)
+ if (mod.isLeaf(node))
+ descent += rowHeight;
+ else
{
- }
+ if (depth > 0 || tree.isRootVisible())
+ descent += rowHeight;
- /**
- * Invoked after the tree has drastically changed structure from a given
- * node down. If the path returned by e.getPath() is of length one and the
- * first element does not identify the current root node the first element
- * should become the new root of the tree. Use e.getPath() to get the path
- * to the node. e.getChildIndices() returns null.
- *
- * @param e is the event that occured
- */
- public void treeStructureChanged(TreeModelEvent e)
- {
- }
- }// TreeModelHandler
-
- /**
- * TreePageAction handles page up and page down events.
- */
- public class TreePageAction
- extends AbstractAction
- {
- /** Specifies the direction to adjust the selection by. */
- protected int direction;
-
- /**
- * Constructor
- *
- * @param direction up or down
- * @param name is the name of the direction
- */
- public TreePageAction(int direction, String name)
- {
- }
+ int max = 0;
+ if (!mod.isLeaf(node))
+ max = mod.getChildCount(node);
+ if (tree.isExpanded(new TreePath(getPathToRoot(node, 0))))
+ {
+ if (!node.equals(mod.getRoot()))
+ ei.paintIcon(tree, g, indentation - rightChildIndent - 3, h);
+
+ for (int i = 0; i < max; i++)
+ {
+ int indent = indentation + rightChildIndent;
+ if (depth == 0 && !tree.isRootVisible())
+ indent = -1;
+
+ descent = paintControlIcons(g, indent, descent, i, depth + 1,
+ tree, mod, mod.getChild(node, i));
+ }
+ }
+ else if (!node.equals(mod.getRoot()))
+ ci.paintIcon(tree, g, indentation - rightChildIndent - 3,
+ descent - getRowHeight());
+ }
+
+ return descent;
+ }
+
+ /**
+ * Returns true if the LookAndFeel implements the control icons Package
+ * private for use in inner classes.
+ *
+ * @return true if control icons are visible
+ */
+ boolean hasControlIcons()
+ {
+ if (UIManager.getLookAndFeelDefaults().getIcon("Tree.expandedIcon") == null
+ || UIManager.getLookAndFeelDefaults().getIcon("Tree.collapsedIcon") == null)
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the parent of the current node
+ *
+ * @param root
+ * is the root of the tree
+ * @param node
+ * is the current node
+ * @return is the parent of the current node
+ */
+ Object getParent(Object root, Object node)
+ {
+ if (root == null || node == null)
+ return null;
+ if (node instanceof TreeNode)
+ return ((TreeNode) node).getParent();
+ return findNode(root, node);
+ }
+
+ /**
+ * Recursively checks the tree for the specified node, starting at the root.
+ *
+ * @param root
+ * is starting node to start searching at.
+ * @param node
+ * is the node to search for
+ * @return the parent node of node
+ */
+ private Object findNode(Object root, Object node)
+ {
+ TreeModel mod = tree.getModel();
+ int size = 0;
+ if (!mod.isLeaf(root))
+ size = mod.getChildCount(root);
+ for (int i = 0; i < size; i++)
+ {
+ if (mod.getIndexOfChild(root, node) != -1)
+ return root;
+
+ Object n = findNode(mod.getChild(root, i), node);
+ if (n != null)
+ return n;
+ }
+ return null;
+ }
+
+ /**
+ * Get next visible node in the tree. Package private for use in inner
+ * classes.
+ *
+ * @param the
+ * current node
+ * @return the next visible node in the JTree. Return null if there are no
+ * more.
+ */
+ Object getNextVisibleNode(Object node)
+ {
+ Object next = null;
+ TreePath current = null;
+
+ if (node != null)
+ next = getNextNode(node);
+
+ if (next != null)
+ {
+ current = new TreePath(getPathToRoot(next, 0));
+ if (tree.isVisible(current))
+ return next;
+
+ while (next != null && !tree.isVisible(current))
+ {
+ next = getNextNode(next);
- /**
- * Invoked when an action occurs.
- *
- * @param e is the event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
+ if (next != null)
+ current = new TreePath(getPathToRoot(next, 0));
+ }
+ }
+ return next;
+ }
+
+ /**
+ * Get previous visible node in the tree. Package private for use in inner
+ * classes.
+ *
+ * @param the
+ * current node
+ * @return the next visible node in the JTree. Return null if there are no
+ * more.
+ */
+ Object getPreviousVisibleNode(Object node)
+ {
+ Object prev = null;
+ TreePath current = null;
+
+ if (node != null)
+ prev = getPreviousNode(node);
+
+ if (prev != null)
+ {
+ current = new TreePath(getPathToRoot(prev, 0));
+ if (tree.isVisible(current))
+ return prev;
+
+ while (prev != null && !tree.isVisible(current))
+ {
+ prev = getPreviousNode(prev);
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled.
- */
- public boolean isEnabled()
- {
- return false;
- }
- }// TreePageAction
-
- /**
- * Listens for changes in the selection model and updates the display
- * accordingly.
- */
- public class TreeSelectionHandler
- implements TreeSelectionListener
- {
- /**
- * Constructor
- */
- public TreeSelectionHandler()
- {
- }
+ if (prev != null)
+ current = new TreePath(getPathToRoot(prev, 0));
+ }
+ }
+ return prev;
+ }
+
+ /**
+ * Returns the next node in the tree Package private for use in inner classes.
+ *
+ * @param the
+ * current node
+ * @return the next node in the tree
+ */
+ Object getNextNode(Object curr)
+ {
+ TreeModel mod = tree.getModel();
+ if (!mod.isLeaf(curr) && mod.getChildCount(curr) > 0)
+ return mod.getChild(curr, 0);
+
+ Object node = curr;
+ Object sibling = null;
+
+ do
+ {
+ sibling = getNextSibling(node);
+ node = getParent(mod.getRoot(), node);
+ }
+ while (sibling == null && node != null);
+
+ return sibling;
+ }
+
+ /**
+ * Returns the previous node in the tree Package private for use in inner
+ * classes.
+ *
+ * @param the
+ * current node
+ * @return the previous node in the tree
+ */
+ Object getPreviousNode(Object node)
+ {
+ TreeModel mod = tree.getModel();
+ Object parent = getParent(mod.getRoot(), node);
+ if (parent == null)
+ return null;
- /**
- * Messaged when the selection changes in the tree we're displaying for.
- * Stops editing, messages super and displays the changed paths.
- *
- * @param event the event that characterizes the change.
- */
- public void valueChanged(TreeSelectionEvent event)
- {
- }
- }// TreeSelectionHandler
-
- /**
- * For the first selected row expandedness will be toggled.
- */
- public class TreeToggleAction
- extends AbstractAction
- {
- /**
- * Constructor
- *
- * @param name is the name of Action
field
- */
- public TreeToggleAction(String name)
- {
- }
+ Object sibling = getPreviousSibling(node);
+
+ if (sibling == null)
+ return parent;
+
+ int size = 0;
+ if (!mod.isLeaf(sibling))
+ size = mod.getChildCount(sibling);
+ while (size > 0)
+ {
+ sibling = mod.getChild(sibling, size - 1);
+ if (!mod.isLeaf(sibling))
+ size = mod.getChildCount(sibling);
+ else
+ size = 0;
+ }
+
+ return sibling;
+ }
+
+ /**
+ * Returns the next sibling in the tree Package private for use in inner
+ * classes.
+ *
+ * @param the
+ * current node
+ * @return the next sibling in the tree
+ */
+ Object getNextSibling(Object node)
+ {
+ TreeModel mod = tree.getModel();
+ Object parent = getParent(mod.getRoot(), node);
+ if (parent == null)
+ return null;
- /**
- * Invoked when an action occurs.
- *
- * @param e the event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
+ int index = mod.getIndexOfChild(parent, node) + 1;
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled, false otherwise
- */
- public boolean isEnabled()
- {
- return false;
- }
- } // TreeToggleAction
-
- /**
- * TreeTraverseAction is the action used for left/right keys. Will toggle
- * the expandedness of a node, as well as potentially incrementing the
- * selection.
- */
- public class TreeTraverseAction
- extends AbstractAction
- {
- /**
- * Determines direction to traverse, 1 means expand, -1 means collapse.
- */
- protected int direction;
-
- /**
- * Constructor
- *
- * @param direction to traverse
- * @param name is the name of the direction
- */
- public TreeTraverseAction(int direction, String name)
- {
- }
+ int size = 0;
+ if (!mod.isLeaf(parent))
+ size = mod.getChildCount(parent);
+ if (index == 0 || index >= size)
+ return null;
- /**
- * Invoked when an action occurs.
- *
- * @param e the event that occured
- */
- public void actionPerformed(ActionEvent e)
- {
- }
+ return mod.getChild(parent, index);
+ }
+
+ /**
+ * Returns the previous sibling in the tree Package private for use in inner
+ * classes.
+ *
+ * @param the
+ * current node
+ * @return the previous sibling in the tree
+ */
+ Object getPreviousSibling(Object node)
+ {
+ TreeModel mod = tree.getModel();
+ Object parent = getParent(mod.getRoot(), node);
+ if (parent == null)
+ return null;
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled, false otherwise
- */
- public boolean isEnabled()
- {
- return false;
- }
- } // TreeTraverseAction
-
- /**
- * Returns the cell bounds for painting selected cells
- *
- * @param x is the x location of the cell
- * @param y is the y location of the cell
- * @param cell is the Object to get the bounds for
- *
- * @returns Rectangle that represents the cell bounds
- */
- private Rectangle getCellBounds(int x, int y, Object cell)
- {
- if (cell != null)
- {
- String s = cell.toString();
- Font f = tree.getFont();
- FontMetrics fm = tree.getToolkit().getFontMetrics(tree.getFont());
+ int index = mod.getIndexOfChild(parent, node) - 1;
- return new Rectangle(x, y, SwingUtilities.computeStringWidth(fm, s),
- fm.getHeight());
- }
+ int size = 0;
+ if (!mod.isLeaf(parent))
+ size = mod.getChildCount(parent);
+ if (index < 0 || index >= size)
return null;
- }
-
- /**
- * Retrieves the location of some node, recursively starting at from
- * some node.
- *
- * @param x is the starting x position, offset
- * @param y is the starting y position, offset
- * @param tree is the tree to traverse
- * @param mod is the TreeModel to use
- * @param node is the node to get the location for
- * @param startNode is the node to start searching from
- *
- * @return Point - the location of node
- */
- private Point getCellLocation(int x, int y, JTree tree, TreeModel mod,
- Object node, Object startNode)
- {
- int rowHeight = getRowHeight();
- if (startNode == null || startNode.equals(node))
- return new Point(x + ((((DefaultMutableTreeNode) node).
- getLevel() + 1) * rightChildIndent), y);
-
- if (!mod.isLeaf(startNode)
- && tree.isExpanded(new TreePath(
- ((DefaultMutableTreeNode) startNode).getPath())))
- {
- Object child = mod.getChild(startNode, 0);
- if (child != null)
- return getCellLocation(x, y + rowHeight, tree, mod,
- node, child);
- }
-
- return getCellLocation(x, y + rowHeight, tree, mod, node,
- getNextVisibleNode((DefaultMutableTreeNode) startNode));
- }
-
- /**
- * Paints a leaf in the tree
- *
- * @param g the Graphics context in which to paint
- * @param x the x location of the leaf
- * @param y the y location of the leaf
- * @param tree the tree to draw on
- * @param leaf the object to draw
- */
- private void paintLeaf(Graphics g, int x, int y, JTree tree, Object leaf)
- {
- TreePath curr = new TreePath(((DefaultMutableTreeNode) leaf).getPath());
- boolean selected = tree.isPathSelected(curr);
-
- if (tree.isVisible(curr))
- {
- DefaultTreeCellRenderer dtcr = (DefaultTreeCellRenderer)
- tree.getCellRenderer();
- boolean hasIcons = false;
- Icon li = dtcr.getLeafIcon();
- if (li != null)
- hasIcons = true;
-
- if (selected)
- {
- Component c = dtcr.getTreeCellRendererComponent(tree, leaf,
- true, false, true, 0, false);
-
- if (hasIcons)
- {
- li.paintIcon(c, g, x, y + 2);
- x += li.getIconWidth() + 4;
- }
- rendererPane.paintComponent(g, c, tree,
- getCellBounds(x, y, leaf));
- }
- else
- {
- Component c = dtcr.getTreeCellRendererComponent(
- tree, leaf, false, false, true, 0, false);
-
- g.translate(x, y);
-
- if (hasIcons)
- {
- Component icon = dtcr.getTreeCellRendererComponent(tree,
- li, false, false, true, 0, false);
- icon.paint(g);
- }
-
- c.paint(g);
- g.translate(-x, -y);
- }
- }
- }
-
- /**
- * Paints a non-leaf in the tree
- *
- * @param g the Graphics context in which to paint
- * @param x the x location of the non-leaf
- * @param y the y location of the non-leaf
- * @param tree the tree to draw on
- * @param nonLeaf the object to draw
- */
- private void paintNonLeaf(Graphics g, int x, int y, JTree tree,
- Object nonLeaf)
- {
- TreePath curr = new TreePath(((DefaultMutableTreeNode) nonLeaf).getPath());
- boolean selected = tree.isPathSelected(curr);
- boolean expanded = tree.isExpanded(curr);
-
- if (tree.isVisible(curr))
- {
- DefaultTreeCellRenderer dtcr = (DefaultTreeCellRenderer)
- tree.getCellRenderer();
- boolean hasIcons = false;
- boolean hasOtherIcons = false;
- Icon oi = dtcr.getOpenIcon();
- Icon ci = dtcr.getClosedIcon();
-
- if (oi != null || ci != null)
- hasIcons = true;
-
- if (selected)
- {
- Component c = dtcr.getTreeCellRendererComponent(tree, nonLeaf,
- true, expanded, false, 0, false);
-
- if (hasIcons)
- {
- if (expanded)
- {
- oi.paintIcon(c, g, x, y + 2);
- x += (oi.getIconWidth() + 4);
- }
- else
- {
- ci.paintIcon(c, g, x, y + 2);
- x += (ci.getIconWidth() + 4);
- }
-
- }
- rendererPane.paintComponent(g, c, tree,
- getCellBounds(x, y, nonLeaf));
- }
- else
- {
- Component c = dtcr.getTreeCellRendererComponent(tree, nonLeaf,
- false, expanded, false, 0, false);
- g.translate(x, y);
-
- if (hasIcons)
- {
- Component icon;
- if (expanded)
- icon = dtcr.getTreeCellRendererComponent(tree,
- oi, false, false, false, 0, false);
- else
- icon = dtcr.getTreeCellRendererComponent(tree,
- ci, false, false, false, 0, false);
-
- icon.paint(g);
- }
- c.paint(g);
- g.translate(-x, -y);
- }
- }
- }
-
- /**
- * Recursively paints all elements of the tree
- *
- * @param g the Graphics context in which to paint
- * @param indentation of the current object
- * @param descent is the number of elements drawn
- * @param childNumber is the index of the current child in the tree
- * @param depth is the depth of the current object in the tree
- * @param tree is the tree to draw to
- * @param mod is the TreeModel we are using to draw
- * @param curr is the current object to draw
- *
- * @return int - current descent of the tree
- */
- private int paintRecursive(Graphics g, int indentation, int descent,
- int childNumber, int depth, JTree tree, TreeModel mod, Object curr)
- {
- Rectangle clip = g.getClipBounds();
- if (indentation > clip.x + clip.width + rightChildIndent
- || descent > clip.y + clip.height + getRowHeight())
- return descent;
-
- int halfHeight = getRowHeight() / 2;
- int halfWidth = rightChildIndent / 2;
- int y0 = descent + halfHeight;
- int heightOfLine = descent + halfHeight;
-
- if (mod.isLeaf(curr))
- {
- paintLeaf(g, indentation + 4, descent, tree, curr);
- descent += getRowHeight();
- }
- else
- {
- if (depth > 0 || tree.isRootVisible())
- {
- paintNonLeaf(g, indentation + 4, descent, tree, curr);
- descent += getRowHeight();
- y0 += halfHeight;
- }
-
- int max = mod.getChildCount(curr);
- if (tree.isExpanded(new TreePath(((DefaultMutableTreeNode) curr)
- .getPath())))
- {
- for (int i = 0; i < max; ++i)
- {
- g.setColor(getHashColor());
- heightOfLine = descent + halfHeight;
- g.drawLine(indentation + halfWidth, heightOfLine,
- indentation + rightChildIndent, heightOfLine);
-
- descent = paintRecursive(g, indentation + rightChildIndent,
- descent, i, depth + 1, tree, mod, mod.getChild(curr, i));
- }
- }
- }
- if (tree.isExpanded(new TreePath(((DefaultMutableTreeNode) curr)
- .getPath())))
- if (y0 != heightOfLine)
- {
- g.setColor(getHashColor());
- g.drawLine(indentation + halfWidth, y0, indentation + halfWidth,
- heightOfLine);
- }
-
- return descent;
- }
-
- /**
- * Recursively paints all the control icons on the tree.
- *
- * @param g the Graphics context in which to paint
- * @param indentation of the current object
- * @param descent is the number of elements drawn
- * @param childNumber is the index of the current child in the tree
- * @param depth is the depth of the current object in the tree
- * @param tree is the tree to draw to
- * @param mod is the TreeModel we are using to draw
- * @param curr is the current object to draw
- *
- * @return int - current descent of the tree
- */
- private int paintControlIcons(Graphics g, int indentation, int descent,
- int childNumber, int depth, JTree tree, TreeModel mod, Object node)
- {
- int h = descent;
- int rowHeight = getRowHeight();
- Icon ei = UIManager.getLookAndFeelDefaults().
- getIcon("Tree.expandedIcon");
- Icon ci = UIManager.getLookAndFeelDefaults().
- getIcon("Tree.collapsedIcon");
- Rectangle clip = g.getClipBounds();
- if (ci == null || ei == null || indentation > clip.x + clip.width +
- rightChildIndent || descent > clip.y + clip.height +
- getRowHeight())
- return descent;
-
- if (mod.isLeaf(node))
- descent += rowHeight;
- else
- {
- if (depth > 0 || tree.isRootVisible())
- descent += rowHeight;
-
- int max = mod.getChildCount(node);
- if (tree.isExpanded(new TreePath(((DefaultMutableTreeNode) node)
- .getPath())))
- {
- if (!node.equals(mod.getRoot()))
- ei.paintIcon(tree, g, indentation - rightChildIndent - 3, h);
-
- for (int i = 0; i < max; ++i)
- {
- descent = paintControlIcons(g, indentation + rightChildIndent,
- descent, i, depth + 1, tree, mod, mod.getChild(node, i));
- }
- }
- else if (!node.equals(mod.getRoot()))
- ci.paintIcon(tree, g, indentation - rightChildIndent - 3,
- descent - getRowHeight());
- }
-
- return descent;
- }
-} // BasicTreeUI
\ No newline at end of file
+ return mod.getChild(parent, index);
+ }
+
+ /**
+ * Selects the specified path in the tree depending on modes. Package private
+ * for use in inner classes.
+ *
+ * @param tree
+ * is the tree we are selecting the path in
+ * @param path
+ * is the path we are selecting
+ */
+ void selectPath(JTree tree, TreePath path)
+ {
+ if (path != null)
+ {
+ if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
+ {
+ tree.addSelectionPath(path);
+ tree.setLeadSelectionPath(path);
+ }
+ else if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
+ {
+ // TODO
+ }
+ else
+ {
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+ tree.getSelectionModel().clearSelection();
+ tree.addSelectionPath(path);
+ tree.setLeadSelectionPath(path);
+ }
+ }
+ }
+
+ /**
+ * Returns the path from node to the root. Package private for use in inner
+ * classes.
+ *
+ * @param node
+ * the node to get the path to
+ * @param depth
+ * the depth of the tree to return a path for
+ * @return an array of tree nodes that represent the path to node.
+ */
+ Object[] getPathToRoot(Object node, int depth)
+ {
+ TreeModel mod = tree.getModel();
+ if (node == null)
+ {
+ if (depth == 0)
+ return null;
+
+ return new Object[depth];
+ }
+
+ Object[] path = getPathToRoot(getParent(mod.getRoot(), node), depth + 1);
+ path[path.length - depth - 1] = node;
+ return path;
+ }
+
+ /**
+ * Returns the level of the node in the tree.
+ *
+ * @param the
+ * current node
+ * @return the number of the level
+ */
+ int getLevel(Object node)
+ {
+ int count = -1;
+ Object current = node;
+
+ do
+ {
+ current = getParent(tree.getModel().getRoot(), current);
+ count++;
+ }
+ while (current != null);
+
+ return count;
+ }
+
+ /**
+ * Draws a vertical line using the given graphic context
+ *
+ * @param g
+ * is the graphic context
+ * @param c
+ * is the component the new line will belong to
+ * @param x
+ * is the horizonal position
+ * @param top
+ * specifies the top of the line
+ * @param bottom
+ * specifies the bottom of the line
+ */
+ protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
+ int bottom)
+ {
+ g.drawLine(x, top, x, bottom);
+ }
+
+ /**
+ * Draws a horizontal line using the given graphic context
+ *
+ * @param g
+ * is the graphic context
+ * @param c
+ * is the component the new line will belong to
+ * @param y
+ * is the vertical position
+ * @param left
+ * specifies the left point of the line
+ * @param right
+ * specifies the right point of the line
+ */
+ protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left,
+ int right)
+ {
+ g.drawLine(left, y, right, y);
+ }
+
+ /**
+ * Draws an icon at around a specific position
+ *
+ * @param c
+ * is the component the new line will belong to
+ * @param g
+ * is the graphic context
+ * @param icon
+ * is the icon which will be drawn
+ * @param x
+ * is the center position in x-direction
+ * @param y
+ * is the center position in y-direction FIXME what to do if x <
+ * (icon.width / 2). Same with y
+ */
+ protected void drawCentered(JComponent c, Graphics g, Icon icon, int x, int y)
+ {
+ int beginPositionX = x - icon.getIconWidth() / 2;
+ int beginPositionY = y - icon.getIconHeight() / 2;
+ icon.paintIcon(c, g, beginPositionX, beginPositionY);
+ }
+} // BasicTreeUI
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicViewportUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicViewportUI.java
index 8ce772b..0d46133 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicViewportUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicViewportUI.java
@@ -160,18 +160,18 @@ public class BasicViewportUI extends ViewportUI
Rectangle viewBounds,
Rectangle portBounds)
{
- Rectangle oldClip = g.getClipBounds ();
- g.setClip (oldClip.intersection (viewBounds));
+ Rectangle oldClip = g.getClipBounds();
+ g.setClip(new Rectangle(0, 0, portBounds.width, portBounds.height));
g.translate (-pos.x, -pos.y);
try
- {
+ {
view.paint(g);
}
finally
{
g.translate (pos.x, pos.y);
g.setClip (oldClip);
- }
+ }
}
private void paintBackingStore(Graphics g,
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java b/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java
index f260ef6..f555106 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java
@@ -45,14 +45,18 @@ import java.awt.Insets;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
-import javax.swing.JButton;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JTextField;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.UIResource;
-import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicBorders;
+
/**
* This factory class creates borders for the different Swing components
* UI.
@@ -68,6 +72,9 @@ public class MetalBorders
/** The shared instance for getRolloverButtonBorder(). */
private static Border toolbarButtonBorder;
+ /** The shared instance for getTextFieldBorder(). */
+ private static Border textFieldBorder;
+
/**
* A MarginBorder that gets shared by multiple components.
* Created on demand by the private helper function {@link
@@ -184,6 +191,373 @@ public class MetalBorders
}
/**
+ * A simple 3D border.
+ */
+ public static class Flush3DBorder extends AbstractBorder
+ implements UIResource
+ {
+ /**
+ * Creates a new border instance.
+ */
+ public Flush3DBorder()
+ {
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return getBorderInsets(c, null);
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c, Insets newInsets)
+ {
+ if (newInsets == null)
+ newInsets = new Insets(2, 2, 2, 2);
+ else
+ {
+ newInsets.top = 2;
+ newInsets.left = 2;
+ newInsets.bottom = 2;
+ newInsets.right = 2;
+ }
+ return newInsets;
+ }
+
+ /**
+ * Paints the border for the specified component.
+ *
+ * @param c the component (ignored).
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+ Color savedColor = g.getColor();
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawRect(x, y, w - 2, h - 2);
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawRect(x + 1, y + 1, w - 2, h - 2);
+ g.setColor(MetalLookAndFeel.getControl());
+ g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
+ g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
+ g.setColor(savedColor);
+ }
+
+ }
+
+ /**
+ * A border used for the {@link JTextField} component.
+ */
+ public static class TextFieldBorder extends Flush3DBorder
+ implements UIResource
+ {
+ /**
+ * Creates a new border instance.
+ */
+ public TextFieldBorder()
+ {
+ }
+
+ /**
+ * Paints the border for the specified component.
+ *
+ * @param c the component (ignored).
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+ if (c.isEnabled())
+ super.paintBorder(c, g, x, y, w, h);
+ else
+ {
+ Color savedColor = g.getColor();
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawRect(x, y, w - 1, h - 1);
+ g.setColor(savedColor);
+ }
+ }
+
+ }
+
+ /**
+ * A border used when painting {@link JInternalFrame} instances.
+ */
+ public static class InternalFrameBorder extends AbstractBorder
+ implements UIResource
+ {
+ /**
+ * Creates a new border instance.
+ */
+ public InternalFrameBorder()
+ {
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return getBorderInsets(c, null);
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c, Insets newInsets)
+ {
+ if (newInsets == null)
+ newInsets = new Insets(5, 5, 5, 5);
+ else
+ {
+ newInsets.top = 5;
+ newInsets.left = 5;
+ newInsets.bottom = 5;
+ newInsets.right = 5;
+ }
+ return newInsets;
+ }
+
+ /**
+ * Paints the border for the specified component.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param w the width.
+ * @param h the height.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+
+ JInternalFrame f = (JInternalFrame) c;
+ if (f.isSelected())
+ g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
+ else
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+
+ // fill the border background
+ g.fillRect(x, y, w, 5);
+ g.fillRect(x, y, 5, h);
+ g.fillRect(x + w - 5, y, 5, h);
+ g.fillRect(x, y + h - 5, w, 5);
+
+ // draw a dot in each corner
+ g.setColor(MetalLookAndFeel.getControl());
+ g.fillRect(x, y, 1, 1);
+ g.fillRect(x + w - 1, y, 1, 1);
+ g.fillRect(x + w - 1, y + h - 1, 1, 1);
+ g.fillRect(x, y + h - 1, 1, 1);
+
+ // draw the lines
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 14, y + 2, x + w - 15, y + 2);
+ g.drawLine(x + 14, y + h - 3, x + w - 15, y + h - 3);
+ g.drawLine(x + 2, y + 14, x + 2, y + h - 15);
+ g.drawLine(x + w - 3, y + 14, x + w - 3, y + h - 15);
+
+ // draw the line highlights
+ g.setColor(MetalLookAndFeel.getControl());
+ g.drawLine(x + 15, y + 3, x + w - 14, y + 3);
+ g.drawLine(x + 15, y + h - 2, x + w - 14, y + h - 2);
+ g.drawLine(x + 3, y + 15, x + 3, y + h - 14);
+ g.drawLine(x + w - 2, y + 15, x + w - 2, y + h - 14);
+ }
+
+ }
+
+ /**
+ * A border used for {@link JMenu} and {@link JMenuItem} components.
+ */
+ public static class MenuItemBorder
+ extends AbstractBorder
+ implements UIResource
+ {
+ /** The border insets. */
+ protected static Insets borderInsets = new Insets(2, 2, 2, 2);
+
+ // TODO: find where the real colors come from
+ private static Color borderColorDark = new Color(102, 102, 153);
+ private static Color borderColorLight = new Color(255, 255, 255);
+
+ /**
+ * Creates a new border instance.
+ */
+ public MenuItemBorder()
+ {
+ }
+
+ /**
+ * Paints the border for the component. A border is painted only if the
+ * component is a selected {@link JMenu} or an armed {@link JMenuItem}.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate of the border area.
+ * @param y the y-coordinate of the border area.
+ * @param w the width of the border area.
+ * @param h the height of the border area.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+ if (c instanceof JMenu) {
+ JMenu menu = (JMenu) c;
+ if (menu.isSelected())
+ {
+ g.setColor(borderColorDark);
+ g.drawLine(x, y, x, y + h);
+ g.drawLine(x, y, x + w, y);
+ g.drawLine(x + w - 2, y + 1, x + w - 2, y + h);
+ g.setColor(borderColorLight);
+ g.drawLine(x + w - 1, y + 1, x + w - 1, y + h);
+ }
+ }
+ else if (c instanceof JMenuItem)
+ {
+ JMenuItem item = (JMenuItem) c;
+ if (item.isArmed())
+ {
+ g.setColor(borderColorDark);
+ g.drawLine(x, y, x + w, y);
+ g.setColor(borderColorLight);
+ g.drawLine(x, y + h - 1, x + w, y + h - 1);
+ }
+ }
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return borderInsets;
+ }
+
+ /**
+ * Populates insets
with the border insets, then returns it.
+ *
+ * @param c the component (ignored).
+ * @param insets the object to populate with the border insets.
+ *
+ * @return The border insets.
+ *
+ * @throws NullPointerException if insets
is null
.
+ */
+ public Insets getBorderInsets(Component c, Insets insets)
+ {
+ insets.left = borderInsets.left;
+ insets.top = borderInsets.top;
+ insets.bottom = borderInsets.bottom;
+ insets.right = borderInsets.right;
+ return insets;
+ }
+ }
+
+ /**
+ * A border used for {@link JMenuBar} components.
+ */
+ public static class MenuBarBorder
+ extends AbstractBorder
+ implements UIResource
+ {
+ /** The border insets. */
+ protected static Insets borderInsets = new Insets(1, 0, 1, 0);
+
+ // TODO: find where this color really comes from
+ private static Color borderColor = new Color(153, 153, 153);
+
+ /**
+ * Creates a new border instance.
+ */
+ public MenuBarBorder()
+ {
+ }
+
+ /**
+ * Paints the border for the component. A border is painted only if the
+ * component is a selected {@link JMenu} or an armed {@link JMenuItem}.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate of the border area.
+ * @param y the y-coordinate of the border area.
+ * @param w the width of the border area.
+ * @param h the height of the border area.
+ */
+ public void paintBorder(Component c, Graphics g, int x, int y, int w,
+ int h)
+ {
+ g.setColor(borderColor);
+ g.drawLine(x, y + h - 1, x + w, y + h - 1);
+ }
+
+ /**
+ * Returns the border insets.
+ *
+ * @param c the component (ignored).
+ *
+ * @return The border insets.
+ */
+ public Insets getBorderInsets(Component c)
+ {
+ return borderInsets;
+ }
+
+ /**
+ * Populates insets
with the border insets, then returns it.
+ *
+ * @param c the component (ignored).
+ * @param insets the object to populate with the border insets.
+ *
+ * @return The border insets.
+ *
+ * @throws NullPointerException if insets
is null
.
+ */
+ public Insets getBorderInsets(Component c, Insets insets)
+ {
+ insets.left = borderInsets.left;
+ insets.top = borderInsets.top;
+ insets.bottom = borderInsets.bottom;
+ insets.right = borderInsets.right;
+ return insets;
+ }
+ }
+
+ /**
* A border for JScrollPanes.
*/
public static class ScrollPaneBorder
@@ -413,6 +787,20 @@ public class MetalBorders
}
/**
+ * Returns a border for use by the {@link JTextField} component.
+ *
+ * @return A border.
+ *
+ * @since 1.3
+ */
+ public static Border getTextFieldBorder()
+ {
+ if (textFieldBorder == null)
+ textFieldBorder = new TextFieldBorder();
+ return textFieldBorder;
+ }
+
+ /**
* Returns a border for Toolbar buttons in the Metal Look & Feel.
*
* @return a border for Toolbar buttons in the Metal Look & Feel
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java
index a7b53c4..0dac5ec 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.JToolBar;
@@ -56,18 +58,60 @@ public class MetalButtonUI
extends BasicButtonUI
{
- // FIXME: probably substitute with a Map in the future in the case
- // that this UI becomes stateful
-
/** The cached MetalButtonUI instance. */
private static MetalButtonUI instance = null;
+ /** The color for the focus border. */
+ protected Color focusColor;
+
+ /** The color that indicates a selected button. */
+ protected Color selectColor;
+
+ /** The color for disabled button labels. */
+ protected Color disabledTextColor;
+
/**
* Creates a new instance of MetalButtonUI.
*/
public MetalButtonUI()
{
super();
+ focusColor = getFocusColor();
+ selectColor = getSelectColor();
+ disabledTextColor = getDisabledTextColor();
+ }
+
+ /**
+ * Returns the color for the focus border.
+ *
+ * @return the color for the focus border
+ */
+ protected Color getFocusColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".focus");
+ }
+
+ /**
+ * Returns the color that indicates a selected button.
+ *
+ * @return the color that indicates a selected button
+ */
+ protected Color getSelectColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".select");
+ }
+
+ /**
+ * Returns the color for the text label of disabled buttons.
+ *
+ * @return the color for the text label of disabled buttons
+ */
+ protected Color getDisabledTextColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".disabledText");
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxIcon.java b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxIcon.java
index eba21a4..3f3c9ce 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxIcon.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxIcon.java
@@ -80,10 +80,10 @@ public class MetalCheckBoxIcon
protected void drawCheck(Component c, Graphics g, int x, int y)
{
g.setColor(Color.BLACK);
- g.drawLine(3, 5, 3, 9);
- g.drawLine(4, 5, 4, 9);
- g.drawLine(5, 7, 9, 3);
- g.drawLine(5, 8, 9, 4);
+ g.drawLine(3 + x, 5 + y, 3 + x, 9 + y);
+ g.drawLine(4 + x, 5 + y, 4 + x, 9 + y);
+ g.drawLine(5 + x, 7 + y, 9 + x, 3 + y);
+ g.drawLine(5 + x, 8 + y, 9 + x, 4 + y);
}
/**
@@ -124,7 +124,7 @@ public class MetalCheckBoxIcon
* @param c the Component to draw on (gets casted to JCheckBox)
* @param g the Graphics context to draw with
* @param x the X position
- * @param x the Y position
+ * @param y the Y position
*/
public void paintIcon(Component c, Graphics g, int x, int y)
{
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java
index d59e38c..c46cb5f 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java
@@ -38,12 +38,17 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import javax.swing.JCheckBox;
import javax.swing.JComponent;
+import javax.swing.UIDefaults;
import javax.swing.plaf.ComponentUI;
-import javax.swing.plaf.basic.BasicCheckBoxUI;
+/**
+ * A UI delegate for the {@link JCheckBox} component under the
+ * {@link MetalLookAndFeel}.
+ */
public class MetalCheckBoxUI
- extends BasicCheckBoxUI
+ extends MetalRadioButtonUI
{
// FIXME: maybe replace by a Map of instances when this becomes stateful
@@ -71,4 +76,15 @@ public class MetalCheckBoxUI
instance = new MetalCheckBoxUI();
return instance;
}
+
+ /**
+ * Returns the prefix for properties defined in the {@link UIDefaults} table.
+ *
+ * @return The property prefix ("CheckBox."
).
+ */
+ public String getPropertyPrefix()
+ {
+ return "CheckBox.";
+ }
}
+
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
index e770f47..d8c7743 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java
@@ -44,7 +44,14 @@ import java.awt.Graphics;
import java.io.Serializable;
import javax.swing.Icon;
+import javax.swing.JCheckBox;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JInternalFrame;
+import javax.swing.JRadioButton;
+import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSlider;
+import javax.swing.plaf.UIResource;
+
/**
* Creates icons for the {@link MetalLookAndFeel}.
@@ -59,6 +66,77 @@ public class MetalIconFactory implements Serializable
public static final boolean LIGHT = true;
/**
+ * An icon displayed for {@link JCheckBoxMenuItem} components.
+ */
+ private static class CheckBoxMenuItemIcon implements Icon, Serializable
+ {
+ /**
+ * Creates a new icon instance.
+ */
+ public CheckBoxMenuItemIcon()
+ {
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon (10 pixels).
+ */
+ public int getIconWidth()
+ {
+ return 10;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon (10 pixels).
+ */
+ public int getIconHeight()
+ {
+ return 10;
+ }
+
+ /**
+ * Paints the icon.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) c;
+
+ if (item.isArmed())
+ g.setColor(MetalLookAndFeel.getBlack());
+ else
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawLine(x, y, x + 8, y);
+ g.drawLine(x, y + 1, x, y + 8);
+ g.drawLine(x + 2, y + 8, x + 8, y + 8);
+ g.drawLine(x + 8, y + 2, x + 8, y + 7);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.drawLine(x + 1, y + 1, x + 7, y + 1);
+ g.drawLine(x + 1, y + 2, x + 1, y + 7);
+ g.drawLine(x + 1, y + 9, x + 9, y + 9);
+ g.drawLine(x + 9, y + 1, x + 9, y + 8);
+
+ // if the item is selected, we should draw a tick
+ if (item.isSelected())
+ {
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.fillRect(x + 2, y + 2, 2, 5);
+ for (int i = 0; i < 6; i++)
+ g.drawLine(x + 8 - i, y + i, x + 9 - i, y + i);
+ }
+
+ }
+ }
+
+ /**
* An icon representing a file (drawn as a piece of paper with the top-right
* corner turned down).
*/
@@ -208,7 +286,180 @@ public class MetalIconFactory implements Serializable
}
+ /**
+ * An {@link Icon} implementation for {@link JCheckBox}es in the
+ * Metal Look & Feel.
+ *
+ * @author Roman Kennke (roman@kennke.org)
+ */
+ static class RadioButtonIcon
+ implements Icon, UIResource, Serializable
+ {
/**
+ * Draws the check in the RadioButton.
+ *
+ * @param c the component to draw on
+ * @param g the Graphics context to draw with
+ */
+ protected void drawCheck(Component c, Graphics g)
+ {
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.fillRect(4, 3, 4, 6);
+ g.drawLine(3, 4, 3, 7);
+ g.drawLine(8, 4, 8, 7);
+ }
+
+ /**
+ * Returns the width of the icon in pixels.
+ *
+ * @return the width of the icon in pixels
+ */
+ public int getIconWidth()
+ {
+ return 13;
+ }
+
+ /**
+ * Returns the height of the icon in pixels.
+ *
+ * @return the height of the icon in pixels
+ */
+ public int getIconHeight()
+ {
+ return 13;
+ }
+
+ /**
+ * Paints the icon. This first paints the border of the RadioButton and
+ * if the CheckBox is selected it calls {@link #drawCheck} to draw
+ * the check.
+ *
+ * @param c the Component to draw on (gets casted to JCheckBox)
+ * @param g the Graphics context to draw with
+ * @param x the X position
+ * @param y the Y position
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color dark = MetalLookAndFeel.getControlDarkShadow();
+ Color light = MetalLookAndFeel.getWhite();
+ g.translate(x, y);
+
+ // The light 'circle'
+ g.setColor(light);
+ g.drawLine(4, 1, 10, 1);
+ g.drawLine(2, 2, 3, 2);
+ g.drawLine(8, 2, 11, 2);
+ g.drawLine(2, 3, 2, 3);
+ g.drawLine(11, 2, 11, 9);
+ g.drawLine(1, 4, 1, 7);
+ g.drawLine(12, 4, 12, 7);
+ g.drawLine(2, 8, 2, 11);
+ g.drawLine(11, 8, 11, 9);
+ g.drawLine(10, 10, 10, 10);
+ g.drawLine(2, 11, 9, 11);
+ g.drawLine(4, 12, 7, 12);
+
+ // The dark 'circle'
+ g.setColor(dark);
+ g.drawLine(4, 0, 7, 0);
+ g.drawLine(2, 1, 3, 1);
+ g.drawLine(8, 1, 9, 1);
+ g.drawLine(1, 2, 1, 3);
+ g.drawLine(10, 2, 10, 3);
+ g.drawLine(0, 4, 0, 7);
+ g.drawLine(11, 4, 11, 7);
+ g.drawLine(1, 8, 1, 9);
+ g.drawLine(10, 8, 10, 9);
+ g.drawLine(2, 10, 3, 10);
+ g.drawLine(8, 10, 9, 10);
+ g.drawLine(4, 11, 7, 11);
+
+ JRadioButton rb = (JRadioButton) c;
+ if (rb.isSelected())
+ drawCheck(c, g);
+
+ g.translate(-x, -y);
+ }
+ }
+
+ /**
+ * An icon displayed for {@link JRadioButtonMenuItem} components.
+ */
+ private static class RadioButtonMenuItemIcon
+ implements Icon, Serializable
+ {
+ /**
+ * Creates a new icon instance.
+ */
+ public RadioButtonMenuItemIcon()
+ {
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 10;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 10;
+ }
+
+ /**
+ * Paints the icon.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color savedColor = g.getColor();
+ JRadioButtonMenuItem item = (JRadioButtonMenuItem) c;
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 2, y, x + 6, y);
+ g.drawLine(x + 7, y + 1, x + 7, y + 1);
+ g.drawLine(x + 8, y + 2, x + 8, y + 6);
+ g.drawLine(x + 7, y + 7, x + 7, y + 7);
+ g.drawLine(x + 2, y + 8, x + 6, y + 8);
+ g.drawLine(x + 1, y + 7, x + 1, y + 7);
+ g.drawLine(x, y + 2, x, y + 6);
+ g.drawLine(x + 1, y + 1, x + 1, y + 1);
+
+ if (item.isSelected())
+ {
+ g.drawLine(x + 3, y + 2, x + 5, y + 2);
+ g.fillRect(x + 2, y + 3, 5, 3);
+ g.drawLine(x + 3, y + 6, x + 5, y + 6);
+ }
+
+ // highlight
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawLine(x + 3, y + 1, x + 6, y + 1);
+ g.drawLine(x + 8, y + 1, x + 8, y + 1);
+ g.drawLine(x + 9, y + 2, x + 9, y + 7);
+ g.drawLine(x + 8, y + 8, x + 8, y + 8);
+ g.drawLine(x + 2, y + 9, x + 7, y + 9);
+ g.drawLine(x + 1, y + 8, x + 1, y + 8);
+ g.drawLine(x + 1, y + 3, x + 1, y + 6);
+ g.drawLine(x + 2, y + 2, x + 2, y + 2);
+ g.setColor(savedColor);
+ }
+ }
+
+ /**
* The icon used to display the thumb control on a horizontally oriented
* {@link JSlider} component.
*/
@@ -309,6 +560,447 @@ public class MetalIconFactory implements Serializable
}
/**
+ * An icon used for the 'close' button in the title frame of a
+ * {@link JInternalFrame}.
+ */
+ private static class InternalFrameCloseIcon implements Icon, Serializable
+ {
+ /** The icon size in pixels. */
+ private int size;
+
+ /**
+ * Creates a new icon.
+ *
+ * @param size the icon size (width and height) in pixels.
+ */
+ public InternalFrameCloseIcon(int size)
+ {
+ this.size = size;
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return size;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return size;
+ }
+
+ /**
+ * Paints the icon.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ // draw the gray areas first
+ g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
+ g.drawLine(x + 1, y + 1, x + 13, y + 1);
+ g.drawLine(x + 1, y + 2, x + 1, y + 12);
+ g.drawLine(x + 1, y + 13, x + 13, y + 13);
+ g.drawLine(x + 13, y + 2, x + 13, y + 12);
+
+ g.fillRect(x + 4, y + 4, 2, 2);
+ g.fillRect(x + 4, y + 9, 2, 2);
+ g.fillRect(x + 9, y + 4, 2, 2);
+ g.fillRect(x + 9, y + 9, 2, 2);
+ g.fillRect(x + 5, y + 5, 5, 5);
+
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x, y, x + 13, y);
+ g.drawLine(x, y + 1, x, y + 13);
+ g.drawLine(x + 3, y + 4, x + 4, y + 3);
+ g.drawLine(x + 3, y + 9, x + 5, y + 7);
+ g.drawLine(x + 7, y + 5, x + 9, y + 3);
+
+ g.drawLine(x + 12, y + 3, x + 12, y + 11);
+ g.drawLine(x + 3, y + 12, x + 12, y + 12);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.drawLine(x + 1, y + 14, x + 14, y + 14);
+ g.drawLine(x + 14, y + 1, x + 14, y + 14);
+
+ g.drawLine(x + 5, y + 10, x + 5, y + 10);
+ g.drawLine(x + 6, y + 9, x + 7, y + 9);
+ g.drawLine(x + 10, y + 5, x + 10, y + 5);
+ g.drawLine(x + 9, y + 6, x + 9, y + 7);
+ g.drawLine(x + 10, y + 10, x + 11, y + 10);
+ g.drawLine(x + 10, y + 11, x + 10, y + 11);
+ }
+ }
+
+ /**
+ * The icon displayed at the top-left corner of a {@link JInternalFrame}.
+ */
+ private static class InternalFrameDefaultMenuIcon
+ implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new instance.
+ */
+ public InternalFrameDefaultMenuIcon()
+ {
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x coordinate.
+ * @param y the y coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ g.setColor(new Color(102, 102, 153));
+ g.fillRect(x + 1, y, 14, 2);
+ g.fillRect(x, y + 1, 2, 14);
+ g.fillRect(x + 1, y + 14, 14, 2);
+ g.fillRect(x + 14, y + 1, 2, 14);
+ g.drawLine(x + 2, y + 5, x + 14, y + 5);
+
+ g.setColor(new Color(204, 204, 255));
+ g.fillRect(x + 2, y + 2, 12, 3);
+
+ g.setColor(new Color(102, 102, 153));
+ g.drawLine(x + 3, y + 3, x + 3, y + 3);
+ g.drawLine(x + 6, y + 3, x + 6, y + 3);
+ g.drawLine(x + 9, y + 3, x + 9, y + 3);
+ g.drawLine(x + 12, y + 3, x + 12, y + 3);
+
+ g.setColor(Color.white);
+ g.fillRect(x + 2, y + 6, 12, 8);
+ g.drawLine(x + 2, y + 2, x + 2, y + 2);
+ g.drawLine(x + 5, y + 2, x + 5, y + 2);
+ g.drawLine(x + 8, y + 2, x + 8, y + 2);
+ g.drawLine(x + 11, y + 2, x + 11, y + 2);
+ }
+ }
+
+ /**
+ * An icon used in the title frame of a {@link JInternalFrame}. When you
+ * maximise an internal frame, this icon will replace the 'maximise' icon to
+ * provide a 'restore' option.
+ */
+ private static class InternalFrameAltMaximizeIcon
+ implements Icon, Serializable
+ {
+ /** The icon size in pixels. */
+ private int size;
+
+ /**
+ * Creates a new icon.
+ *
+ * @param size the icon size in pixels.
+ */
+ public InternalFrameAltMaximizeIcon(int size)
+ {
+ this.size = size;
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return size;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return size;
+ }
+
+ /**
+ * Paints the icon at the specified location.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x coordinate.
+ * @param y the y coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color color = MetalLookAndFeel.getControlDarkShadow();
+ if (c instanceof JInternalFrame)
+ {
+ JInternalFrame f = (JInternalFrame) c;
+ if (f.isSelected())
+ color = MetalLookAndFeel.getPrimaryControlShadow();
+ }
+ g.setColor(color);
+ g.drawLine(x + 12, y + 1, x + 13, y + 1);
+ g.drawLine(x + 11, y + 2, x + 12, y + 2);
+ g.drawLine(x + 10, y + 3, x + 11, y + 3);
+ g.drawLine(x + 8, y + 2, x + 8, y + 3);
+ g.fillRect(x + 8, y + 4, 3, 3);
+ g.drawLine(x + 11, y + 6, x + 12, y + 6);
+
+ g.drawLine(x + 1, y + 5, x + 5, y + 5);
+ g.drawLine(x + 1, y + 6, x + 1, y + 12);
+ g.drawLine(x + 9, y + 9, x + 9, y + 12);
+ g.drawLine(x + 1, y + 13, x + 9, y + 13);
+
+ g.drawLine(x + 2, y + 12, x + 2, y + 12);
+
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 12, y, x + 9, y + 3);
+ g.drawLine(x + 7, y + 1, x + 8, y + 1);
+ g.drawLine(x + 7, y + 2, x + 7, y + 6);
+ g.drawLine(x + 11, y + 5, x + 12, y + 5);
+ g.drawLine(x, y + 4, x + 5, y + 4);
+ g.drawLine(x, y + 5, x, y + 13);
+ g.drawLine(x + 3, y + 12, x + 8, y + 12);
+ g.drawLine(x + 8, y + 8, x + 8, y + 11);
+ g.drawLine(x + 9, y + 8, x + 9, y + 8);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.drawLine(x + 9, y + 2, x + 9, y + 2);
+ g.drawLine(x + 11, y + 4, x + 13, y + 2);
+ g.drawLine(x + 13, y + 6, x + 13, y + 6);
+ g.drawLine(x + 8, y + 7, x + 13, y + 7);
+ g.drawLine(x + 6, y + 5, x + 6, y + 5);
+ g.drawLine(x + 2, y + 6, x + 6, y + 6);
+ g.drawLine(x + 2, y + 6, x + 2, y + 11);
+ g.drawLine(x + 10, y + 8, x + 10, y + 13);
+ g.drawLine(x + 1, y + 14, x + 10, y + 14);
+ }
+ }
+
+ /**
+ * An icon used for the 'maximize' button in the title frame of a
+ * {@link JInternalFrame}.
+ */
+ private static class InternalFrameMaximizeIcon
+ implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new instance.
+ */
+ public InternalFrameMaximizeIcon()
+ {
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x coordinate.
+ * @param y the y coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color color = MetalLookAndFeel.getControlDarkShadow();
+ if (c instanceof JInternalFrame)
+ {
+ JInternalFrame f = (JInternalFrame) c;
+ if (f.isSelected())
+ color = MetalLookAndFeel.getPrimaryControlShadow();
+ }
+ g.setColor(color);
+ g.drawLine(x + 9, y + 1, x + 10, y + 1);
+ g.fillRect(x + 11, y + 1, 3, 3);
+ g.fillRect(x + 12, y + 4, 2, 2);
+ g.drawLine(x + 10, y + 3, x + 10, y + 3);
+ g.drawLine(x + 9, y + 4, x + 10, y + 4);
+ g.drawLine(x + 1, y + 5, x + 9, y + 5);
+ g.drawLine(x + 1, y + 6, x + 1, y + 12);
+ g.drawLine(x + 9, y + 6, x + 9, y + 12);
+ g.drawLine(x + 1, y + 13, x + 9, y + 13);
+
+ // fill
+ g.drawLine(x + 7, y + 6, x + 8, y + 6);
+ g.drawLine(x + 6, y + 7, x + 8, y + 7);
+ g.drawLine(x + 5, y + 8, x + 6, y + 8);
+ g.drawLine(x + 4, y + 9, x + 5, y + 9);
+ g.drawLine(x + 3, y + 10, x + 4, y + 10);
+ g.drawLine(x + 2, y + 11, x + 3, y + 11);
+ g.drawLine(x + 2, y + 12, x + 4, y + 12);
+ g.drawLine(x + 8, y + 8, x + 8, y + 8);
+
+ // draw black
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 8, y, x + 13, y);
+ g.drawLine(x + 8, y + 1, x + 8, y + 1);
+ g.drawLine(x + 10, y + 2, x + 9, y + 3);
+ g.drawLine(x, y + 4, x + 8, y + 4);
+ g.drawLine(x, y + 5, x, y + 13);
+
+ g.drawLine(x + 2, y + 10, x + 6, y + 6);
+ g.drawLine(x + 8, y + 9, x + 8, y + 11);
+ g.drawLine(x + 5, y + 12, x + 8, y + 12);
+
+ // draw white
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.drawLine(x + 2, y + 6, x + 5, y + 6);
+ g.drawLine(x + 2, y + 7, x + 2, y + 9);
+ g.drawLine(x + 4, y + 11, x + 7, y + 8);
+
+ g.drawLine(x + 1, y + 14, x + 10, y + 14);
+ g.drawLine(x + 10, y + 5, x + 10, y + 13);
+
+ g.drawLine(x + 9, y + 2, x + 9, y + 2);
+ g.drawLine(x + 11, y + 4, x + 11, y + 5);
+ g.drawLine(x + 13, y + 6, x + 14, y + 6);
+ g.drawLine(x + 14, y + 1, x + 14, y + 5);
+ }
+ }
+
+ /**
+ * An icon used in the title frame of a {@link JInternalFrame}.
+ */
+ private static class InternalFrameMinimizeIcon
+ implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new instance.
+ */
+ public InternalFrameMinimizeIcon()
+ {
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 16;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 16;
+ }
+
+ /**
+ * Paints the icon at the specified location.
+ *
+ * @param c the component.
+ * @param g the graphics device.
+ * @param x the x coordinate.
+ * @param y the y coordinate.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color color = MetalLookAndFeel.getControlDarkShadow();
+ if (c instanceof JInternalFrame)
+ {
+ JInternalFrame f = (JInternalFrame) c;
+ if (f.isSelected())
+ color = MetalLookAndFeel.getPrimaryControlShadow();
+ }
+ g.setColor(color);
+ g.drawLine(x + 12, y + 1, x + 13, y + 1);
+ g.drawLine(x + 11, y + 2, x + 12, y + 2);
+ g.drawLine(x + 10, y + 3, x + 11, y + 3);
+ g.drawLine(x + 8, y + 2, x + 8, y + 3);
+ g.fillRect(x + 8, y + 4, 3, 3);
+ g.drawLine(x + 11, y + 6, x + 12, y + 6);
+
+ g.drawLine(x + 1, y + 8, x + 6, y + 8);
+ g.drawLine(x + 1, y + 9, x + 1, y + 12);
+ g.drawLine(x + 6, y + 9, x + 6, y + 12);
+ g.drawLine(x + 1, y + 13, x + 6, y + 13);
+
+ g.drawLine(x + 5, y + 9, x + 5, y + 9);
+ g.drawLine(x + 2, y + 12, x + 2, y + 12);
+
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x + 12, y, x + 9, y + 3);
+ g.drawLine(x + 7, y + 1, x + 8, y + 1);
+ g.drawLine(x + 7, y + 2, x + 7, y + 6);
+ g.drawLine(x, y + 7, x + 6, y + 7);
+ g.drawLine(x, y + 8, x, y + 13);
+ g.drawLine(x + 3, y + 12, x + 5, y + 12);
+ g.drawLine(x + 5, y + 10, x + 5, y + 11);
+ g.drawLine(x + 11, y + 5, x + 12, y + 5);
+
+ g.setColor(MetalLookAndFeel.getWhite());
+ g.drawLine(x + 9, y + 2, x + 9, y + 2);
+ g.drawLine(x + 11, y + 4, x + 13, y + 2);
+ g.drawLine(x + 13, y + 6, x + 13, y + 6);
+ g.drawLine(x + 8, y + 7, x + 13, y + 7);
+ g.drawLine(x + 2, y + 9, x + 4, y + 9);
+ g.drawLine(x + 2, y + 10, x + 2, y + 11);
+ g.drawLine(x + 7, y + 9, x + 7, y + 13);
+ g.drawLine(x + 1, y + 14, x + 7, y + 14);
+ }
+ }
+
+ /**
* The icon used to display the thumb control on a horizontally oriented
* {@link JSlider} component.
*/
@@ -606,6 +1298,9 @@ public class MetalIconFactory implements Serializable
}
}
+ /** The cached RadioButtonIcon instance. */
+ private static RadioButtonIcon radioButtonIcon;
+
/**
* Creates a new instance. All the methods are static, so creating an
* instance isn't necessary.
@@ -613,8 +1308,53 @@ public class MetalIconFactory implements Serializable
public MetalIconFactory()
{
}
+
+ /**
+ * Returns an icon for use when rendering the {@link JCheckBox} component.
+ *
+ * @return A check box icon.
+ *
+ * @since 1.3
+ */
+ public static Icon getCheckBoxIcon()
+ {
+ return new MetalCheckBoxIcon();
+ }
/**
+ * Returns an icon for use when rendering the {@link JCheckBoxMenuItem}
+ * component.
+ *
+ * @return An icon.
+ */
+ public static Icon getCheckBoxMenuItemIcon()
+ {
+ return new CheckBoxMenuItemIcon();
+ }
+
+ /**
+ * Returns an icon for RadioButtons in the Metal L&F.
+ *
+ * @return an icon for RadioButtons in the Metal L&F
+ */
+ public static Icon getRadioButtonIcon()
+ {
+ if (radioButtonIcon == null)
+ radioButtonIcon = new RadioButtonIcon();
+ return radioButtonIcon;
+ }
+
+ /**
+ * Creates a new instance of the icon used in a {@link JRadioButtonMenuItem}.
+ *
+ * @return A new icon instance.
+ */
+ public static Icon getRadioButtonMenuItemIcon()
+ {
+ return new RadioButtonMenuItemIcon();
+ }
+
+ /**
* Returns the icon used to display the thumb for a horizontally oriented
* {@link JSlider}.
*
@@ -626,6 +1366,72 @@ public class MetalIconFactory implements Serializable
}
/**
+ * Creates a new icon used to represent the 'close' button in the title
+ * pane of a {@link JInternalFrame}.
+ *
+ * @param size the icon size.
+ *
+ * @return A close icon.
+ */
+ public static Icon getInternalFrameCloseIcon(int size)
+ {
+ return new InternalFrameCloseIcon(size);
+ }
+
+ /**
+ * Creates a new icon for the menu in a {@link JInternalFrame}. This is the
+ * icon displayed at the top left of the frame.
+ *
+ * @return A menu icon.
+ */
+ public static Icon getInternalFrameDefaultMenuIcon()
+ {
+ return new InternalFrameDefaultMenuIcon();
+ }
+
+ /**
+ * Creates a new icon for the 'maximize' button in a {@link JInternalFrame}.
+ *
+ * @param size the icon size in pixels.
+ *
+ * @return The icon.
+ *
+ * @see #getInternalFrameAltMaximizeIcon(int)
+ */
+ public static Icon getInternalFrameMaximizeIcon(int size)
+ {
+ return new InternalFrameMaximizeIcon();
+ }
+
+ /**
+ * Returns the icon used for the minimize button in the frame title for a
+ * {@link JInternalFrame}.
+ *
+ * @param size the icon size in pixels (ignored by this implementation).
+ *
+ * @return The icon.
+ */
+ public static Icon getInternalFrameMinimizeIcon(int size)
+ {
+ return new InternalFrameMinimizeIcon();
+ }
+
+ /**
+ * Creates a new icon for the 'restore' button in a {@link JInternalFrame}
+ * that has been maximised.
+ *
+ * @param size the icon size in pixels.
+ *
+ * @return The icon.
+ *
+ * @see #getInternalFrameMaximizeIcon(int)
+ */
+ public static Icon getInternalFrameAltMaximizeIcon(int size)
+ {
+ return new InternalFrameAltMaximizeIcon(size);
+ }
+
+ /**
* Returns the icon used to display the thumb for a vertically oriented
* {@link JSlider}.
*
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java
index 1414351..7c7cb92 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java
@@ -42,9 +42,11 @@ import java.util.HashMap;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
+import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicInternalFrameUI;
+
public class MetalInternalFrameUI
extends BasicInternalFrameUI
{
@@ -85,4 +87,13 @@ public class MetalInternalFrameUI
return instance;
}
+
+ protected JComponent createNorthPane(JInternalFrame w)
+ {
+ titlePane = new MetalInternalFrameTitlePane(w);
+ titlePane.setBorder(new EmptyBorder(2, 2, 2, 2));
+ return titlePane;
+ }
+
+
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLabelUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalLabelUI.java
index cdd8612..fe8a9e4 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalLabelUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalLabelUI.java
@@ -38,17 +38,26 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+import java.awt.Graphics;
+
import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicLabelUI;
+/**
+ * A UI delegate used for {@link JLabel}s in the {@link MetalLookAndFeel}.
+ */
public class MetalLabelUI
extends BasicLabelUI
{
- // FIXME: maybe replace by a Map of instances when this becomes stateful
/** The shared UI instance for JLabels. */
- private static MetalLabelUI instance = null;
+ protected static MetalLabelUI metalLabelUI;
/**
* Constructs a new instance of MetalLabelUI.
@@ -67,8 +76,36 @@ public class MetalLabelUI
*/
public static ComponentUI createUI(JComponent component)
{
- if (instance == null)
- instance = new MetalLabelUI();
- return instance;
+ if (metalLabelUI == null)
+ metalLabelUI = new MetalLabelUI();
+ return metalLabelUI;
+ }
+
+ /**
+ * Draws the text for a disabled label, using the color defined in the
+ * {@link UIDefaults} with the key Label.disabledForeground
.
+ *
+ * @param l the label.
+ * @param g the graphics device.
+ * @param s the label text.
+ * @param textX the x-coordinate for the label.
+ * @param textY the y-coordinate for the label.
+ *
+ * @see UIManager#getLookAndFeelDefaults()
+ */
+ protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
+ int textY)
+ {
+ Color savedColor = g.getColor();
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ g.setColor(defaults.getColor("Label.disabledForeground"));
+ int mnemIndex = l.getDisplayedMnemonicIndex();
+ if (mnemIndex != -1)
+ BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
+ textY);
+ else
+ g.drawString(s, textX, textY);
+
+ g.setColor(savedColor);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
index 46519fc..d9cf7c6 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -42,13 +42,14 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
-import javax.swing.ImageIcon;
import javax.swing.UIDefaults;
+import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
-import javax.swing.plaf.IconUIResource;
+import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.basic.BasicLookAndFeel;
+
/**
* A custom look and feel that is designed to look similar across different
* operating systems.
@@ -771,7 +772,15 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Button.select", new ColorUIResource(getPrimaryControlShadow()),
"Button.shadow", new ColorUIResource(getPrimaryControlShadow()),
"CheckBox.background", new ColorUIResource(getControl()),
+ "CheckBox.border", MetalBorders.getButtonBorder(),
+ "CheckBox.icon",
+ new UIDefaults.ProxyLazyValue
+ ("javax.swing.plaf.metal.MetalCheckBoxIcon"),
+ "CheckBox.checkIcon",
+ new UIDefaults.ProxyLazyValue
+ ("javax.swing.plaf.metal.MetalCheckBoxIcon"),
"CheckBoxMenuItem.background", new ColorUIResource(getControl()),
+ "CheckBoxMenuItem.checkIcon", MetalIconFactory.getCheckBoxMenuItemIcon(),
"ToolBar.background", new ColorUIResource(getControl()),
"Panel.background", new ColorUIResource(getControl()),
"Slider.background", new ColorUIResource(getControl()),
@@ -779,16 +788,53 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"ProgressBar.background", new ColorUIResource(getControl()),
"ScrollPane.border", new MetalBorders.ScrollPaneBorder(),
"TabbedPane.background", new ColorUIResource(getControl()),
+ "InternalFrame.border", new MetalBorders.InternalFrameBorder(),
+ "InternalFrame.icon", MetalIconFactory.getInternalFrameDefaultMenuIcon(),
+ "InternalFrame.closeIcon",
+ MetalIconFactory.getInternalFrameCloseIcon(16),
+ "InternalFrame.maximizeIcon",
+ MetalIconFactory.getInternalFrameMaximizeIcon(16),
+ "InternalFrame.iconifyIcon",
+ MetalIconFactory.getInternalFrameMinimizeIcon(16),
"Label.background", new ColorUIResource(getControl()),
"Label.font", getControlTextFont(),
- "Label.disabledForeground", new ColorUIResource(getControlDisabled()),
- "Label.foreground", new ColorUIResource(getSystemTextColor()),
+ "Label.disabledForeground", new ColorUIResource(getInactiveControlTextColor()),
+ "Label.foreground", new ColorUIResource(getControlTextColor()),
"Menu.background", new ColorUIResource(getControl()),
+ "Menu.border", new MetalBorders.MenuItemBorder(),
+ "Menu.borderPainted", Boolean.TRUE,
"Menu.font", getControlTextFont(),
+ "Menu.selectionBackground", getMenuSelectedBackground(),
+ "Menu.selectionForeground", getMenuSelectedForeground(),
"MenuBar.background", new ColorUIResource(getControl()),
+ "MenuBar.border", new MetalBorders.MenuBarBorder(),
"MenuBar.font", getControlTextFont(),
"MenuItem.background", new ColorUIResource(getControl()),
+ "MenuItem.border", new MetalBorders.MenuItemBorder(),
"MenuItem.font", getControlTextFont(),
+ "MenuItem.selectionBackground", getMenuSelectedBackground(),
+ "MenuItem.selectionForeground", getMenuSelectedForeground(),
+ "Panel.background", new ColorUIResource(getControl()),
+ "RadioButton.icon",
+ new UIDefaults.LazyValue()
+ {
+ public Object createValue(UIDefaults def)
+ {
+ return MetalIconFactory.getRadioButtonIcon();
+ }
+ },
+
+ "RadioButtonMenuItem.border", new MetalBorders.MenuItemBorder(),
+ "RadioButtonMenuItem.borderPainted", Boolean.TRUE,
+ "RadioButtonMenuItem.checkIcon",
+ MetalIconFactory.getRadioButtonMenuItemIcon(),
+ "RadioButtonMenuItem.font", MetalLookAndFeel.getControlTextFont(),
+ "RadioButtonMenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
+ "RadioButtonMenuItem.selectionBackground",
+ MetalLookAndFeel.getMenuSelectedBackground(),
+ "RadioButtonMenuItem.selectionForeground",
+ MetalLookAndFeel.getMenuSelectedForeground(),
+
"ScrollBar.background", new ColorUIResource(getControl()),
"ScrollBar.shadow", new ColorUIResource(getControlShadow()),
"ScrollBar.thumb", new ColorUIResource(getPrimaryControlShadow()),
@@ -802,6 +848,32 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"SplitPane.highlight",
new ColorUIResource(getControlHighlight()),
+ "Slider.focusInsets", new InsetsUIResource(0, 0, 0, 0),
+ "Slider.horizontalThumbIcon",
+ MetalIconFactory.getHorizontalSliderThumbIcon(),
+ "Slider.verticalThumbIcon",
+ MetalIconFactory.getVerticalSliderThumbIcon(),
+ "Slider.trackWidth", new Integer(7),
+ "Slider.majorTickLength", new Integer(6),
+
+ "TabbedPane.font", new FontUIResource("Dialog", Font.BOLD, 12),
+ "TabbedPane.tabInsets", new InsetsUIResource(0, 9, 1, 9),
+ "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1),
+ "TabbedPane.tabAreaInsets", new InsetsUIResource(4, 2, 0, 6),
+
+ "ToggleButton.background", new ColorUIResource(getControl()),
+ "ToggleButton.border", MetalBorders.getButtonBorder(),
+ "ToggleButton.darkShadow", new ColorUIResource(getControlDarkShadow()),
+ "ToggleButton.disabledText", new ColorUIResource(getControlDisabled()),
+ "ToggleButton.focus", new ColorUIResource(getFocusColor()),
+ "ToggleButton.font", getControlTextFont(),
+ "ToggleButton.foreground", new ColorUIResource(getSystemTextColor()),
+ "ToggleButton.highlight", new ColorUIResource(getControlHighlight()),
+ "ToggleButton.light", new ColorUIResource(getControlHighlight()),
+ "ToggleButton.margin", new Insets(2, 14, 2, 14),
+ "ToggleButton.select", new ColorUIResource(getPrimaryControlShadow()),
+ "ToggleButton.shadow", new ColorUIResource(getPrimaryControlShadow()),
+
"Tree.openIcon", MetalIconFactory.getTreeFolderIcon(),
"Tree.closedIcon", MetalIconFactory.getTreeFolderIcon(),
"Tree.leafIcon", MetalIconFactory.getTreeLeafIcon(),
@@ -818,6 +890,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"Tree.selectionBackground", new ColorUIResource(new Color(204, 204, 255)),
"Tree.nonSelectionBackground", new ColorUIResource(Color.white),
"Tree.selectionBorderColor", new ColorUIResource(new Color(102, 102, 153)),
+ "Tree.selectionBorder", new BorderUIResource.LineBorderUIResource(new Color(102, 102, 153)),
+ "Tree.nonSelectionBorder", new BorderUIResource.LineBorderUIResource(Color.white),
"Tree.selectionForeground", new ColorUIResource(Color.black),
"Tree.textBackground", new ColorUIResource(new Color(204, 204, 255)),
"Tree.textForeground", new ColorUIResource(Color.black),
@@ -845,7 +919,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel
super.initSystemColorDefaults(defaults);
Object[] uiDefaults;
uiDefaults = new Object[] {
- "control", new ColorUIResource(getControl())
+ "control", new ColorUIResource(getControl()),
+ "desktop", new ColorUIResource(getDesktopColor())
};
defaults.putDefaults(uiDefaults);
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java
index a857d6a..4b52c4b 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java
@@ -38,25 +38,72 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.beans.PropertyChangeListener;
import java.util.HashMap;
+import javax.swing.Icon;
import javax.swing.JComponent;
+import javax.swing.JSlider;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicSliderUI;
+/**
+ * A UI delegate for the {@link JSlider} component.
+ */
public class MetalSliderUI
extends BasicSliderUI
{
+ // TODO: find a use for this
+ protected static Color thumbColor;
+
+ // TODO: find a use for this
+ protected static Color highlightColor;
+
+ // TODO: find a use for this
+ protected static Color darkShadowColor;
+
+ /** The track width. */
+ protected static int trackWidth = UIManager.getInt("Slider.trackWidth");
+
+ /** The length of the major tick marks. */
+ protected static int tickLength = UIManager.getInt("Slider.majorTickLength");
+
+ /** The icon used for the thumb control of horizontally oriented sliders. */
+ protected static Icon horizThumbIcon = UIManager.getIcon(
+ "Slider.horizontalThumbIcon");
+
+ /** The icon used for the thumb control of vertically oriented sliders. */
+ protected static Icon vertThumbIcon = UIManager.getIcon(
+ "Slider.verticalThumbIcon");
+ /** The gap between the track and the tick marks. */
+ protected final int TICK_BUFFER = 4;
+
+ /**
+ * A flag that controls whether or not the track is filled up to the value
+ * of the slider.
+ */
+ protected boolean filledSlider;
+
+ /** A key to look up the filledSlider setting in the {@link UIManager}. */
+ protected final String SLIDER_FILL = "JSlider.isFilled";
+
/** The UI instances for MetalSliderUIs */
private static HashMap instances;
/**
- * Constructs a new instance of MetalSliderUI.
+ * Constructs a new instance.
*/
public MetalSliderUI()
{
super(null);
+ filledSlider = UIManager.getBoolean(SLIDER_FILL);
}
/**
@@ -71,17 +118,225 @@ public class MetalSliderUI
if (instances == null)
instances = new HashMap();
-
Object o = instances.get(component);
MetalSliderUI instance;
if (o == null)
{
- instance = new MetalSliderUI();
- instances.put(component, instance);
+ instance = new MetalSliderUI();
+ instances.put(component, instance);
}
else
instance = (MetalSliderUI) o;
return instance;
}
+
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ Boolean b = (Boolean) c.getClientProperty(SLIDER_FILL);
+ if (b != null)
+ filledSlider = b.booleanValue();
+ }
+
+ /**
+ * Paints the thumb icon for the slider.
+ *
+ * @param g the graphics device.
+ */
+ public void paintThumb(Graphics g)
+ {
+ if (slider.getOrientation() == JSlider.HORIZONTAL)
+ horizThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
+ else
+ vertThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
+ }
+
+ /**
+ * Creates a property change listener for the slider.
+ *
+ * @param slider the slider.
+ */
+ protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
+ {
+ // TODO: try to figure out why it might be necessary to override this
+ // method as is done in Sun's implementation
+ return super.createPropertyChangeListener(slider);
+ }
+
+ /**
+ * Paints the track along which the thumb control moves.
+ *
+ * @param g the graphics device.
+ */
+ public void paintTrack(Graphics g)
+ {
+ if (slider.getOrientation() == JSlider.HORIZONTAL)
+ {
+ if (filledSlider)
+ {
+ // TODO: fill the track
+ }
+ BasicGraphicsUtils.drawEtchedRect(g, trackRect.x, trackRect.y
+ + (trackRect.height - getTrackWidth()) / 2, trackRect.width - 1,
+ getTrackWidth(), Color.darkGray, Color.gray, Color.darkGray,
+ Color.white);
+ }
+ else
+ {
+ if (filledSlider)
+ {
+ // TODO: fill the track
+ }
+ BasicGraphicsUtils.drawEtchedRect(g, trackRect.x + (trackRect.width
+ - getTrackWidth()) / 2, trackRect.y, getTrackWidth(),
+ trackRect.height - 1, Color.darkGray, Color.gray, Color.darkGray,
+ Color.white);
+ }
+ }
+
+ /**
+ * Draws the focus rectangle for the slider. The Metal look and feel
+ * indicates that the {@link JSlider} has the focus by changing the color of
+ * the thumb control - this is handled elsewhere and so this method is empty
+ * (it overrides the method in the {@link BasicSliderUI} class to prevent
+ * a default focus highlight from being drawn).
+ *
+ * @param g the graphics device.
+ */
+ public void paintFocus(Graphics g)
+ {
+ // do nothing as focus is shown by different color on thumb control
+ }
+
+ /**
+ * Returns the size of the thumb icon.
+ *
+ * @return The size of the thumb icon.
+ */
+ protected Dimension getThumbSize()
+ {
+ if (slider.getOrientation() == JSlider.HORIZONTAL)
+ return new Dimension(horizThumbIcon.getIconWidth(),
+ horizThumbIcon.getIconHeight());
+ else
+ return new Dimension(vertThumbIcon.getIconWidth(),
+ vertThumbIcon.getIconHeight());
+ }
+
+ /**
+ * Returns the length of the major tick marks.
+ *
+ * @return The length of the major tick marks.
+ */
+ public int getTickLength()
+ {
+ return tickLength + TICK_BUFFER;
+ }
+
+ /**
+ * Returns the track width.
+ *
+ * @return The track width.
+ */
+ protected int getTrackWidth()
+ {
+ return trackWidth;
+ }
+
+ /**
+ * Returns the track length.
+ *
+ * @return The track length.
+ */
+ protected int getTrackLength()
+ {
+ return (slider.getOrientation() == JSlider.HORIZONTAL
+ ? tickRect.width : tickRect.height);
+ }
+
+ /**
+ * Returns the thumb overhang.
+ *
+ * @return The thumb overhang.
+ */
+ protected int getThumbOverhang()
+ {
+ // TODO: figure out what this is used for
+ return 0;
+ }
+
+ protected void scrollDueToClickInTrack(int dir)
+ {
+ super.scrollDueToClickInTrack(dir);
+ }
+
+ /**
+ * Paints the minor ticks for a slider with a horizontal orientation.
+ *
+ * @param g the graphics device.
+ * @param tickBounds the tick bounds.
+ * @param x the x value for the tick.
+ */
+ protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds,
+ int x)
+ {
+ // Note the incoming 'g' has a translation in place to get us to the
+ // start of the tick rect already...
+ // TODO: get color from UIManager...
+ g.setColor(new Color(153, 153, 204));
+ g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength / 2);
+ }
+
+ /**
+ * Paints the major ticks for a slider with a horizontal orientation.
+ *
+ * @param g the graphics device.
+ * @param tickBounds the tick bounds.
+ * @param x the x value for the tick.
+ */
+ protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds,
+ int x)
+ {
+ // Note the incoming 'g' has a translation in place to get us to the
+ // start of the tick rect already...
+ // TODO: get color from UIManager...
+ g.setColor(new Color(153, 153, 204));
+ g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength);
+ }
+
+ /**
+ * Paints the minor ticks for a slider with a vertical orientation.
+ *
+ * @param g the graphics device.
+ * @param tickBounds the tick bounds.
+ * @param y the y value for the tick.
+ */
+ protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
+ int y)
+ {
+ // Note the incoming 'g' has a translation in place to get us to the
+ // start of the tick rect already...
+ // TODO: get color from UIManager...
+ g.setColor(new Color(153, 153, 204));
+ g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength / 2, y);
+ }
+
+ /**
+ * Paints the major ticks for a slider with a vertical orientation.
+ *
+ * @param g the graphics device.
+ * @param tickBounds the tick bounds.
+ * @param y the y value for the tick.
+ */
+ protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
+ int y)
+ {
+ // Note the incoming 'g' has a translation in place to get us to the
+ // start of the tick rect already...
+ // TODO: get color from UIManager...
+ g.setColor(new Color(153, 153, 204));
+ g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength, y);
+ }
+
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index bf50f91..1b5fe14 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -38,16 +38,70 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Graphics;
+import java.awt.LayoutManager;
import java.util.HashMap;
import javax.swing.JComponent;
+import javax.swing.JTabbedPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
+/**
+ * A UI delegate used for the {@link JTabbedPane} component in the
+ * {@link MetalLookAndFeel}.
+ */
public class MetalTabbedPaneUI
extends BasicTabbedPaneUI
{
+ /**
+ * A {@link LayoutManager} responsible for placing all the tabs and the
+ * visible component inside the {@link JTabbedPane}. This class is only used
+ * for {@link JTabbedPane#WRAP_TAB_LAYOUT}.
+ *
+ * @specnote Apparently this class was intended to be protected,
+ * but was made public by a compiler bug and is now
+ * public for compatibility.
+ */
+ public class TabbedPaneLayout
+ extends BasicTabbedPaneUI.TabbedPaneLayout
+ {
+ /**
+ * Creates a new instance of the layout manager.
+ */
+ public TabbedPaneLayout()
+ {
+ }
+
+ /**
+ * Overridden to do nothing, because tab runs are not rotated in the
+ * {@link MetalLookAndFeel}.
+ *
+ * @param tabPlacement the tab placement (one of {@link #TOP},
+ * {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
+ * @param selectedRun the index of the selected run.
+ */
+ protected void rotateTabRuns(int tabPlacement, int selectedRun)
+ {
+ // do nothing, because tab runs are not rotated in the MetalLookAndFeel
+ }
+
+ /**
+ * Overridden to do nothing, because the selected tab does not have extra
+ * padding in the {@link MetalLookAndFeel}.
+ *
+ * @param tabPlacement the tab placement (one of {@link #TOP},
+ * {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
+ * @param selectedIndex the index of the selected tab.
+ */
+ protected void padSelectedTab(int tabPlacement, int selectedIndex)
+ {
+ // do nothing, because the selected tab does not have extra padding in
+ // the MetalLookAndFeel
+ }
+ }
+
/** The shared UI instance for JTabbedPanes. */
private static HashMap instances = null;
@@ -83,4 +137,228 @@ public class MetalTabbedPaneUI
return instance;
}
+
+ /**
+ * Creates and returns an instance of {@link TabbedPaneLayout}.
+ *
+ * @return A layout manager used by this UI delegate.
+ */
+ protected LayoutManager createLayoutManager()
+ {
+ return new TabbedPaneLayout();
+ }
+
+ /**
+ * Paints the border for a single tab.
+ *
+ * @param g the graphics device.
+ * @param tabPlacement the tab placement ({@link #TOP}, {@link #LEFT},
+ * {@link #BOTTOM} or {@link #RIGHT}).
+ * @param tabIndex the index of the tab to draw the border for.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param isSelected indicates whether or not the tab is selected.
+ */
+ protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
+ int x, int y, int w, int h, boolean isSelected)
+ {
+ if (tabPlacement == TOP)
+ paintTopTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+ else if (tabPlacement == LEFT)
+ paintLeftTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+ else if (tabPlacement == BOTTOM)
+ paintBottomTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+ else if (tabPlacement == RIGHT)
+ paintRightTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+ else
+ throw new AssertionError("Unrecognised 'tabPlacement' argument.");
+ }
+
+ /**
+ * Paints the border for a tab assuming that the tab position is at the top
+ * ({@link #TOP}).
+ *
+ * @param tabIndex the tab index.
+ * @param g the graphics device.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param btm ???
+ * @param rght ???
+ * @param isSelected indicates whether the tab is selected.
+ */
+ protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y,
+ int w, int h, int btm, int rght, boolean isSelected)
+ {
+ if (isSelected)
+ {
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawLine(x + 1, y + h, x + 1, y + 6);
+ g.drawLine(x + 1, y + 6, x + 6, y + 1);
+ g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
+ }
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawLine(x, y + h - 1, x, y + 6);
+ g.drawLine(x, y + 6, x + 6, y);
+ g.drawLine(x + 6, y, x + w, y);
+ g.drawLine(x + w, y, x + w, y + h - 1);
+ }
+
+ /**
+ * Paints the border for a tab assuming that the tab position is at the left
+ * ({@link #LEFT}).
+ *
+ * @param tabIndex the tab index.
+ * @param g the graphics device.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param btm ???
+ * @param rght ???
+ * @param isSelected indicates whether the tab is selected.
+ */
+ protected void paintLeftTabBorder(int tabIndex, Graphics g, int x, int y,
+ int w, int h, int btm, int rght, boolean isSelected)
+ {
+ if (isSelected)
+ {
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawLine(x + 1, y + h, x + 1, y + 6);
+ g.drawLine(x + 1, y + 6, x + 6, y + 1);
+ g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
+ }
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawLine(x, y + h, x, y + 6);
+ g.drawLine(x, y + 6, x + 6, y);
+ g.drawLine(x + 6, y, x + w - 1, y);
+ g.drawLine(x, y + h, x + w - 1, y + h);
+ }
+
+ /**
+ * Paints the border for a tab assuming that the tab position is at the right
+ * ({@link #RIGHT}).
+ *
+ * @param tabIndex the tab index.
+ * @param g the graphics device.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param btm ???
+ * @param rght ???
+ * @param isSelected indicates whether the tab is selected.
+ */
+ protected void paintRightTabBorder(int tabIndex, Graphics g, int x, int y,
+ int w, int h, int btm, int rght, boolean isSelected)
+ {
+ if (isSelected)
+ {
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawLine(x, y + 1, x + w - 7, y + 1);
+ g.drawLine(x + w - 7, y + 1, x + w - 1, y + 7);
+ }
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawLine(x, y, x + w - 7, y);
+ g.drawLine(x + w - 7, y, x + w - 1, y + 6);
+ g.drawLine(x + w - 1, y + 6, x + w - 1, y + h - 1);
+ g.drawLine(x + w - 1, y + h, x, y + h);
+ }
+
+ /**
+ * Paints the border for a tab assuming that the tab position is at the bottom
+ * ({@link #BOTTOM}).
+ *
+ * @param tabIndex the tab index.
+ * @param g the graphics device.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param btm ???
+ * @param rght ???
+ * @param isSelected indicates whether the tab is selected.
+ */
+ protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y,
+ int w, int h, int btm, int rght, boolean isSelected)
+ {
+ if (isSelected)
+ {
+ g.setColor(MetalLookAndFeel.getControlHighlight());
+ g.drawLine(x + 1, y, x + 1, y + h - 7);
+ g.drawLine(x + 1, y + h - 7, x + 7, y + h - 1);
+ }
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+ g.drawLine(x, y, x, y + h - 7);
+ g.drawLine(x, y + h - 7, x + 6, y + h - 1);
+ g.drawLine(x + 6, y + h - 1, x + w, y + h - 1);
+ g.drawLine(x + w, y + h - 1, x + w, y);
+ }
+
+ /**
+ * Paints the background for a tab.
+ *
+ * @param g the graphics device.
+ * @param tabPlacement the tab placement ({@link #TOP}, {@link #LEFT},
+ * {@link #BOTTOM} or {@link #RIGHT}).
+ * @param tabIndex the index of the tab to draw the border for.
+ * @param x the x-coordinate for the tab's bounding rectangle.
+ * @param y the y-coordinate for the tab's bounding rectangle.
+ * @param w the width for the tab's bounding rectangle.
+ * @param h the height for the tab's bounding rectangle.
+ * @param isSelected indicates whether or not the tab is selected.
+ */
+ protected void paintTabBackground(Graphics g, int tabPlacement,
+ int tabIndex, int x, int y, int w, int h, boolean isSelected)
+ {
+ if (isSelected)
+ g.setColor(MetalLookAndFeel.getControl());
+ else
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ int[] px, py;
+ if (tabPlacement == TOP)
+ {
+ px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
+ py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
+ }
+ else if (tabPlacement == LEFT)
+ {
+ px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
+ py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
+ }
+ else if (tabPlacement == BOTTOM)
+ {
+ px = new int[] {x + 2, x + w - 1, x + w -1, x + 8, x + 2};
+ py = new int[] {y, y, y + h - 1, y + h -1, y + h - 7};
+ }
+ else if (tabPlacement == RIGHT)
+ {
+ px = new int[] {x + 2, x + w - 7, x + w - 1, x + w - 1, x + 2};
+ py = new int[] {y + 2, y + 2, y + 7, y + h -1, y + h - 1};
+ }
+ else
+ throw new AssertionError("Unrecognised 'tabPlacement' argument.");
+ g.fillPolygon(px, py, 5);
+ }
+
+ /**
+ * Returns true
if the tabs in the specified run should be
+ * padded to make the run fill the width/height of the {@link JTabbedPane}.
+ *
+ * @param tabPlacement the tab placement for the {@link JTabbedPane} (one of
+ * {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} and {@link #RIGHT}).
+ * @param run the run index.
+ *
+ * @return A boolean.
+ */
+ protected boolean shouldPadTabRun(int tabPlacement, int run)
+ {
+ // as far as I can tell, all runs should be padded except the last run
+ // (which is drawn at the very top for tabPlacement == TOP)
+ return run < this.runCount - 1;
+ }
+
}
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalToggleButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalToggleButtonUI.java
index 7913cdb..be6d0c3 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalToggleButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalToggleButtonUI.java
@@ -38,7 +38,11 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import java.awt.Color;
+
import javax.swing.JComponent;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToggleButtonUI;
@@ -46,7 +50,15 @@ public class MetalToggleButtonUI
extends BasicToggleButtonUI
{
- // FIXME: maybe replace by a Map of instances when this becomes stateful
+ /** The color for the focus border. */
+ protected Color focusColor;
+
+ /** The color that indicates a selected button. */
+ protected Color selectColor;
+
+ /** The color for disabled button labels. */
+ protected Color disabledTextColor;
+
/** The shared UI instance for MetalToggleButtonUIs */
private static MetalToggleButtonUI instance = null;
@@ -56,6 +68,43 @@ public class MetalToggleButtonUI
public MetalToggleButtonUI()
{
super();
+ focusColor = getFocusColor();
+ selectColor = getSelectColor();
+ disabledTextColor = getDisabledTextColor();
+ }
+
+
+ /**
+ * Returns the color for the focus border.
+ *
+ * @return the color for the focus border
+ */
+ protected Color getFocusColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".focus");
+ }
+
+ /**
+ * Returns the color that indicates a selected button.
+ *
+ * @return the color that indicates a selected button
+ */
+ protected Color getSelectColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".select");
+ }
+
+ /**
+ * Returns the color for the text label of disabled buttons.
+ *
+ * @return the color for the text label of disabled buttons
+ */
+ protected Color getDisabledTextColor()
+ {
+ UIDefaults def = UIManager.getLookAndFeelDefaults();
+ return def.getColor(getPropertyPrefix() + ".disabledText");
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTreeUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTreeUI.java
index d85d61c..8d16f74 100644
--- a/libjava/classpath/javax/swing/plaf/metal/MetalTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/metal/MetalTreeUI.java
@@ -75,8 +75,8 @@ public class MetalTreeUI
MetalTreeUI instance;
if (o == null)
{
- instance = new MetalTreeUI();
- instances.put(component, instance);
+ instance = new MetalTreeUI();
+ instances.put(component, instance);
}
else
instance = (MetalTreeUI) o;
diff --git a/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
index 02e9fd7..349f4ba 100644
--- a/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
+++ b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
@@ -47,6 +47,7 @@ import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
+import javax.swing.JTextField;
/**
* Class to display every cells.
@@ -123,7 +124,11 @@ public class DefaultTableCellRenderer extends JLabel
int row, int column)
{
if (value != null)
- super.setText(value.toString());
+ {
+ if (value instanceof JTextField)
+ return new JTextField(((JTextField)value).getText());
+ super.setText(value.toString());
+ }
setOpaque(true);
diff --git a/libjava/classpath/javax/swing/text/AbstractDocument.java b/libjava/classpath/javax/swing/text/AbstractDocument.java
index c3a3d70..3c9a4d4 100644
--- a/libjava/classpath/javax/swing/text/AbstractDocument.java
+++ b/libjava/classpath/javax/swing/text/AbstractDocument.java
@@ -56,70 +56,193 @@ import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CompoundEdit;
import javax.swing.undo.UndoableEdit;
+/**
+ * An abstract base implementation for the {@link Document} interface.
+ * This class provides some common functionality for all Element
s,
+ * most notably it implements a locking mechanism to make document modification
+ * thread-safe.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public abstract class AbstractDocument
implements Document, Serializable
{
+ /** The serial version UID for this class as of JDK1.4. */
private static final long serialVersionUID = -116069779446114664L;
-
+
+ /**
+ * Standard error message to indicate a bad location.
+ */
protected static final String BAD_LOCATION = "document location failure";
-
+
+ /**
+ * Standard name for unidirectional Element
s.
+ */
public static final String BidiElementName = "bidi level";
+
+ /**
+ * Standard name for content Element
s. These are usually
+ * {@link LeafElement}s.
+ */
public static final String ContentElementName = "content";
+
+ /**
+ * Standard name for paragraph Element
s. These are usually
+ * {@link BranchElement}s.
+ */
public static final String ParagraphElementName = "paragraph";
+
+ /**
+ * Standard name for section Element
s. These are usually
+ * {@link DefaultStyledDocument.SectionElement}s.
+ */
public static final String SectionElementName = "section";
+
+ /**
+ * Attribute key for storing the element name.
+ */
public static final String ElementNameAttribute = "$ename";
+ /**
+ * The actual content model of this Document
.
+ */
Content content;
+
+ /**
+ * The AttributeContext for this Document
.
+ */
AttributeContext context;
+
+ /**
+ * The currently installed DocumentFilter
.
+ */
DocumentFilter documentFilter;
- /** The documents properties. */
+ /**
+ * The documents properties.
+ */
Dictionary properties;
+ /**
+ * Manages event listeners for this Document
.
+ */
protected EventListenerList listenerList = new EventListenerList();
+ /**
+ * Creates a new AbstractDocument
with the specified
+ * {@link Content} model.
+ *
+ * @param doc the Content
model to be used in this
+ * Document
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected AbstractDocument(Content doc)
{
this(doc, StyleContext.getDefaultStyleContext());
}
+ /**
+ * Creates a new
AbstractDocument
with the specified
+ * {@link Content} model and {@link AttributeContext}.
+ *
+ * @param doc the Content
model to be used in this
+ * Document
if the style should
+ * be unnamed
+ * @param parent the parent in which unspecified style attributes are
+ * resolved, or
+ * @param ctx the
changes to the AttributeContext
to use
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected AbstractDocument(Content doc, AttributeContext ctx)
{
content = doc;
context = ctx;
}
- // These still need to be implemented by a derived class:
+ /**
+ * Returns the paragraph {@link Element} that holds the specified position.
+ *
+ * @param pos the position for which to get the paragraph element
+ *
+ * @return the paragraph {@link Element} that holds the specified position
+ */
public abstract Element getParagraphElement(int pos);
+ /**
+ * Returns the default root {@link Element} of this Document
.
+ * Usual Document
s only have one root element and return this.
+ * However, there may be Document
implementations that
+ * support multiple root elements, they have to return a default root element
+ * here.
+ *
+ * @return the default root {@link Element} of this Document
+ */
public abstract Element getDefaultRootElement();
+ /**
+ * Creates and returns a branch element with the specified
+ * parent
and attributes
. Note that the new
+ * Element
is linked to the parent Element
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent Element
as child.
+ *
+ * @param parent the parent Element
for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch Element
+ *
+ * @see BranchElement
+ */
protected Element createBranchElement(Element parent,
AttributeSet attributes)
{
return new BranchElement(parent, attributes);
}
+ /**
+ * Creates and returns a leaf element with the specified
+ * parent
and attributes
. Note that the new
+ * Element
is linked to the parent Element
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent Element
as child.
+ *
+ * @param parent the parent Element
for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch Element
+ *
+ * @see LeafElement
+ */
protected Element createLeafElement(Element parent, AttributeSet attributes,
int start, int end)
{
return new LeafElement(parent, attributes, start, end);
}
+ /**
+ * Creates a {@link Position} that keeps track of the location at the
+ * specified offset
.
+ *
+ * @param offset the location in the document to keep track by the new
+ * Position
+ *
+ * @return the newly created Position
+ *
+ * @throws BadLocationException if offset
is not a valid
+ * location in the documents content model
+ */
public Position createPosition(final int offset) throws BadLocationException
{
- if (offset < 0 || offset > getLength())
- throw new BadLocationException(getText(0, getLength()), offset);
-
- return new Position()
- {
- public int getOffset()
- {
- return offset;
- }
- };
+ return content.createPosition(offset);
}
+ /**
+ * Notifies all registered listeners when the document model changes.
+ *
+ * @param event the DocumentEvent
to be fired
+ */
protected void fireChangedUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -128,6 +251,12 @@ public abstract class AbstractDocument
listeners[index].changedUpdate(event);
}
+ /**
+ * Notifies all registered listeners when content is inserted in the document
+ * model.
+ *
+ * @param event the DocumentEvent
to be fired
+ */
protected void fireInsertUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -136,6 +265,12 @@ public abstract class AbstractDocument
listeners[index].insertUpdate(event);
}
+ /**
+ * Notifies all registered listeners when content is removed from the
+ * document model.
+ *
+ * @param event the DocumentEvent
to be fired
+ */
protected void fireRemoveUpdate(DocumentEvent event)
{
DocumentListener[] listeners = getDocumentListeners();
@@ -144,6 +279,12 @@ public abstract class AbstractDocument
listeners[index].removeUpdate(event);
}
+ /**
+ * Notifies all registered listeners when an UndoableEdit
has
+ * been performed on this Document
.
+ *
+ * @param event the UndoableEditEvent
to be fired
+ */
protected void fireUndoableEditUpdate(UndoableEditEvent event)
{
UndoableEditListener[] listeners = getUndoableEditListeners();
@@ -152,31 +293,70 @@ public abstract class AbstractDocument
listeners[index].undoableEditHappened(event);
}
+ /**
+ * Returns the asynchronous loading priority. Returns -1
if this
+ * document should not be loaded asynchronously.
+ *
+ * @return the asynchronous loading priority
+ */
public int getAsynchronousLoadPriority()
{
return 0;
}
+ /**
+ * Returns the {@link AttributeContext} used in this Document
.
+ *
+ * @return the {@link AttributeContext} used in this Document
+ */
protected AttributeContext getAttributeContext()
{
return context;
}
+ /**
+ * Returns the root element for bidirectional content.
+ *
+ * @return the root element for bidirectional content
+ */
public Element getBidiRootElement()
{
return null;
}
+ /**
+ * Returns the {@link Content} model for this Document
+ *
+ * @return the {@link Content} model for this Document
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected Content getContent()
{
return content;
}
+ /**
+ * Returns the thread that currently modifies this Document
+ * if there is one, otherwise null
. This can be used to
+ * distinguish between a method call that is part of an ongoing modification
+ * or if it is a separate modification for which a new lock must be aquired.
+ *
+ * @return the thread that currently modifies this Document
+ * if there is one, otherwise null
+ */
protected Thread getCurrentWriter()
{
+ // FIXME: Implement locking!
return null;
}
+ /**
+ * Returns the properties of this Document
.
+ *
+ * @return the properties of this Document
+ */
public Dictionary getDocumentProperties()
{
// FIXME: make me thread-safe
@@ -186,8 +366,16 @@ public abstract class AbstractDocument
return properties;
}
+ /**
+ * Returns a {@link Position} which will always mark the end of the
+ * Document
.
+ *
+ * @return a {@link Position} which will always mark the end of the
+ * Document
+ */
public Position getEndPosition()
{
+ // FIXME: Properly implement this by calling Content.createPosition().
return new Position()
{
public int getOffset()
@@ -197,16 +385,39 @@ public abstract class AbstractDocument
};
}
+ /**
+ * Returns the length of this Document
's content.
+ *
+ * @return the length of this Document
's content
+ */
public int getLength()
{
+ // We return Content.getLength() -1 here because there is always an
+ // implicit \n at the end of the Content which does count in Content
+ // but not in Document.
return content.length() - 1;
}
+ /**
+ * Returns all registered listeners of a given listener type.
+ *
+ * @param listenerType the type of the listeners to be queried
+ *
+ * @return all registered listeners of the specified type
+ */
public EventListener[] getListeners(Class listenerType)
{
return listenerList.getListeners(listenerType);
}
+ /**
+ * Returns a property from this Document
's property list.
+ *
+ * @param key the key of the property to be fetched
+ *
+ * @return the property for key
or null
if there
+ * is no such property stored
+ */
public Object getProperty(Object key)
{
// FIXME: make me thread-safe
@@ -217,6 +428,15 @@ public abstract class AbstractDocument
return value;
}
+ /**
+ * Returns all root elements of this Document
. By default
+ * this just returns the single root element returned by
+ * {@link #getDefaultRootElement()}. Document
implementations
+ * that support multiple roots must override this method and return all roots
+ * here.
+ *
+ * @return all root elements of this Document
+ */
public Element[] getRootElements()
{
Element[] elements = new Element[1];
@@ -224,8 +444,16 @@ public abstract class AbstractDocument
return elements;
}
+ /**
+ * Returns a {@link Position} which will always mark the beginning of the
+ * Document
.
+ *
+ * @return a {@link Position} which will always mark the beginning of the
+ * Document
+ */
public Position getStartPosition()
{
+ // FIXME: Properly implement this using Content.createPosition().
return new Position()
{
public int getOffset()
@@ -235,17 +463,53 @@ public abstract class AbstractDocument
};
}
+ /**
+ * Returns a piece of this Document
's content.
+ *
+ * @param offset the start offset of the content
+ * @param length the length of the content
+ *
+ * @return the piece of content specified by offset
and
+ * length
+ *
+ * @throws BadLocationException if offset
or offset +
+ * length
are invalid locations with this
+ * Document
+ */
public String getText(int offset, int length) throws BadLocationException
{
return content.getString(offset, length);
}
+ /**
+ * Fetches a piece of this Document
's content and stores
+ * it in the given {@link Segment}.
+ *
+ * @param offset the start offset of the content
+ * @param length the length of the content
+ * @param segment the Segment
to store the content in
+ *
+ * @throws BadLocationException if offset
or offset +
+ * length
are invalid locations with this
+ * Document
+ */
public void getText(int offset, int length, Segment segment)
throws BadLocationException
{
content.getChars(offset, length, segment);
}
+ /**
+ * Inserts a String into this Document
at the specified
+ * position and assigning the specified attributes to it.
+ *
+ * @param offset the location at which the string should be inserted
+ * @param text the content to be inserted
+ * @param attributes the text attributes to be assigned to that string
+ *
+ * @throws BadLocationException if offset
is not a valid
+ * location in this Document
+ */
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
@@ -261,14 +525,37 @@ public abstract class AbstractDocument
fireInsertUpdate(event);
}
+ /**
+ * Called to indicate that text has been inserted into this
+ * Document
. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the DefaultDocumentEvent
describing the change
+ * @param attr the attributes of the changed content
+ */
protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
{
+ // Do nothing here. Subclasses may want to override this.
}
+ /**
+ * Called after some content has been removed from this
+ * Document
. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the DefaultDocumentEvent
describing the change
+ */
protected void postRemoveUpdate(DefaultDocumentEvent chng)
{
+ // Do nothing here. Subclasses may want to override this.
}
+ /**
+ * Stores a property in this Document
's property list.
+ *
+ * @param key the key of the property to be stored
+ * @param value the value of the property to be stored
+ */
public void putProperty(Object key, Object value)
{
// FIXME: make me thread-safe
@@ -278,14 +565,31 @@ public abstract class AbstractDocument
properties.put(key, value);
}
+ /**
+ * Blocks until a read lock can be obtained.
+ */
public void readLock()
{
}
+ /**
+ * Releases the read lock. If this was the only reader on this
+ * Document
, writing may begin now.
+ */
public void readUnlock()
{
}
+ /**
+ * Removes a piece of content from this Document
.
+ *
+ * @param offset the start offset of the fragment to be removed
+ * @param length the length of the fragment to be removed
+ *
+ * @throws BadLocationException if offset
or
+ * offset + length
or invalid locations within this
+ * document
+ */
public void remove(int offset, int length) throws BadLocationException
{
DefaultDocumentEvent event =
@@ -298,7 +602,17 @@ public abstract class AbstractDocument
}
/**
- * Replaces some text in the document.
+ * Replaces a piece of content in this Document
with
+ * another piece of content.
+ *
+ * @param offset the start offset of the fragment to be removed
+ * @param length the length of the fragment to be removed
+ * @param text the text to replace the content with
+ * @param attributes the text attributes to assign to the new content
+ *
+ * @throws BadLocationException if offset
or
+ * offset + length
or invalid locations within this
+ * document
*
* @since 1.4
*/
@@ -331,9 +645,9 @@ public abstract class AbstractDocument
}
/**
- * Returns add added DocumentListener
objects.
+ * Returns all registered DocumentListener
s.
*
- * @return an array of listeners
+ * @return all registered DocumentListener
s
*/
public DocumentListener[] getDocumentListeners()
{
@@ -341,7 +655,7 @@ public abstract class AbstractDocument
}
/**
- * Adds a UndoableEditListener
object to this document.
+ * Adds an {@link UndoableEditListener} to this Document
.
*
* @param listener the listener to add
*/
@@ -351,7 +665,7 @@ public abstract class AbstractDocument
}
/**
- * Removes a UndoableEditListener
object from this document.
+ * Removes an {@link UndoableEditListener} from this Document
.
*
* @param listener the listener to remove
*/
@@ -361,42 +675,93 @@ public abstract class AbstractDocument
}
/**
- * Returns add added UndoableEditListener
objects.
+ * Returns all registered {@link UndoableEditListener}s.
*
- * @return an array of listeners
+ * @return all registered {@link UndoableEditListener}s
*/
public UndoableEditListener[] getUndoableEditListeners()
{
return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
}
+ /**
+ * Called before some content gets removed from this Document
.
+ * The default implementation does nothing but may be overridden by
+ * subclasses to modify the Document
structure in response
+ * to a remove request. The method is executed within a write lock.
+ *
+ * @param chng the DefaultDocumentEvent
describing the change
+ */
protected void removeUpdate(DefaultDocumentEvent chng)
{
+ // Do nothing here. Subclasses may wish to override this.
}
- public void render(Runnable r)
+ /**
+ * Called to render this Document
visually. It obtains a read
+ * lock, ensuring that no changes will be made to the document
+ * during the rendering process. It then calls the {@link Runnable#run()}
+ * method on runnable
. This method must not attempt
+ * to modifiy the Document
, since a deadlock will occur if it
+ * tries to obtain a write lock. When the {@link Runnable#run()} method
+ * completes (either naturally or by throwing an exception), the read lock
+ * is released. Note that there is nothing in this method related to
+ * the actual rendering. It could be used to execute arbitrary code within
+ * a read lock.
+ *
+ * @param runnable the {@link Runnable} to execute
+ */
+ public void render(Runnable runnable)
{
+ // FIXME: Implement me!
}
+ /**
+ * Sets the asynchronous loading priority for this Document
.
+ * A value of -1
indicates that this Document
+ * should be loaded synchronously.
+ *
+ * @param p the asynchronous loading priority to set
+ */
public void setAsynchronousLoadPriority(int p)
{
}
- public void setDocumentProperties(Dictionary x)
+ /**
+ * Sets the properties of this Document
.
+ *
+ * @param p the document properties to set
+ */
+ public void setDocumentProperties(Dictionary p)
{
// FIXME: make me thread-safe
- properties = x;
+ properties = p;
}
+ /**
+ * Blocks until a write lock can be obtained.
+ */
protected void writeLock()
{
+ // FIXME: Implement me.
}
+ /**
+ * Releases the write lock. This allows waiting readers or writers to
+ * obtain the lock.
+ */
protected void writeUnlock()
{
+ // FIXME: Implement me.
}
/**
+ * Returns the currently installed {@link DocumentFilter} for this
+ * Document
.
+ *
+ * @return the currently installed {@link DocumentFilter} for this
+ * Document
+ *
* @since 1.4
*/
public DocumentFilter getDocumentFilter()
@@ -405,6 +770,10 @@ public abstract class AbstractDocument
}
/**
+ * Sets the {@link DocumentFilter} for this Document
.
+ *
+ * @param filter the DocumentFilter
to set
+ *
* @since 1.4
*/
public void setDocumentFilter(DocumentFilter filter)
@@ -412,209 +781,592 @@ public abstract class AbstractDocument
this.documentFilter = filter;
}
+ /**
+ * Dumps diagnostic information to the specified PrintStream
.
+ *
+ * @param out the stream to write the diagnostic information to
+ */
public void dump(PrintStream out)
{
((AbstractElement) getDefaultRootElement()).dump(out, 0);
}
+ /**
+ * Defines a set of methods for managing text attributes for one or more
+ * Document
s.
+ *
+ * Replicating {@link AttributeSet}s throughout a Document
can
+ * be very expensive. Implementations of this interface are intended to
+ * provide intelligent management of AttributeSet
s, eliminating
+ * costly duplication.
+ *
+ * @see StyleContext
+ */
public interface AttributeContext
{
+ /**
+ * Returns an {@link AttributeSet} that contains the attributes
+ * of old
plus the new attribute specified by
+ * name
and value
.
+ *
+ * @param old the attribute set to be merged with the new attribute
+ * @param name the name of the attribute to be added
+ * @param value the value of the attribute to be added
+ *
+ * @return the old attributes plus the new attribute
+ */
AttributeSet addAttribute(AttributeSet old, Object name, Object value);
+ /**
+ * Returns an {@link AttributeSet} that contains the attributes
+ * of old
plus the new attributes in attributes
.
+ *
+ * @param old the set of attributes where to add the new attributes
+ * @param attributes the attributes to be added
+ *
+ * @return an {@link AttributeSet} that contains the attributes
+ * of old
plus the new attributes in
+ * attributes
+ */
AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
+ /**
+ * Returns an empty {@link AttributeSet}.
+ *
+ * @return an empty {@link AttributeSet}
+ */
AttributeSet getEmptySet();
+ /**
+ * Called to indicate that the attributes in attributes
are
+ * no longer used.
+ *
+ * @param attributes the attributes are no longer used
+ */
void reclaim(AttributeSet attributes);
+ /**
+ * Returns a {@link AttributeSet} that has the attribute with the specified
+ * name
removed from old
.
+ *
+ * @param old the attribute set from which an attribute is removed
+ * @param name the name of the attribute to be removed
+ *
+ * @return the attributes of old
minus the attribute
+ * specified by name
+ */
AttributeSet removeAttribute(AttributeSet old, Object name);
+ /**
+ * Removes all attributes in attributes
from old
+ * and returns the resulting AttributeSet
.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param attributes the attributes to be removed from old
+ *
+ * @return the attributes of old
minus the attributes in
+ * attributes
+ */
AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
+ /**
+ * Removes all attributes specified by names
from
+ * old
and returns the resulting AttributeSet
.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param names the names of the attributes to be removed from
+ * old
+ *
+ * @return the attributes of old
minus the attributes in
+ * attributes
+ */
AttributeSet removeAttributes(AttributeSet old, Enumeration names);
}
+ /**
+ * A sequence of data that can be edited. This is were the actual content
+ * in AbstractDocument
's is stored.
+ */
public interface Content
{
+ /**
+ * Creates a {@link Position} that keeps track of the location at
+ * offset
.
+ *
+ * @return a {@link Position} that keeps track of the location at
+ * offset
.
+ *
+ * @throw BadLocationException if offset
is not a valid
+ * location in this Content
model
+ */
Position createPosition(int offset) throws BadLocationException;
+ /**
+ * Returns the length of the content.
+ *
+ * @return the length of the content
+ */
int length();
+ /**
+ * Inserts a string into the content model.
+ *
+ * @param where the offset at which to insert the string
+ * @param str the string to be inserted
+ *
+ * @return an UndoableEdit
or null
if undo is
+ * not supported by this Content
model
+ *
+ * @throws BadLocationException if where
is not a valid
+ * location in this Content
model
+ */
UndoableEdit insertString(int where, String str)
throws BadLocationException;
+ /**
+ * Removes a piece of content from the content model.
+ *
+ * @param where the offset at which to remove content
+ * @param nitems the number of characters to be removed
+ *
+ * @return an UndoableEdit
or null
if undo is
+ * not supported by this Content
model
+ *
+ * @throws BadLocationException if where
is not a valid
+ * location in this Content
model
+ */
UndoableEdit remove(int where, int nitems) throws BadLocationException;
+ /**
+ * Returns a piece of content.
+ *
+ * @param where the start offset of the requested fragment
+ * @param len the length of the requested fragment
+ *
+ * @return the requested fragment
+ * @throws BadLocationException if offset
or
+ * offset + len
is not a valid
+ * location in this Content
model
+ */
String getString(int where, int len) throws BadLocationException;
+ /**
+ * Fetches a piece of content and stores it in txt
.
+ *
+ * @param where the start offset of the requested fragment
+ * @param len the length of the requested fragment
+ * @param txt the Segment
where to fragment is stored into
+ *
+ * @throws BadLocationException if offset
or
+ * offset + len
is not a valid
+ * location in this Content
model
+ */
void getChars(int where, int len, Segment txt) throws BadLocationException;
}
+ /**
+ * An abstract base implementation of the {@link Element} interface.
+ */
public abstract class AbstractElement
implements Element, MutableAttributeSet, TreeNode, Serializable
{
+ /** The serial version UID for AbstractElement. */
private static final long serialVersionUID = 1265312733007397733L;
+
+ /** The number of characters that this Element spans. */
int count;
+
+ /** The starting offset of this Element. */
int offset;
+ /** The attributes of this Element. */
AttributeSet attributes;
+ /** The parent element. */
Element element_parent;
+ /** The parent in the TreeNode interface. */
TreeNode tree_parent;
+
+ /** The children of this element. */
Vector tree_children;
+ /**
+ * Creates a new instance of AbstractElement
with a
+ * specified parent Element
and AttributeSet
.
+ *
+ * @param p the parent of this AbstractElement
+ * @param s the attributes to be assigned to this
+ * AbstractElement
+ */
public AbstractElement(Element p, AttributeSet s)
{
element_parent = p;
- attributes = s;
+ AttributeContext ctx = getAttributeContext();
+ attributes = ctx.getEmptySet();
+ if (s != null)
+ attributes = ctx.addAttributes(attributes, s);
}
- // TreeNode implementation
-
+ /**
+ * Returns the child nodes of this Element
as an
+ * Enumeration
of {@link TreeNode}s.
+ *
+ * @return the child nodes of this Element
as an
+ * Enumeration
of {@link TreeNode}s
+ */
public abstract Enumeration children();
-
+
+ /**
+ * Returns true
if this AbstractElement
+ * allows children.
+ *
+ * @return true
if this AbstractElement
+ * allows children
+ */
public abstract boolean getAllowsChildren();
-
+
+ /**
+ * Returns the child of this AbstractElement
at
+ * index
.
+ *
+ * @param index the position in the child list of the child element to
+ * be returned
+ *
+ * @return the child of this AbstractElement
at
+ * index
+ */
public TreeNode getChildAt(int index)
{
return (TreeNode) tree_children.get(index);
}
-
+
+ /**
+ * Returns the number of children of this AbstractElement
.
+ *
+ * @return the number of children of this AbstractElement
+ */
public int getChildCount()
{
return tree_children.size();
}
-
+
+ /**
+ * Returns the index of a given child TreeNode
or
+ * -1
if node
is not a child of this
+ * AbstractElement
.
+ *
+ * @param node the node for which the index is requested
+ *
+ * @return the index of a given child TreeNode
or
+ * -1
if node
is not a child of this
+ * AbstractElement
+ */
public int getIndex(TreeNode node)
{
return tree_children.indexOf(node);
}
+ /**
+ * Returns the parent TreeNode
of this
+ * AbstractElement
or null
if this element
+ * has no parent.
+ *
+ * @return the parent TreeNode
of this
+ * AbstractElement
or null
if this
+ * element has no parent
+ */
public TreeNode getParent()
{
return tree_parent;
}
+ /**
+ * Returns true
if this AbstractElement
is a
+ * leaf element, false
otherwise.
+ *
+ * @return true
if this AbstractElement
is a
+ * leaf element, false
otherwise
+ */
public abstract boolean isLeaf();
-
- // MutableAttributeSet support
-
+ /**
+ * Adds an attribute to this element.
+ *
+ * @param name the name of the attribute to be added
+ * @param value the value of the attribute to be added
+ */
public void addAttribute(Object name, Object value)
{
attributes = getAttributeContext().addAttribute(attributes, name, value);
}
+ /**
+ * Adds a set of attributes to this element.
+ *
+ * @param attrs the attributes to be added to this element
+ */
public void addAttributes(AttributeSet attrs)
{
attributes = getAttributeContext().addAttributes(attributes, attrs);
}
+ /**
+ * Removes an attribute from this element.
+ *
+ * @param name the name of the attribute to be removed
+ */
public void removeAttribute(Object name)
{
attributes = getAttributeContext().removeAttribute(attributes, name);
}
+ /**
+ * Removes a set of attributes from this element.
+ *
+ * @param attrs the attributes to be removed
+ */
public void removeAttributes(AttributeSet attrs)
{
attributes = getAttributeContext().removeAttributes(attributes, attrs);
}
+ /**
+ * Removes a set of attribute from this element.
+ *
+ * @param names the names of the attributes to be removed
+ */
public void removeAttributes(Enumeration names)
{
attributes = getAttributeContext().removeAttributes(attributes, names);
}
+ /**
+ * Sets the parent attribute set against which the element can resolve
+ * attributes that are not defined in itself.
+ *
+ * @param parent the resolve parent to set
+ */
public void setResolveParent(AttributeSet parent)
{
- attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
+ attributes = getAttributeContext().addAttribute(attributes,
+ ResolveAttribute,
+ parent);
}
-
- // AttributeSet interface support
-
+ /**
+ * Returns true
if this element contains the specified
+ * attribute.
+ *
+ * @param name the name of the attribute to check
+ * @param value the value of the attribute to check
+ *
+ * @return true
if this element contains the specified
+ * attribute
+ */
public boolean containsAttribute(Object name, Object value)
{
return attributes.containsAttribute(name, value);
}
+ /**
+ * Returns true
if this element contains all of the
+ * specified attributes.
+ *
+ * @param attrs the attributes to check
+ *
+ * @return true
if this element contains all of the
+ * specified attributes
+ */
public boolean containsAttributes(AttributeSet attrs)
{
return attributes.containsAttributes(attrs);
}
+ /**
+ * Returns a copy of the attributes of this element.
+ *
+ * @return a copy of the attributes of this element
+ */
public AttributeSet copyAttributes()
{
return attributes.copyAttributes();
}
+ /**
+ * Returns the attribute value with the specified key. If this attribute
+ * is not defined in this element and this element has a resolving
+ * parent, the search goes upward to the resolve parent chain.
+ *
+ * @param key the key of the requested attribute
+ *
+ * @return the attribute value for key
of null
+ * if key
is not found locally and cannot be resolved
+ * in this element's resolve parents
+ */
public Object getAttribute(Object key)
{
return attributes.getAttribute(key);
}
+ /**
+ * Returns the number of defined attributes in this element.
+ *
+ * @return the number of defined attributes in this element
+ */
public int getAttributeCount()
{
return attributes.getAttributeCount();
}
-
+
+ /**
+ * Returns the names of the attributes of this element.
+ *
+ * @return the names of the attributes of this element
+ */
public Enumeration getAttributeNames()
{
return attributes.getAttributeNames();
}
-
+
+ /**
+ * Returns the resolve parent of this element.
+ *
+ * @return the resolve parent of this element
+ *
+ * @see #setResolveParent(AttributeSet)
+ */
public AttributeSet getResolveParent()
{
return attributes.getResolveParent();
}
+ /**
+ * Returns true
if an attribute with the specified name
+ * is defined in this element, false
otherwise.
+ *
+ * @param attrName the name of the requested attributes
+ *
+ * @return true
if an attribute with the specified name
+ * is defined in this element, false
otherwise
+ */
public boolean isDefined(Object attrName)
{
return attributes.isDefined(attrName);
}
-
+
+ /**
+ * Returns true
if the specified AttributeSet
+ * is equal to this element's AttributeSet
, false
+ * otherwise.
+ *
+ * @param attrs the attributes to compare this element to
+ *
+ * @return true
if the specified AttributeSet
+ * is equal to this element's AttributeSet
,
+ * false
otherwise
+ */
public boolean isEqual(AttributeSet attrs)
{
return attributes.isEqual(attrs);
}
- // Element interface support
-
+ /**
+ * Returns the attributes of this element.
+ *
+ * @return the attributes of this element
+ */
public AttributeSet getAttributes()
{
- return attributes;
+ return this;
}
+ /**
+ * Returns the {@link Document} to which this element belongs.
+ *
+ * @return the {@link Document} to which this element belongs
+ */
public Document getDocument()
{
return AbstractDocument.this;
}
-
+
+ /**
+ * Returns the child element at the specified index
.
+ *
+ * @param index the index of the requested child element
+ *
+ * @return the requested element
+ */
public abstract Element getElement(int index);
-
+
+ /**
+ * Returns the name of this element.
+ *
+ * @return the name of this element
+ */
public String getName()
{
return (String) getAttribute(NameAttribute);
}
-
+
+ /**
+ * Returns the parent element of this element.
+ *
+ * @return the parent element of this element
+ */
public Element getParentElement()
{
return element_parent;
}
-
+
+ /**
+ * Returns the offset inside the document model that is after the last
+ * character of this element.
+ *
+ * @return the offset inside the document model that is after the last
+ * character of this element
+ */
public abstract int getEndOffset();
-
+
+ /**
+ * Returns the number of child elements of this element.
+ *
+ * @return the number of child elements of this element
+ */
public abstract int getElementCount();
-
+
+ /**
+ * Returns the index of the child element that spans the specified
+ * offset in the document model.
+ *
+ * @param offset the offset for which the responsible element is searched
+ *
+ * @return the index of the child element that spans the specified
+ * offset in the document model
+ */
public abstract int getElementIndex(int offset);
-
+
+ /**
+ * Returns the start offset if this element inside the document model.
+ *
+ * @return the start offset if this element inside the document model
+ */
public abstract int getStartOffset();
- private void dumpElement(PrintStream stream, String indent, Element element)
+ /**
+ * Prints diagnostic information to the specified stream.
+ *
+ * @param stream the stream to dump to
+ * @param indent the indentation level
+ * @param element the element to be dumped
+ */
+ private void dumpElement(PrintStream stream, String indent,
+ Element element)
{
+ // FIXME: Should the method be removed?
System.out.println(indent + "<" + element.getName() +">");
-
+
if (element.isLeaf())
{
int start = element.getStartOffset();
@@ -626,6 +1378,12 @@ public abstract class AbstractDocument
}
catch (BadLocationException e)
{
+ AssertionError error =
+ new AssertionError("BadLocationException should not be "
+ + "thrown here. start = " + start
+ + ", end = " + end);
+ error.initCause(e);
+ throw error;
}
System.out.println(indent + " ["
+ start + ","
@@ -638,7 +1396,13 @@ public abstract class AbstractDocument
dumpElement(stream, indent + " ", element.getElement(i));
}
}
-
+
+ /**
+ * Prints diagnostic output to the specified stream.
+ *
+ * @param stream the stream to write to
+ * @param indent the indentation level
+ */
public void dump(PrintStream stream, int indent)
{
String indentStr = "";
@@ -648,17 +1412,36 @@ public abstract class AbstractDocument
}
}
+ /**
+ * An implementation of {@link Element} to represent composite
+ * Element
s that contain other Element
s.
+ */
public class BranchElement extends AbstractElement
{
+ /** The serial version UID for BranchElement. */
private static final long serialVersionUID = -8595176318868717313L;
-
+
+ /** The child elements of this BranchElement. */
private Element[] children = new Element[0];
+ /**
+ * Creates a new BranchElement
with the specified
+ * parent and attributes.
+ *
+ * @param parent the parent element of this BranchElement
+ * @param attributes the attributes to set on this
+ * BranchElement
+ */
public BranchElement(Element parent, AttributeSet attributes)
{
super(parent, attributes);
}
+ /**
+ * Returns the children of this BranchElement
.
+ *
+ * @return the children of this BranchElement
+ */
public Enumeration children()
{
if (children.length == 0)
@@ -672,11 +1455,25 @@ public abstract class AbstractDocument
return tmp.elements();
}
+ /**
+ * Returns true
since BranchElements
allow
+ * child elements.
+ *
+ * @return true
since BranchElements
allow
+ * child elements
+ */
public boolean getAllowsChildren()
{
return true;
}
+ /**
+ * Returns the child element at the specified index
.
+ *
+ * @param index the index of the requested child element
+ *
+ * @return the requested element
+ */
public Element getElement(int index)
{
if (index < 0 || index >= children.length)
@@ -685,47 +1482,113 @@ public abstract class AbstractDocument
return children[index];
}
+ /**
+ * Returns the number of child elements of this element.
+ *
+ * @return the number of child elements of this element
+ */
public int getElementCount()
{
return children.length;
}
+ /**
+ * Returns the index of the child element that spans the specified
+ * offset in the document model.
+ *
+ * @param offset the offset for which the responsible element is searched
+ *
+ * @return the index of the child element that spans the specified
+ * offset in the document model
+ */
public int getElementIndex(int offset)
{
+ // If we have no children, return -1.
+ if (getElementCount() == 0)
+ return - 1;
+
// XXX: There is surely a better algorithm
// as beginning from first element each time.
for (int index = 0; index < children.length; ++index)
{
- Element elem = children[index];
+ Element elem = children[index];
- if ((elem.getStartOffset() <= offset)
- && (offset < elem.getEndOffset()))
- return index;
+ if ((elem.getStartOffset() <= offset)
+ && (offset < elem.getEndOffset()))
+ return index;
}
- return 0;
+ // If offset is greater than the index of the last element, return
+ // the index of the last element.
+ return getElementCount() - 1;
}
+ /**
+ * Returns the offset inside the document model that is after the last
+ * character of this element.
+ * This is the end offset of the last child element. If this element
+ * has no children, this method throws a NullPointerException
.
+ *
+ * @return the offset inside the document model that is after the last
+ * character of this element
+ *
+ * @throws NullPointerException if this branch element has no children
+ */
public int getEndOffset()
{
+ if (getElementCount() == 0)
+ throw new NullPointerException("This BranchElement has no children.");
return children[children.length - 1].getEndOffset();
}
+ /**
+ * Returns the name of this element. This is {@link #ParagraphElementName}
+ * in this case.
+ *
+ * @return the name of this element
+ */
public String getName()
{
return ParagraphElementName;
}
+ /**
+ * Returns the start offset of this element inside the document model.
+ * This is the start offset of the first child element. If this element
+ * has no children, this method throws a NullPointerException
.
+ *
+ * @return the start offset of this element inside the document model
+ *
+ * @throws NullPointerException if this branch element has no children
+ */
public int getStartOffset()
{
+ if (getElementCount() == 0)
+ throw new NullPointerException("This BranchElement has no children.");
return children[0].getStartOffset();
}
+ /**
+ * Returns false
since BranchElement
are no
+ * leafes.
+ *
+ * @return false
since BranchElement
are no
+ * leafes
+ */
public boolean isLeaf()
{
return false;
}
+ /**
+ * Returns the Element
at the specified Document
+ * offset.
+ *
+ * @return the Element
at the specified Document
+ * offset
+ *
+ * @see #getElementIndex(int)
+ */
public Element positionToElement(int position)
{
// XXX: There is surely a better algorithm
@@ -742,6 +1605,13 @@ public abstract class AbstractDocument
return null;
}
+ /**
+ * Replaces a set of child elements with a new set of child elemens.
+ *
+ * @param offset the start index of the elements to be removed
+ * @param length the number of elements to be removed
+ * @param elements the new elements to be inserted
+ */
public void replace(int offset, int length, Element[] elements)
{
Element[] target = new Element[children.length - length
@@ -754,6 +1624,11 @@ public abstract class AbstractDocument
children = target;
}
+ /**
+ * Returns a string representation of this element.
+ *
+ * @return a string representation of this element
+ */
public String toString()
{
return ("BranchElement(" + getName() + ") "
@@ -761,59 +1636,157 @@ public abstract class AbstractDocument
}
}
+ /**
+ * Stores the changes when a Document
is beeing modified.
+ */
public class DefaultDocumentEvent extends CompoundEdit
implements DocumentEvent
{
+ /** The serial version UID of DefaultDocumentEvent. */
private static final long serialVersionUID = -7406103236022413522L;
-
+
+ /** The starting offset of the change. */
private int offset;
+
+ /** The length of the change. */
private int length;
+
+ /** The type of change. */
private DocumentEvent.EventType type;
+ /**
+ * Maps Element
to their change records.
+ */
+ Hashtable changes;
+
+ /**
+ * Creates a new DefaultDocumentEvent
.
+ *
+ * @param offset the starting offset of the change
+ * @param length the length of the change
+ * @param type the type of change
+ */
public DefaultDocumentEvent(int offset, int length,
DocumentEvent.EventType type)
{
this.offset = offset;
this.length = length;
this.type = type;
+ changes = new Hashtable();
}
+ /**
+ * Adds an UndoableEdit to this DocumentEvent
. If this
+ * edit is an instance of {@link ElementEdit}, then this record can
+ * later be fetched by calling {@link #getChange}.
+ *
+ * @param edit the undoable edit to add
+ */
+ public boolean addEdit(UndoableEdit edit)
+ {
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ if (edit instanceof DocumentEvent.ElementChange)
+ {
+ DocumentEvent.ElementChange elEdit =
+ (DocumentEvent.ElementChange) edit;
+ changes.put(elEdit.getElement(), elEdit);
+ }
+ return super.addEdit(edit);
+ }
+
+ /**
+ * Returns the document that has been modified.
+ *
+ * @return the document that has been modified
+ */
public Document getDocument()
{
return AbstractDocument.this;
}
+ /**
+ * Returns the length of the modification.
+ *
+ * @return the length of the modification
+ */
public int getLength()
{
return length;
}
+ /**
+ * Returns the start offset of the modification.
+ *
+ * @return the start offset of the modification
+ */
public int getOffset()
{
return offset;
}
+ /**
+ * Returns the type of the modification.
+ *
+ * @return the type of the modification
+ */
public DocumentEvent.EventType getType()
{
return type;
}
+ /**
+ * Returns the changes for an element.
+ *
+ * @param elem the element for which the changes are requested
+ *
+ * @return the changes for elem
or null
if
+ * elem
has not been changed
+ */
public DocumentEvent.ElementChange getChange(Element elem)
{
- return null;
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ return (DocumentEvent.ElementChange) changes.get(elem);
}
}
+ /**
+ * An implementation of {@link DocumentEvent.ElementChange} to be added
+ * to {@link DefaultDocumentEvent}s.
+ */
public static class ElementEdit extends AbstractUndoableEdit
implements DocumentEvent.ElementChange
{
+ /** The serial version UID of ElementEdit. */
private static final long serialVersionUID = -1216620962142928304L;
+ /**
+ * The changed element.
+ */
private Element elem;
+
+ /**
+ * The index of the change.
+ */
private int index;
+
+ /**
+ * The removed elements.
+ */
private Element[] removed;
+
+ /**
+ * The added elements.
+ */
private Element[] added;
+ /**
+ * Creates a new ElementEdit
.
+ *
+ * @param elem the changed element
+ * @param index the index of the change
+ * @param removed the removed elements
+ * @param added the added elements
+ */
public ElementEdit(Element elem, int index,
Element[] removed, Element[] added)
{
@@ -823,86 +1796,211 @@ public abstract class AbstractDocument
this.added = added;
}
+ /**
+ * Returns the added elements.
+ *
+ * @return the added elements
+ */
public Element[] getChildrenAdded()
{
return added;
}
-
+
+ /**
+ * Returns the removed elements.
+ *
+ * @return the removed elements
+ */
public Element[] getChildrenRemoved()
{
return removed;
}
+ /**
+ * Returns the changed element.
+ *
+ * @return the changed element
+ */
public Element getElement()
{
return elem;
}
+ /**
+ * Returns the index of the change.
+ *
+ * @return the index of the change
+ */
public int getIndex()
{
return index;
}
}
+ /**
+ * An implementation of {@link Element} that represents a leaf in the
+ * document structure. This is used to actually store content.
+ */
public class LeafElement extends AbstractElement
{
+ /** The serial version UID of LeafElement. */
private static final long serialVersionUID = 5115368706941283802L;
- int start;
- int end;
+ /** Manages the start offset of this element. */
+ Position startPos;
+
+ /** Manages the end offset of this element. */
+ Position endPos;
+
+ /**
+ * Creates a new LeafElement
.
+ *
+ * @param parent the parent of this LeafElement
+ * @param attributes the attributes to be set
+ * @param start the start index of this element inside the document model
+ * @param end the end index of this element inside the document model
+ */
public LeafElement(Element parent, AttributeSet attributes, int start,
int end)
{
super(parent, attributes);
- this.start = start;
- this.end = end;
+ {
+ try
+ {
+ if (parent != null)
+ {
+ startPos = parent.getDocument().createPosition(start);
+ endPos = parent.getDocument().createPosition(end);
+ }
+ else
+ {
+ startPos = createPosition(start);
+ endPos = createPosition(end);
+ }
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError as;
+ as = new AssertionError("BadLocationException thrown "
+ + "here. start=" + start
+ + ", end=" + end
+ + ", length=" + getLength());
+ as.initCause(ex);
+ throw as;
+ }
+ }
}
+ /**
+ * Returns null
since LeafElement
s cannot have
+ * children.
+ *
+ * @return null
since LeafElement
s cannot have
+ * children
+ */
public Enumeration children()
{
return null;
}
+ /**
+ * Returns false
since LeafElement
s cannot have
+ * children.
+ *
+ * @return false
since LeafElement
s cannot have
+ * children
+ */
public boolean getAllowsChildren()
{
return false;
}
+ /**
+ * Returns null
since LeafElement
s cannot have
+ * children.
+ *
+ * @return null
since LeafElement
s cannot have
+ * children
+ */
public Element getElement(int index)
{
return null;
}
+ /**
+ * Returns 0
since LeafElement
s cannot have
+ * children.
+ *
+ * @return 0
since LeafElement
s cannot have
+ * children
+ */
public int getElementCount()
{
return 0;
}
+ /**
+ * Returns -1
since LeafElement
s cannot have
+ * children.
+ *
+ * @return -1
since LeafElement
s cannot have
+ * children
+ */
public int getElementIndex(int offset)
{
return -1;
}
+ /**
+ * Returns the end offset of this Element
inside the
+ * document.
+ *
+ * @return the end offset of this Element
inside the
+ * document
+ */
public int getEndOffset()
{
- return end;
+ return endPos.getOffset();
}
+ /**
+ * Returns the name of this Element
. This is
+ * {@link #ContentElementName} in this case.
+ *
+ * @return the name of this Element
+ */
public String getName()
{
return ContentElementName;
}
+ /**
+ * Returns the start offset of this Element
inside the
+ * document.
+ *
+ * @return the start offset of this Element
inside the
+ * document
+ */
public int getStartOffset()
{
- return start;
+ return startPos.getOffset();
}
+ /**
+ * Returns true
.
+ *
+ * @return true
+ */
public boolean isLeaf()
{
return true;
}
+ /**
+ * Returns a string representation of this Element
.
+ *
+ * @return a string representation of this Element
+ */
public String toString()
{
return ("LeafElement(" + getName() + ") "
diff --git a/libjava/classpath/javax/swing/text/AttributeSet.java b/libjava/classpath/javax/swing/text/AttributeSet.java
index 87e7b98..2f1f189 100644
--- a/libjava/classpath/javax/swing/text/AttributeSet.java
+++ b/libjava/classpath/javax/swing/text/AttributeSet.java
@@ -1,5 +1,5 @@
/* AttributeSet.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,34 +39,153 @@ package javax.swing.text;
import java.util.Enumeration;
+/**
+ * A set of attributes. An attribute has a key and a value. They typically
+ * describe features of a piece of text that make up its graphical
+ * representation.
+ *
+ * An AttributeSet
may have a resolving parent,
+ * that is another AttributeSet
that is searched for attribute
+ * keys that are not stored locally in this AttributeSet
.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public interface AttributeSet
{
+ /**
+ * Used as keys to identify character-run attributes.
+ */
static interface CharacterAttribute
{
}
+ /**
+ * Used as keys to identify color attributes.
+ */
static interface ColorAttribute
{
}
+ /**
+ * Used as keys to identify font attributes.
+ */
static interface FontAttribute
{
}
+ /**
+ * Used as keys to identify paragraph level attributes.
+ */
static interface ParagraphAttribute
{
}
+ /**
+ * Key of the attribute that is used to describe the name of an
+ * AttributeSet
.
+ */
Object NameAttribute = StyleConstants.NameAttribute;
+
+ /**
+ * Key of the attribute that is used to identify the resolving parent of
+ * an AttributeSet
.
+ */
Object ResolveAttribute = StyleConstants.ResolveAttribute;
+ /**
+ * Returns true
if this AttributeSet
contains
+ * an attribute with the specified name
and value
,
+ * false
otherwise.
+ *
+ * @param name the name of the requested attribute
+ * @param the value of the requested attribute
+ *
+ * @return true
if this AttributeSet
contains
+ * an attribute with the specified name
and
+ * value
, false
otherwise
+ */
boolean containsAttribute(Object name, Object value);
+
+ /**
+ * Returns true
of this AttributeSet
contains all
+ * of the specified attributes
.
+ *
+ * @param attributes the requested attributes
+ *
+ * @return true
of this AttributeSet
contains all
+ * of the specified attributes
+ */
boolean containsAttributes(AttributeSet attributes);
+
+ /**
+ * Creates and returns a copy of this AttributeSet
.
+ *
+ * @return a copy of this AttributeSet
+ */
AttributeSet copyAttributes();
+
+ /**
+ * Returns the attribute with the specified key
or
+ * null
if no such attribute is defined in this
+ * AttributeSet
and its resolving parents.
+ *
+ * @param key the key of the attribute that is looked up
+ *
+ * @return the attribute with the specified key
or
+ * null
if no such attribute is defined in this
+ * AttributeSet
and its resolving parents
+ */
Object getAttribute(Object key);
+
+ /**
+ * Returns the number of attributes that are stored locally in this
+ * AttributeSet
.
+ *
+ * @return the number of attributes that are stored locally in this
+ * AttributeSet
+ */
int getAttributeCount();
+
+ /**
+ * Returns the names of the attributes that are stored in this
+ * AttributeSet
.
+ *
+ * @return the names of the attributes that are stored in this
+ * AttributeSet
+ */
Enumeration getAttributeNames();
+
+ /**
+ * Returns the resolving parent of this AttributeSet
.
+ * If a key is not stored locally, then a {@link #getAttribute(Object)}
+ * request is resolved up in the resolving parent of this
+ * AttributeSet
.
+ *
+ * @return the resolving parent of this AttributeSet
+ */
AttributeSet getResolveParent();
+
+ /**
+ * Returns true
if an attribute with the specified name is
+ * defined locally in this AttributeSet
, without resolving
+ * through the resolving parents.
+ *
+ * @return true
if an attribute with the specified name is
+ * defined locally in this AttributeSet
+ */
boolean isDefined(Object attrName);
+
+ /**
+ * Returns true
if all of the attributes in attr
+ * are equal to the attributes in this AttributeSet
,
+ * false
otherwise.
+ *
+ * @param attr the attributes to be compared to this
+ *
+ * @return true
if all of the attributes in attr
+ * are equal to the attributes in this AttributeSet
,
+ * false
otherwise
+ */
boolean isEqual(AttributeSet attr);
}
diff --git a/libjava/classpath/javax/swing/text/BadLocationException.java b/libjava/classpath/javax/swing/text/BadLocationException.java
index e1a2ebc..7059140 100644
--- a/libjava/classpath/javax/swing/text/BadLocationException.java
+++ b/libjava/classpath/javax/swing/text/BadLocationException.java
@@ -1,5 +1,5 @@
/* BadLocationException.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,17 +37,28 @@ exception statement from your version. */
package javax.swing.text;
+/**
+ * Indicates that an invalid location within a Document
has been
+ * accessed.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class BadLocationException extends Exception
{
+ /** The serial version UID for BadLocationException. */
private static final long serialVersionUID = -7712259886815656766L;
-
+
+ /**
+ * The invalid location.
+ */
int offset;
/**
* Constructs a BadLocationException
*
- * @param str A string indicating what was wrong with the arguments
- * @param offset Offset within the document that was requested >= 0
+ * @param str a string indicating what was wrong with the arguments
+ * @param offset offset within the document that was requested >= 0
*/
public BadLocationException(String str, int offset)
{
@@ -56,7 +67,9 @@ public class BadLocationException extends Exception
}
/**
- * Returns the offset into the document that was not legal
+ * Returns the offset into the document that was not legal.
+ *
+ * @return the offset into the document that was not legal
*/
public int offsetRequested()
{
diff --git a/libjava/classpath/javax/swing/text/Caret.java b/libjava/classpath/javax/swing/text/Caret.java
index 46072ef..d641190 100644
--- a/libjava/classpath/javax/swing/text/Caret.java
+++ b/libjava/classpath/javax/swing/text/Caret.java
@@ -1,5 +1,5 @@
/* Caret.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,39 +43,165 @@ import java.awt.Point;
import javax.swing.event.ChangeListener;
+/**
+ * Defines the method to be implemented by a caret that can be used in Swing
+ * text components.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public interface Caret
{
+ /**
+ * Registers a {@link ChangeListener} that is notified whenever that state
+ * of this Caret
changes.
+ *
+ * @param l the listener to register to this caret
+ */
void addChangeListener(ChangeListener l);
+
+ /**
+ * Removes a {@link ChangeListener} from the list of registered listeners.
+ *
+ * @param l the listener to remove
+ */
+ void removeChangeListener(ChangeListener l);
+
+ /**
+ * Installs this Caret
on the specified text component. This
+ * usually involves setting up listeners.
+ *
+ * This method is called by {@link JTextComponent#setCaret(Caret)} after
+ * this caret has been set on the text component.
+ *
+ * @param c the text component to install this caret to
+ */
+ void install(JTextComponent c);
+ /**
+ * Deinstalls this Caret
from the specified text component.
+ * This usually involves removing listeners from the text component.
+ *
+ * This method is called by {@link JTextComponent#setCaret(Caret)} before
+ * this caret is removed from the text component.
+ *
+ * @param c the text component to deinstall this caret from
+ */
void deinstall(JTextComponent c);
-
+
+ /**
+ * Returns the blink rate of this Caret
in milliseconds.
+ * A value of 0
means that the caret does not blink.
+ *
+ * @return the blink rate of this Caret
or 0
if
+ * this caret does not blink
+ */
int getBlinkRate();
+
+ /**
+ * Sets the blink rate of this Caret
in milliseconds.
+ * A value of 0
means that the caret does not blink.
+ *
+ * @param rate the new blink rate to set
+ */
+ void setBlinkRate(int rate);
+ /**
+ * Returns the current position of this Caret
within the
+ * Document
.
+ *
+ * @return the current position of this Caret
within the
+ * Document
+ */
int getDot();
+
+ /**
+ * Sets the current position of this Caret
within the
+ * Document
. This also sets the mark
to the
+ * new location.
+ *
+ * @param dot the new position to be set
+ *
+ * @see #moveDot(int)
+ */
+ void setDot(int dot);
- Point getMagicCaretPosition();
-
- int getMark();
-
- void install(JTextComponent c);
-
- boolean isSelectionVisible();
-
- boolean isVisible();
-
+ /**
+ * Moves the dot
location without touching the
+ * mark
. This is used when making a selection.
+ *
+ * @param dot the location where to move the dot
+ *
+ * @see #setDot(int)
+ */
void moveDot(int dot);
- void paint(Graphics g);
-
- void removeChangeListener(ChangeListener l);
-
- void setBlinkRate(int rate);
-
- void setDot(int dot);
+ /**
+ * Returns the current position of the mark
. The
+ * mark
marks the location in the Document
that
+ * is the end of a selection. If there is no selection, the mark
+ * is the same as the dot
.
+ *
+ * @return the current position of the mark
+ */
+ int getMark();
+ /**
+ * Returns the current visual position of this Caret
.
+ *
+ * @return the current visual position of this Caret
+ *
+ * @see #setMagicCaretPosition
+ */
+ Point getMagicCaretPosition();
+
+ /**
+ * Sets the current visual position of this Caret
.
+ *
+ * @param p the Point to use for the saved location. May be null
+ * to indicate that there is no visual location
+ */
void setMagicCaretPosition(Point p);
-
+
+ /**
+ * Returns true
if the selection is currently visible,
+ * false
otherwise.
+ *
+ * @return true
if the selection is currently visible,
+ * false
otherwise
+ */
+ boolean isSelectionVisible();
+
+ /**
+ * Sets the visiblity state of the selection.
+ *
+ * @param v true
if the selection should be visible,
+ * false
otherwise
+ */
void setSelectionVisible(boolean v);
-
+
+ /**
+ * Returns true
if this Caret
is currently visible,
+ * and false
if it is not.
+ *
+ * @return true
if this Caret
is currently visible,
+ * and false
if it is not
+ */
+ boolean isVisible();
+
+ /**
+ * Sets the visibility state of the caret. true
shows the
+ * Caret
, false
hides it.
+ *
+ * @param v the visibility to set
+ */
void setVisible(boolean v);
+
+ /**
+ * Paints this Caret
to the specified Graphics
+ * context.
+ *
+ * @param g the graphics context to render to
+ */
+ void paint(Graphics g);
}
diff --git a/libjava/classpath/javax/swing/text/ComponentView.java b/libjava/classpath/javax/swing/text/ComponentView.java
index 744d537..f6feda2 100644
--- a/libjava/classpath/javax/swing/text/ComponentView.java
+++ b/libjava/classpath/javax/swing/text/ComponentView.java
@@ -100,4 +100,22 @@ public class ComponentView extends View
{
return 0;
}
+
+ /**
+ * Maps coordinates from the View
's space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this View
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates x, y
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias b)
+ {
+ // FIXME: Implement this properly.
+ return 0;
+ }
}
diff --git a/libjava/classpath/javax/swing/text/DateFormatter.java b/libjava/classpath/javax/swing/text/DateFormatter.java
index 0e20b77..869f9a0 100644
--- a/libjava/classpath/javax/swing/text/DateFormatter.java
+++ b/libjava/classpath/javax/swing/text/DateFormatter.java
@@ -54,7 +54,7 @@ public class DateFormatter extends InternationalFormatter
/**
* Creates a new instance using the default {@link DateFormat} object
- * returned by {@link DateFormat#getDateInstance}.
+ * returned by {@link DateFormat#getDateInstance()}.
*/
public DateFormatter()
{
diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java
index b57b365..33c3ae3 100644
--- a/libjava/classpath/javax/swing/text/DefaultCaret.java
+++ b/libjava/classpath/javax/swing/text/DefaultCaret.java
@@ -1,5 +1,5 @@
/* DefaultCaret.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -51,69 +51,203 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
-
+/**
+ * The default implementation of the {@link Caret} interface.
+ *
+ * @author orgininal author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class DefaultCaret extends Rectangle
implements Caret, FocusListener, MouseListener, MouseMotionListener
{
+ /**
+ * The serial version UID for DefaultCaret.
+ */
private static final long serialVersionUID = 228155774675466193L;
-
+
+ /**
+ * The ChangeEvent
that is fired by {@link #fireStateChanged()}.
+ */
protected ChangeEvent changeEvent = new ChangeEvent(this);
+
+ /**
+ * Stores all registered event listeners.
+ */
protected EventListenerList listenerList = new EventListenerList();
-
+
+ /**
+ * The text component in which this caret is installed.
+ */
private JTextComponent textComponent;
-
+
+ /**
+ * Indicates if the selection should be visible or not.
+ */
private boolean selectionVisible = true;
+
+ /**
+ * The blink rate of this Caret
.
+ */
private int blinkRate = 500;
+
+ /**
+ * The current dot position.
+ */
private int dot = 0;
+
+ /**
+ * The current mark position.
+ */
private int mark = 0;
+
+ /**
+ * The current visual caret position.
+ */
private Point magicCaretPosition = null;
+
+ /**
+ * Indicates if this Caret
is currently visible or not.
+ */
private boolean visible = true;
+
+ /**
+ * The current highlight entry.
+ */
private Object highlightEntry;
+ /**
+ * Moves the caret position when the mouse is dragged over the text
+ * component, modifying the selection accordingly.
+ *
+ * @param event the MouseEvent
describing the drag operation
+ */
public void mouseDragged(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates a mouse movement over the text component. Does nothing here.
+ *
+ * @param event the MouseEvent
describing the mouse operation
+ */
public void mouseMoved(MouseEvent event)
{
- }
-
+ // Nothing to do here.
+ }
+
+ /**
+ * When the click is received from Button 1 then the following actions
+ * are performed here:
+ *
+ *
+ *
+ *
+ * @param event the MouseEvent
describing the click operation
+ */
public void mouseClicked(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates that the mouse has entered the text component. Nothing is done
+ * here.
+ *
+ * @param event the MouseEvent
describing the mouse operation
+ */
public void mouseEntered(MouseEvent event)
{
+ // Nothing to do here.
}
+ /**
+ * Indicates that the mouse has exited the text component. Nothing is done
+ * here.
+ *
+ * @param event the MouseEvent
describing the mouse operation
+ */
public void mouseExited(MouseEvent event)
{
}
+ /**
+ * If the button 1 is pressed, the caret position is updated to the
+ * position of the mouse click and the text component requests the input
+ * focus if it is enabled. If the SHIFT key is held down, the caret will
+ * be moved, which might select the text between the old and new location.
+ *
+ * @param event the MouseEvent
describing the press operation
+ */
public void mousePressed(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Indicates that a mouse button has been released on the text component.
+ * Nothing is done here.
+ *
+ * @param event the MouseEvent
describing the mouse operation
+ */
public void mouseReleased(MouseEvent event)
{
+ // Nothing to do here.
}
+ /**
+ * Sets the caret to visible
if the text component is editable.
+ *
+ * @param event the FocusEvent
+ */
public void focusGained(FocusEvent event)
{
}
+ /**
+ * Sets the caret to invisible
.
+ *
+ * @param event the FocusEvent
+ */
public void focusLost(FocusEvent event)
{
}
+ /**
+ * Moves the caret to the position specified in the MouseEvent
.
+ * This will cause a selection if the dot and mark are different.
+ *
+ * @param event the MouseEvent
from which to fetch the position
+ */
protected void moveCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Repositions the caret to the position specified in the
+ * MouseEvent
.
+ *
+ * @param event the MouseEvent
from which to fetch the position
+ */
protected void positionCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Deinstalls this Caret
from the specified
+ * JTextComponent
. This removes any listeners that have been
+ * registered by this Caret
.
+ *
+ * @param c the text component from which to install this caret
+ */
public void deinstall(JTextComponent c)
{
textComponent.removeFocusListener(this);
@@ -122,6 +256,13 @@ public class DefaultCaret extends Rectangle
textComponent = null;
}
+ /**
+ * Installs this Caret
on the specified
+ * JTextComponent
. This registers a couple of listeners
+ * on the text component.
+ *
+ * @param c the text component on which to install this caret
+ */
public void install(JTextComponent c)
{
textComponent = c;
@@ -131,16 +272,37 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Sets the current visual position of this Caret
.
+ *
+ * @param p the Point to use for the saved location. May be null
+ * to indicate that there is no visual location
+ */
public void setMagicCaretPosition(Point p)
{
magicCaretPosition = p;
}
+ /**
+ * Returns the current visual position of this Caret
.
+ *
+ * @return the current visual position of this Caret
+ *
+ * @see #setMagicCaretPosition
+ */
public Point getMagicCaretPosition()
{
return magicCaretPosition;
}
+ /**
+ * Returns the current position of the mark
. The
+ * mark
marks the location in the Document
that
+ * is the end of a selection. If there is no selection, the mark
+ * is the same as the dot
.
+ *
+ * @return the current position of the mark
+ */
public int getMark()
{
return mark;
@@ -181,6 +343,12 @@ public class DefaultCaret extends Rectangle
}
}
+ /**
+ * Sets the visiblity state of the selection.
+ *
+ * @param v true
if the selection should be visible,
+ * false
otherwise
+ */
public void setSelectionVisible(boolean v)
{
if (selectionVisible == v)
@@ -191,17 +359,35 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Returns true
if the selection is currently visible,
+ * false
otherwise.
+ *
+ * @return true
if the selection is currently visible,
+ * false
otherwise
+ */
public boolean isSelectionVisible()
{
return selectionVisible;
}
+ /**
+ * Causes the Caret
to repaint itself.
+ */
protected final void repaint()
{
+ // FIXME: Is this good? This possibly causes alot of the component
+ // hierarchy to be repainted on every caret blink.
if (textComponent != null)
textComponent.repaint();
}
+ /**
+ * Paints this Caret
using the specified Graphics
+ * context.
+ *
+ * @param g the graphics context to use
+ */
public void paint(Graphics g)
{
if (textComponent == null)
@@ -234,26 +420,53 @@ public class DefaultCaret extends Rectangle
}
}
+ /**
+ * Returns all registered event listeners of the specified type.
+ *
+ * @param listenerType the type of listener to return
+ *
+ * @return all registered event listeners of the specified type
+ */
public EventListener[] getListeners(Class listenerType)
{
return listenerList.getListeners(listenerType);
}
+ /**
+ * Registers a {@link ChangeListener} that is notified whenever that state
+ * of this Caret
changes.
+ *
+ * @param listener the listener to register to this caret
+ */
public void addChangeListener(ChangeListener listener)
{
listenerList.add(ChangeListener.class, listener);
}
+ /**
+ * Removes a {@link ChangeListener} from the list of registered listeners.
+ *
+ * @param listener the listener to remove
+ */
public void removeChangeListener(ChangeListener listener)
{
listenerList.remove(ChangeListener.class, listener);
}
+ /**
+ * Returns all registered {@link ChangeListener}s of this Caret
.
+ *
+ * @return all registered {@link ChangeListener}s of this Caret
+ */
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) getListeners(ChangeListener.class);
}
+ /**
+ * Notifies all registered {@link ChangeListener}s that the state
+ * of this Caret
has changed.
+ */
protected void fireStateChanged()
{
ChangeListener[] listeners = getChangeListeners();
@@ -262,26 +475,61 @@ public class DefaultCaret extends Rectangle
listeners[index].stateChanged(changeEvent);
}
+ /**
+ * Returns the JTextComponent
on which this Caret
+ * is installed.
+ *
+ * @return the JTextComponent
on which this Caret
+ * is installed
+ */
protected final JTextComponent getComponent()
{
return textComponent;
}
-
+
+ /**
+ * Returns the blink rate of this Caret
in milliseconds.
+ * A value of 0
means that the caret does not blink.
+ *
+ * @return the blink rate of this Caret
or 0
if
+ * this caret does not blink
+ */
public int getBlinkRate()
{
return blinkRate;
}
+ /**
+ * Sets the blink rate of this Caret
in milliseconds.
+ * A value of 0
means that the caret does not blink.
+ *
+ * @param rate the new blink rate to set
+ */
public void setBlinkRate(int rate)
{
blinkRate = rate;
}
+ /**
+ * Returns the current position of this Caret
within the
+ * Document
.
+ *
+ * @return the current position of this Caret
within the
+ * Document
+ */
public int getDot()
{
return dot;
}
+ /**
+ * Moves the dot
location without touching the
+ * mark
. This is used when making a selection.
+ *
+ * @param dot the location where to move the dot
+ *
+ * @see #setDot(int)
+ */
public void moveDot(int dot)
{
this.dot = dot;
@@ -289,6 +537,15 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Sets the current position of this Caret
within the
+ * Document
. This also sets the mark
to the
+ * new location.
+ *
+ * @param dot the new position to be set
+ *
+ * @see #moveDot(int)
+ */
public void setDot(int dot)
{
this.dot = dot;
@@ -297,17 +554,37 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Returns true
if this Caret
is currently visible,
+ * and false
if it is not.
+ *
+ * @return true
if this Caret
is currently visible,
+ * and false
if it is not
+ */
public boolean isVisible()
{
return visible;
}
+ /**
+ * Sets the visibility state of the caret. true
shows the
+ * Caret
, false
hides it.
+ *
+ * @param v the visibility to set
+ */
public void setVisible(boolean v)
{
visible = v;
repaint();
}
+ /**
+ * Returns the {@link Highlighter.HighlightPainter} that should be used
+ * to paint the selection.
+ *
+ * @return the {@link Highlighter.HighlightPainter} that should be used
+ * to paint the selection
+ */
protected Highlighter.HighlightPainter getSelectionPainter()
{
return DefaultHighlighter.DefaultPainter;
diff --git a/libjava/classpath/javax/swing/text/DefaultEditorKit.java b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
index aa2fbe85..a14f3ff 100644
--- a/libjava/classpath/javax/swing/text/DefaultEditorKit.java
+++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java
@@ -51,44 +51,135 @@ import java.io.Writer;
import javax.swing.Action;
+/**
+ * The default implementation of {@link EditorKit}. This EditorKit
+ * a plain text Document
and several commands that together
+ * make up a basic editor, like cut / copy + paste.
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class DefaultEditorKit extends EditorKit
{
+ /**
+ * Creates a beep on the PC speaker.
+ *
+ * @see Toolkit#beep()
+ */
public static class BeepAction
extends TextAction
{
+ /**
+ * Creates a new BeepAction
.
+ */
public BeepAction()
{
super(beepAction);
}
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
Toolkit.getDefaultToolkit().beep();
}
}
+ /**
+ * Copies the selected content into the system clipboard.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CutAction
+ * @see PasteAction
+ */
public static class CopyAction
extends TextAction
{
+
+ /**
+ * Create a new CopyAction
.
+ */
public CopyAction()
{
super(copyAction);
}
+
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
}
}
+
+ /**
+ * Copies the selected content into the system clipboard and deletes the
+ * selection.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CopyAction
+ * @see PasteAction
+ */
public static class CutAction
extends TextAction
{
+
+ /**
+ * Create a new CutAction
.
+ */
public CutAction()
{
super(cutAction);
}
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
+ }
+ }
+
+ /**
+ * Copies content from the system clipboard into the editor.
+ *
+ * @see Toolkit#getSystemClipboard()
+ * @see CopyAction
+ * @see CutAction
+ */
+ public static class PasteAction
+ extends TextAction
+ {
+
+ /**
+ * Create a new PasteAction
.
+ */
+ public PasteAction()
+ {
+ super(pasteAction);
+ }
+
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ // FIXME: Implement me. Tookit.getSystemClipboard should be used
+ // for that.
}
}
@@ -99,17 +190,26 @@ public class DefaultEditorKit extends EditorKit
* the control characters and characters with the ALT-modifier.
*
* If an event does not get filtered, it is inserted into the document
- * of the text component. If there is some text selected in the text component,
- * this text will be replaced.
+ * of the text component. If there is some text selected in the text
+ * component, this text will be replaced.
*/
public static class DefaultKeyTypedAction
extends TextAction
{
+
+ /**
+ * Creates a new DefaultKeyTypedAction
.
+ */
public DefaultKeyTypedAction()
{
super(defaultKeyTypedAction);
}
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
// first we filter the following events:
@@ -124,9 +224,11 @@ public class DefaultEditorKit extends EditorKit
{
try
{
- t.getDocument().insertString(t.getCaret().getDot(), event.getActionCommand(), null);
+ t.getDocument().insertString(t.getCaret().getDot(),
+ event.getActionCommand(), null);
t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
- t.getDocument().getEndPosition().getOffset()));
+ t.getDocument().getEndPosition()
+ .getOffset()));
}
catch (BadLocationException be)
{
@@ -144,11 +246,20 @@ public class DefaultEditorKit extends EditorKit
public static class InsertBreakAction
extends TextAction
{
+
+ /**
+ * Creates a new InsertBreakAction
.
+ */
public InsertBreakAction()
{
super(insertBreakAction);
}
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
@@ -156,101 +267,446 @@ public class DefaultEditorKit extends EditorKit
}
}
+ /**
+ * Places content into the associated editor. If there currently is a
+ * selection, this selection is replaced.
+ */
+ // FIXME: Figure out what this Action is supposed to do. Obviously text
+ // that is entered by the user is inserted through DefaultKeyTypedAction.
public static class InsertContentAction
extends TextAction
{
+
+ /**
+ * Creates a new InsertContentAction
.
+ */
public InsertContentAction()
{
super(insertContentAction);
}
+
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
}
}
+ /**
+ * Inserts a TAB character into the text editor.
+ */
public static class InsertTabAction
extends TextAction
{
+
+ /**
+ * Creates a new TabAction
.
+ */
public InsertTabAction()
{
super(insertTabAction);
}
+ /**
+ * Performs the Action
.
+ *
+ * @param event the action event describing the user action
+ */
public void actionPerformed(ActionEvent event)
{
+ // FIXME: Implement this.
}
}
- public static class PasteAction
- extends TextAction
- {
- public PasteAction()
- {
- super(pasteAction);
- }
-
- public void actionPerformed(ActionEvent event)
- {
- }
- }
-
+ /**
+ * The serial version of DefaultEditorKit.
+ */
private static final long serialVersionUID = 9017245433028523428L;
-
+
+ /**
+ * The name of the Action
that moves the caret one character
+ * backwards.
+ *
+ * @see #getActions()
+ */
public static final String backwardAction = "caret-backward";
+
+ /**
+ * The name of the Action
that creates a beep in the speaker.
+ *
+ * @see #getActions()
+ */
public static final String beepAction = "beep";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the Document
.
+ *
+ * @see #getActions()
+ */
public static final String beginAction = "caret-begin";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current line.
+ *
+ * @see #getActions()
+ */
public static final String beginLineAction = "caret-begin-line";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current paragraph.
+ *
+ * @see #getActions()
+ */
public static final String beginParagraphAction = "caret-begin-paragraph";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current word.
+ *
+ * @see #getActions()
+ */
public static final String beginWordAction = "caret-begin-word";
+
+ /**
+ * The name of the Action
that copies the selected content
+ * into the system clipboard.
+ *
+ * @see #getActions()
+ */
public static final String copyAction = "copy-to-clipboard";
+
+ /**
+ * The name of the Action
that copies the selected content
+ * into the system clipboard and removes the selection.
+ *
+ * @see #getActions()
+ */
public static final String cutAction = "cut-to-clipboard";
+
+ /**
+ * The name of the Action
that is performed by default if
+ * a key is typed and there is no keymap entry.
+ *
+ * @see #getActions()
+ */
public static final String defaultKeyTypedAction = "default-typed";
+
+ /**
+ * The name of the Action
that deletes the character that
+ * follows the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deleteNextCharAction = "delete-next";
+
+ /**
+ * The name of the Action
that deletes the character that
+ * precedes the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deletePrevCharAction = "delete-previous";
+
+ /**
+ * The name of the Action
that moves the caret one line down.
+ *
+ * @see #getActions()
+ */
public static final String downAction = "caret-down";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the Document
.
+ *
+ * @see #getActions()
+ */
public static final String endAction = "caret-end";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current line.
+ *
+ * @see #getActions()
+ */
public static final String endLineAction = "caret-end-line";
+
+ /**
+ * When a document is read and an CRLF is encountered, then we add a property
+ * with this name and a value of "\r\n".
+ */
public static final String EndOfLineStringProperty = "__EndOfLine__";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current paragraph.
+ *
+ * @see #getActions()
+ */
public static final String endParagraphAction = "caret-end-paragraph";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current word.
+ *
+ * @see #getActions()
+ */
public static final String endWordAction = "caret-end-word";
+
+ /**
+ * The name of the Action
that moves the caret one character
+ * forward.
+ *
+ * @see #getActions()
+ */
public static final String forwardAction = "caret-forward";
+
+ /**
+ * The name of the Action
that inserts a line break.
+ *
+ * @see #getActions()
+ */
public static final String insertBreakAction = "insert-break";
+
+ /**
+ * The name of the Action
that inserts some content.
+ *
+ * @see #getActions()
+ */
public static final String insertContentAction = "insert-content";
+
+ /**
+ * The name of the Action
that inserts a TAB.
+ *
+ * @see #getActions()
+ */
public static final String insertTabAction = "insert-tab";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the next word.
+ *
+ * @see #getActions()
+ */
public static final String nextWordAction = "caret-next-word";
+
+ /**
+ * The name of the Action
that moves the caret one page down.
+ *
+ * @see #getActions()
+ */
public static final String pageDownAction = "page-down";
+
+ /**
+ * The name of the Action
that moves the caret one page up.
+ *
+ * @see #getActions()
+ */
public static final String pageUpAction = "page-up";
+
+ /**
+ * The name of the Action
that copies content from the system
+ * clipboard into the document.
+ *
+ * @see #getActions()
+ */
public static final String pasteAction = "paste-from-clipboard";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the previous word.
+ *
+ * @see #getActions()
+ */
public static final String previousWordAction = "caret-previous-word";
+
+ /**
+ * The name of the Action
that sets the editor in read only
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String readOnlyAction = "set-read-only";
+
+ /**
+ * The name of the Action
that selects the whole document.
+ *
+ * @see #getActions()
+ */
public static final String selectAllAction = "select-all";
+
+ /**
+ * The name of the Action
that moves the caret one character
+ * backwards, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBackwardAction = "selection-backward";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the document, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginAction = "selection-begin";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current line, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginLineAction = "selection-begin-line";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current paragraph, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginParagraphAction =
"selection-begin-paragraph";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the current word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionBeginWordAction = "selection-begin-word";
+
+ /**
+ * The name of the Action
that moves the caret one line down,
+ * possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionDownAction = "selection-down";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the document, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndAction = "selection-end";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current line, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndLineAction = "selection-end-line";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current paragraph, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndParagraphAction =
"selection-end-paragraph";
+
+ /**
+ * The name of the Action
that moves the caret to the end
+ * of the current word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionEndWordAction = "selection-end-word";
+
+ /**
+ * The name of the Action
that moves the caret one character
+ * forwards, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionForwardAction = "selection-forward";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the next word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionNextWordAction = "selection-next-word";
+
+ /**
+ * The name of the Action
that moves the caret to the beginning
+ * of the previous word, possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionPreviousWordAction =
"selection-previous-word";
+
+ /**
+ * The name of the Action
that moves the caret one line up,
+ * possibly extending the current selection.
+ *
+ * @see #getActions()
+ */
public static final String selectionUpAction = "selection-up";
+
+ /**
+ * The name of the Action
that selects the line around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectLineAction = "select-line";
+
+ /**
+ * The name of the Action
that selects the paragraph around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectParagraphAction = "select-paragraph";
+
+ /**
+ * The name of the Action
that selects the word around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectWordAction = "select-word";
+
+ /**
+ * The name of the Action
that moves the caret one line up.
+ *
+ * @see #getActions()
+ */
public static final String upAction = "caret-up";
+
+ /**
+ * The name of the Action
that sets the editor in read-write
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String writableAction = "set-writable";
+ /**
+ * Creates a new DefaultEditorKit
.
+ */
public DefaultEditorKit()
{
}
+ /**
+ * The Action
s that are supported by the
+ * DefaultEditorKit
.
+ */
+ // TODO: All these inner classes look ugly. Maybe work out a better way
+ // to handle this.
private static Action[] defaultActions =
new Action[] {
new BeepAction(),
@@ -356,37 +812,98 @@ public class DefaultEditorKit extends EditorKit
},
};
+ /**
+ * Creates the Caret
for this EditorKit
. This
+ * returns a {@link DefaultCaret} in this case.
+ *
+ * @return the Caret
for this EditorKit
+ */
public Caret createCaret()
{
return new DefaultCaret();
}
+ /**
+ * Creates the default {@link Document} that this EditorKit
+ * supports. This is a {@link PlainDocument} in this case.
+ *
+ * @return the default {@link Document} that this EditorKit
+ * supports
+ */
public Document createDefaultDocument()
{
return new PlainDocument();
}
-
+
+ /**
+ * Returns the Action
s supported by this EditorKit
.
+ *
+ * @return the Action
s supported by this EditorKit
+ */
public Action[] getActions()
{
return defaultActions;
}
+ /**
+ * Returns the content type that this EditorKit
supports.
+ * The DefaultEditorKit
supports the content type
+ * text/plain
.
+ *
+ * @return the content type that this EditorKit
supports
+ */
public String getContentType()
{
return "text/plain";
}
-
+
+ /**
+ * Returns a {@link ViewFactory} that is able to create {@link View}s for
+ * the Element
s that are used in this EditorKit
's
+ * model. This returns null which lets the UI of the text component supply
+ * View
s.
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s for
+ * the Element
s that are used in this
+ * EditorKit
's model
+ */
public ViewFactory getViewFactory()
{
return null;
}
+ /**
+ * Reads a document of the supported content type from an {@link InputStream}
+ * into the actual {@link Document} object.
+ *
+ * @param in the stream from which to read the document
+ * @param document the document model into which the content is read
+ * @param offset the offset inside to document where the content is inserted
+ *
+ * @throws BadLocationException if offset
is an invalid location
+ * inside document
+ * @throws IOException if something goes wrong while reading from
+ * in
+ */
public void read(InputStream in, Document document, int offset)
throws BadLocationException, IOException
{
read(new InputStreamReader(in), document, offset);
}
+ /**
+ * Reads a document of the supported content type from a {@link Reader}
+ * into the actual {@link Document} object.
+ *
+ * @param in the reader from which to read the document
+ * @param document the document model into which the content is read
+ * @param offset the offset inside to document where the content is inserted
+ *
+ * @throws BadLocationException if offset
is an invalid location
+ * inside document
+ * @throws IOException if something goes wrong while reading from
+ * in
+ */
public void read(Reader in, Document document, int offset)
throws BadLocationException, IOException
{
@@ -405,14 +922,47 @@ public class DefaultEditorKit extends EditorKit
SimpleAttributeSet.EMPTY);
}
+ /**
+ * Writes the Document
(or a fragment of the
+ * Document
) to an {@link OutputStream} in the
+ * supported content type format.
+ *
+ * @param out the stream to write to
+ * @param document the document that should be written out
+ * @param offset the beginning offset from where to write
+ * @param len the length of the fragment to write
+ *
+ * @throws BadLocationException if offset
or
+ * offset + len
is an invalid location inside
+ * document
+ * @throws IOException if something goes wrong while writing to
+ * out
+ */
public void write(OutputStream out, Document document, int offset, int len)
throws BadLocationException, IOException
{
write(new OutputStreamWriter(out), document, offset, len);
}
+ /**
+ * Writes the Document
(or a fragment of the
+ * Document
) to a {@link Writer} in the
+ * supported content type format.
+ *
+ * @param out the writer to write to
+ * @param document the document that should be written out
+ * @param offset the beginning offset from where to write
+ * @param len the length of the fragment to write
+ *
+ * @throws BadLocationException if offset
or
+ * offset + len
is an invalid location inside
+ * document
+ * @throws IOException if something goes wrong while writing to
+ * out
+ */
public void write(Writer out, Document document, int offset, int len)
throws BadLocationException, IOException
{
+ // TODO: Implement this properly.
}
}
diff --git a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
index 6fe206a..3545e52 100644
--- a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
+++ b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java
@@ -42,42 +42,174 @@ import java.awt.Color;
import java.awt.Font;
import java.io.Serializable;
+import javax.swing.event.DocumentEvent;
+
/**
+ * The default implementation of {@link StyledDocument}.
+ *
+ * The document is modeled as an {@link Element} tree, which has
+ * a {@link SectionElement} as single root, which has one or more
+ * {@link AbstractDocument.BranchElement}s as paragraph nodes
+ * and each paragraph node having one or more
+ * {@link AbstractDocument.LeafElement}s as content nodes.
+ *
* @author Michael Koch (konqueror@gmx.de)
+ * @author Roman Kennke (roman@kennke.org)
*/
public class DefaultStyledDocument extends AbstractDocument
implements StyledDocument
{
+ /**
+ * Performs all structuralElement
+ * hierarchy.
+ */
public class ElementBuffer
implements Serializable
{
+ /** The root element of the hierarchy. */
private Element root;
-
+
+ /** Holds the offset for structural changes. */
+ private int offset;
+
+ /** Holds the length of structural changes. */
+ private int length;
+
+ /**
+ * Creates a new ElementBuffer
for the specified
+ * root
element.
+ *
+ * @param root the root element for this ElementBuffer
+ */
public ElementBuffer(Element root)
{
this.root = root;
}
+ /**
+ * Returns the root element of this ElementBuffer
.
+ *
+ * @return the root element of this ElementBuffer
+ */
public Element getRootElement()
{
return root;
}
+
+ /**
+ * Modifies the element structure so that the specified interval starts
+ * and ends at an element boundary. Content and paragraph elements
+ * are split and created as necessary.
+ *
+ * This also updates the DefaultDocumentEvent
to reflect the
+ * structural changes.
+ *
+ * The bulk work is delegated to {@link #changeUpdate()}.
+ *
+ * @param offset the start index of the interval to be changed
+ * @param length the length of the interval to be changed
+ * @param ev the DefaultDocumentEvent
describing the change
+ */
+ public void change(int offset, int length, DefaultDocumentEvent ev)
+ {
+ this.offset = offset;
+ this.length = length;
+ changeUpdate();
+ }
+
+ /**
+ * Performs the actual work for {@link #change}.
+ * The elements at the interval boundaries are split up (if necessary)
+ * so that the interval boundaries are located at element boundaries.
+ */
+ protected void changeUpdate()
+ {
+ // Split up the element at the start offset if necessary.
+ Element el = getCharacterElement(offset);
+ split(el, offset);
+
+ int endOffset = offset + length;
+ el = getCharacterElement(endOffset);
+ split(el, endOffset);
+ }
+
+ /**
+ * Splits an element if offset
is not alread at its boundary.
+ *
+ * @param el the Element to possibly split
+ * @param offset the offset at which to possibly split
+ */
+ void split(Element el, int offset)
+ {
+ if (el instanceof AbstractElement)
+ {
+ AbstractElement ael = (AbstractElement) el;
+ int startOffset = ael.getStartOffset();
+ int endOffset = ael.getEndOffset();
+ int len = endOffset - startOffset;
+ if (startOffset != offset && endOffset != offset)
+ {
+ Element paragraph = ael.getParentElement();
+ if (paragraph instanceof BranchElement)
+ {
+ BranchElement par = (BranchElement) paragraph;
+ Element child1 = createLeafElement(par, ael, startOffset,
+ offset);
+ Element child2 = createLeafElement(par, ael, offset,
+ endOffset);
+ int index = par.getElementIndex(startOffset);
+ par.replace(index, 1, new Element[]{ child1, child2 });
+ }
+ else
+ throw new AssertionError("paragraph elements are expected to "
+ + "be instances of "
+ + "javax.swing.text.AbstractDocument.BranchElement");
+ }
+ }
+ else
+ throw new AssertionError("content elements are expected to be "
+ + "instances of "
+ + "javax.swing.text.AbstractDocument.AbstractElement");
+ }
}
-
+
+ /**
+ * The default size to use for new content buffers.
+ */
public static final int BUFFER_SIZE_DEFAULT = 4096;
+ /**
+ * The EditorBuffer
that is used to manage to
+ * Element
hierarchy.
+ */
protected DefaultStyledDocument.ElementBuffer buffer;
-
+
+ /**
+ * Creates a new DefaultStyledDocument
.
+ */
public DefaultStyledDocument()
{
this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext());
}
+ /**
+ * Creates a new DefaultStyledDocument
that uses the
+ * specified {@link StyleContext}.
+ *
+ * @param context the StyleContext
to use
+ */
public DefaultStyledDocument(StyleContext context)
{
this(new GapContent(BUFFER_SIZE_DEFAULT), context);
}
+ /**
+ * Creates a new DefaultStyledDocument
that uses the
+ * specified {@link StyleContext} and {@link Content} buffer.
+ *
+ * @param content the Content
buffer to use
+ * @param context the StyleContext
to use
+ */
public DefaultStyledDocument(AbstractDocument.Content content,
StyleContext context)
{
@@ -86,15 +218,38 @@ public class DefaultStyledDocument extends AbstractDocument
setLogicalStyle(0, context.getStyle(StyleContext.DEFAULT_STYLE));
}
+ /**
+ * Adds a style into the style hierarchy. Unspecified style attributes
+ * can be resolved in the parent
style, if one is specified.
+ *
+ * While it is legal to add nameless styles (nm == null
nullnull
if that is not necessary
+ *
+ * @return the newly created Style
+ */
public Style addStyle(String nm, Style parent)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.addStyle(nm, parent);
}
-
+
+ /**
+ * Create the default root element for this kind of Document
.
+ *
+ * @return the default root element for this kind of Document
+ */
protected AbstractDocument.AbstractElement createDefaultRoot()
{
Element[] tmp;
+ // FIXME: Create a SecionElement here instead of a BranchElement.
+ // Use createBranchElement() and createLeafElement instead.
BranchElement section = new BranchElement(null, null);
BranchElement paragraph = new BranchElement(section, null);
@@ -109,7 +264,17 @@ public class DefaultStyledDocument extends AbstractDocument
return section;
}
-
+
+ /**
+ * Returns the Element
that corresponds to the character
+ * at the specified position.
+ *
+ * @param position the position of which we query the corresponding
+ * Element
+ *
+ * @return the Element
that corresponds to the character
+ * at the specified position
+ */
public Element getCharacterElement(int position)
{
Element element = getDefaultRootElement();
@@ -122,63 +287,172 @@ public class DefaultStyledDocument extends AbstractDocument
return element;
}
-
+
+ /**
+ * Extracts a background color from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a background color
+ *
+ * @return the background color that correspond to the attributes
+ */
public Color getBackground(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getBackground(attributes);
}
-
+
+ /**
+ * Returns the default root element.
+ *
+ * @return the default root element
+ */
public Element getDefaultRootElement()
{
return buffer.getRootElement();
}
-
+
+ /**
+ * Extracts a font from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a font
+ *
+ * @return the font that correspond to the attributes
+ */
public Font getFont(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getFont(attributes);
}
+ /**
+ * Extracts a foreground color from a set of attributes.
+ *
+ * @param attributes the attributes from which to get a foreground color
+ *
+ * @return the foreground color that correspond to the attributes
+ */
public Color getForeground(AttributeSet attributes)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getForeground(attributes);
}
-
+
+ /**
+ * Returns the logical Style
for the specified position.
+ *
+ * @param position the position from which to query to logical style
+ *
+ * @return the logical Style
for the specified position
+ */
public Style getLogicalStyle(int position)
{
Element paragraph = getParagraphElement(position);
AttributeSet attributes = paragraph.getAttributes();
return (Style) attributes.getResolveParent();
}
-
+
+ /**
+ * Returns the paragraph element for the specified position.
+ *
+ * @param position the position for which to query the paragraph element
+ *
+ * @return the paragraph element for the specified position
+ */
public Element getParagraphElement(int position)
{
Element element = getCharacterElement(position);
return element.getParentElement();
}
+ /**
+ * Looks up and returns a named Style
.
+ *
+ * @param nm the name of the Style
+ *
+ * @return the found Style
of null
if no such
+ * Style
exists
+ */
public Style getStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getStyle(nm);
}
+ /**
+ * Removes a named Style
from the style hierarchy.
+ *
+ * @param nm the name of the Style
to be removed
+ */
public void removeStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
context.removeStyle(nm);
}
+ /**
+ * Sets text attributes for the fragment specified by offset
+ * and length
.
+ *
+ * @param offset the start offset of the fragment
+ * @param length the length of the fragment
+ * @param attributes the text attributes to set
+ * @param replace if true
, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ */
public void setCharacterAttributes(int offset, int length,
AttributeSet attributes,
boolean replace)
{
- // FIXME: Implement me.
- throw new Error("not implemented");
+ DefaultDocumentEvent ev =
+ new DefaultDocumentEvent(offset, length,
+ DocumentEvent.EventType.CHANGE);
+
+ // Modify the element structure so that the interval begins at an element
+ // start and ends at an element end.
+ buffer.change(offset, length, ev);
+
+ Element root = getDefaultRootElement();
+ // Visit all paragraph elements within the specified interval
+ int paragraphCount = root.getElementCount();
+ for (int pindex = 0; pindex < paragraphCount; pindex++)
+ {
+ Element paragraph = root.getElement(pindex);
+ // Skip paragraphs that lie outside the interval.
+ if ((paragraph.getStartOffset() > offset + length)
+ || (paragraph.getEndOffset() < offset))
+ continue;
+
+ // Visit content elements within this paragraph
+ int contentCount = paragraph.getElementCount();
+ for (int cindex = 0; cindex < contentCount; cindex++)
+ {
+ Element content = paragraph.getElement(cindex);
+ // Skip content that lies outside the interval.
+ if ((content.getStartOffset() > offset + length)
+ || (content.getEndOffset() < offset))
+ continue;
+
+ if (content instanceof AbstractElement)
+ {
+ AbstractElement el = (AbstractElement) content;
+ if (replace)
+ el.removeAttributes(el);
+ el.addAttributes(attributes);
+ }
+ else
+ throw new AssertionError("content elements are expected to be"
+ + "instances of "
+ + "javax.swing.text.AbstractDocument.AbstractElement");
+ }
+ }
}
+ /**
+ * Sets the logical style for the paragraph at the specified position.
+ *
+ * @param position the position at which the logical style is added
+ * @param style the style to set for the current paragraph
+ */
public void setLogicalStyle(int position, Style style)
{
Element el = getParagraphElement(position);
@@ -192,6 +466,15 @@ public class DefaultStyledDocument extends AbstractDocument
+ "instances of javax.swing.text.AbstractDocument.AbstractElement");
}
+ /**
+ * Sets text attributes for the paragraph at the specified fragment.
+ *
+ * @param offset the beginning of the fragment
+ * @param length the length of the fragment
+ * @param attributes the text attributes to set
+ * @param replace if true
, the attributes of the current
+ * selection are overridden, otherwise they are merged
+ */
public void setParagraphAttributes(int offset, int length,
AttributeSet attributes,
boolean replace)
diff --git a/libjava/classpath/javax/swing/text/FieldView.java b/libjava/classpath/javax/swing/text/FieldView.java
index 4d5c51c..e2e04d7 100644
--- a/libjava/classpath/javax/swing/text/FieldView.java
+++ b/libjava/classpath/javax/swing/text/FieldView.java
@@ -173,4 +173,9 @@ public class FieldView extends PlainView
super.removeUpdate(ev, newAlloc, vf);
}
+ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
+ {
+ return super.viewToModel(fx, fy, a, bias);
+ }
+
}
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java
index 1bbef8f..1dd46c4 100644
--- a/libjava/classpath/javax/swing/text/GapContent.java
+++ b/libjava/classpath/javax/swing/text/GapContent.java
@@ -39,29 +39,93 @@ exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.ListIterator;
import javax.swing.undo.UndoableEdit;
/**
- * This implementation of {@link AbstractDocument.Content} uses a gapped
- * buffer. This takes advantage of the fact that text area content is
- * mostly inserted sequentially. The buffer is a char array that maintains
- * a gap at the current insertion point. If characters a inserted at
- * gap boundaries, the cost is minimal (simple array access). The array only
- * has to be shifted around when the insertion point moves (then the gap also
- * moves and one array copy is necessary) or when the gap is filled up and
- * the buffer has to be enlarged.
- *
+ * This implementation of {@link AbstractDocument.Content} uses a gapped buffer.
+ * This takes advantage of the fact that text area content is mostly inserted
+ * sequentially. The buffer is a char array that maintains a gap at the current
+ * insertion point. If characters a inserted at gap boundaries, the cost is
+ * minimal (simple array access). The array only has to be shifted around when
+ * the insertion point moves (then the gap also moves and one array copy is
+ * necessary) or when the gap is filled up and the buffer has to be enlarged.
+ *
* TODO: Implement UndoableEdit support stuff
*/
public class GapContent
- implements AbstractDocument.Content, Serializable
+ implements AbstractDocument.Content, Serializable
{
+
+ /**
+ * A {@link Position} implementation for GapContent
.
+ */
+ class GapContentPosition
+ implements Position, Comparable
+ {
+
+ /** The index within the buffer array. */
+ int mark;
+
+ /**
+ * Creates a new GapContentPosition object.
+ *
+ * @param mark the mark of this Position
+ */
+ GapContentPosition(int mark)
+ {
+ this.mark = mark;
+ }
+
+ /**
+ * Comparable interface implementation. This is used to store all
+ * positions in an ordered fashion.
+ *
+ * @param o the object to be compared to this
+ *
+ * @return a negative integer if this is less than o
, zero
+ * if both are equal or a positive integer if this is greater than
+ * o
+ *
+ * @throws ClassCastException if o
is not a
+ * GapContentPosition or Integer object
+ */
+ public int compareTo(Object o)
+ {
+ if (o instanceof Integer)
+ {
+ int otherMark = ((Integer) o).intValue();
+ return mark - otherMark;
+ }
+ else
+ {
+ GapContentPosition other = (GapContentPosition) o;
+ return mark - other.mark;
+ }
+ }
+
+ /**
+ * Returns the current offset of this Position within the content.
+ *
+ * @return the current offset of this Position within the content.
+ */
+ public int getOffset()
+ {
+ if (mark <= gapStart)
+ return mark;
+ else
+ return mark - (gapEnd - gapStart);
+ }
+ }
+
private static final long serialVersionUID = 8374645204155842629L;
/**
- * This is the default buffer size and the amount of bytes that
- * a buffer is extended if it is full.
+ * This is the default buffer size and the amount of bytes that a buffer is
+ * extended if it is full.
*/
static final int DEFAULT_BUFSIZE = 64;
@@ -81,6 +145,12 @@ public class GapContent
int gapEnd;
/**
+ * The positions generated by this GapContent. They are kept in an ordered
+ * fashion, so they can be looked up easily.
+ */
+ LinkedList positions;
+
+ /**
* Creates a new GapContent object.
*/
public GapContent()
@@ -90,7 +160,7 @@ public class GapContent
/**
* Creates a new GapContent object with a specified initial size.
- *
+ *
* @param size the initial size of the buffer
*/
public GapContent(int size)
@@ -99,14 +169,15 @@ public class GapContent
gapStart = 0;
gapEnd = size - 1;
buffer[size - 1] = '\n';
+ positions = new LinkedList();
}
/**
* Allocates an array of the specified length that can then be used as
* buffer.
- *
+ *
* @param size the size of the array to be allocated
- *
+ *
* @return the allocated array
*/
protected Object allocateArray(int size)
@@ -116,7 +187,7 @@ public class GapContent
/**
* Returns the length of the allocated buffer array.
- *
+ *
* @return the length of the allocated buffer array
*/
protected int getArrayLength()
@@ -126,7 +197,7 @@ public class GapContent
/**
* Returns the length of the content.
- *
+ *
* @return the length of the content
*/
public int length()
@@ -136,18 +207,18 @@ public class GapContent
/**
* Inserts a string at the specified position.
- *
+ *
* @param where the position where the string is inserted
* @param str the string that is to be inserted
- *
+ *
* @return an UndoableEdit object (currently not supported, so
* null
is returned)
- *
- * @throws BadLocationException if where
is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if where
is not a valid
+ * location in the buffer
*/
public UndoableEdit insertString(int where, String str)
- throws BadLocationException
+ throws BadLocationException
{
// check arguments
int length = length();
@@ -155,190 +226,230 @@ public class GapContent
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
-
- // check if the gap is big enough to hold the string
- if ((gapEnd - gapStart) < strLen)
- // make room for this string and some more
- shiftEnd(strLen + DEFAULT_BUFSIZE);
+ + " than the content length", where);
- // are we at the gap boundary?
- if (where != gapStart)
- shiftGap(where);
+ replace(where, 0, str.toCharArray(), str.length());
- // now we can simple copy the string into the gap and adjust the
- // gap boundaries
- System.arraycopy(str.toCharArray(), 0, buffer, gapStart, strLen);
- gapStart += strLen;
return null;
}
/**
* Removes a piece of content at th specified position.
- *
+ *
* @param where the position where the content is to be removed
* @param nitems number of characters to be removed
- *
+ *
* @return an UndoableEdit object (currently not supported, so
* null
is returned)
- *
- * @throws BadLocationException if where
is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if where
is not a valid
+ * location in the buffer
*/
- public UndoableEdit remove(int where, int nitems)
- throws BadLocationException
+ public UndoableEdit remove(int where, int nitems) throws BadLocationException
{
// check arguments
int length = length();
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
+ + " than the content length", where);
if ((where + nitems) > length)
throw new BadLocationException("where + nitems cannot be greater"
- + " than the content length",
- where + nitems);
+ + " than the content length", where + nitems);
- // check if we are at the gap boundary
- if (where != gapStart)
- shiftGap(where);
+ replace(where, nitems, null, 0);
- // now we simply have to enlarge the gap
- gapEnd += nitems;
return null;
}
/**
* Returns a piece of content as String.
- *
+ *
* @param where the start location of the fragment
* @param len the length of the fragment
- *
+ *
* @throws BadLocationException if where
or
* where + len
are no valid locations in the buffer
*/
public String getString(int where, int len) throws BadLocationException
{
Segment seg = new Segment();
- getChars(where, len, seg);
- return new String(seg.array, seg.offset, seg.count);
+ try
+ {
+ getChars(where, len, seg);
+ return new String(seg.array, seg.offset, seg.count);
+ }
+ catch (StringIndexOutOfBoundsException ex)
+ {
+ int invalid = 0;
+ if (seg.offset < 0 || seg.offset >= seg.array.length)
+ invalid = seg.offset;
+ else
+ invalid = seg.offset + seg.count;
+ throw new BadLocationException("Illegal location: array.length = "
+ + seg.array.length + ", offset = "
+ + seg.offset + ", count = "
+ + seg.count, invalid);
+ }
}
/**
* Fetches a piece of content and stores it in a {@link Segment} object.
- *
- * If the requested piece of text spans the gap, the content is copied
- * into a new array. If it doesn't then it is contiguous and the
- * actual content store is returned.
- *
+ *
+ * If the requested piece of text spans the gap, the content is copied into a
+ * new array. If it doesn't then it is contiguous and the actual content
+ * store is returned.
+ *
* @param where the start location of the fragment
* @param len the length of the fragment
* @param txt the Segment object to store the fragment in
- *
+ *
* @throws BadLocationException if where
or
* where + len
are no valid locations in the buffer
*/
public void getChars(int where, int len, Segment txt)
- throws BadLocationException
+ throws BadLocationException
{
// check arguments
int length = length();
if (where >= length)
throw new BadLocationException("the where argument cannot be greater"
- + " than the content length", where);
+ + " than the content length", where);
if ((where + len) > length)
throw new BadLocationException("len plus where cannot be greater"
- + " than the content length",
- len + where);
+ + " than the content length", len + where);
// check if requested segment is contiguous
if ((where < gapStart) && ((gapStart - where) < len))
- {
- // requested segment is not contiguous -> copy the pieces together
- char[] copy = new char[len];
- int lenFirst = gapStart - where; // the length of the first segment
- System.arraycopy(buffer, where, copy, 0, lenFirst);
- System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
- txt.array = copy;
- txt.offset = 0;
- txt.count = len;
- }
+ {
+ // requested segment is not contiguous -> copy the pieces together
+ char[] copy = new char[len];
+ int lenFirst = gapStart - where; // the length of the first segment
+ System.arraycopy(buffer, where, copy, 0, lenFirst);
+ System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
+ txt.array = copy;
+ txt.offset = 0;
+ txt.count = len;
+ }
else
- {
- // requested segment is contiguous -> we can simply return the
- // actual content
- txt.array = buffer;
- if (where < gapStart)
- txt.offset = where;
- else
- txt.offset = where + (gapEnd - gapStart);
- txt.count = len;
- }
+ {
+ // requested segment is contiguous -> we can simply return the
+ // actual content
+ txt.array = buffer;
+ if (where < gapStart)
+ txt.offset = where;
+ else
+ txt.offset = where + (gapEnd - gapStart);
+ txt.count = len;
+ }
}
/**
* Creates and returns a mark at the specified position.
- *
+ *
* @param offset the position at which to create the mark
- *
+ *
* @return the create Position object for the mark
- *
- * @throws BadLocationException if the offset is not a valid position in
- * the buffer
+ *
+ * @throws BadLocationException if the offset is not a valid position in the
+ * buffer
*/
public Position createPosition(final int offset) throws BadLocationException
{
- return new Position()
- {
- int off = offset;
-
- public int getOffset()
- {
- return off;
- }
- };
+ if (offset < 0 || offset > length())
+ throw new BadLocationException("The offset was out of the bounds of this"
+ + " buffer", offset);
+
+ // We store the actual array index in the GapContentPosition. The real
+ // offset is then calculated in the GapContentPosition.
+ int mark = offset;
+ if (offset > gapStart)
+ mark += gapEnd - gapStart;
+ GapContentPosition pos = new GapContentPosition(mark);
+
+ // Add this into our list in a sorted fashion.
+ int index = Collections.binarySearch(positions, pos);
+ if (index < 0)
+ index = -(index + 1);
+ positions.add(index, pos);
+
+ return pos;
}
/**
* Enlarges the gap. This allocates a new bigger buffer array, copy the
- * segment before the gap as it is and the segment after the gap at
- * the end of the new buffer array. This does change the gapEnd mark
- * but not the gapStart mark.
- *
+ * segment before the gap as it is and the segment after the gap at the end
+ * of the new buffer array. This does change the gapEnd mark but not the
+ * gapStart mark.
+ *
* @param newSize the new size of the gap
*/
protected void shiftEnd(int newSize)
{
+ int delta = (gapEnd - gapStart) - newSize;
char[] newBuf = (char[]) allocateArray(length() + newSize);
System.arraycopy(buffer, 0, newBuf, 0, gapStart);
- System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,
- buffer.length - gapEnd);
+ System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, buffer.length
+ - gapEnd);
gapEnd = gapStart + newSize;
buffer = newBuf;
+
+ // Update the marks after the gapEnd.
+ int index = Collections.binarySearch(positions, new GapContentPosition(
+ gapEnd));
+ if (index < 0)
+ {
+ index = -(index + 1);
+ }
+ for (ListIterator i = positions.listIterator(index); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ p.mark += delta;
+ }
}
/**
* Shifts the gap to the specified position.
- *
+ *
* @param newGapStart the new start position of the gap
*/
protected void shiftGap(int newGapStart)
{
int newGapEnd = newGapStart + (gapEnd - gapStart);
+ // Update the positions between newGapEnd and (old) gapEnd. The marks
+ // must be shifted by (gapEnd - newGapEnd).
+ int index1 = Collections.binarySearch(positions,
+ new GapContentPosition(gapEnd));
+ int index2 = Collections.binarySearch(positions,
+ new GapContentPosition(newGapEnd));
+ if (index1 > 0 && index2 > 0)
+ {
+ int i1 = Math.min(index1, index2);
+ int i2 = Math.max(index1, index2);
+ for (ListIterator i = positions.listIterator(i1); i.hasNext();)
+ {
+ if (i.nextIndex() > i2)
+ break;
+
+ GapContentPosition p = (GapContentPosition) i.next();
+ p.mark += gapEnd - newGapEnd;
+ }
+ }
+
if (newGapStart == gapStart)
return;
else if (newGapStart < gapStart)
{
- System.arraycopy(buffer, newGapStart, buffer, newGapEnd,
- gapStart - newGapStart);
+ System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart
+ - newGapStart);
gapStart = newGapStart;
gapEnd = newGapEnd;
}
else
{
- System.arraycopy(buffer, gapEnd, buffer, gapStart,
- newGapStart - gapStart);
+ System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart
+ - gapStart);
gapStart = newGapStart;
gapEnd = newGapEnd;
}
@@ -346,11 +457,38 @@ public class GapContent
/**
* Returns the allocated buffer array.
- *
+ *
* @return the allocated buffer array
*/
protected Object getArray()
{
return buffer;
}
+
+ /**
+ * Replaces a portion of the storage with the specified items.
+ *
+ * @param position the position at which to remove items
+ * @param rmSize the number of items to remove
+ * @param addItems the items to add at location
+ * @param addSize the number of items to add
+ */
+ protected void replace(int position, int rmSize, Object addItems,
+ int addSize)
+ {
+ // Remove content
+ shiftGap(position);
+ gapEnd += rmSize;
+
+ // If gap is too small, enlarge the gap.
+ if ((gapEnd - gapStart) < addSize)
+ shiftEnd(addSize);
+
+ // Add new items to the buffer.
+ if (addItems != null)
+ {
+ System.arraycopy(addItems, 0, buffer, gapStart, addSize);
+ gapStart += addSize;
+ }
+ }
}
diff --git a/libjava/classpath/javax/swing/text/InternationalFormatter.java b/libjava/classpath/javax/swing/text/InternationalFormatter.java
index 531a4c1..cedaf59 100644
--- a/libjava/classpath/javax/swing/text/InternationalFormatter.java
+++ b/libjava/classpath/javax/swing/text/InternationalFormatter.java
@@ -214,7 +214,7 @@ public class InternationalFormatter
/**
* Converts a value object into a String. This is done by invoking
- * {@link Format#format} on the specified Format
object.
+ * {@link Format#format(Object)} on the specified Format
object.
* If no format is set, then {@link DefaultFormatter#valueToString(Object)}
* is called as a fallback.
*
diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java
index f2ef4d7..b3fad79 100644
--- a/libjava/classpath/javax/swing/text/JTextComponent.java
+++ b/libjava/classpath/javax/swing/text/JTextComponent.java
@@ -96,7 +96,6 @@ public abstract class JTextComponent extends JComponent
/**
* Constructor AccessibleJTextComponent
- * @param component TODO
*/
public AccessibleJTextComponent()
{
@@ -712,8 +711,8 @@ public abstract class JTextComponent extends JComponent
* @return A Keymap associated with the provided name, or
* null
if no such Keymap exists
*
- * @see #addKeymap()
- * @see #removeKeymap()
+ * @see #addKeymap
+ * @see #removeKeymap
* @see #keymaps
*/
public static Keymap getKeymap(String n)
@@ -728,7 +727,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The keymap removed from the global table
*
- * @see #addKeymap()
+ * @see #addKeymap
* @see #getKeymap()
* @see #keymaps
*/
@@ -751,7 +750,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The newly created Keymap
*
- * @see #removeKeymap()
+ * @see #removeKeymap
* @see #getKeymap()
* @see #keymaps
*/
@@ -769,7 +768,7 @@ public abstract class JTextComponent extends JComponent
*
* @return The component's current Keymap
*
- * @see #setKeymap()
+ * @see #setKeymap
* @see #keymap
*/
public Keymap getKeymap()
@@ -901,8 +900,8 @@ public abstract class JTextComponent extends JComponent
* @param actions The set of actions to resolve binding names against
*
* @see Action#NAME
- * @see Action#getValue()
- * @see KeyBinding#ActionName
+ * @see Action#getValue
+ * @see KeyBinding#actionName
*/
public static void loadKeymap(Keymap map,
JTextComponent.KeyBinding[] bindings,
@@ -921,12 +920,12 @@ public abstract class JTextComponent extends JComponent
* editor can run. Equivalent to calling
* getUI().getEditorKit().getActions()
. This set of Actions
* is a reasonable value to provide as a parameter to {@link
- * #loadKeymap()}, when resolving a set of {@link #KeyBinding} objects
+ * #loadKeymap}, when resolving a set of {@link KeyBinding} objects
* against this component.
*
* @return The set of available Actions on this component's {@link EditorKit}
*
- * @see TextUI#getEditorKit()
+ * @see TextUI#getEditorKit
* @see EditorKit#getActions()
*/
public Action[] getActions()
@@ -1122,7 +1121,7 @@ public abstract class JTextComponent extends JComponent
/**
* This method sets the label's UI delegate.
*
- * @param ui The label's UI delegate.
+ * @param newUI The label's UI delegate.
*/
public void setUI(TextUI newUI)
{
@@ -1360,7 +1359,7 @@ public abstract class JTextComponent extends JComponent
/**
* Selects the text from the given postion to the selection end position.
*
- * @param end the start positon of the selected text.
+ * @param start the start positon of the selected text.
*/
public void setSelectionStart(int start)
{
@@ -1391,7 +1390,7 @@ public abstract class JTextComponent extends JComponent
* Selects a part of the content of the text component.
*
* @param start the start position of the selected text
- * @param ent the end position of the selected text
+ * @param end the end position of the selected text
*/
public void select(int start, int end)
{
@@ -1635,7 +1634,7 @@ public abstract class JTextComponent extends JComponent
*
* @throws IOException if the reader throws it.
*
- * @see getDocument()
+ * @see #getDocument()
* @see Document#getProperty(Object)
*/
public void read(Reader input, Object streamDescription)
diff --git a/libjava/classpath/javax/swing/text/PasswordView.java b/libjava/classpath/javax/swing/text/PasswordView.java
index 229fd2b..c3aa66c 100644
--- a/libjava/classpath/javax/swing/text/PasswordView.java
+++ b/libjava/classpath/javax/swing/text/PasswordView.java
@@ -1,56 +1,59 @@
/* PasswordView.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
package javax.swing.text;
import java.awt.Color;
+import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Shape;
import javax.swing.JPasswordField;
-public class PasswordView extends FieldView
+public class PasswordView
+ extends FieldView
{
/**
* Buffer for putting the echo char into it and
* then using it to draw it into the view.
*/
private char[] oneCharBuffer = new char[1];
-
+
public PasswordView(Element elem)
{
super(elem);
@@ -70,7 +73,7 @@ public class PasswordView extends FieldView
{
// Update font metrics.
updateMetrics();
-
+
// Draw character.
oneCharBuffer[0] = ch;
g.drawChars(oneCharBuffer, 0, 1, x, y);
@@ -82,7 +85,7 @@ public class PasswordView extends FieldView
private char getEchoChar()
{
char ch = ((JPasswordField) getContainer()).getEchoChar();
-
+
if (ch == 0)
ch = '*';
@@ -107,10 +110,10 @@ public class PasswordView extends FieldView
// Update font metrics.
updateMetrics();
-
+
// Get echo character.
char ch = getEchoChar();
-
+
// Set color for selected text.
g.setColor(selectedColor);
g.setColor(Color.BLACK);
@@ -120,7 +123,7 @@ public class PasswordView extends FieldView
char[] buffer = new char[len];
for (int index = 0; index < len; ++index)
buffer[index] = ch;
-
+
// Draw echo charaters.
g.drawChars(buffer, 0, len, x, y);
@@ -146,25 +149,96 @@ public class PasswordView extends FieldView
// Update font metrics.
updateMetrics();
-
+
// Get echo character.
char ch = getEchoChar();
-
+ Segment segment = new Segment();
+
// Set color for unselected text.
g.setColor(unselectedColor);
g.setColor(Color.BLACK);
// Initialize buffer for faster drawing of all characters.
- int len = p1 - p0;
+ p1--;
+ getDocument().getText(p0, p1 - p0, segment);
+ int len = segment.toString().length();
+
char[] buffer = new char[len];
for (int index = 0; index < len; ++index)
buffer[index] = ch;
+ y += getPreferredSpan(Y_AXIS)/2;
+
// Draw echo charaters.
g.drawChars(buffer, 0, len, x, y);
-
+
// Return new x position right of all drawn characters.
- return x + len * metrics.charWidth(ch);
+ return x + (len * metrics.charWidth(ch));
+ }
+
+ /**
+ * Determines the preferred span for this view along an axis.
+ *
+ * @param axis to get the preferred span of
+ * @return the preferred span of the axis
+ */
+ public float getPreferredSpan(int axis)
+ {
+ if (axis != X_AXIS && axis != Y_AXIS)
+ throw new IllegalArgumentException();
+
+ FontMetrics fm = getFontMetrics();
+
+ if (axis == Y_AXIS)
+ return fm.getHeight();
+
+ String text;
+ Element elem = getElement();
+
+ try
+ {
+ text = elem.getDocument().getText(elem.getStartOffset(),
+ elem.getEndOffset());
+ }
+ catch (BadLocationException e)
+ {
+ // This should never happen.
+ text = "";
+ }
+ return fm.stringWidth(text);
}
-}
+ /**
+ * Provides a mapping from the document model coordinate space to the
+ * coordinate space of the view mapped to it.
+ *
+ * @param pos - the position to convert >= 0
+ * @param a - the allocated region to render into
+ * @param b - typesafe enumeration to indicate bias to a position in the model.
+ * @return the bounding box of the given position
+ * @throws BadLocationException if the given position does not
+ * represent a valid location in the associated document
+ */
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ return super.modelToView(pos, a, b);
+ }
+
+ /**
+ * Provides a mapping from the view coordinate space to the logical
+ * coordinate space of the model.
+ *
+ * @param fx - the X coordinate >= 0.0f
+ * @param fy - the Y coordinate >= 0.0f
+ * @param a - the allocated region to render into
+ * @param bias - typesafe enumeration to indicate bias to a position in the model.
+ * @return the location within the model that best represents
+ * the given point in the view
+ *
+ */
+ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
+ {
+ return super.viewToModel(fx, fy, a, bias);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/PlainDocument.java b/libjava/classpath/javax/swing/text/PlainDocument.java
index c3f59e4..71070e9 100644
--- a/libjava/classpath/javax/swing/text/PlainDocument.java
+++ b/libjava/classpath/javax/swing/text/PlainDocument.java
@@ -135,22 +135,6 @@ public class PlainDocument extends AbstractDocument
start, end - len);
rootElement.replace(i1, i2 - i1, new Element[]{ newEl });
}
- else
- {
- // otherwise only adjust indices of the element
- LeafElement el1 = (LeafElement) rootElement.getElement(i1);
- el1.end -= len;
- }
-
- // reindex remaining elements
- for (int i = rootElement.getElementIndex(p0) + 1;
- i < rootElement.getElementCount(); i++)
- {
- LeafElement el = (LeafElement) rootElement.getElement(i);
- el.start -= len;
- el.end -= len;
- }
-
}
public Element getDefaultRootElement()
diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java
index 5d1fab0..91d7547 100644
--- a/libjava/classpath/javax/swing/text/PlainView.java
+++ b/libjava/classpath/javax/swing/text/PlainView.java
@@ -237,5 +237,23 @@ public class PlainView extends View
return span;
}
+
+ /**
+ * Maps coordinates from the View
's space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this View
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates x, y
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
+ {
+ // FIXME: not implemented
+ return 0;
+ }
}
diff --git a/libjava/classpath/javax/swing/text/StyledEditorKit.java b/libjava/classpath/javax/swing/text/StyledEditorKit.java
index 459f243..89c4cf1 100644
--- a/libjava/classpath/javax/swing/text/StyledEditorKit.java
+++ b/libjava/classpath/javax/swing/text/StyledEditorKit.java
@@ -46,458 +46,663 @@ import java.io.Serializable;
import javax.swing.Action;
import javax.swing.JEditorPane;
+import javax.swing.JTextPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
/**
- * StyledEditorKit
+ * An {@link EditorKit} that supports editing styled text.
*
* @author Andrew Selkirk
+ * @author Roman Kennke (roman@kennke.org)
*/
public class StyledEditorKit extends DefaultEditorKit
{
+ /** The serialVersionUID. */
private static final long serialVersionUID = 7002391892985555948L;
/**
- * UnderlineAction
+ * Toggles the underline attribute for the selected text.
*/
public static class UnderlineAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor UnderlineAction
+ * Creates an instance of UnderlineAction
.
*/
public UnderlineAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out name for this action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isUnderline = StyleConstants.isUnderline(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setUnderline(atts, ! isUnderline);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * ItalicAction
+ * Toggles the italic attribute for the selected text.
*/
public static class ItalicAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor ItalicAction
+ * Creates an instance of ItalicAction
.
*/
public ItalicAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out correct name of this Action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isItalic = StyleConstants.isItalic(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setItalic(atts, ! isItalic);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * BoldAction
+ * Toggles the bold attribute for the selected text.
*/
public static class BoldAction extends StyledEditorKit.StyledTextAction
{
/**
- * Constructor BoldAction
+ * Creates an instance of BoldAction
.
*/
public BoldAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out correct name of this Action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ JEditorPane editor = getEditor(event);
+ StyledDocument doc = getStyledDocument(editor);
+ Element el = doc.getCharacterElement(editor.getSelectionStart());
+ boolean isBold = StyleConstants.isBold(el.getAttributes());
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setItalic(atts, ! isBold);
+ setCharacterAttributes(editor, atts, false);
}
}
/**
- * AlignmentAction
+ * Sets the alignment attribute on the selected text.
*/
public static class AlignmentAction extends StyledEditorKit.StyledTextAction
{
/**
- * a
+ * The aligment to set.
*/
private int a;
/**
- * Constructor AlignmentAction
- * @param nm TODO
- * @param a TODO
+ * Creates a new instance of AlignmentAction
to set the
+ * alignment to a
.
+ *
+ * @param nm the name of the Action
+ * @param a the alignment to set
*/
public AlignmentAction(String nm, int a)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.a = a;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setAlignment(atts, a);
+ setParagraphAttributes(getEditor(event), atts, false);
}
}
/**
- * ForegroundAction
+ * Sets the foreground color attribute on the selected text.
*/
public static class ForegroundAction extends StyledEditorKit.StyledTextAction
{
/**
- * fg
+ * The foreground color to set.
*/
private Color fg;
/**
- * Constructor ForegroundAction
- * @param nm TODO
- * @param fg TODO
+ * Creates a new instance of ForegroundAction
to set the
+ * foreground color to fg
.
+ *
+ * @param nm the name of the Action
+ * @param fg the foreground color to set
*/
public ForegroundAction(String nm, Color fg)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.fg = fg;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setForeground(atts, fg);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * FontSizeAction
+ * Sets the font size attribute on the selected text.
*/
public static class FontSizeAction extends StyledEditorKit.StyledTextAction
{
/**
- * size
+ * The font size to set.
*/
private int size;
/**
- * Constructor FontSizeAction
- * @param nm TODO
- * @param size TODO
+ * Creates a new instance of FontSizeAction
to set the
+ * font size to size
.
+ *
+ * @param nm the name of the Action
+ * @param size the font size to set
*/
public FontSizeAction(String nm, int size)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.size = size;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setFontSize(atts, size);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * FontFamilyAction
+ * Sets the font family attribute on the selected text.
*/
public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
{
/**
- * family
+ * The font family to set.
*/
private String family;
/**
- * Constructor FontFamilyAction
- * @param nm TODO
- * @param family TODO
+ * Creates a new instance of FontFamilyAction
to set the
+ * font family to family
.
+ *
+ * @param nm the name of the Action
+ * @param family the font family to set
*/
public FontFamilyAction(String nm, String family)
{
- super("TODO");
- // TODO
+ super(nm);
+ this.family = family;
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the ActionEvent
that describes the action
*/
public void actionPerformed(ActionEvent event)
{
- // TODO
+ SimpleAttributeSet atts = new SimpleAttributeSet();
+ StyleConstants.setFontFamily(atts, family);
+ setCharacterAttributes(getEditor(event), atts, false);
}
}
/**
- * StyledTextAction
+ * The abstract superclass of all styled TextActions. This class
+ * provides some useful methods to manipulate the text attributes.
*/
public abstract static class StyledTextAction extends TextAction
{
/**
- * Constructor StyledTextAction
- * @param nm TODO
+ * Creates a new instance of StyledTextAction
.
+ *
+ * @param nm the name of the StyledTextAction
*/
public StyledTextAction(String nm)
{
super(nm);
- // TODO
}
/**
- * getEditor
- * @param event TODO
- * @returns JEditorPane
+ * Returns the JEditorPane
component from which the
+ * ActionEvent
originated.
+ *
+ * @param event the ActionEvent
+ * @return the JEditorPane
component from which the
+ * ActionEvent
originated
*/
protected final JEditorPane getEditor(ActionEvent event)
{
- return null; // TODO
+ return (JEditorPane) getTextComponent(event);
}
/**
- * setCharacterAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Sets the specified character attributes on the currently selected
+ * text of editor
. If editor
does not have
+ * a selection, then the attributes are used as input attributes
+ * for newly inserted content.
+ *
+ * @param editor the JEditorPane
component
+ * @param atts the text attributes to set
+ * @param replace if true
the current attributes of the
+ * selection are replaces, otherwise they are merged
*/
- protected final void setCharacterAttributes(JEditorPane value0,
- AttributeSet value1,
- boolean value2)
+ protected final void setCharacterAttributes(JEditorPane editor,
+ AttributeSet atts,
+ boolean replace)
{
- // TODO
+ Document doc = editor.getDocument();
+ if (doc instanceof StyledDocument)
+ {
+ StyledDocument styleDoc = (StyledDocument) editor.getDocument();
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ {
+ StyledEditorKit styleKit = (StyledEditorKit) kit;
+ int start = editor.getSelectionStart();
+ int end = editor.getSelectionEnd();
+ int dot = editor.getCaret().getDot();
+ if (start == dot && end == dot)
+ {
+ // If there is no selection, then we only update the
+ // input attributes.
+ MutableAttributeSet inputAttributes =
+ styleKit.getInputAttributes();
+ inputAttributes.addAttributes(atts);
+ }
+ else
+ styleDoc.setCharacterAttributes(start, end, atts, replace);
+ }
+ else
+ throw new AssertionError("The EditorKit for StyledTextActions "
+ + "is expected to be a StyledEditorKit");
+ }
+ else
+ throw new AssertionError("The Document for StyledTextActions is "
+ + "expected to be a StyledDocument.");
}
/**
- * getStyledDocument
- * @param value0 TODO
- * @returns StyledDocument
+ * Returns the {@link StyledDocument} that is used by editor
.
+ *
+ * @param editor the JEditorPane
from which to get the
+ * StyledDocument
+ *
+ * @return the {@link StyledDocument} that is used by editor
*/
- protected final StyledDocument getStyledDocument(JEditorPane value0)
+ protected final StyledDocument getStyledDocument(JEditorPane editor)
{
- return null; // TODO
+ Document doc = editor.getDocument();
+ if (!(doc instanceof StyledDocument))
+ throw new AssertionError("The Document for StyledEditorKits is "
+ + "expected to be a StyledDocument.");
+
+ return (StyledDocument) doc;
}
/**
- * getStyledEditorKit
- * @param value0 TODO
- * @returns StyledEditorKit
+ * Returns the {@link StyledEditorKit} that is used by editor
.
+ *
+ * @param editor the JEditorPane
from which to get the
+ * StyledEditorKit
+ *
+ * @return the {@link StyledEditorKit} that is used by editor
*/
- protected final StyledEditorKit getStyledEditorKit(JEditorPane value0)
+ protected final StyledEditorKit getStyledEditorKit(JEditorPane editor)
{
- return null; // TODO
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ throw new AssertionError("The EditorKit for StyledDocuments is "
+ + "expected to be a StyledEditorKit.");
+
+ return (StyledEditorKit) kit;
}
/**
- * setParagraphAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Sets the specified character attributes on the paragraph that
+ * contains the currently selected
+ * text of editor
. If editor
does not have
+ * a selection, then the attributes are set on the paragraph that
+ * contains the current caret position.
+ *
+ * @param editor the JEditorPane
component
+ * @param atts the text attributes to set
+ * @param replace if true
the current attributes of the
+ * selection are replaces, otherwise they are merged
*/
- protected final void setParagraphAttributes(JEditorPane value0,
- AttributeSet value1,
- boolean value2)
+ protected final void setParagraphAttributes(JEditorPane editor,
+ AttributeSet atts,
+ boolean replace)
{
- // TODO
+ Document doc = editor.getDocument();
+ if (doc instanceof StyledDocument)
+ {
+ StyledDocument styleDoc = (StyledDocument) editor.getDocument();
+ EditorKit kit = editor.getEditorKit();
+ if (!(kit instanceof StyledEditorKit))
+ {
+ StyledEditorKit styleKit = (StyledEditorKit) kit;
+ int start = editor.getSelectionStart();
+ int end = editor.getSelectionEnd();
+ int dot = editor.getCaret().getDot();
+ if (start == dot && end == dot)
+ {
+ // If there is no selection, then we only update the
+ // input attributes.
+ MutableAttributeSet inputAttributes =
+ styleKit.getInputAttributes();
+ inputAttributes.addAttributes(atts);
+ }
+ else
+ styleDoc.setParagraphAttributes(start, end, atts, replace);
+ }
+ else
+ throw new AssertionError("The EditorKit for StyledTextActions "
+ + "is expected to be a StyledEditorKit");
+ }
+ else
+ throw new AssertionError("The Document for StyledTextActions is "
+ + "expected to be a StyledDocument.");
}
}
/**
- * StyledViewFactory
+ * A {@link ViewFactory} that is able to create {@link View}s for
+ * the Element
s that are supported by
+ * StyledEditorKit
, namely the following types of Elements:
+ *
+ *
+ *
*/
static class StyledViewFactory
implements ViewFactory
{
/**
- * Constructor StyledViewFactory
- */
- StyledViewFactory()
- {
- // TODO
- }
-
- /**
- * create
- * @param value0 TODO
- * @returns View
+ * Creates a {@link View} for the specified Element
.
+ *
+ * @param element the Element
to create a View
+ * for
+ * @return the View
for the specified Element
+ * or null
if the type of element
is
+ * not supported
*/
- public View create(Element value0)
+ public View create(Element element)
{
- return null; // TODO
+ String name = element.getName();
+ View view = null;
+ if (name.equals(AbstractDocument.ContentElementName))
+ view = new LabelView(element);
+ else if (name.equals(AbstractDocument.ParagraphElementName))
+ view = new ParagraphView(element);
+ else if (name.equals(AbstractDocument.SectionElementName))
+ view = new BoxView(element, View.Y_AXIS);
+ else if (name.equals(StyleConstants.ComponentElementName))
+ view = new ComponentView(element);
+ else if (name.equals(StyleConstants.IconElementName))
+ view = new IconView(element);
+ else
+ throw new AssertionError("Unknown Element type: "
+ + element.getClass().getName() + " : "
+ + name);
+ return view;
}
}
/**
- * AttributeTracker
+ * Keeps track of the caret position and updates the currentRun
+ * Element
and the inputAttributes
.
*/
- class AttributeTracker
- implements CaretListener, PropertyChangeListener, Serializable
+ class CaretTracker
+ implements CaretListener
{
/**
- * Constructor AttributeTracker
- * @param value0 TODO
- */
- AttributeTracker(StyledEditorKit value0)
- {
- // TODO
- }
-
- /**
- * updateInputAttributes
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Notifies an update of the caret position.
+ *
+ * @param ev the event for the caret update
*/
- void updateInputAttributes(int value0, int value1, JTextComponent value2)
+ public void caretUpdate(CaretEvent ev)
{
- // TODO
- }
-
- /**
- * propertyChange
- * @param value0 TODO
- */
- public void propertyChange(PropertyChangeEvent value0)
- {
- // TODO
- }
-
- /**
- * caretUpdate
- * @param value0 TODO
- */
- public void caretUpdate(CaretEvent value0)
- {
- // TODO
+ Object source = ev.getSource();
+ if (!(source instanceof JTextComponent))
+ throw new AssertionError("CaretEvents are expected to come from a"
+ + "JTextComponent.");
+
+ JTextComponent text = (JTextComponent) source;
+ Document doc = text.getDocument();
+ if (!(doc instanceof StyledDocument))
+ throw new AssertionError("The Document used by StyledEditorKits is"
+ + "expected to be a StyledDocument");
+
+ StyledDocument styleDoc = (StyledDocument) doc;
+ currentRun = styleDoc.getCharacterElement(ev.getDot());
+ createInputAttributes(currentRun, inputAttributes);
}
}
/**
- * currentRun
+ * Stores the Element
at the current caret position. This
+ * is updated by {@link CaretTracker}.
*/
Element currentRun;
/**
- * currentParagraph
+ * The current input attributes. This is updated by {@link CaretTracker}.
*/
- Element currentParagraph;
+ MutableAttributeSet inputAttributes;
/**
- * inputAttributes
+ * The CaretTracker that keeps track of the current input attributes, and
+ * the current character run Element.
*/
- MutableAttributeSet inputAttributes;
+ CaretTracker caretTracker;
+
+ /**
+ * The ViewFactory for StyledEditorKits.
+ */
+ StyledViewFactory viewFactory;
/**
- * Constructor StyledEditorKit
+ * Creates a new instance of StyledEditorKit
.
*/
public StyledEditorKit()
{
- // TODO
+ inputAttributes = new SimpleAttributeSet();
}
/**
- * clone
- * @returns Object
+ * Creates an exact copy of this StyledEditorKit
.
+ *
+ * @return an exact copy of this StyledEditorKit
*/
public Object clone()
{
- return null; // TODO
+ StyledEditorKit clone = (StyledEditorKit) super.clone();
+ // FIXME: Investigate which fields must be copied.
+ return clone;
}
/**
- * getActions
- * @returns Action[]
+ * Returns the Action
s supported by this {@link EditorKit}.
+ * This includes the {@link BoldAction}, {@link ItalicAction} and
+ * {@link UnderlineAction} as well as the Action
s supported
+ * by {@link DefaultEditorKit}.
+ *
+ * The other Action
s of StyledEditorKit
are not
+ * returned here, since they require a parameter and thus custom
+ * instantiation.
+ *
+ * @return the Action
s supported by this {@link EditorKit}
*/
public Action[] getActions()
{
- return null; // TODO
+ Action[] actions1 = super.getActions();
+ Action[] myActions = new Action[] { new BoldAction(), new ItalicAction(),
+ new UnderlineAction() };
+ return TextAction.augmentList(actions1, myActions);
}
/**
- * getInputAttributes
- * @returns MutableAttributeSet
+ * Returns the current input attributes. These are automatically set on
+ * any newly inserted content, if not specified otherwise.
+ *
+ * @return the current input attributes
*/
public MutableAttributeSet getInputAttributes()
{
- return null; // TODO
+ return inputAttributes;
}
/**
- * getCharacterAttributeRun
- * @returns Element
+ * Returns the {@link Element} that represents the character run at the
+ * current caret position.
+ *
+ * @return the {@link Element} that represents the character run at the
+ * current caret position
*/
public Element getCharacterAttributeRun()
{
- return null; // TODO
+ return currentRun;
}
/**
- * createDefaultDocument
- * @returns Document
+ * Creates the default {@link Document} supported by this
+ * EditorKit
. This is an instance of
+ * {@link DefaultStyledDocument} in this case but may be overridden by
+ * subclasses.
+ *
+ * @return an instance of DefaultStyledDocument
*/
public Document createDefaultDocument()
{
- return null; // TODO
+ return new DefaultStyledDocument();
}
/**
- * install
- * @param component TODO
+ * Installs this EditorKit
on the specified {@link JEditorPane}.
+ * This basically involves setting up required listeners on the
+ * JEditorPane
.
+ *
+ * @param component the JEditorPane
to install this
+ * EditorKit
on
*/
public void install(JEditorPane component)
{
- // TODO
+ CaretTracker tracker = new CaretTracker();
+ component.addCaretListener(tracker);
}
/**
- * deinstall
- * @param component TODO
+ * Deinstalls this EditorKit
from the specified
+ * {@link JEditorPane}. This basically involves removing all listeners from
+ * JEditorPane
that have been set up by this
+ * EditorKit
.
+ *
+ * @param component the JEditorPane
from which to deinstall this
+ * EditorKit
*/
public void deinstall(JEditorPane component)
{
- // TODO
+ CaretTracker t = caretTracker;
+ if (t != null)
+ component.removeCaretListener(t);
+ caretTracker = null;
}
/**
- * getViewFactory
- * @returns ViewFactory
+ * Returns a {@link ViewFactory} that is able to create {@link View}s
+ * for {@link Element}s that are supported by this EditorKit
,
+ * namely the following types of Element
s:
+ *
+ *
+ *
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s
+ * for {@link Element}s that are supported by this EditorKit
*/
public ViewFactory getViewFactory()
{
- return null; // TODO
+ if (viewFactory == null)
+ viewFactory = new StyledViewFactory();
+ return viewFactory;
}
/**
- * createInputAttributes
- * @param element TODO
- * @param set TODO
+ * Copies the text attributes from element
to set
.
+ * This is called everytime when the caret position changes to keep
+ * track of the current input attributes. The attributes in set
+ * are cleaned before adding the attributes of element
.
+ *
+ * This method filters out attributes for element names, Icon
s
+ * and Component
s.
+ *
+ * @param element the Element
from which to copy the text
+ * attributes
+ * @param set the inputAttributes to copy the attributes to
*/
- protected void createInputAttributes(Element element, MutableAttributeSet set)
+ protected void createInputAttributes(Element element,
+ MutableAttributeSet set)
{
- // TODO
+ AttributeSet atts = element.getAttributes();
+ set.removeAttributes(set);
+ // FIXME: Filter out component, icon and element name attributes.
+ set.addAttributes(atts);
}
}
diff --git a/libjava/classpath/javax/swing/text/View.java b/libjava/classpath/javax/swing/text/View.java
index 4d9ed7b..24efba9 100644
--- a/libjava/classpath/javax/swing/text/View.java
+++ b/libjava/classpath/javax/swing/text/View.java
@@ -62,11 +62,6 @@ public abstract class View implements SwingConstants
private View parent;
/**
- * The child views.
- */
- View[] children;
-
- /**
* Creates a new View
instance.
*
* @param elem an Element
value
@@ -74,7 +69,6 @@ public abstract class View implements SwingConstants
public View(Element elem)
{
elt = elem;
- children = new View[0];
}
public abstract void paint(Graphics g, Shape s);
@@ -92,7 +86,10 @@ public abstract class View implements SwingConstants
public Container getContainer()
{
View parent = getParent();
- return parent != null ? parent.getContainer() : null;
+ if (parent == null)
+ throw new AssertionError("The parent of a View must not be null.");
+
+ return parent.getContainer();
}
public Document getDocument()
@@ -178,12 +175,13 @@ public abstract class View implements SwingConstants
public void append(View view)
{
View[] array = { view };
- replace(getViewCount(), 1, array);
+ int offset = getViewCount();
+ replace(offset, 0, array);
}
public void removeAll()
{
- replace(0, getViewCount(), null);
+ replace(0, getViewCount(), new View[0]);
}
public void remove(int index)
@@ -250,8 +248,6 @@ public abstract class View implements SwingConstants
{
if (parent != null)
parent.preferenceChanged(this, width, height);
- else
- ((JComponent) getContainer()).revalidate();
}
public int getBreakWeight(int axis, float pos, float len)
@@ -351,7 +347,7 @@ public abstract class View implements SwingConstants
Element el = getElement();
DocumentEvent.ElementChange ec = ev.getChange(el);
if (ec != null)
- updateChildren(ec, ev, vf);
+ updateChildren(ec, ev, vf);
forwardUpdate(ec, ev, shape, vf);
updateLayout(ec, ev, shape);
}
@@ -382,16 +378,12 @@ public abstract class View implements SwingConstants
{
Element[] added = ec.getChildrenAdded();
Element[] removed = ec.getChildrenRemoved();
- View[] newChildren = new View[children.length + added.length
- - removed.length];
int index = ec.getIndex();
- System.arraycopy(children, 0, newChildren, 0, index);
- System.arraycopy(children, index, added, 0, added.length);
- int index2 = index + removed.length;
- int len2 = children.length - index2;
- System.arraycopy(children, index2, newChildren, index + added.length,
- len2);
- children = newChildren;
+
+ View[] newChildren = new View[added.length];
+ for (int i = 0; i < added.length; ++i)
+ newChildren[i] = vf.create(added[i]);
+ replace(index, removed.length, newChildren);
return true;
}
@@ -412,9 +404,10 @@ public abstract class View implements SwingConstants
protected void forwardUpdate(DocumentEvent.ElementChange ec,
DocumentEvent ev, Shape shape, ViewFactory vf)
{
- for (int i = 0; i < children.length; i++)
+ int count = getViewCount();
+ for (int i = 0; i < count; i++)
{
- View child = children[i];
+ View child = getView(i);
forwardUpdateToView(child, ev, shape, vf);
}
}
@@ -459,5 +452,104 @@ public abstract class View implements SwingConstants
if (ec != null)
preferenceChanged(this, true, true);
}
-}
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * @param pos the position of the character in the model
+ * @param a the area that is occupied by the view
+ * @param b either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward} depending on the preferred
+ * direction bias. If null
this defaults to
+ * Position.Bias.Forward
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if pos
is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
+ public abstract Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException;
+
+ /**
+ * Maps a region in the document into the coordinate space of the View.
+ *
+ * @param p1 the beginning position inside the document
+ * @param b1 the direction bias for the beginning position
+ * @param p2 the end position inside the document
+ * @param b2 the direction bias for the end position
+ * @param a the area that is occupied by the view
+ *
+ * @return a rectangle that gives the span of the document region
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if p1
or p2
are
+ * invalid
+ * @throws IllegalArgumentException if b1 or b2 is not one of the above
+ * listed valid values
+ */
+ public Shape modelToView(int p1, Position.Bias b1,
+ int p2, Position.Bias b2, Shape a)
+ throws BadLocationException
+ {
+ if (b1 != Position.Bias.Forward && b1 != Position.Bias.Backward)
+ throw new IllegalArgumentException
+ ("b1 must be either Position.Bias.Forward or Position.Bias.Backward");
+ if (b2 != Position.Bias.Forward && b2 != Position.Bias.Backward)
+ throw new IllegalArgumentException
+ ("b2 must be either Position.Bias.Forward or Position.Bias.Backward");
+ Shape s1 = modelToView(p1, a, b1);
+ Shape s2 = modelToView(p2, a, b2);
+ return s1.getBounds().union(s2.getBounds());
+ }
+
+ /**
+ * Maps coordinates from the View
's space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this View
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates x, y
+ */
+ public abstract int viewToModel(float x, float y, Shape a, Position.Bias[] b);
+
+
+ /**
+ * Dumps the complete View hierarchy. This method can be used for debugging
+ * purposes.
+ */
+ void dump()
+ {
+ // Climb up the hierarchy to the parent.
+ View parent = getParent();
+ if (parent != null)
+ parent.dump();
+ else
+ dump(0);
+ }
+
+ /**
+ * Dumps the view hierarchy below this View with the specified indentation
+ * level.
+ *
+ * @param indent the indentation level to be used for this view
+ */
+ void dump(int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ System.out.print('.');
+ System.out.println(this);
+
+ int count = getViewCount();
+ for (int i = 0; i < count; ++i)
+ getView(i).dump(indent + 1);
+ }
+}
diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
index 7ae78ec..c0182fe 100644
--- a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
+++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing.text.html;
+import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
@@ -75,7 +76,7 @@ public class HTMLEditorKit
public abstract void parse(Reader reader, ParserCallback callback,
boolean ignoreCharSet
)
- throws java.io.IOException;
+ throws IOException;
}
/**
@@ -123,8 +124,8 @@ public class HTMLEditorKit
* The method is called when the HTML closing tag ((like </table>)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
- * @position the tag position in the text being parsed.
+ * @param tag The tag being handled
+ * @param position the tag position in the text being parsed.
*/
public void handleEndTag(HTML.Tag tag, int position)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTD.java b/libjava/classpath/javax/swing/text/html/parser/DTD.java
index 63d03ea..f17ca01 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DTD.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DTD.java
@@ -62,7 +62,8 @@ import java.util.Vector;
* TreeModelListener
listeners.
- *
- * @return an array of listeners.
- *
- * @since 1.4
- */
- public TreeModelListener[] getTreeModelListeners()
- {
- return (TreeModelListener[]) listenerList
- .getListeners(TreeModelListener.class);
- }
-
- /**
- * fireTreeNodesChanged
- *
- * @param source the node being changed
- * @param path the path to the root node
- * @param childIndices the indices of the changed elements
- * @param children the changed elements
- */
- protected void fireTreeNodesChanged(Object source, Object[] path,
- int[] childIndices, Object[] children)
- {
- TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
- children);
- TreeModelListener[] listeners = getTreeModelListeners();
-
- for (int i = listeners.length - 1; i >= 0; --i)
- listeners[i].treeNodesChanged(event);
- }
-
- /**
- * fireTreeNodesInserted
- *
- * @param source the node where new nodes got inserted
- * @param path the path to the root node
- * @param childIndices the indices of the new elements
- * @param children the new elements
- */
- protected void fireTreeNodesInserted(Object source, Object[] path,
- int[] childIndices, Object[] children)
- {
- TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
- children);
- TreeModelListener[] listeners = getTreeModelListeners();
-
- for (int i = listeners.length - 1; i >= 0; --i)
- listeners[i].treeNodesInserted(event);
- }
-
- /**
- * fireTreeNodesRemoved
- *
- * @param source the node where nodes got removed-
- * @param path the path to the root node
- * @param childIndices the indices of the removed elements
- * @param children the removed elements
- */
- protected void fireTreeNodesRemoved(Object source, Object[] path,
- int[] childIndices, Object[] children)
- {
- TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
- children);
- TreeModelListener[] listeners = getTreeModelListeners();
-
- for (int i = listeners.length - 1; i >= 0; --i)
- listeners[i].treeNodesRemoved(event);
- }
-
- /**
- * fireTreeStructureChanged
- *
- * @param source the node where the model has changed
- * @param path the path to the root node
- * @param childIndices the indices of the affected elements
- * @param children the affected elements
- */
- protected void fireTreeStructureChanged(Object source, Object[] path,
- int[] childIndices, Object[] children)
- {
- TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
- children);
- TreeModelListener[] listeners = getTreeModelListeners();
-
- for (int i = listeners.length - 1; i >= 0; --i)
- listeners[i].treeStructureChanged(event);
- }
-
- /**
- * Returns the registered listeners of a given type.
- *
- * @param listenerType the listener type to return
- *
- * @return an array of listeners
- *
- * @since 1.3
- */
- public EventListener[] getListeners(Class listenerType)
- {
- return listenerList.getListeners(listenerType);
- }
+ static final long serialVersionUID = -2621068368932566998L;
+
+ /**
+ * root
+ */
+ protected TreeNode root = null;
+
+ /**
+ * listenerList
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /**
+ * asksAllowsChildren
+ */
+ protected boolean asksAllowsChildren;
+
+ /**
+ * Constructor DefaultTreeModel
+ *
+ * @param root the tree root.
+ */
+ public DefaultTreeModel(TreeNode root)
+ {
+ if (root == null)
+ root = new DefaultMutableTreeNode();
+ setRoot(root);
+ }
+
+ /**
+ * Constructor DefaultTreeModel
+ *
+ * @param root the tree root.
+ * @param asksAllowsChildren TODO
+ */
+ public DefaultTreeModel(TreeNode root, boolean asksAllowsChildren)
+ {
+ setRoot(root);
+ this.asksAllowsChildren = asksAllowsChildren;
+ }
+
+ /**
+ * writeObject
+ *
+ * @param obj the object.
+ * @exception IOException TODO
+ */
+ private void writeObject(ObjectOutputStream obj) throws IOException
+ {
+ // TODO
+ }
+
+ /**
+ * readObject
+ *
+ * @param value0 TODO
+ * @exception IOException TODO
+ * @exception ClassNotFoundException TODO
+ */
+ private void readObject(ObjectInputStream value0) throws IOException,
+ ClassNotFoundException
+ {
+ // TODO
+ }
+
+ /**
+ * asksAllowsChildren
+ *
+ * @return boolean
+ */
+ public boolean asksAllowsChildren()
+ {
+ return asksAllowsChildren;
+ }
+
+ /**
+ * setAsksAllowsChildren
+ *
+ * @param value TODO
+ */
+ public void setAsksAllowsChildren(boolean value)
+ {
+ asksAllowsChildren = value;
+ }
+
+ /**
+ * setRoot
+ *
+ * @param root the root node.
+ */
+ public void setRoot(TreeNode root)
+ {
+ // Sanity Check
+ if (root == null)
+ {
+ throw new IllegalArgumentException("null root");
+ }
+ // Set new root
+ this.root = root;
+ }
+
+ /**
+ * getRoot
+ *
+ * @return Object
+ */
+ public Object getRoot()
+ {
+ return root;
+ }
+
+ /**
+ * getIndexOfChild
+ *
+ * @param parent TODO
+ * @param child TODO
+ * @return int
+ */
+ public int getIndexOfChild(Object parent, Object child)
+ {
+ for (int i = 0; i < getChildCount(parent); i++)
+ {
+ if (getChild(parent, i).equals(child))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * getChild
+ *
+ * @param node TODO
+ * @param idx TODO
+ * @return Object
+ */
+ public Object getChild(Object node, int idx)
+ {
+ if (node instanceof TreeNode)
+ return ((TreeNode) node).getChildAt(idx);
+ else
+ return null;
+ }
+
+ /**
+ * getChildCount
+ *
+ * @param node TODO
+ * @return int
+ */
+ public int getChildCount(Object node)
+ {
+ if (node instanceof TreeNode)
+ return ((TreeNode) node).getChildCount();
+ else
+ return 0;
+ }
+
+ /**
+ * isLeaf
+ *
+ * @param node TODO
+ * @return boolean
+ */
+ public boolean isLeaf(Object node)
+ {
+ if (node instanceof TreeNode)
+ return ((TreeNode) node).isLeaf();
+ else
+ return true;
+ }
+
+ /**
+ * Invoke this method if you've modified the TreeNodes upon
+ * which this model depends. The model will notify all of its
+ * listeners that the model has changed.
+ */
+ public void reload()
+ {
+ // TODO
+ }
+
+ /**
+ * Invoke this method if you've modified the TreeNodes upon
+ * which this model depends. The model will notify all of its
+ * listeners that the model has changed.
+ *
+ * @param node - TODO
+ */
+ public void reload(TreeNode node)
+ {
+ // TODO
+ }
+
+ /**
+ * Messaged when the user has altered the value for the item
+ * identified by path to newValue. If newValue signifies a truly new
+ * value the model should post a treeNodesChanged event.
+ * This sets the user object of the TreeNode identified by
+ * path and posts a node changed. If you use custom user objects
+ * in the TreeModel you're going to need to subclass this and set
+ * the user object of the changed node to something meaningful.
+ *
+ * @param path - path to the node that the user has altered
+ * @param newValue - the new value from the TreeCellEditor
+ */
+ public void valueForPathChanged(TreePath path, Object newValue)
+ {
+ Object node = path.getLastPathComponent();
+ if (node instanceof MutableTreeNode)
+ {
+ ((MutableTreeNode) node).setUserObject(newValue);
+ int[] ci = null;
+ Object[] c = null;
+ Object[] parentPath = path.getPath();
+ if (path.getPathCount() > 1)
+ {
+ Object parent = ((TreeNode) node).getParent();
+ ci = new int[1];
+ ci[0] = getIndexOfChild(parent, node);
+ node = newValue;
+ path = path.getParentPath().pathByAddingChild(node);
+ c = new Object[1];
+ c[0] = node;
+ parentPath = path.getParentPath().getPath();
+ }
+
+ fireTreeNodesChanged(this, parentPath, ci, c);
+ }
+ }
+
+ /**
+ * Invoked this to insert newChild at location index in parents children.
+ * This will then message nodesWereInserted to create the appropriate event.
+ * This is the preferred way to add children as it will create the
+ * appropriate event.
+ *
+ * @param newChild is the node to add to the parent's children
+ * @param parent is the parent of the newChild
+ * @param index is the index of the newChild
+ */
+ public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent,
+ int index)
+ {
+ parent.insert(newChild, index);
+ int[] childIndices = new int[1];
+ childIndices[0] = index;
+ nodesWereInserted(parent, childIndices);
+ }
+
+ /**
+ * Message this to remove node from its parent. This will message
+ * nodesWereRemoved to create the appropriate event. This is the preferred
+ * way to remove a node as it handles the event creation for you.
+ *
+ * @param node to be removed
+ */
+ public void removeNodeFromParent(MutableTreeNode node)
+ {
+ TreeNode parent = node.getParent();
+ Object[] children = new Object[1];
+ children[0] = node;
+ int[] childIndices = new int[1];
+ childIndices[0] = getIndexOfChild(parent, node);
+ node.removeFromParent();
+ nodesWereRemoved(parent, childIndices, children);
+ }
+
+ /**
+ * Invoke this method after you've changed how node is to be represented
+ * in the tree.
+ *
+ * @param node that was changed
+ */
+ public void nodeChanged(TreeNode node)
+ {
+ TreeNode parent = node.getParent();
+ int[] childIndices = new int[1];
+ childIndices[0] = getIndexOfChild(parent, node);
+ Object[] children = new Object[1];
+ children[0] = node;
+ fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
+ }
+
+ /**
+ * Invoke this method after you've inserted some TreeNodes
+ * into node. childIndices should be the index of the new elements and must
+ * be sorted in ascending order.
+ *
+ * @param parent that had a child added to
+ * @param childIndices of the children added
+ */
+ public void nodesWereInserted(TreeNode parent, int[] childIndices)
+ {
+ Object[] children = new Object[childIndices.length];
+ for (int i = 0; i < children.length; i++)
+ children[i] = getChild(parent, childIndices[i]);
+ fireTreeNodesInserted(this, getPathToRoot(parent), childIndices, children);
+ }
+
+ /**
+ * Invoke this method after you've removed some TreeNodes from node.
+ * childIndices should be the index of the removed elements and
+ * must be sorted in ascending order. And removedChildren should be the
+ * array of the children objects that were removed.
+ *
+ * @param parent that had a child added to
+ * @param childIndices of the children added
+ * @param removedChildren are all the children removed from parent.
+ */
+ public void nodesWereRemoved(TreeNode parent, int[] childIndices,
+ Object[] removedChildren)
+ {
+ fireTreeNodesRemoved(this, getPathToRoot(parent), childIndices,
+ removedChildren);
+ }
+
+ /**
+ * Invoke this method after you've changed how the children identified by
+ * childIndices are to be represented in the tree.
+ *
+ * @param node that is the parent of the children that changed in a tree.
+ * @param childIndices are the child nodes that changed.
+ */
+ public void nodesChanged(TreeNode node, int[] childIndices)
+ {
+ Object[] children = new Object[childIndices.length];
+ for (int i = 0; i < children.length; i++)
+ children[i] = getChild(node, childIndices[i]);
+ fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
+ }
+
+ /**
+ * Invoke this method if you've totally changed the children of node and
+ * its childrens children. This will post a treeStructureChanged event.
+ *
+ * @param node that had its children and grandchildren changed.
+ */
+ public void nodeStructureChanged(TreeNode node)
+ {
+ // TODO
+ }
+
+ /**
+ * Builds the parents of node up to and including the root node, where
+ * the original node is the last element in the returned array. The
+ * length of the returned array gives the node's depth in the tree.
+ *
+ * @param node - the TreeNode to get the path for
+ * @return TreeNode[] - the path from node to the root
+ */
+ public TreeNode[] getPathToRoot(TreeNode node)
+ {
+ return getPathToRoot(node, 0);
+ }
+
+ /**
+ * Builds the parents of node up to and including the root node, where
+ * the original node is the last element in the returned array. The
+ * length of the returned array gives the node's depth in the tree.
+ *
+ * @param node - the TreeNode to get the path for
+ * @param depth - an int giving the number of steps already taken
+ * towards the root (on recursive calls), used to size the returned array
+ * @return an array of TreeNodes giving the path from the root to the
+ * specified node
+ */
+ protected TreeNode[] getPathToRoot(TreeNode node, int depth)
+ {
+ if (node == null)
+ {
+ if (depth == 0)
+ return null;
+
+ return new TreeNode[depth];
+ }
+
+ TreeNode[] path = getPathToRoot(node.getParent(), depth + 1);
+ path[path.length - depth - 1] = node;
+ return path;
+ }
+
+ /**
+ * Registers a listere to the model.
+ *
+ * @param listener the listener to add
+ */
+ public void addTreeModelListener(TreeModelListener listener)
+ {
+ listenerList.add(TreeModelListener.class, listener);
+ }
+
+ /**
+ * Removes a listener from the model.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeTreeModelListener(TreeModelListener listener)
+ {
+ listenerList.remove(TreeModelListener.class, listener);
+ }
+
+ /**
+ * Returns all registered TreeModelListener
listeners.
+ *
+ * @return an array of listeners.
+ *
+ * @since 1.4
+ */
+ public TreeModelListener[] getTreeModelListeners()
+ {
+ return (TreeModelListener[]) listenerList
+ .getListeners(TreeModelListener.class);
+ }
+
+ /**
+ * Notifies 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.
+ *
+ * @param source the node being changed
+ * @param path the path to the root node
+ * @param childIndices the indices of the changed elements
+ * @param children the changed elements
+ */
+ protected void fireTreeNodesChanged(Object source, Object[] path,
+ int[] childIndices, Object[] children)
+ {
+ TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
+ children);
+
+ TreeModelListener[] listeners = getTreeModelListeners();
+
+ for (int i = listeners.length - 1; i >= 0; --i)
+ listeners[i].treeNodesChanged(event);
+ }
+
+ /**
+ * fireTreeNodesInserted
+ *
+ * @param source the node where new nodes got inserted
+ * @param path the path to the root node
+ * @param childIndices the indices of the new elements
+ * @param children the new elements
+ */
+ protected void fireTreeNodesInserted(Object source, Object[] path,
+ int[] childIndices, Object[] children)
+ {
+ TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
+ children);
+ TreeModelListener[] listeners = getTreeModelListeners();
+
+ for (int i = listeners.length - 1; i >= 0; --i)
+ listeners[i].treeNodesInserted(event);
+ }
+
+ /**
+ * fireTreeNodesRemoved
+ *
+ * @param source the node where nodes got removed-
+ * @param path the path to the root node
+ * @param childIndices the indices of the removed elements
+ * @param children the removed elements
+ */
+ protected void fireTreeNodesRemoved(Object source, Object[] path,
+ int[] childIndices, Object[] children)
+ {
+ TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
+ children);
+ TreeModelListener[] listeners = getTreeModelListeners();
+
+ for (int i = listeners.length - 1; i >= 0; --i)
+ listeners[i].treeNodesRemoved(event);
+ }
+
+ /**
+ * fireTreeStructureChanged
+ *
+ * @param source the node where the model has changed
+ * @param path the path to the root node
+ * @param childIndices the indices of the affected elements
+ * @param children the affected elements
+ */
+ protected void fireTreeStructureChanged(Object source, Object[] path,
+ int[] childIndices, Object[] children)
+ {
+ TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
+ children);
+ TreeModelListener[] listeners = getTreeModelListeners();
+
+ for (int i = listeners.length - 1; i >= 0; --i)
+ listeners[i].treeStructureChanged(event);
+ }
+
+ /**
+ * Returns the registered listeners of a given type.
+ *
+ * @param listenerType the listener type to return
+ *
+ * @return an array of listeners
+ *
+ * @since 1.3
+ */
+ public EventListener[] getListeners(Class listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
}
diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java
index de27dad..75b76a9 100644
--- a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java
+++ b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java
@@ -116,7 +116,7 @@ public class DefaultTreeSelectionModel
*/
public DefaultTreeSelectionModel()
{
- setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
+ setSelectionMode(SINGLE_TREE_SELECTION);
listenerList = new EventListenerList();
}
diff --git a/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java b/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java
index 67a21f0..535417e 100644
--- a/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java
+++ b/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java
@@ -125,7 +125,7 @@ public class FixedHeightLayoutCache
/**
* getPathForRow
*
- * @param value0 TODO
+ * @param row TODO
* @returns TreePath
*/
public TreePath getPathForRow(int row)
--
cgit v1.1