summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing')
-rw-r--r--libjava/classpath/javax/swing/AbstractAction.java3
-rw-r--r--libjava/classpath/javax/swing/AbstractButton.java58
-rw-r--r--libjava/classpath/javax/swing/AbstractCellEditor.java5
-rw-r--r--libjava/classpath/javax/swing/AbstractListModel.java13
-rw-r--r--libjava/classpath/javax/swing/AbstractSpinnerModel.java7
-rw-r--r--libjava/classpath/javax/swing/Action.java2
-rw-r--r--libjava/classpath/javax/swing/ActionMap.java8
-rw-r--r--libjava/classpath/javax/swing/BorderFactory.java7
-rw-r--r--libjava/classpath/javax/swing/BoundedRangeModel.java58
-rw-r--r--libjava/classpath/javax/swing/Box.java6
-rw-r--r--libjava/classpath/javax/swing/BoxLayout.java9
-rw-r--r--libjava/classpath/javax/swing/ButtonGroup.java20
-rw-r--r--libjava/classpath/javax/swing/CellRendererPane.java10
-rw-r--r--libjava/classpath/javax/swing/ComponentInputMap.java9
-rw-r--r--libjava/classpath/javax/swing/DebugGraphics.java8
-rw-r--r--libjava/classpath/javax/swing/DefaultBoundedRangeModel.java4
-rw-r--r--libjava/classpath/javax/swing/DefaultButtonModel.java20
-rw-r--r--libjava/classpath/javax/swing/DefaultCellEditor.java154
-rw-r--r--libjava/classpath/javax/swing/DefaultComboBoxModel.java4
-rw-r--r--libjava/classpath/javax/swing/DefaultDesktopManager.java4
-rw-r--r--libjava/classpath/javax/swing/DefaultFocusManager.java8
-rw-r--r--libjava/classpath/javax/swing/DefaultListCellRenderer.java12
-rw-r--r--libjava/classpath/javax/swing/DefaultListModel.java2
-rw-r--r--libjava/classpath/javax/swing/DefaultListSelectionModel.java34
-rw-r--r--libjava/classpath/javax/swing/DefaultSingleSelectionModel.java3
-rw-r--r--libjava/classpath/javax/swing/FocusManager.java8
-rw-r--r--libjava/classpath/javax/swing/GrayFilter.java6
-rw-r--r--libjava/classpath/javax/swing/Icon.java23
-rw-r--r--libjava/classpath/javax/swing/ImageIcon.java110
-rw-r--r--libjava/classpath/javax/swing/InputMap.java12
-rw-r--r--libjava/classpath/javax/swing/InputVerifier.java7
-rw-r--r--libjava/classpath/javax/swing/InternalFrameFocusTraversalPolicy.java7
-rw-r--r--libjava/classpath/javax/swing/JApplet.java5
-rw-r--r--libjava/classpath/javax/swing/JButton.java31
-rw-r--r--libjava/classpath/javax/swing/JCheckBox.java11
-rw-r--r--libjava/classpath/javax/swing/JCheckBoxMenuItem.java17
-rw-r--r--libjava/classpath/javax/swing/JColorChooser.java6
-rw-r--r--libjava/classpath/javax/swing/JComboBox.java10
-rw-r--r--libjava/classpath/javax/swing/JComponent.java218
-rw-r--r--libjava/classpath/javax/swing/JDesktopPane.java2
-rw-r--r--libjava/classpath/javax/swing/JDialog.java11
-rw-r--r--libjava/classpath/javax/swing/JEditorPane.java25
-rw-r--r--libjava/classpath/javax/swing/JFileChooser.java15
-rw-r--r--libjava/classpath/javax/swing/JFormattedTextField.java22
-rw-r--r--libjava/classpath/javax/swing/JFrame.java14
-rw-r--r--libjava/classpath/javax/swing/JLabel.java251
-rw-r--r--libjava/classpath/javax/swing/JLayeredPane.java51
-rw-r--r--libjava/classpath/javax/swing/JList.java59
-rw-r--r--libjava/classpath/javax/swing/JMenuBar.java2
-rw-r--r--libjava/classpath/javax/swing/JOptionPane.java60
-rw-r--r--libjava/classpath/javax/swing/JPasswordField.java46
-rw-r--r--libjava/classpath/javax/swing/JPopupMenu.java6
-rw-r--r--libjava/classpath/javax/swing/JScrollBar.java2
-rw-r--r--libjava/classpath/javax/swing/JScrollPane.java26
-rw-r--r--libjava/classpath/javax/swing/JSeparator.java2
-rw-r--r--libjava/classpath/javax/swing/JSlider.java66
-rw-r--r--libjava/classpath/javax/swing/JSpinner.java3
-rw-r--r--libjava/classpath/javax/swing/JSplitPane.java2
-rw-r--r--libjava/classpath/javax/swing/JTable.java265
-rw-r--r--libjava/classpath/javax/swing/JTextArea.java20
-rw-r--r--libjava/classpath/javax/swing/JTextField.java2
-rw-r--r--libjava/classpath/javax/swing/JTextPane.java581
-rw-r--r--libjava/classpath/javax/swing/JToggleButton.java23
-rw-r--r--libjava/classpath/javax/swing/JTree.java124
-rw-r--r--libjava/classpath/javax/swing/JViewport.java43
-rw-r--r--libjava/classpath/javax/swing/MenuSelectionManager.java17
-rw-r--r--libjava/classpath/javax/swing/RepaintManager.java9
-rw-r--r--libjava/classpath/javax/swing/SizeRequirements.java1
-rw-r--r--libjava/classpath/javax/swing/SortingFocusTraversalPolicy.java10
-rw-r--r--libjava/classpath/javax/swing/SpinnerListModel.java2
-rw-r--r--libjava/classpath/javax/swing/Spring.java6
-rw-r--r--libjava/classpath/javax/swing/SpringLayout.java10
-rw-r--r--libjava/classpath/javax/swing/SwingUtilities.java31
-rw-r--r--libjava/classpath/javax/swing/UIDefaults.java36
-rw-r--r--libjava/classpath/javax/swing/UIManager.java298
-rw-r--r--libjava/classpath/javax/swing/ViewportLayout.java14
-rw-r--r--libjava/classpath/javax/swing/border/AbstractBorder.java2
-rw-r--r--libjava/classpath/javax/swing/border/BevelBorder.java4
-rw-r--r--libjava/classpath/javax/swing/border/EtchedBorder.java2
-rw-r--r--libjava/classpath/javax/swing/border/LineBorder.java2
-rw-r--r--libjava/classpath/javax/swing/border/SoftBevelBorder.java4
-rw-r--r--libjava/classpath/javax/swing/border/TitledBorder.java6
-rw-r--r--libjava/classpath/javax/swing/event/DocumentEvent.java134
-rw-r--r--libjava/classpath/javax/swing/event/EventListenerList.java4
-rw-r--r--libjava/classpath/javax/swing/event/MenuKeyEvent.java2
-rw-r--r--libjava/classpath/javax/swing/event/SwingPropertyChangeSupport.java494
-rw-r--r--libjava/classpath/javax/swing/event/TreeSelectionEvent.java4
-rw-r--r--libjava/classpath/javax/swing/plaf/BorderUIResource.java4
-rw-r--r--libjava/classpath/javax/swing/plaf/FileChooserUI.java4
-rw-r--r--libjava/classpath/javax/swing/plaf/TextUI.java15
-rw-r--r--libjava/classpath/javax/swing/plaf/UIResource.java4
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java30
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java12
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicComboBoxEditor.java5
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicDesktopPaneUI.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java39
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java16
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java306
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java51
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java24
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java173
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicListUI.java92
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java85
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java22
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java23
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java8
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java4
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java105
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java8
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java270
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java11
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java12
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java785
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java463
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java13
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java6146
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicViewportUI.java8
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalBorders.java392
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java50
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxIcon.java10
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java20
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java806
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java11
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalLabelUI.java47
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java85
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java263
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java278
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalToggleButtonUI.java51
-rw-r--r--libjava/classpath/javax/swing/plaf/metal/MetalTreeUI.java4
-rw-r--r--libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java7
-rw-r--r--libjava/classpath/javax/swing/text/AbstractDocument.java1236
-rw-r--r--libjava/classpath/javax/swing/text/AttributeSet.java121
-rw-r--r--libjava/classpath/javax/swing/text/BadLocationException.java23
-rw-r--r--libjava/classpath/javax/swing/text/Caret.java168
-rw-r--r--libjava/classpath/javax/swing/text/ComponentView.java18
-rw-r--r--libjava/classpath/javax/swing/text/DateFormatter.java2
-rw-r--r--libjava/classpath/javax/swing/text/DefaultCaret.java293
-rw-r--r--libjava/classpath/javax/swing/text/DefaultEditorKit.java590
-rw-r--r--libjava/classpath/javax/swing/text/DefaultStyledDocument.java307
-rw-r--r--libjava/classpath/javax/swing/text/FieldView.java5
-rw-r--r--libjava/classpath/javax/swing/text/GapContent.java360
-rw-r--r--libjava/classpath/javax/swing/text/InternationalFormatter.java2
-rw-r--r--libjava/classpath/javax/swing/text/JTextComponent.java27
-rw-r--r--libjava/classpath/javax/swing/text/PasswordView.java170
-rw-r--r--libjava/classpath/javax/swing/text/PlainDocument.java16
-rw-r--r--libjava/classpath/javax/swing/text/PlainView.java18
-rw-r--r--libjava/classpath/javax/swing/text/StyledEditorKit.java569
-rw-r--r--libjava/classpath/javax/swing/text/View.java140
-rw-r--r--libjava/classpath/javax/swing/text/html/HTMLEditorKit.java7
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTD.java7
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DTDConstants.java6
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/DocumentParser.java12
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Element.java2
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/Parser.java12
-rw-r--r--libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java4
-rw-r--r--libjava/classpath/javax/swing/tree/AbstractLayoutCache.java14
-rw-r--r--libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java520
-rw-r--r--libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java1216
-rw-r--r--libjava/classpath/javax/swing/tree/DefaultTreeModel.java924
-rw-r--r--libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java2
-rw-r--r--libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java2
167 files changed, 15184 insertions, 6151 deletions
diff --git a/libjava/classpath/javax/swing/AbstractAction.java b/libjava/classpath/javax/swing/AbstractAction.java
index 6bb42339439..da65bdd1d32 100644
--- a/libjava/classpath/javax/swing/AbstractAction.java
+++ b/libjava/classpath/javax/swing/AbstractAction.java
@@ -50,8 +50,7 @@ import javax.swing.event.SwingPropertyChangeSupport;
/**
* A base class for implementing the {@link Action} interface.
*
- * @author Andrew Selkirk
- * @version 1.0
+ * @author Andrew Selkirk
*/
public abstract class AbstractAction
implements Action, Cloneable, Serializable
diff --git a/libjava/classpath/javax/swing/AbstractButton.java b/libjava/classpath/javax/swing/AbstractButton.java
index 0b5859bf591..21c4fc0a26c 100644
--- a/libjava/classpath/javax/swing/AbstractButton.java
+++ b/libjava/classpath/javax/swing/AbstractButton.java
@@ -47,9 +47,10 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
-import java.io.Serializable;
+import java.awt.image.ImageObserver;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.io.Serializable;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleIcon;
@@ -64,18 +65,13 @@ import javax.swing.text.AttributeSet;
/**
- * <p>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.</p>
+ * Provides an abstract implementation of common button behaviour,
+ * data model and look &amp; feel.
*
- * <p>Furthermore this class is supposed to serve as a base class for
+ * <p>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.</p>
+ * toggle buttons (radio buttons and checkboxes), simple push buttons,
+ * menu items, etc.</p>
*
* <p>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.</p>
*
* <p>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.</p>
@@ -1363,7 +1361,7 @@ public abstract class AbstractButton extends JComponent
* <code>null</code>, 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
* <p>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}.</p>
*
* <p>The button calls this method during construction, stores the
@@ -1553,10 +1551,10 @@ public abstract class AbstractButton extends JComponent
* <p>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.</p>
+ * #configurePropertiesFromAction} method.</p>
*
* <p>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
* <code>actionPropertyChangeListener</code> 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.</p>
+ * AbstractButton#fireStateChanged} method.</p>
*
* <p>The button calls this method during construction, stores the
* resulting ChangeListener in its <code>changeListener</code> 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.</p>
+ * AbstractButton#fireItemStateChanged} method.</p>
*
* <p>The button calls this method during construction, stores the
* resulting ItemListener in its <code>changeListener</code> member
@@ -1737,7 +1735,7 @@ public abstract class AbstractButton extends JComponent
* paint this icon when the "rolloverEnabled" property of the button is
* <code>true</code> 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 <code>true</code>, the "selected" property of the button's model is
* <code>true</code>, 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 <code>false</code> 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 86d3017f73d..4ed15809a83 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 a924b73a25f..8973e529232 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 <code>getListeners(ListDataListener.class)</code>.
*
- * @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 05a98923fb0..d61113b0827 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 17168c3be18..3dd63539ddc 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 c6092578a5e..c14bafdb4be 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 <code>InputMap</code>. The result is an object which
+ * serves as a key to the components <code>ActionMap</code>. Finally
+ * the <code>Action</code> 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 b084b61a16a..45cf3bbe074 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 5f85000d66b..5ca5a7e043e 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 <i>range</i> that is constrained to fit
+ * within specified <i>bounds</i>. The range is defined as <code>value</code>
+ * to <code>value + extent</code>, where both <code>value</code> and
+ * <code>extent</code> are integers, and <code>extent >= 0</code>. The bounds
+ * are defined by integers <code>minimum</code> and <code>maximum</code>.
+ * <p>
+ * 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
+ * <code>min <= value <= value + extent <= max</code>.
*
* @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 <code>true</code> if value is adjusting,
* otherwise <code>false</code>
*
- * @see setValueIsAdjusting(boolean)
+ * @see #setValueIsAdjusting(boolean)
*/
boolean getValueIsAdjusting();
/**
- * setValueIsAdjusting
+ * Sets the <code>valueIsAdjusting</code> property.
*
* @param adjusting <code>true</code> if adjusting,
* <code>false</code> 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 546a2822088..b2cb44aceb5 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 <code>Box</code>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 <code>Box.Filler</code>.
+ */
// 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 5dfe1d6b735..28bb53928ef 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 <code>insets.top</code> for vertical direction
* and <code>insets.left</code> 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 <code>insets.top</code> for vertical direction
* and <code>insets.left</code> 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 bea8aea0311..3de1d4b9f16 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 <code>ButtonGroup</code> can be selected at the same time. If one
+ * button in a <code>ButtonGroup</code> is selected, all other buttons
+ * are automatically deselected.
+ *
+ * While <code>ButtonGroup</code> 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 <code>ButtonGroup</code> because they don't implement the
+ * <code>selected</code> 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 db7a1434166..886d5c5f2a8 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 4ecc0585267..f95c3104535 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 <code>ComponentInputMap</code> 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 <code>InputMap</code>.
*
- * @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
* <code>ComponentInputMap</code> 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 e73c120e317..137b82337af 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. <code>DebugGraphics</code> 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 53c0fb34343..10de4b94837 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 <code>BoundedRangeModel</code>.
+ * The default implementation of <code>BoundedRangeModel</code>.
*
* @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}<code>.class</code>.
*
* @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 2cfb9e96eb8..f7d09d5780d 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 <code>true</code>.
*
* @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 e67e2f5a403..00e00864432 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 1cea886b793..b48b968d697 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 15ed262e8e8..2b8977e9d6d 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 dd8e6047bb8..08db651680a 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 0f2417d04d6..5a34ba7aa18 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 <code>DefaultListCellRenderers</code> and implements
+ * {@link javax.swing.plaf.UIResource}. This is used by
+ * {@link javax.swing.plaf.ListUI} subclasses to provide a default for
+ * the <code>List.cellRenderer</code> property. If you want to override
+ * this property, use <code>DefaultListCellRenderer</code> 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 d7ff2599b58..fdbbb562c90 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 d08ca6fc3d2..f8d544d9b20 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;
/**
- * <p>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. </p>
+ * elements.
*
* <p>The class is organized <em>abstractly</em> 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
* <code>[A,L]</code> be the range of indices between {@link
- * anchorSelectionIndex} and {@link leadSelectionIndex} inclusive, and
+ * #anchorSelectionIndex} and {@link #leadSelectionIndex} inclusive, and
* let <code>[i0,i1]</code> be the range of indices changed in a given
* call which generates a {@link ListSelectionEvent}. Then when this
* property is <code>true</code>, 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.</p>
*
- * @param anchorIndex The new property value
+ * @param leadIndex The new property value
*
* @see #getAnchorSelectionIndex
*/
@@ -292,9 +292,9 @@ public class DefaultListSelectionModel implements Cloneable,
/**
* Sets the value of the {@link #leadAnchorNotificationEnabled} property.
*
- * @param flag The new property value
+ * @param l The new property value
*
- * @see #getLeadAnchorNotificationEnabled
+ * @see #isLeadAnchorNotificationEnabled
*/
public void setLeadAnchorNotificationEnabled(boolean l)
{
@@ -588,7 +588,7 @@ public class DefaultListSelectionModel implements Cloneable,
* indicate that a series of adjustment has just ended.
*
* The values of {@link #getMinSelectionIndex} and
- * {@link getMaxSelectionIndex} are used in the {@link ListSelectionEvent}
+ * {@link #getMaxSelectionIndex} are used in the {@link ListSelectionEvent}
* that gets fired.
*
* @param isAdjusting <code>true</code> 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 039883e23ae..8f4d405f9d4 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 9f898e69252..179fa6f82d2 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 1a88f6f19a8..b920b088a17 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 c00eee46238..c73ad2d4049 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 36f23d2b225..b650cd81f23 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 <code>g.drawImage()</code> 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 afc431d4836..a7ec38c4117 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 <code>InputMap</code>. The result is an object which
+ * serves as a key to the components <code>ActionMap</code>. Finally
+ * the <code>Action</code> 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 <code>InputMap</code>.
*
- * @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 836c1a558ad..8e02ab813a3 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 <code>InputVerifier</code>
+ * 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 0609f09f8f2..4780a67c521 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 95a05c0329f..cafb2dabbb8 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 0234e47afb6..5653fbf42f1 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. <code>JButton</code>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 <code>JButton</code>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 5e7e80c94b9..a743308dcca 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
+ * <code>selected</code> state. This works very similar to
+ * {@link JToggleButton} and {@link JRadioButton}, but in UI design it
+ * has different semantics. <code>JCheckBox</code>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
+ * <code>JCheckBox</code>.
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
diff --git a/libjava/classpath/javax/swing/JCheckBoxMenuItem.java b/libjava/classpath/javax/swing/JCheckBoxMenuItem.java
index 46a42ad210f..f9dd56500fe 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 <code>JCheckBox</code>, 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.
+ * <code>JCheckBoxMenuItem</code> uses
+ * <code>ToggleButtonModel</code> 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 <code>JCheckBoxMenuItem</code>.
+ */
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 e16b98112af..4016b82f3fd 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 <code>JColorChooser</code>.
*/
protected class AccessibleJColorChooser
extends JComponent.AccessibleJComponent
diff --git a/libjava/classpath/javax/swing/JComboBox.java b/libjava/classpath/javax/swing/JComboBox.java
index 4284ec8ea52..47d18323a25 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 <code>JComboBox</code>.
*/
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 42a5317dc77..dc7689b0930 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 <code>JComponent</code> derived
+ * widgets.
+ */
public abstract class AccessibleJComponent
extends AccessibleAWTContainer
implements AccessibleExtendedComponent
{
+ /**
+ * Accessibility support for <code>JComponent</code>'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 <code>JComponent</code>'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 <code>nextFocusableComponent</code> property.
*
* @return The current value of the property, or <code>null</code>
* 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 <code>toolTip</code> property of this component, creating it and
* setting it if it is currently <code>null</code>. 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 <code>null</code> 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.</p>
*
* <p>This method should not be called by clients; it is intended for
- * focus implementations. Use {@link Component#requestFocus} instead.</p>
+ * focus implementations. Use {@link Component#requestFocus()} instead.</p>
*
- * @see {@link Component#requestFocus}
+ * @see Component#requestFocus()
*/
public void grabFocus()
{
@@ -1317,8 +1334,8 @@ public abstract class JComponent extends Container implements Serializable
* @return <code>true</code> if you want this component to manage its own
* focus, otherwise (by default) <code>false</code>
*
- * @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 <code>true</code> 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 <code>false</code>, but some
- * components such as {@link JViewPort} will want to return
+ * components such as {@link JViewport} will want to return
* <code>true</code>.
*
* @return Whether this component is a validation root
@@ -1386,7 +1403,7 @@ public abstract class JComponent extends Container implements Serializable
/**
* <p>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.</p>
*
* <p>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 <code>enabled</code> 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 <code>font</code> 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 <code>background</code> 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 <code>foreground</code> 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 <code>"ComponentUI"</code>
@@ -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 <code>false</code> if the focus change request will definitly
* fail, <code>true</code> 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 <code>false</code> if the focus change request will definitly
* fail, <code>true</code> 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 <code>false</code> if the focus change request will definitly
* fail, <code>true</code> 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 ff512114e93..f4c80eca7d6 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 83865f836f3..0f528ab1b45 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 <code>java.awt.Dialog</code>s, JDialogs support the
+ * Swing Pluggable Look &amp; 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 63c79ffdf12..e2f1319a2a7 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:
+ * <ul>
+ * <li><code>text/plain</code>: Plain text, handled by
+ * {@link javax.swing.text.DefaultEditorKit}.</li>
+ * <li><code>text/html</code>: HTML 4.0 styled text, handled by
+ * {@link javax.swing.text.html.HTMLEditorKit}.</li>
+ * <li><code>text/rtf</code>: RTF text, handled by
+ * {@link javax.swing.text.rtf.RTFEditorKit}.</li>
+ * </ul>
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
+ */
public class JEditorPane extends JTextComponent
{
private static final long serialVersionUID = 3140472492599046285L;
diff --git a/libjava/classpath/javax/swing/JFileChooser.java b/libjava/classpath/javax/swing/JFileChooser.java
index 17292fa4f61..7569061ab2e 100644
--- a/libjava/classpath/javax/swing/JFileChooser.java
+++ b/libjava/classpath/javax/swing/JFileChooser.java
@@ -54,7 +54,17 @@ import javax.swing.plaf.FileChooserUI;
/**
- * DOCUMENT ME!
+ * A component that provides the user a dialog box to browse through a
+ * filesystem and choose one or more files or directories.
+ *
+ * A JFileChooser can be configured to filter the displayed file list
+ * by adding a {@link FileFilter} instance using
+ * {@link #addChoosableFileFilter(FileFilter)}. Additional components can
+ * be embedded in the file chooser using {@link #setAccessory(JComponent)}.
+ * The JFileChooser properties also provide mechanisms to customize the
+ * behaviour of the file chooser.
+ *
+ * @author Kim Ho (kho@luxsci.net)
*/
public class JFileChooser extends JComponent implements Accessible
{
@@ -415,7 +425,8 @@ public class JFileChooser extends JComponent implements Accessible
*/
public void changeToParentDirectory()
{
- setCurrentDirectory(fsv.getParentDirectory(currentDir));
+ if (fsv.getParentDirectory(currentDir) != null)
+ setCurrentDirectory(fsv.getParentDirectory(currentDir));
}
/**
diff --git a/libjava/classpath/javax/swing/JFormattedTextField.java b/libjava/classpath/javax/swing/JFormattedTextField.java
index f8230f69fb3..9890df20087 100644
--- a/libjava/classpath/javax/swing/JFormattedTextField.java
+++ b/libjava/classpath/javax/swing/JFormattedTextField.java
@@ -51,13 +51,29 @@ import javax.swing.text.DocumentFilter;
import javax.swing.text.NavigationFilter;
/**
+ * A text field that makes use of a formatter to display and edit a specific
+ * type of data. The value that is displayed can be an arbitrary object. The
+ * formatter is responsible for displaying the value in a textual form and
+ * it may allow editing of the value.
+ *
+ * Formatters are usually obtained using an instance of
+ * {@link AbstractFormatterFactory}. This factory is responsible for providing
+ * an instance of {@link AbstractFormatter} that is able to handle the
+ * formatting of the value of the JFormattedTextField.
+ *
* @author Michael Koch
+ *
* @since 1.4
*/
public class JFormattedTextField extends JTextField
{
private static final long serialVersionUID = 5464657870110180632L;
+ /**
+ * An abstract base implementation for a formatter that can be used by
+ * a JTextField. A formatter can display a specific type of object and
+ * may provide a way to edit this value.
+ */
public abstract static class AbstractFormatter implements Serializable
{
private static final long serialVersionUID = -5193212041738979680L;
@@ -124,7 +140,11 @@ public class JFormattedTextField extends JTextField
public abstract String valueToString (Object value)
throws ParseException;
}
-
+
+ /**
+ * Delivers instances of an {@link AbstractFormatter} for
+ * a specific value type for a JFormattedTextField.
+ */
public abstract static class AbstractFormatterFactory
{
public AbstractFormatterFactory ()
diff --git a/libjava/classpath/javax/swing/JFrame.java b/libjava/classpath/javax/swing/JFrame.java
index d8b10d5e36d..7081f5980e4 100644
--- a/libjava/classpath/javax/swing/JFrame.java
+++ b/libjava/classpath/javax/swing/JFrame.java
@@ -53,9 +53,15 @@ import java.awt.event.WindowEvent;
import javax.accessibility.AccessibleContext;
/**
- * Unlike JComponent derivatives, JFrame inherits from
- * java.awt.Frame. But also lets a look-and-feel component to its work.
+ * A window that supports window decorations (titlebar and borders).
+ * This is an extension of {@link java.awt.Frame} 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.
*
+ * Also, unlike <code>java.awt.Frame</code>s, JFrames support the
+ * Swing Pluggable Look &amp; 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 <code>GraphicsConfiguration</code> that is used for
* the new <code>JFrame</code>
*
- * @see Frame(GraphicsConfiguration)
+ * @see Frame#Frame(GraphicsConfiguration)
*/
public JFrame(GraphicsConfiguration gc)
{
@@ -114,7 +120,7 @@ public class JFrame extends Frame
* @param gc the <code>GraphicsConfiguration</code> that is used for
* the new <code>JFrame</code>
*
- * @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 088f7d69345..2e7ad98ddae 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
+ * <code>AttributeSet</code> 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
+ * <code>part</code> 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 <code>index</code>
+ */
+ 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
+ * <code>part</code> 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 <code>index</code>
+ */
+ 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
+ * <code>part</code> 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 <code>index</code>
+ */
+ 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 c9a4fd40413..1ea39dc5007 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;
/**
- * <p>The "Layered Pane" is a container which divides its children into 6 (or
- * more) disjoint sets. the pre-defined sets are:</p>
+ * A container that adds depth to the usual <code>Container</code> semantics.
+ * Each child component of a <code>Layered Pane</code> is placed within one
+ * of several layers. <code>JLayeredPane</code> defines a set of standard
+ * layers. The pre-defined sets are (in the order from button to top):
*
- * <ul>
- * <li>"Frame Content"</li>
- * <li>"Default"</li>
- * <li>"Palette"</li>
- * <li>"Modal"</li>
- * <li>"Popup"</li>
- * <li>"Drag"</li>
- * </ul>
+ * <dl>
+ * <dt>{@link #DEFAULT_LAYER}</dt>
+ * <dd>The layer where most of the normal components are placed. This
+ * is the bottommost layer.</dd>
+ *
+ * <dt>{@link #PALETTE_LAYER}</dt>
+ * <dd>Palette windows are placed in this layer.</dd>
+ *
+ * <dt>{@link #MODAL_LAYER}</dt>
+ * <dd>The layer where internal modal dialog windows are placed.</dd>
+ *
+ * <dt>{@link #POPUP_LAYER}</dt>
+ * <dd>The layer for popup menus</dd>
+ *
+ * <dt>{@link #DRAG_LAYER}</dt>
+ * <dd>Components that are beeing dragged are temporarily placed in
+ * this layer.</dd>
+ * </dl>
*
* <p>A child is in exactly one of these layers at any time, though there may
* be other layers if someone creates them.</p>
*
+ * <p>You can add a component to a specific layer using the
+ * {@link Container#add(Component, Object)} method. I.e.
+ * <code>layeredPane.add(comp, JLayeredPane.MODAL_LAYER)</code> will add the
+ * component <code>comp</code> to the modal layer of <code>layeredPane</code>.
+ * </p>
+ *
+ * <p>To change the layer of a component that is already a child of
+ * a <code>JLayeredPane</code>, use the {@link #setLayer(Component, int)}
+ * method.</p>
+ *
* <p>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}.</p>
@@ -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 fb8d18b8565..92fe1ccfa67 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 <code>-1</code>
+ * @return The index of the last visible list cell, or <code>-1</code>
* 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 a464fff9bae..eebb1a050be 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 88fa993be00..ad0772ab8d3 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 <code>JDesktopPane</code> that is found in
+ * <code>parent</code>'s ancestors. The behaviour of the JDK
+ * is that it actually looks up the nearest
+ * <code>JLayeredPane</code> in <code>parent</code>'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 f9df10217c8..151d2484a82 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 <code>true</code> if the echo char is set,
* <code>false</code> 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 a0a735965c5..c4ee5fe7346 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 caed92cf60e..a2cc76c656b 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 377f05a88c2..e83513f07de 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 <code>JScrollPane</code> 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 064c465b511..6a3b97d35c6 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 7f995115d8f..2caf509a1bb 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 <code>orientation</code> 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 <code>orientation</code> 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 (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>model</code> is <code>null</code>.
*/
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 <code>increment</code> 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 <code>increment</code> is not greater
+ * than zero, or <code>start</code> 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 96fe10f7268..fc2b13e81a9 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 <code>DateEditor</code> 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 d7abce99a7c..cea5afef20a 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 505a4602d98..21680d567e2 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 <code>JTable</code> 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 fb35eb3d14c..53591ffcc3a 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 <code>JTextArea</code> 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 <code>JTextArea</code> 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 <code>direction</code>.
*
* @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 <code>true</code> to enable line wrapping,
+ * @param flag <code>true</code> to enable line wrapping,
* <code>false</code> otherwise
*/
public void setLineWrap(boolean flag)
diff --git a/libjava/classpath/javax/swing/JTextField.java b/libjava/classpath/javax/swing/JTextField.java
index 7d8407fa019..5ae9c9f1a82 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 532181258c8..80632fff38e 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 <code>JTextPane</code> with a <code>null</code> document.
+ */
+ public JTextPane()
+ {
+ super();
+ }
+
+ /**
+ * Creates a new <code>JTextPane</code> and sets the specified
+ * <code>document</code>.
+ *
+ * @param document the content model to use
+ */
+ public JTextPane(StyledDocument document)
+ {
+ this();
+ setStyledDocument(document);
+ }
+
+ /**
+ * Returns the UI class ID. This is <code>TextPaneUI</code>.
+ *
+ * @return <code>TextPaneUI</code>
+ */
+ public String getUIClassID()
+ {
+ return "TextPaneUI";
+ }
+
+ /**
+ * Sets the content model for this <code>JTextPane</code>.
+ * <code>JTextPane</code> can only be used with {@link StyledDocument}s,
+ * if you try to set a different type of <code>Document</code>, an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
+ * @param document the content model to set
+ *
+ * @throws IllegalArgumentException if <code>document</code> is not an
+ * instance of <code>StyledDocument</code>
+ *
+ * @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 <code>JTextPane</code>. This is a typed wrapper for
+ * {@link #getDocument}.
+ *
+ * @return the content model of this <code>JTextPane</code>
+ */
+ public StyledDocument getStyledDocument()
+ {
+ return (StyledDocument) super.getDocument();
+ }
+
+ /**
+ * Sets the content model for this <code>JTextPane</code>.
+ *
+ * @param document the content model to set
+ */
+ public void setStyledDocument(StyledDocument document)
+ {
+ super.setDocument(document);
+ }
+
+ /**
+ * Replaces the currently selected text with the specified
+ * <code>content</code>. If there is no selected text, this results
+ * in a simple insertion at the current caret position. If there is
+ * no <code>content</code> 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 <code>Icon</code> into the text at the current caret position.
+ *
+ * @param icon the <code>Icon</code> 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 <code>parent</code> style, if one is specified.
+ *
+ * While it is legal to add nameless styles (<code>nm == null</code),
+ * you must be aware that the client application is then responsible
+ * for managing the style hierarchy, since unnamed styles cannot be
+ * looked up by their name.
+ *
+ * @param nm the name of the style or <code>null</code> if the style should
+ * be unnamed
+ * @param parent the parent in which unspecified style attributes are
+ * resolved, or <code>null</code> if that is not necessary
+ *
+ * @return the newly created <code>Style</code>
+ */
+ public Style addStyle(String nm, Style parent)
+ {
+ return getStyledDocument().addStyle(nm, parent);
+ }
+
+ /**
+ * Removes a named <code>Style</code> from the style hierarchy.
+ *
+ * @param nm the name of the <code>Style</code> to be removed
+ */
+ public void removeStyle(String nm)
+ {
+ getStyledDocument().removeStyle(nm);
+ }
+
+ /**
+ * Looks up and returns a named <code>Style</code>.
+ *
+ * @param nm the name of the <code>Style</code>
+ *
+ * @return the found <code>Style</code> of <code>null</code> if no such
+ * <code>Style</code> 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 <code>true</code>, 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 <code>true</code>, 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
+ * <code>JTextPane</code>.
+ *
+ * @return the current <code>StyledEditorKit</code> of this
+ * <code>JTextPane</code>
+ */
+ protected final StyledEditorKit getStyledEditorKit()
+ {
+ return (StyledEditorKit) getEditorKit();
+ }
+
+ /**
+ * Creates the default {@link EditorKit} that is used in
+ * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}.
+ *
+ * @return the default {@link EditorKit} that is used in
+ * <code>JTextPane</code>s
+ */
+ protected EditorKit createDefaultEditorKit()
+ {
+ return new StyledEditorKit();
+ }
+
+ /**
+ * Sets the {@link EditorKit} to use for this <code>JTextPane</code>.
+ * <code>JTextPane</code>s can only handle {@link StyledEditorKit}s,
+ * if client programs try to set a different type of <code>EditorKit</code>
+ * then an IllegalArgumentException is thrown
+ *
+ * @param editor the <code>EditorKit</code> to set
+ *
+ * @throws IllegalArgumentException if <code>editor</code> is no
+ * <code>StyledEditorKit</code>
+ */
+ 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 0e1b9e60111..25d67f59e4f 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 bccd983b756..bb24c7a459d 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 <code>TreeExpansionListener</code> 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 <code>true</code> then <code>path</code> itself
+ * @param includeSelected if <code>true</code> then <code>path</code> itself
* will also be remove if it's selected
*
* @return <code>true</code> if something has been removed,
diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java
index 397cb31acdf..d750bad29cc 100644
--- a/libjava/classpath/javax/swing/JViewport.java
+++ b/libjava/classpath/javax/swing/JViewport.java
@@ -89,7 +89,7 @@ import javax.swing.plaf.ViewportUI;
*
* <p>But in terms of drawing its child, the viewport thinks of itself as
* covering a particular position <em>of the view's coordinate space</em>.
- * For example, the {@link javax.JViewPort.getViewPosition} method returns
+ * For example, the {@link #getViewPosition} method returns
* the position <code>(VX,VY)</code> shown above, which is an position in
* "view space", even though this is <em>implemented</em> by positioning
* the underlying child at position <code>(-VX,-VY)</code></p>
@@ -487,4 +487,45 @@ public class JViewport extends JComponent
{
return new ViewportLayout();
}
+
+ /**
+ * Scrolls the view so that contentRect becomes visible.
+ *
+ * @param contentRect the rectangle to make visible within the view
+ */
+ public void scrollRectToVisible(Rectangle contentRect)
+ {
+ Point pos = getViewPosition();
+ Rectangle viewBounds = getView().getBounds();
+ Rectangle portBounds = getBounds();
+
+ // FIXME: should validate the view if it is not valid, however
+ // this may cause excessive validation when the containment
+ // hierarchy is being created.
+
+ // if contentRect is larger than the portBounds, center the view
+ if (contentRect.height > portBounds.height ||
+ contentRect.width > portBounds.width)
+ {
+ setViewPosition(new Point(contentRect.x, contentRect.y));
+ return;
+ }
+
+ // Y-DIRECTION
+ if (contentRect.y < -viewBounds.y)
+ setViewPosition(new Point(pos.x, contentRect.y));
+ else if (contentRect.y + contentRect.height >
+ -viewBounds.y + portBounds.height)
+ setViewPosition (new Point(pos.x, contentRect.y -
+ (portBounds.height - contentRect.height)));
+
+ // X-DIRECTION
+ pos = getViewPosition();
+ if (contentRect.x < -viewBounds.x)
+ setViewPosition(new Point(contentRect.x, pos.y));
+ else if (contentRect.x + contentRect.width >
+ -viewBounds.x + portBounds.width)
+ setViewPosition (new Point(contentRect.x -
+ (portBounds.width - contentRect.width), pos.y));
+ }
}
diff --git a/libjava/classpath/javax/swing/MenuSelectionManager.java b/libjava/classpath/javax/swing/MenuSelectionManager.java
index acaee974e3a..32d56b958a1 100644
--- a/libjava/classpath/javax/swing/MenuSelectionManager.java
+++ b/libjava/classpath/javax/swing/MenuSelectionManager.java
@@ -211,17 +211,18 @@ public class MenuSelectionManager
public boolean isComponentPartOfCurrentMenu(Component c)
{
MenuElement[] subElements;
- for (int i = 0; i < selectedPath.size(); i++)
+ for (int i = 0; i < selectedPath.size(); i++)
{
- subElements = ((MenuElement) selectedPath.get(i)).getSubElements();
- for (int j = 0; j < subElements.length; j++)
- {
- if ((subElements[j].getComponent()).equals(c))
- return true;
- }
+ subElements = ((MenuElement) selectedPath.get(i)).getSubElements();
+ for (int j = 0; j < subElements.length; j++)
+ {
+ MenuElement me = subElements[j];
+ if (me != null && (me.getComponent()).equals(c))
+ return true;
+ }
}
- return false;
+ return false;
}
/**
diff --git a/libjava/classpath/javax/swing/RepaintManager.java b/libjava/classpath/javax/swing/RepaintManager.java
index 8c4c323c90a..698dbe8e898 100644
--- a/libjava/classpath/javax/swing/RepaintManager.java
+++ b/libjava/classpath/javax/swing/RepaintManager.java
@@ -42,6 +42,7 @@ import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
+import java.awt.image.VolatileImage;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
@@ -72,7 +73,7 @@ public class RepaintManager
* typically only one of these objects active at any time. When the
* {@link RepaintManager} is told to queue a repaint, it checks to see if
* a {@link RepaintWorker} is "live" in the system event queue, and if
- * not it inserts one using {@link SwingUtilities.invokeLater}.</p>
+ * not it inserts one using {@link SwingUtilities#invokeLater}.</p>
*
* <p>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 430aeed5151..77b42db1ce9 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 48f864b5bd9..fada17c6339 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 <code>SortingFocusTraversalPolicy</code> 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 a0dc4d14462..85dc4efa6f1 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 <code>SpinnerModel</code> 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 4255e86f8e6..69c88c77d96 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 b45edba5357..df9ddffb654 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 <code>edgeName</code>.
* 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 <code>edgeName</code> of the
* component c.
*/
diff --git a/libjava/classpath/javax/swing/SwingUtilities.java b/libjava/classpath/javax/swing/SwingUtilities.java
index 69b634579e5..ee5fa74d47a 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 <code>(x,y)</code>, or
* <code>null</code>
*
- * @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 <code>true</code> 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 06fee05c658..ab78ca6442f 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 <code>key</code> 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 7f6d65e74a6..f4648f1e219 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 <code>UIManager</code>. 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 (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>laf</code> is <code>null</code>.
+ *
+ * @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 <code>true</code> if the LAF was removed, and <code>false</code>
+ * otherwise.
+ */
public static boolean removeAuxiliaryLookAndFeel(LookAndFeel laf)
{
- if (aux_installed == null)
+ if (auxLookAndFeels == null)
return false;
-
- for (int i=0;i<aux_installed.length;i++)
+ int count = auxLookAndFeels.length;
+ if (count == 1 && auxLookAndFeels[0] == laf)
{
- if (aux_installed[i] == laf)
+ auxLookAndFeels = null;
+ return true;
+ }
+ for (int i = 0; i < count; i++)
+ {
+ if (auxLookAndFeels[i] == laf)
{
- aux_installed[ i ] = aux_installed[aux_installed.length-1];
- LookAndFeel[] T = new LookAndFeel[ aux_installed.length-1 ];
- System.arraycopy (aux_installed, 0, T, 0, aux_installed.length-1);
- aux_installed = T;
+ LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length - 1];
+ if (i == 0)
+ {
+ System.arraycopy(auxLookAndFeels, 1, temp, 0, count - 1);
+ }
+ else if (i == count - 1)
+ {
+ System.arraycopy(auxLookAndFeels, 0, temp, 0, count - 1);
+ }
+ else
+ {
+ System.arraycopy(auxLookAndFeels, 0, temp, 0, i);
+ System.arraycopy(auxLookAndFeels, i + 1, temp, i,
+ count - i - 1);
+ }
+ auxLookAndFeels = temp;
return true;
}
}
return false;
}
- public static LookAndFeel[] getAuxiliaryLookAndFeels()
+ /**
+ * Returns an array (possibly <code>null</code>) containing the auxiliary
+ * {@link LookAndFeel}s that are in use. These are used by the
+ * {@link javax.swing.plaf.multi.MultiLookAndFeel} class.
+ *
+ * @return The auxiliary look and feels (possibly <code>null</code>).
+ *
+ * @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 <code>"javax.swing.plaf.metal.MetalLookAndFeel"</code>
*/
- 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 <code>null</code>).
+ *
+ * @return The current look and feel.
+ *
+ * @see #setLookAndFeel(LookAndFeel)
+ */
public static LookAndFeel getLookAndFeel()
{
- return look_and_feel;
+ return currentLookAndFeel;
}
/**
* Returns the <code>UIDefaults</code> 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 (<code>null</code> 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 18b49125743..19735839387 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 d755b6779d8..951debd5207 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 <code>insets</code>.
*
- * @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 e755fdcc94c..fcdc1c64675 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 <code>highlight</code> or
* <code>shadow</code> is <code>null</code>.
*
- * @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 <code>insets</code>.
*
- * @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 ea2a61d9e67..0bd76ff0fb6 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 <code>insets</code>.
*
- * @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 00c16342c96..c34e38c5789 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 <code>insets</code>.
*
- * @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 fa718e35bac..379ecb65a35 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 <code>highlight</code> or
* <code>shadow</code> is <code>null</code>.
*
- * @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 <code>insets</code>.
*
- * @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 30e4bcd6947..ceae2b1c9e3 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 <code>insets</code>.
*
- * @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
* <code>null</code> 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 6a005ea7a5b..6cd8e61fee4 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 ea14d4d1474..3b9f4c807de 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 <code>listener</code> is not
* an instance of <code>t</code> (or a subclass thereof).
*
- * @throws Exception if <code>t</code> is <code>null</code>.
+ * @throws NullPointerException if <code>t</code> is <code>null</code>.
*/
public void add(Class t, EventListener listener)
{
@@ -246,7 +246,7 @@ public class EventListenerList
* @throws IllegalArgumentException if <code>listener</code> is not
* an instance of <code>t</code> (or a subclass thereof).
*
- * @throws Exception if <code>t</code> is <code>null</code>.
+ * @throws NullPointerException if <code>t</code> is <code>null</code>.
*/
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 48fcb45b5b3..511cb2254cd 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 ddbb4865883..408ca957e95 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 <code>String</code> 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 (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>source</code> is <code>null</code>.
+ */
+ public SwingPropertyChangeSupport(Object source)
+ {
+ super(source);
+ this.source = source;
+ this.listeners = new EventListenerList();
+ this.propertyListeners = new Hashtable();
+ }
+
+ /**
+ * Registers <code>listener</code> to receive notification of any future
+ * {@link PropertyChangeEvent}s generated by this instance.
+ *
+ * @param listener the listener (<code>null</code> is ignored).
+ *
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener
+ listener)
+ {
+ listeners.add(PropertyChangeListener.class, listener);
+ }
+
+ /**
+ * Registers <code>listener</code> 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 <code>listener</code> 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 <code>listener</code> 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 <code>SwingPropertyChangeSupport</code> 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 <code>source</code> for this
+ * <code>SwingPropertyChangeSupport</code> instance) and forwards it to all
+ * registered listeners via the
+ * {@link PropertyChangeListener#propertyChange(PropertyChangeEvent)} method.
+ * <p>
+ * Note that if <code>oldValue</code> and <code>newValue</code> 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 <code>event</code> to registered listeners.
+ * <p>
+ * Note that if the event's <code>getOldValue()</code> and
+ * <code>getNewValue()</code> 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 <code>true</code> 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 df4e0ff9128..9b87667a387 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 1bf854033b2..4402bbb48b6 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 87847c44fe1..8b661e399a5 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 <code>JFileChooser</code> 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 <code>JFileChooser</code> 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 86d1f1f1b80..dcabdfcdbf3 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 <code>pos</code> 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 <code>pos</code> 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 <code>JTextComponent</code> for which this
+ * @param t the <code>JTextComponent</code> 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 <code>loc</code>.
*
@@ -191,7 +188,7 @@ public abstract class TextUI
*
* @throws IllegalArgumentException if <code>direction</code>
* is not one of <code>Position.Bias.Forward</code>
- * or <code>Position.Biad.Backward</code>.
+ * or <code>Position.Bias.Backward</code>.
*/
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 1e28280e82f..59edf566605 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
- * <code>ComponentUI</code> delegates. When uninstalling the user public interface
+ * {@link ComponentUI} delegates. When uninstalling the user public interface
* renderer with <code>ComponentUI.uninstallUI()</code> the renderer
* property is set to <code>null</code>.
* <br>
@@ -50,6 +50,6 @@ package javax.swing.plaf;
* they are initialized or set to <code>null</code>.
*
* @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 4da4691f6d8..836ef223494 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 d893c5d0a1b..6c80f14b6fc 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 da11898bf0b..945aea53dc3 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 e3167327c3a..3cf02a00156 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 04296df0a85..dd867f0dc55 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 b15700d6fc8..b59261b17f3 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 6dd15a8f982..d5b34d9eef6 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 <code>BasicEditorPaneUI</code> for the text
+ * component <code>comp</code>.
+ *
+ * @param comp the component for which to create an UI
+ *
+ * @return the UI for <code>comp</code>
+ */
public static ComponentUI createUI(JComponent comp)
{
return new BasicEditorPaneUI();
}
+ /**
+ * Creates a new <code>BasicEditorPaneUI</code>
+ */
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
+ * <code>EditorPane</code> in this case.
+ *
+ * @return <code>EditorPane</code>
+ */
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 fd34fbd6227..f74e9229893 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 78ee62f95f8..757ac47c903 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 e7aad8964ba..56a67b02935 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&amp;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&amp;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 91db0cbeb7c..cc262948ded 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 16379668278..8f76ea0cc19 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 e71e82f03d1..bb9ce6cb1d9 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 24c6cd20b61..841bd670f67 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 14fe28f7110..d35ac9eb926 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 a5bf0822ac5..8aa1193bcc4 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 6bd15ede2c5..30be592ee79 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;i<mb.getMenuCount();i++)
- if (((JMenu)mb.getComponent(i)).isPopupMenuVisible())
+ for (int i = 0; i < mb.getMenuCount(); i++)
+ {
+ JMenu m = mb.getMenu(i);
+ if (m != null && m.isPopupMenuVisible())
return true;
+ }
return false;
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java
index ce29f24b42a..c9f623259ba 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java
@@ -910,7 +910,9 @@ public class BasicOptionPaneUI extends OptionPaneUI
*/
protected Container createSeparator()
{
- return (Container) Box.createVerticalStrut(17);
+ // FIXME: Figure out what this method is supposed to return and where
+ // this should be added to the OptionPane.
+ return null;
}
/**
@@ -1115,6 +1117,10 @@ public class BasicOptionPaneUI extends OptionPaneUI
optionPane.add(msg);
}
+ // FIXME: Figure out if the separator should be inserted here or what
+ // this thing is supposed to do. Note: The JDK does NOT insert another
+ // component at this place. The JOptionPane only has two panels in it
+ // and there actually are applications that depend on this beeing so.
Container sep = createSeparator();
if (sep != null)
optionPane.add(sep);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java
index 0896721ca99..b715c57b360 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java
@@ -40,6 +40,8 @@ package javax.swing.plaf.basic;
import javax.swing.JComponent;
import javax.swing.JPanel;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
@@ -62,6 +64,8 @@ public class BasicPanelUI extends PanelUI
public void installDefaults(JPanel p)
{
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ p.setBackground(defaults.getColor("Panel.background"));
p.setOpaque(true);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
index d5cd7f4488e..fa74a008bae 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
@@ -77,13 +77,13 @@ public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
}
/**
- * DOCUMENT ME!
+ * Returns the prefix for entries in the {@link UIDefaults} table.
*
- * @return $returnType$ DOCUMENT ME!
+ * @return "RadioButtonMenuItem"
*/
protected String getPropertyPrefix()
{
- return null;
+ return "RadioButtonMenuItem";
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
index 38e117b18b2..fbd21241a0d 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
@@ -38,50 +38,125 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+/**
+ * The BasicLookAndFeel UI implementation for
+ * {@link javax.swing.JRadioButton}s.
+ */
public class BasicRadioButtonUI extends BasicToggleButtonUI
{
-
+ /**
+ * 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.
+ */
protected Icon icon;
+ /**
+ * Creates and returns a new instance of <code>BasicRadioButtonUI</code>.
+ *
+ * @return a new instance of <code>BasicRadioButtonUI</code>
+ */
public static ComponentUI createUI(final JComponent c) {
return new BasicRadioButtonUI();
}
+ /**
+ * Creates a new instance of <code>BasicButtonUI</code>.
+ */
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 &amp; 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
+ * <code>RadioButton</code> 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 892db2b031b..22242afcd8a 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 7bb7acffb8d..bd1576f37a5 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 0a72a62ff9c..0b4058429c5 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 ff7e8acfbb6..ef8e2282349 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 8a27f98a3c9..7e9d9b9820c 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 778743619bc..4559937eb69 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 dd0828e466a..91ccb0056bb 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 <code>true</code> if the width preference has changed
+ * @param height <code>true</code> 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 <code>1</code> since the RootView always contains one
+ * child, that is the real root of the View hierarchy.
+ *
+ * @return <code>1</code> 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 <code>Container</code> that contains this view. This
+ * normally will be the text component that is managed by this TextUI.
+ *
+ * @return the <code>Container</code> that contains this view
+ */
public Container getContainer()
{
return textComponent;
}
-
+
+ /**
+ * Returns the preferred span along the specified <code>axis</code>.
+ * 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 <code>Graphics</code> 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 <code>null</code> this defaults to
+ * <code>Position.Bias.Forward</code>
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> 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 <code>View</code>'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 <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ 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 <code>BasicTextUI</code> 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 <code>Highlighter</code> 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 <code>condition</code>.
+ *
+ * @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 <code>Graphics</code> 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 <code>Graphics</code> 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 <code>Graphics</code> 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 <code>pos</code>.
+ *
+ * @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 <code>pos</code> 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 <code>null</code> this defaults to
+ * <code>Position.Bias.Forward</code>
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> 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 <code>View</code> 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
+ * <code>pt</code>
+ */
public int viewToModel(JTextComponent t, Point pt)
{
return viewToModel(t, pt, null);
}
+ /**
+ * Maps a point in the <code>View</code> 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
+ * <code>pt</code>
+ */
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 <code>Element</code> to create a <code>View</code> 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 <code>Element</code> to create a <code>View</code> 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 <code>View</code> 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 84509ad6efd..9106b0b6673 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 bc655a2742d..8be89efcfa6 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 b9d3b629b66..6f714a39cb2 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 <code>JTree</code> 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 <code>JComponent</code> for which we need a UI delegate for.
+ * @return the <code>ComponentUI</code> for c.
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new BasicTreeUI();
+ }
+
+ /**
+ * Returns the Hash color.
+ *
+ * @return the <code>Color</code> of the Hash.
+ */
+ protected Color getHashColor()
+ {
+ return UIManager.getLookAndFeelDefaults().getColor("Tree.hash");
+ }
+
+ /**
+ * Sets the Hash color.
+ *
+ * @param color
+ * the <code>Color</code> 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 <code>tcr</code>. This invokes
+ * <code>updateRenderer</code>.
+ *
+ * @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 <code>TreeCellEditor</code> 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 <code>path</code>
+ * 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 <code>parent</code>
+ *
+ * @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
+ * <code>treeDidChange</code>.
+ */
+ protected void updateSize()
+ {
+ // FIXME: not implemented
+ }
+
+ /**
+ * Updates the <code>preferredSize</code> instance variable, which is
+ * returned from <code>getPreferredSize()</code>. 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
+ * <code>getInvokesStopCellEditing</code>, 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>row</code> is a leaf.
+ *
+ * @param row
+ * is the row we are concerned with.
+ * @return true if the node at <code>row</code> 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 <code>JComponent</code> for which we need a UI delegate
- * for.
- * @return the <code>ComponentUI</code> for c.
- */
- public static ComponentUI createUI(JComponent c)
- {
- return new BasicTreeUI();
- }
-
- /**
- * Returns the Hash color.
- *
- * @return the <code>Color</code> of the Hash.
- */
- protected Color getHashColor()
- {
- return UIManager.getLookAndFeelDefaults().getColor("Tree.hash");
- }
-
- /**
- * Sets the Hash color.
- *
- * @param the <code>Color</code> 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 <code>tcr</code>. This invokes
- * <code>updateRenderer</code>.
- *
- * @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 <code>TreeCellEditor</code> 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 <code>path</code>
- * 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 <code>parent</code>
- *
- * @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
- * <code>treeDidChange</code>.
- */
- protected void updateSize()
- {
- // FIXME: not implemented
- }
-
- /**
- * Updates the <code>preferredSize</code> instance variable, which is
- * returned from <code>getPreferredSize()</code>. 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
- * <code>getInvokesStopCellEditing</code>, 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>mouseX</code> and <code>mouseY</code> 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 <code>row</code> is a leaf.
- *
- * @param row is the row we are concerned with.
- * @return true if the node at <code>row</code> 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 <code>Action</code> 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 <code>Action</code> 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 8ce772bedf9..0d461332a70 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 f260ef6e34c..f55510684c6 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 <code>insets</code> 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 <code>insets</code> is <code>null</code>.
+ */
+ 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 <code>insets</code> 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 <code>insets</code> is <code>null</code>.
+ */
+ 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 &amp; Feel.
*
* @return a border for Toolbar buttons in the Metal Look &amp; Feel
diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java
index a7b53c4b430..0dac5ec3953 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 eba21a4bfcf..3f3c9ce58b3 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 d59e38c5474..c46cb5f2fb1 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 (<code>"CheckBox."</code>).
+ */
+ 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 e770f474680..d8c77432653 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 &amp; 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&amp;F.
+ *
+ * @return an icon for RadioButtons in the Metal L&amp;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 14143512e67..7c7cb92e549 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 cdd861227a2..fe8a9e4e4ea 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 <code>Label.disabledForeground</code>.
+ *
+ * @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 46519fc3f78..d9cf7c6220c 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 a857d6a9d8d..4b52c4b0041 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 bf50f9172a1..1b5fe144f6c 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 <code>true</code> 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 7913cdb83e9..be6d0c39ec8 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 d85d61c24ca..8d16f7463fe 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 02e9fd7dcb6..349f4baad12 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 c3a3d70ae37..3c9a4d497a5 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 <code>Element</code>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 <code>Element</code>s.
+ */
public static final String BidiElementName = "bidi level";
+
+ /**
+ * Standard name for content <code>Element</code>s. These are usually
+ * {@link LeafElement}s.
+ */
public static final String ContentElementName = "content";
+
+ /**
+ * Standard name for paragraph <code>Element</code>s. These are usually
+ * {@link BranchElement}s.
+ */
public static final String ParagraphElementName = "paragraph";
+
+ /**
+ * Standard name for section <code>Element</code>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 <code>Document</code>.
+ */
Content content;
+
+ /**
+ * The AttributeContext for this <code>Document</code>.
+ */
AttributeContext context;
+
+ /**
+ * The currently installed <code>DocumentFilter</code>.
+ */
DocumentFilter documentFilter;
- /** The documents properties. */
+ /**
+ * The documents properties.
+ */
Dictionary properties;
+ /**
+ * Manages event listeners for this <code>Document</code>.
+ */
protected EventListenerList listenerList = new EventListenerList();
+ /**
+ * Creates a new <code>AbstractDocument</code> with the specified
+ * {@link Content} model.
+ *
+ * @param doc the <code>Content</code> model to be used in this
+ * <code>Document<code>
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected AbstractDocument(Content doc)
{
this(doc, StyleContext.getDefaultStyleContext());
}
+ /**
+ * Creates a new <code>AbstractDocument</code> with the specified
+ * {@link Content} model and {@link AttributeContext}.
+ *
+ * @param doc the <code>Content</code> model to be used in this
+ * <code>Document<code>
+ * @param ctx the <code>AttributeContext</code> 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 <code>Document</code>.
+ * Usual <code>Document</code>s only have one root element and return this.
+ * However, there may be <code>Document</code> implementations that
+ * support multiple root elements, they have to return a default root element
+ * here.
+ *
+ * @return the default root {@link Element} of this <code>Document</code>
+ */
public abstract Element getDefaultRootElement();
+ /**
+ * Creates and returns a branch element with the specified
+ * <code>parent</code> and <code>attributes</code>. Note that the new
+ * <code>Element</code> is linked to the parent <code>Element</code>
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent <code>Element</code> as child.
+ *
+ * @param parent the parent <code>Element</code> for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch <code>Element</code>
+ *
+ * @see BranchElement
+ */
protected Element createBranchElement(Element parent,
AttributeSet attributes)
{
return new BranchElement(parent, attributes);
}
+ /**
+ * Creates and returns a leaf element with the specified
+ * <code>parent</code> and <code>attributes</code>. Note that the new
+ * <code>Element</code> is linked to the parent <code>Element</code>
+ * through {@link Element#getParentElement}, but it is not yet added
+ * to the parent <code>Element</code> as child.
+ *
+ * @param parent the parent <code>Element</code> for the new branch element
+ * @param attributes the text attributes to be installed in the new element
+ *
+ * @return the new branch <code>Element</code>
+ *
+ * @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 <code>offset</code>.
+ *
+ * @param offset the location in the document to keep track by the new
+ * <code>Position</code>
+ *
+ * @return the newly created <code>Position</code>
+ *
+ * @throws BadLocationException if <code>offset</code> 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 <code>DocumentEvent</code> 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 <code>DocumentEvent</code> 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 <code>DocumentEvent</code> 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 <code>UndoableEdit</code> has
+ * been performed on this <code>Document</code>.
+ *
+ * @param event the <code>UndoableEditEvent</code> 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 <code>-1</code> 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 <code>Document</code>.
+ *
+ * @return the {@link AttributeContext} used in this <code>Document</code>
+ */
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 <code>Document</code>
+ *
+ * @return the {@link Content} model for this <code>Document</code>
+ *
+ * @see GapContent
+ * @see StringContent
+ */
protected Content getContent()
{
return content;
}
+ /**
+ * Returns the thread that currently modifies this <code>Document</code>
+ * if there is one, otherwise <code>null</code>. 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 <code>Document</code>
+ * if there is one, otherwise <code>null</code>
+ */
protected Thread getCurrentWriter()
{
+ // FIXME: Implement locking!
return null;
}
+ /**
+ * Returns the properties of this <code>Document</code>.
+ *
+ * @return the properties of this <code>Document</code>
+ */
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
+ * <code>Document</code>.
+ *
+ * @return a {@link Position} which will always mark the end of the
+ * <code>Document</code>
+ */
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 <code>Document</code>'s content.
+ *
+ * @return the length of this <code>Document</code>'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 <code>Document</code>'s property list.
+ *
+ * @param key the key of the property to be fetched
+ *
+ * @return the property for <code>key</code> or <code>null</code> 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 <code>Document</code>. By default
+ * this just returns the single root element returned by
+ * {@link #getDefaultRootElement()}. <code>Document</code> implementations
+ * that support multiple roots must override this method and return all roots
+ * here.
+ *
+ * @return all root elements of this <code>Document</code>
+ */
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
+ * <code>Document</code>.
+ *
+ * @return a {@link Position} which will always mark the beginning of the
+ * <code>Document</code>
+ */
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 <code>Document</code>'s content.
+ *
+ * @param offset the start offset of the content
+ * @param length the length of the content
+ *
+ * @return the piece of content specified by <code>offset</code> and
+ * <code>length</code>
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>offset +
+ * length</code> are invalid locations with this
+ * <code>Document</code>
+ */
public String getText(int offset, int length) throws BadLocationException
{
return content.getString(offset, length);
}
+ /**
+ * Fetches a piece of this <code>Document</code>'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 <code>Segment</code> to store the content in
+ *
+ * @throws BadLocationException if <code>offset</code> or <code>offset +
+ * length</code> are invalid locations with this
+ * <code>Document</code>
+ */
public void getText(int offset, int length, Segment segment)
throws BadLocationException
{
content.getChars(offset, length, segment);
}
+ /**
+ * Inserts a String into this <code>Document</code> 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 <code>offset</code> is not a valid
+ * location in this <code>Document</code>
+ */
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
+ * <code>Document</code>. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> 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
+ * <code>Document</code>. The default implementation does nothing.
+ * This method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> describing the change
+ */
protected void postRemoveUpdate(DefaultDocumentEvent chng)
{
+ // Do nothing here. Subclasses may want to override this.
}
+ /**
+ * Stores a property in this <code>Document</code>'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
+ * <code>Document</code>, writing may begin now.
+ */
public void readUnlock()
{
}
+ /**
+ * Removes a piece of content from this <code>Document</code>.
+ *
+ * @param offset the start offset of the fragment to be removed
+ * @param length the length of the fragment to be removed
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + length</code> 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 <code>Document</code> 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 <code>offset</code> or
+ * <code>offset + length</code> or invalid locations within this
+ * document
*
* @since 1.4
*/
@@ -331,9 +645,9 @@ public abstract class AbstractDocument
}
/**
- * Returns add added <code>DocumentListener</code> objects.
+ * Returns all registered <code>DocumentListener</code>s.
*
- * @return an array of listeners
+ * @return all registered <code>DocumentListener</code>s
*/
public DocumentListener[] getDocumentListeners()
{
@@ -341,7 +655,7 @@ public abstract class AbstractDocument
}
/**
- * Adds a <code>UndoableEditListener</code> object to this document.
+ * Adds an {@link UndoableEditListener} to this <code>Document</code>.
*
* @param listener the listener to add
*/
@@ -351,7 +665,7 @@ public abstract class AbstractDocument
}
/**
- * Removes a <code>UndoableEditListener</code> object from this document.
+ * Removes an {@link UndoableEditListener} from this <code>Document</code>.
*
* @param listener the listener to remove
*/
@@ -361,42 +675,93 @@ public abstract class AbstractDocument
}
/**
- * Returns add added <code>UndoableEditListener</code> 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 <code>Document</code>.
+ * The default implementation does nothing but may be overridden by
+ * subclasses to modify the <code>Document</code> structure in response
+ * to a remove request. The method is executed within a write lock.
+ *
+ * @param chng the <code>DefaultDocumentEvent</code> 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 <code>Document</code> visually. It obtains a read
+ * lock, ensuring that no changes will be made to the <code>document</code>
+ * during the rendering process. It then calls the {@link Runnable#run()}
+ * method on <code>runnable</code>. This method <em>must not</em> attempt
+ * to modifiy the <code>Document</code>, 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 <code>Document</code>.
+ * A value of <code>-1</code> indicates that this <code>Document</code>
+ * 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 <code>Document</code>.
+ *
+ * @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
+ * <code>Document</code>.
+ *
+ * @return the currently installed {@link DocumentFilter} for this
+ * <code>Document</code>
+ *
* @since 1.4
*/
public DocumentFilter getDocumentFilter()
@@ -405,6 +770,10 @@ public abstract class AbstractDocument
}
/**
+ * Sets the {@link DocumentFilter} for this <code>Document</code>.
+ *
+ * @param filter the <code>DocumentFilter</code> 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 <code>PrintStream</code>.
+ *
+ * @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
+ * <code>Document</code>s.
+ *
+ * Replicating {@link AttributeSet}s throughout a <code>Document</code> can
+ * be very expensive. Implementations of this interface are intended to
+ * provide intelligent management of <code>AttributeSet</code>s, eliminating
+ * costly duplication.
+ *
+ * @see StyleContext
+ */
public interface AttributeContext
{
+ /**
+ * Returns an {@link AttributeSet} that contains the attributes
+ * of <code>old</code> plus the new attribute specified by
+ * <code>name</code> and <code>value</code>.
+ *
+ * @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 <code>old</code> plus the new attributes in <code>attributes</code>.
+ *
+ * @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 <code>old</code> plus the new attributes in
+ * <code>attributes</code>
+ */
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 <code>attributes</code> 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
+ * <code>name</code> removed from <code>old</code>.
+ *
+ * @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 <code>old</code> minus the attribute
+ * specified by <code>name</code>
+ */
AttributeSet removeAttribute(AttributeSet old, Object name);
+ /**
+ * Removes all attributes in <code>attributes</code> from <code>old</code>
+ * and returns the resulting <code>AttributeSet</code>.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param attributes the attributes to be removed from <code>old</code>
+ *
+ * @return the attributes of <code>old</code> minus the attributes in
+ * <code>attributes</code>
+ */
AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
+ /**
+ * Removes all attributes specified by <code>names</code> from
+ * <code>old</code> and returns the resulting <code>AttributeSet</code>.
+ *
+ * @param old the set of attributes from which to remove attributes
+ * @param names the names of the attributes to be removed from
+ * <code>old</code>
+ *
+ * @return the attributes of <code>old</code> minus the attributes in
+ * <code>attributes</code>
+ */
AttributeSet removeAttributes(AttributeSet old, Enumeration names);
}
+ /**
+ * A sequence of data that can be edited. This is were the actual content
+ * in <code>AbstractDocument</code>'s is stored.
+ */
public interface Content
{
+ /**
+ * Creates a {@link Position} that keeps track of the location at
+ * <code>offset</code>.
+ *
+ * @return a {@link Position} that keeps track of the location at
+ * <code>offset</code>.
+ *
+ * @throw BadLocationException if <code>offset</code> is not a valid
+ * location in this <code>Content</code> 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 <code>UndoableEdit</code> or <code>null</code> if undo is
+ * not supported by this <code>Content</code> model
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in this <code>Content</code> 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 <code>UndoableEdit</code> or <code>null</code> if undo is
+ * not supported by this <code>Content</code> model
+ *
+ * @throws BadLocationException if <code>where</code> is not a valid
+ * location in this <code>Content</code> 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 <code>offset</code> or
+ * <code>offset + len</code>is not a valid
+ * location in this <code>Content</code> model
+ */
String getString(int where, int len) throws BadLocationException;
+ /**
+ * Fetches a piece of content and stores it in <code>txt</code>.
+ *
+ * @param where the start offset of the requested fragment
+ * @param len the length of the requested fragment
+ * @param txt the <code>Segment</code> where to fragment is stored into
+ *
+ * @throws BadLocationException if <code>offset</code> or
+ * <code>offset + len</code>is not a valid
+ * location in this <code>Content</code> 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 <code>AbstractElement</code> with a
+ * specified parent <code>Element</code> and <code>AttributeSet</code>.
+ *
+ * @param p the parent of this <code>AbstractElement</code>
+ * @param s the attributes to be assigned to this
+ * <code>AbstractElement</code>
+ */
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 <code>Element</code> as an
+ * <code>Enumeration</code> of {@link TreeNode}s.
+ *
+ * @return the child nodes of this <code>Element</code> as an
+ * <code>Enumeration</code> of {@link TreeNode}s
+ */
public abstract Enumeration children();
-
+
+ /**
+ * Returns <code>true</code> if this <code>AbstractElement</code>
+ * allows children.
+ *
+ * @return <code>true</code> if this <code>AbstractElement</code>
+ * allows children
+ */
public abstract boolean getAllowsChildren();
-
+
+ /**
+ * Returns the child of this <code>AbstractElement</code> at
+ * <code>index</code>.
+ *
+ * @param index the position in the child list of the child element to
+ * be returned
+ *
+ * @return the child of this <code>AbstractElement</code> at
+ * <code>index</code>
+ */
public TreeNode getChildAt(int index)
{
return (TreeNode) tree_children.get(index);
}
-
+
+ /**
+ * Returns the number of children of this <code>AbstractElement</code>.
+ *
+ * @return the number of children of this <code>AbstractElement</code>
+ */
public int getChildCount()
{
return tree_children.size();
}
-
+
+ /**
+ * Returns the index of a given child <code>TreeNode</code> or
+ * <code>-1</code> if <code>node</code> is not a child of this
+ * <code>AbstractElement</code>.
+ *
+ * @param node the node for which the index is requested
+ *
+ * @return the index of a given child <code>TreeNode</code> or
+ * <code>-1</code> if <code>node</code> is not a child of this
+ * <code>AbstractElement</code>
+ */
public int getIndex(TreeNode node)
{
return tree_children.indexOf(node);
}
+ /**
+ * Returns the parent <code>TreeNode</code> of this
+ * <code>AbstractElement</code> or <code>null</code> if this element
+ * has no parent.
+ *
+ * @return the parent <code>TreeNode</code> of this
+ * <code>AbstractElement</code> or <code>null</code> if this
+ * element has no parent
+ */
public TreeNode getParent()
{
return tree_parent;
}
+ /**
+ * Returns <code>true</code> if this <code>AbstractElement</code> is a
+ * leaf element, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if this <code>AbstractElement</code> is a
+ * leaf element, <code>false</code> 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 <code>true</code> 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 <code>true</code> if this element contains the specified
+ * attribute
+ */
public boolean containsAttribute(Object name, Object value)
{
return attributes.containsAttribute(name, value);
}
+ /**
+ * Returns <code>true</code> if this element contains all of the
+ * specified attributes.
+ *
+ * @param attrs the attributes to check
+ *
+ * @return <code>true</code> 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 <code>key</code> of <code>null</code>
+ * if <code>key</code> 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 <code>true</code> if an attribute with the specified name
+ * is defined in this element, <code>false</code> otherwise.
+ *
+ * @param attrName the name of the requested attributes
+ *
+ * @return <code>true</code> if an attribute with the specified name
+ * is defined in this element, <code>false</code> otherwise
+ */
public boolean isDefined(Object attrName)
{
return attributes.isDefined(attrName);
}
-
+
+ /**
+ * Returns <code>true</code> if the specified <code>AttributeSet</code>
+ * is equal to this element's <code>AttributeSet</code>, <code>false</code>
+ * otherwise.
+ *
+ * @param attrs the attributes to compare this element to
+ *
+ * @return <code>true</code> if the specified <code>AttributeSet</code>
+ * is equal to this element's <code>AttributeSet</code>,
+ * <code>false</code> 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 <code>index</code>.
+ *
+ * @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
+ * <code>Element</code>s that contain other <code>Element</code>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 <code>BranchElement</code> with the specified
+ * parent and attributes.
+ *
+ * @param parent the parent element of this <code>BranchElement</code>
+ * @param attributes the attributes to set on this
+ * <code>BranchElement</code>
+ */
public BranchElement(Element parent, AttributeSet attributes)
{
super(parent, attributes);
}
+ /**
+ * Returns the children of this <code>BranchElement</code>.
+ *
+ * @return the children of this <code>BranchElement</code>
+ */
public Enumeration children()
{
if (children.length == 0)
@@ -672,11 +1455,25 @@ public abstract class AbstractDocument
return tmp.elements();
}
+ /**
+ * Returns <code>true</code> since <code>BranchElements</code> allow
+ * child elements.
+ *
+ * @return <code>true</code> since <code>BranchElements</code> allow
+ * child elements
+ */
public boolean getAllowsChildren()
{
return true;
}
+ /**
+ * Returns the child element at the specified <code>index</code>.
+ *
+ * @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 <code>NullPointerException</code>.
+ *
+ * @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 <code>NullPointerException</code>.
+ *
+ * @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 <code>false</code> since <code>BranchElement</code> are no
+ * leafes.
+ *
+ * @return <code>false</code> since <code>BranchElement</code> are no
+ * leafes
+ */
public boolean isLeaf()
{
return false;
}
+ /**
+ * Returns the <code>Element</code> at the specified <code>Document</code>
+ * offset.
+ *
+ * @return the <code>Element</code> at the specified <code>Document</code>
+ * 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 <code>Document</code> 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 <code>Element</code> to their change records.
+ */
+ Hashtable changes;
+
+ /**
+ * Creates a new <code>DefaultDocumentEvent</code>.
+ *
+ * @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 <code>DocumentEvent</code>. 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 <code>elem</code> or <code>null</code> if
+ * <code>elem</code> 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 <code>ElementEdit</code>.
+ *
+ * @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 <code>LeafElement</code>.
+ *
+ * @param parent the parent of this <code>LeafElement</code>
+ * @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 <code>null</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>null</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public Enumeration children()
{
return null;
}
+ /**
+ * Returns <code>false</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>false</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public boolean getAllowsChildren()
{
return false;
}
+ /**
+ * Returns <code>null</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>null</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public Element getElement(int index)
{
return null;
}
+ /**
+ * Returns <code>0</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>0</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public int getElementCount()
{
return 0;
}
+ /**
+ * Returns <code>-1</code> since <code>LeafElement</code>s cannot have
+ * children.
+ *
+ * @return <code>-1</code> since <code>LeafElement</code>s cannot have
+ * children
+ */
public int getElementIndex(int offset)
{
return -1;
}
+ /**
+ * Returns the end offset of this <code>Element</code> inside the
+ * document.
+ *
+ * @return the end offset of this <code>Element</code> inside the
+ * document
+ */
public int getEndOffset()
{
- return end;
+ return endPos.getOffset();
}
+ /**
+ * Returns the name of this <code>Element</code>. This is
+ * {@link #ContentElementName} in this case.
+ *
+ * @return the name of this <code>Element</code>
+ */
public String getName()
{
return ContentElementName;
}
+ /**
+ * Returns the start offset of this <code>Element</code> inside the
+ * document.
+ *
+ * @return the start offset of this <code>Element</code> inside the
+ * document
+ */
public int getStartOffset()
{
- return start;
+ return startPos.getOffset();
}
+ /**
+ * Returns <code>true</code>.
+ *
+ * @return <code>true</code>
+ */
public boolean isLeaf()
{
return true;
}
+ /**
+ * Returns a string representation of this <code>Element</code>.
+ *
+ * @return a string representation of this <code>Element</code>
+ */
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 87e7b98af22..2f1f1890bae 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 <code>AttributeSet</code> may have a resolving parent,
+ * that is another <code>AttributeSet</code> that is searched for attribute
+ * keys that are not stored locally in this <code>AttributeSet</code>.
+ *
+ * @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
+ * <code>AttributeSet</code>.
+ */
Object NameAttribute = StyleConstants.NameAttribute;
+
+ /**
+ * Key of the attribute that is used to identify the resolving parent of
+ * an <code>AttributeSet</code>.
+ */
Object ResolveAttribute = StyleConstants.ResolveAttribute;
+ /**
+ * Returns <code>true</code> if this <code>AttributeSet</code> contains
+ * an attribute with the specified <code>name</code> and <code>value</code>,
+ * <code>false</code> otherwise.
+ *
+ * @param name the name of the requested attribute
+ * @param the value of the requested attribute
+ *
+ * @return <code>true</code> if this <code>AttributeSet</code> contains
+ * an attribute with the specified <code>name</code> and
+ * <code>value</code>, <code>false</code> otherwise
+ */
boolean containsAttribute(Object name, Object value);
+
+ /**
+ * Returns <code>true</code> of this <code>AttributeSet</code> contains all
+ * of the specified <code>attributes</code>.
+ *
+ * @param attributes the requested attributes
+ *
+ * @return <code>true</code> of this <code>AttributeSet</code> contains all
+ * of the specified <code>attributes</code>
+ */
boolean containsAttributes(AttributeSet attributes);
+
+ /**
+ * Creates and returns a copy of this <code>AttributeSet</code>.
+ *
+ * @return a copy of this <code>AttributeSet</code>
+ */
AttributeSet copyAttributes();
+
+ /**
+ * Returns the attribute with the specified <code>key</code> or
+ * <code>null</code> if no such attribute is defined in this
+ * <code>AttributeSet</code> and its resolving parents.
+ *
+ * @param key the key of the attribute that is looked up
+ *
+ * @return the attribute with the specified <code>key</code> or
+ * <code>null</code> if no such attribute is defined in this
+ * <code>AttributeSet</code> and its resolving parents
+ */
Object getAttribute(Object key);
+
+ /**
+ * Returns the number of attributes that are stored locally in this
+ * <code>AttributeSet</code>.
+ *
+ * @return the number of attributes that are stored locally in this
+ * <code>AttributeSet</code>
+ */
int getAttributeCount();
+
+ /**
+ * Returns the names of the attributes that are stored in this
+ * <code>AttributeSet</code>.
+ *
+ * @return the names of the attributes that are stored in this
+ * <code>AttributeSet</code>
+ */
Enumeration getAttributeNames();
+
+ /**
+ * Returns the resolving parent of this <code>AttributeSet</code>.
+ * If a key is not stored locally, then a {@link #getAttribute(Object)}
+ * request is resolved up in the resolving parent of this
+ * <code>AttributeSet</code>.
+ *
+ * @return the resolving parent of this <code>AttributeSet</code>
+ */
AttributeSet getResolveParent();
+
+ /**
+ * Returns <code>true</code> if an attribute with the specified name is
+ * defined locally in this <code>AttributeSet</code>, without resolving
+ * through the resolving parents.
+ *
+ * @return <code>true</code> if an attribute with the specified name is
+ * defined locally in this <code>AttributeSet</code>
+ */
boolean isDefined(Object attrName);
+
+ /**
+ * Returns <code>true</code> if all of the attributes in <code>attr</code>
+ * are equal to the attributes in this <code>AttributeSet</code>,
+ * <code>false</code> otherwise.
+ *
+ * @param attr the attributes to be compared to <code>this</code>
+ *
+ * @return <code>true</code> if all of the attributes in <code>attr</code>
+ * are equal to the attributes in this <code>AttributeSet</code>,
+ * <code>false</code> otherwise
+ */
boolean isEqual(AttributeSet attr);
}
diff --git a/libjava/classpath/javax/swing/text/BadLocationException.java b/libjava/classpath/javax/swing/text/BadLocationException.java
index e1a2ebcc604..70591402cac 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 <code>Document</code> 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 <code>BadLocationException</code>
*
- * @param str A string indicating what was wrong with the arguments
- * @param offset Offset within the document that was requested &gt;= 0
+ * @param str a string indicating what was wrong with the arguments
+ * @param offset offset within the document that was requested &gt;= 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 46072ef19c5..d6411905dda 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 <code>Caret</code> 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 <code>Caret</code> 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 <code>Caret</code> 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 <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @return the blink rate of this <code>Caret</code> or <code>0</code> if
+ * this caret does not blink
+ */
int getBlinkRate();
+
+ /**
+ * Sets the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> 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 <code>Caret</code> within the
+ * <code>Document</code>.
+ *
+ * @return the current position of this <code>Caret</code> within the
+ * <code>Document</code>
+ */
int getDot();
+
+ /**
+ * Sets the current position of this <code>Caret</code> within the
+ * <code>Document</code>. This also sets the <code>mark</code> 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 <code>dot</code> location without touching the
+ * <code>mark</code>. 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 <code>mark</code>. The
+ * <code>mark</code> marks the location in the <code>Document</code> that
+ * is the end of a selection. If there is no selection, the <code>mark</code>
+ * is the same as the <code>dot</code>.
+ *
+ * @return the current position of the mark
+ */
+ int getMark();
+ /**
+ * Returns the current visual position of this <code>Caret</code>.
+ *
+ * @return the current visual position of this <code>Caret</code>
+ *
+ * @see #setMagicCaretPosition
+ */
+ Point getMagicCaretPosition();
+
+ /**
+ * Sets the current visual position of this <code>Caret</code>.
+ *
+ * @param p the Point to use for the saved location. May be <code>null</code>
+ * to indicate that there is no visual location
+ */
void setMagicCaretPosition(Point p);
-
+
+ /**
+ * Returns <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise
+ */
+ boolean isSelectionVisible();
+
+ /**
+ * Sets the visiblity state of the selection.
+ *
+ * @param v <code>true</code> if the selection should be visible,
+ * <code>false</code> otherwise
+ */
void setSelectionVisible(boolean v);
-
+
+ /**
+ * Returns <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not.
+ *
+ * @return <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not
+ */
+ boolean isVisible();
+
+ /**
+ * Sets the visibility state of the caret. <code>true</code> shows the
+ * <code>Caret</code>, <code>false</code> hides it.
+ *
+ * @param v the visibility to set
+ */
void setVisible(boolean v);
+
+ /**
+ * Paints this <code>Caret</code> to the specified <code>Graphics</code>
+ * 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 744d537aec6..f6feda21513 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 <code>View</code>'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 <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ 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 0e20b771b45..869f9a0900f 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 b57b3656384..33c3ae3bf28 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 <code>ChangeEvent</code> 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 <code>Caret</code>.
+ */
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 <code>Caret</code> 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 <code>MouseEvent</code> 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 <code>MouseEvent</code> 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:
+ *
+ * <ul>
+ * <li>If we receive a double click, the caret position (dot) is set
+ * to the position associated to the mouse click and the word at
+ * this location is selected.</li>
+ * <li>If we receive a triple click, the caret position (dot) is set
+ * to the position associated to the mouse click and the line at
+ * this location is selected.</li>
+ * </ul>
+ *
+ * @param event the <code>MouseEvent</code> 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 <code>MouseEvent</code> 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 <code>MouseEvent</code> 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 <code>MouseEvent</code> 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 <code>MouseEvent</code> describing the mouse operation
+ */
public void mouseReleased(MouseEvent event)
{
+ // Nothing to do here.
}
+ /**
+ * Sets the caret to <code>visible</code> if the text component is editable.
+ *
+ * @param event the <code>FocusEvent</code>
+ */
public void focusGained(FocusEvent event)
{
}
+ /**
+ * Sets the caret to <code>invisible</code>.
+ *
+ * @param event the <code>FocusEvent</code>
+ */
public void focusLost(FocusEvent event)
{
}
+ /**
+ * Moves the caret to the position specified in the <code>MouseEvent</code>.
+ * This will cause a selection if the dot and mark are different.
+ *
+ * @param event the <code>MouseEvent</code> from which to fetch the position
+ */
protected void moveCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Repositions the caret to the position specified in the
+ * <code>MouseEvent</code>.
+ *
+ * @param event the <code>MouseEvent</code> from which to fetch the position
+ */
protected void positionCaret(MouseEvent event)
{
+ // FIXME: Implement this properly.
}
+ /**
+ * Deinstalls this <code>Caret</code> from the specified
+ * <code>JTextComponent</code>. This removes any listeners that have been
+ * registered by this <code>Caret</code>.
+ *
+ * @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 <code>Caret</code> on the specified
+ * <code>JTextComponent</code>. 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 <code>Caret</code>.
+ *
+ * @param p the Point to use for the saved location. May be <code>null</code>
+ * to indicate that there is no visual location
+ */
public void setMagicCaretPosition(Point p)
{
magicCaretPosition = p;
}
+ /**
+ * Returns the current visual position of this <code>Caret</code>.
+ *
+ * @return the current visual position of this <code>Caret</code>
+ *
+ * @see #setMagicCaretPosition
+ */
public Point getMagicCaretPosition()
{
return magicCaretPosition;
}
+ /**
+ * Returns the current position of the <code>mark</code>. The
+ * <code>mark</code> marks the location in the <code>Document</code> that
+ * is the end of a selection. If there is no selection, the <code>mark</code>
+ * is the same as the <code>dot</code>.
+ *
+ * @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 <code>true</code> if the selection should be visible,
+ * <code>false</code> otherwise
+ */
public void setSelectionVisible(boolean v)
{
if (selectionVisible == v)
@@ -191,17 +359,35 @@ public class DefaultCaret extends Rectangle
repaint();
}
+ /**
+ * Returns <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the selection is currently visible,
+ * <code>false</code> otherwise
+ */
public boolean isSelectionVisible()
{
return selectionVisible;
}
+ /**
+ * Causes the <code>Caret</code> 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 <code>Caret</code> using the specified <code>Graphics</code>
+ * 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 <code>Caret</code> 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 <code>Caret</code>.
+ *
+ * @return all registered {@link ChangeListener}s of this <code>Caret</code>
+ */
public ChangeListener[] getChangeListeners()
{
return (ChangeListener[]) getListeners(ChangeListener.class);
}
+ /**
+ * Notifies all registered {@link ChangeListener}s that the state
+ * of this <code>Caret</code> has changed.
+ */
protected void fireStateChanged()
{
ChangeListener[] listeners = getChangeListeners();
@@ -262,26 +475,61 @@ public class DefaultCaret extends Rectangle
listeners[index].stateChanged(changeEvent);
}
+ /**
+ * Returns the <code>JTextComponent</code> on which this <code>Caret</code>
+ * is installed.
+ *
+ * @return the <code>JTextComponent</code> on which this <code>Caret</code>
+ * is installed
+ */
protected final JTextComponent getComponent()
{
return textComponent;
}
-
+
+ /**
+ * Returns the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> means that the caret does not blink.
+ *
+ * @return the blink rate of this <code>Caret</code> or <code>0</code> if
+ * this caret does not blink
+ */
public int getBlinkRate()
{
return blinkRate;
}
+ /**
+ * Sets the blink rate of this <code>Caret</code> in milliseconds.
+ * A value of <code>0</code> 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 <code>Caret</code> within the
+ * <code>Document</code>.
+ *
+ * @return the current position of this <code>Caret</code> within the
+ * <code>Document</code>
+ */
public int getDot()
{
return dot;
}
+ /**
+ * Moves the <code>dot</code> location without touching the
+ * <code>mark</code>. 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 <code>Caret</code> within the
+ * <code>Document</code>. This also sets the <code>mark</code> 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 <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not.
+ *
+ * @return <code>true</code> if this <code>Caret</code> is currently visible,
+ * and <code>false</code> if it is not
+ */
public boolean isVisible()
{
return visible;
}
+ /**
+ * Sets the visibility state of the caret. <code>true</code> shows the
+ * <code>Caret</code>, <code>false</code> 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 aa2fbe8509a..a14f3ff4fe0 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 <code>EditorKit</code>
+ * a plain text <code>Document</code> 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 <code>BeepAction</code>.
+ */
public BeepAction()
{
super(beepAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>CopyAction</code>.
+ */
public CopyAction()
{
super(copyAction);
}
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>CutAction</code>.
+ */
public CutAction()
{
super(cutAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>PasteAction</code>.
+ */
+ public PasteAction()
+ {
+ super(pasteAction);
+ }
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>DefaultKeyTypedAction</code>.
+ */
public DefaultKeyTypedAction()
{
super(defaultKeyTypedAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>InsertBreakAction</code>.
+ */
public InsertBreakAction()
{
super(insertBreakAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>InsertContentAction</code>.
+ */
public InsertContentAction()
{
super(insertContentAction);
}
+
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>TabAction</code>.
+ */
public InsertTabAction()
{
super(insertTabAction);
}
+ /**
+ * Performs the <code>Action</code>.
+ *
+ * @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 <code>Action</code> that moves the caret one character
+ * backwards.
+ *
+ * @see #getActions()
+ */
public static final String backwardAction = "caret-backward";
+
+ /**
+ * The name of the <code>Action</code> that creates a beep in the speaker.
+ *
+ * @see #getActions()
+ */
public static final String beepAction = "beep";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the beginning
+ * of the <code>Document</code>.
+ *
+ * @see #getActions()
+ */
public static final String beginAction = "caret-begin";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> that copies the selected content
+ * into the system clipboard.
+ *
+ * @see #getActions()
+ */
public static final String copyAction = "copy-to-clipboard";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> that deletes the character that
+ * follows the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deleteNextCharAction = "delete-next";
+
+ /**
+ * The name of the <code>Action</code> that deletes the character that
+ * precedes the current caret position.
+ *
+ * @see #getActions()
+ */
public static final String deletePrevCharAction = "delete-previous";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line down.
+ *
+ * @see #getActions()
+ */
public static final String downAction = "caret-down";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret to the end
+ * of the <code>Document</code>.
+ *
+ * @see #getActions()
+ */
public static final String endAction = "caret-end";
+
+ /**
+ * The name of the <code>Action</code> 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 &quot;\r\n&quot;.
+ */
public static final String EndOfLineStringProperty = "__EndOfLine__";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> that moves the caret one character
+ * forward.
+ *
+ * @see #getActions()
+ */
public static final String forwardAction = "caret-forward";
+
+ /**
+ * The name of the <code>Action</code> that inserts a line break.
+ *
+ * @see #getActions()
+ */
public static final String insertBreakAction = "insert-break";
+
+ /**
+ * The name of the <code>Action</code> that inserts some content.
+ *
+ * @see #getActions()
+ */
public static final String insertContentAction = "insert-content";
+
+ /**
+ * The name of the <code>Action</code> that inserts a TAB.
+ *
+ * @see #getActions()
+ */
public static final String insertTabAction = "insert-tab";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> that moves the caret one page down.
+ *
+ * @see #getActions()
+ */
public static final String pageDownAction = "page-down";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one page up.
+ *
+ * @see #getActions()
+ */
public static final String pageUpAction = "page-up";
+
+ /**
+ * The name of the <code>Action</code> that copies content from the system
+ * clipboard into the document.
+ *
+ * @see #getActions()
+ */
public static final String pasteAction = "paste-from-clipboard";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> that sets the editor in read only
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String readOnlyAction = "set-read-only";
+
+ /**
+ * The name of the <code>Action</code> that selects the whole document.
+ *
+ * @see #getActions()
+ */
public static final String selectAllAction = "select-all";
+
+ /**
+ * The name of the <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> 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 <code>Action</code> that selects the line around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectLineAction = "select-line";
+
+ /**
+ * The name of the <code>Action</code> that selects the paragraph around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectParagraphAction = "select-paragraph";
+
+ /**
+ * The name of the <code>Action</code> that selects the word around the
+ * caret.
+ *
+ * @see #getActions()
+ */
public static final String selectWordAction = "select-word";
+
+ /**
+ * The name of the <code>Action</code> that moves the caret one line up.
+ *
+ * @see #getActions()
+ */
public static final String upAction = "caret-up";
+
+ /**
+ * The name of the <code>Action</code> that sets the editor in read-write
+ * mode.
+ *
+ * @see #getActions()
+ */
public static final String writableAction = "set-writable";
+ /**
+ * Creates a new <code>DefaultEditorKit</code>.
+ */
public DefaultEditorKit()
{
}
+ /**
+ * The <code>Action</code>s that are supported by the
+ * <code>DefaultEditorKit</code>.
+ */
+ // 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 <code>Caret</code> for this <code>EditorKit</code>. This
+ * returns a {@link DefaultCaret} in this case.
+ *
+ * @return the <code>Caret</code> for this <code>EditorKit</code>
+ */
public Caret createCaret()
{
return new DefaultCaret();
}
+ /**
+ * Creates the default {@link Document} that this <code>EditorKit</code>
+ * supports. This is a {@link PlainDocument} in this case.
+ *
+ * @return the default {@link Document} that this <code>EditorKit</code>
+ * supports
+ */
public Document createDefaultDocument()
{
return new PlainDocument();
}
-
+
+ /**
+ * Returns the <code>Action</code>s supported by this <code>EditorKit</code>.
+ *
+ * @return the <code>Action</code>s supported by this <code>EditorKit</code>
+ */
public Action[] getActions()
{
return defaultActions;
}
+ /**
+ * Returns the content type that this <code>EditorKit</code> supports.
+ * The <code>DefaultEditorKit</code> supports the content type
+ * <code>text/plain</code>.
+ *
+ * @return the content type that this <code>EditorKit</code> supports
+ */
public String getContentType()
{
return "text/plain";
}
-
+
+ /**
+ * Returns a {@link ViewFactory} that is able to create {@link View}s for
+ * the <code>Element</code>s that are used in this <code>EditorKit</code>'s
+ * model. This returns null which lets the UI of the text component supply
+ * <code>View</code>s.
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s for
+ * the <code>Element</code>s that are used in this
+ * <code>EditorKit</code>'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 <code>offset</code> is an invalid location
+ * inside <code>document</code>
+ * @throws IOException if something goes wrong while reading from
+ * <code>in</code>
+ */
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 <code>offset</code> is an invalid location
+ * inside <code>document</code>
+ * @throws IOException if something goes wrong while reading from
+ * <code>in</code>
+ */
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 <code>Document</code> (or a fragment of the
+ * <code>Document</code>) 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 <code>offset</code> or
+ * <code>offset + len</code>is an invalid location inside
+ * <code>document</code>
+ * @throws IOException if something goes wrong while writing to
+ * <code>out</code>
+ */
public void write(OutputStream out, Document document, int offset, int len)
throws BadLocationException, IOException
{
write(new OutputStreamWriter(out), document, offset, len);
}
+ /**
+ * Writes the <code>Document</code> (or a fragment of the
+ * <code>Document</code>) 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 <code>offset</code> or
+ * <code>offset + len</code>is an invalid location inside
+ * <code>document</code>
+ * @throws IOException if something goes wrong while writing to
+ * <code>out</code>
+ */
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 6fe206a8453..3545e52c453 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 <em>structural</code> changes to the <code>Element</code>
+ * 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 <code>ElementBuffer</code> for the specified
+ * <code>root</code> element.
+ *
+ * @param root the root element for this <code>ElementBuffer</code>
+ */
public ElementBuffer(Element root)
{
this.root = root;
}
+ /**
+ * Returns the root element of this <code>ElementBuffer</code>.
+ *
+ * @return the root element of this <code>ElementBuffer</code>
+ */
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 <code>DefaultDocumentEvent</code> 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 <code>DefaultDocumentEvent</code> 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 <code>offset</code> 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 <code>EditorBuffer</code> that is used to manage to
+ * <code>Element</code> hierarchy.
+ */
protected DefaultStyledDocument.ElementBuffer buffer;
-
+
+ /**
+ * Creates a new <code>DefaultStyledDocument</code>.
+ */
public DefaultStyledDocument()
{
this(new GapContent(BUFFER_SIZE_DEFAULT), new StyleContext());
}
+ /**
+ * Creates a new <code>DefaultStyledDocument</code> that uses the
+ * specified {@link StyleContext}.
+ *
+ * @param context the <code>StyleContext</code> to use
+ */
public DefaultStyledDocument(StyleContext context)
{
this(new GapContent(BUFFER_SIZE_DEFAULT), context);
}
+ /**
+ * Creates a new <code>DefaultStyledDocument</code> that uses the
+ * specified {@link StyleContext} and {@link Content} buffer.
+ *
+ * @param content the <code>Content</code> buffer to use
+ * @param context the <code>StyleContext</code> 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 <code>parent</code> style, if one is specified.
+ *
+ * While it is legal to add nameless styles (<code>nm == null</code),
+ * you must be aware that the client application is then responsible
+ * for managing the style hierarchy, since unnamed styles cannot be
+ * looked up by their name.
+ *
+ * @param nm the name of the style or <code>null</code> if the style should
+ * be unnamed
+ * @param parent the parent in which unspecified style attributes are
+ * resolved, or <code>null</code> if that is not necessary
+ *
+ * @return the newly created <code>Style</code>
+ */
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 <code>Document</code>.
+ *
+ * @return the default root element for this kind of <code>Document</code>
+ */
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 <code>Element</code> that corresponds to the character
+ * at the specified position.
+ *
+ * @param position the position of which we query the corresponding
+ * <code>Element</code>
+ *
+ * @return the <code>Element</code> 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 <code>Style</code> for the specified position.
+ *
+ * @param position the position from which to query to logical style
+ *
+ * @return the logical <code>Style</code> 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 <code>Style</code>.
+ *
+ * @param nm the name of the <code>Style</code>
+ *
+ * @return the found <code>Style</code> of <code>null</code> if no such
+ * <code>Style</code> exists
+ */
public Style getStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
return context.getStyle(nm);
}
+ /**
+ * Removes a named <code>Style</code> from the style hierarchy.
+ *
+ * @param nm the name of the <code>Style</code> to be removed
+ */
public void removeStyle(String nm)
{
StyleContext context = (StyleContext) getAttributeContext();
context.removeStyle(nm);
}
+ /**
+ * Sets text attributes for the fragment specified by <code>offset</code>
+ * and <code>length</code>.
+ *
+ * @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 <code>true</code>, 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 <code>true</code>, 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 4d5c51cebb4..e2e04d7c495 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 1bbef8f93d6..1dd46c4b0f4 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 <code>GapContent</code>.
+ */
+ 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 <code>o</code>, zero
+ * if both are equal or a positive integer if this is greater than
+ * <code>o</code>
+ *
+ * @throws ClassCastException if <code>o</code> 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
* <code>null</code> is returned)
- *
- * @throws BadLocationException if <code>where</code> is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if <code>where</code> 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
* <code>null</code> is returned)
- *
- * @throws BadLocationException if <code>where</code> is not a valid location
- * in the buffer
+ *
+ * @throws BadLocationException if <code>where</code> 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 <code>where</code> or
* <code>where + len</code> 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 <code>where</code> or
* <code>where + len</code> 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 531a4c1aa10..cedaf59feeb 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 <code>Format</code> object.
+ * {@link Format#format(Object)} on the specified <code>Format</code> 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 f2ef4d77ffe..b3fad79124c 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
* <code>null</code> 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
* <code>getUI().getEditorKit().getActions()</code>. 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 229fd2b508d..c3aa66cbe17 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 c3f59e436cb..71070e92da7 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 5d1fab00032..91d7547e77c 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 <code>View</code>'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 <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ 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 459f2438679..89c4cf18ee4 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 <code>UnderlineAction</code>.
*/
public UnderlineAction()
{
- super("TODO");
- // TODO
+ super("TODO"); // TODO: Figure out name for this action.
}
/**
- * actionPerformed
- * @param event TODO
+ * Performs the action.
+ *
+ * @param event the <code>ActionEvent</code> 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 <code>ItalicAction</code>.
*/
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 <code>ActionEvent</code> 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 <code>BoldAction</code>.
*/
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 <code>ActionEvent</code> 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 <code>AlignmentAction</code> to set the
+ * alignment to <code>a</code>.
+ *
+ * @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 <code>ActionEvent</code> 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 <code>ForegroundAction</code> to set the
+ * foreground color to <code>fg</code>.
+ *
+ * @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 <code>ActionEvent</code> 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 <code>FontSizeAction</code> to set the
+ * font size to <code>size</code>.
+ *
+ * @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 <code>ActionEvent</code> 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 <code>FontFamilyAction</code> to set the
+ * font family to <code>family</code>.
+ *
+ * @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 <code>ActionEvent</code> 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 <code>StyledTextAction</code>.
+ *
+ * @param nm the name of the <code>StyledTextAction</code>
*/
public StyledTextAction(String nm)
{
super(nm);
- // TODO
}
/**
- * getEditor
- * @param event TODO
- * @returns JEditorPane
+ * Returns the <code>JEditorPane</code> component from which the
+ * <code>ActionEvent</code> originated.
+ *
+ * @param event the <code>ActionEvent</code>
+ * @return the <code>JEditorPane</code> component from which the
+ * <code>ActionEvent</code> 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 <code>editor</code>. If <code>editor</code> does not have
+ * a selection, then the attributes are used as input attributes
+ * for newly inserted content.
+ *
+ * @param editor the <code>JEditorPane</code> component
+ * @param atts the text attributes to set
+ * @param replace if <code>true</code> 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 <code>editor</code>.
+ *
+ * @param editor the <code>JEditorPane</code> from which to get the
+ * <code>StyledDocument</code>
+ *
+ * @return the {@link StyledDocument} that is used by <code>editor</code>
*/
- 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 <code>editor</code>.
+ *
+ * @param editor the <code>JEditorPane</code> from which to get the
+ * <code>StyledEditorKit</code>
+ *
+ * @return the {@link StyledEditorKit} that is used by <code>editor</code>
*/
- 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 <code>editor</code>. If <code>editor</code> does not have
+ * a selection, then the attributes are set on the paragraph that
+ * contains the current caret position.
+ *
+ * @param editor the <code>JEditorPane</code> component
+ * @param atts the text attributes to set
+ * @param replace if <code>true</code> 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 <code>Element</code>s that are supported by
+ * <code>StyledEditorKit</code>, namely the following types of Elements:
+ *
+ * <ul>
+ * <li>{@link AbstractDocument.ContentElementName}</li>
+ * <li>{@link AbstractDocument.ParagraphElementName}</li>
+ * <li>{@link AbstractDocument.SectionElementName}</li>
+ * <li>{@link StyleContext.ComponentElementName}</li>
+ * <li>{@link StyleContext.IconElementName}</li>
+ * </ul>
*/
static class StyledViewFactory
implements ViewFactory
{
/**
- * Constructor StyledViewFactory
- */
- StyledViewFactory()
- {
- // TODO
- }
-
- /**
- * create
- * @param value0 TODO
- * @returns View
+ * Creates a {@link View} for the specified <code>Element</code>.
+ *
+ * @param element the <code>Element</code> to create a <code>View</code>
+ * for
+ * @return the <code>View</code> for the specified <code>Element</code>
+ * or <code>null</code> if the type of <code>element</code> 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
+ * <code>Element</code> and the <code>inputAttributes</code>.
*/
- 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 <code>Element</code> 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 <code>StyledEditorKit</code>.
*/
public StyledEditorKit()
{
- // TODO
+ inputAttributes = new SimpleAttributeSet();
}
/**
- * clone
- * @returns Object
+ * Creates an exact copy of this <code>StyledEditorKit</code>.
+ *
+ * @return an exact copy of this <code>StyledEditorKit</code>
*/
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 <code>Action</code>s supported by this {@link EditorKit}.
+ * This includes the {@link BoldAction}, {@link ItalicAction} and
+ * {@link UnderlineAction} as well as the <code>Action</code>s supported
+ * by {@link DefaultEditorKit}.
+ *
+ * The other <code>Action</code>s of <code>StyledEditorKit</code> are not
+ * returned here, since they require a parameter and thus custom
+ * instantiation.
+ *
+ * @return the <code>Action</code>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
+ * <code>EditorKit</code>. This is an instance of
+ * {@link DefaultStyledDocument} in this case but may be overridden by
+ * subclasses.
+ *
+ * @return an instance of <code>DefaultStyledDocument</code>
*/
public Document createDefaultDocument()
{
- return null; // TODO
+ return new DefaultStyledDocument();
}
/**
- * install
- * @param component TODO
+ * Installs this <code>EditorKit</code> on the specified {@link JEditorPane}.
+ * This basically involves setting up required listeners on the
+ * <code>JEditorPane</code>.
+ *
+ * @param component the <code>JEditorPane</code> to install this
+ * <code>EditorKit</code> on
*/
public void install(JEditorPane component)
{
- // TODO
+ CaretTracker tracker = new CaretTracker();
+ component.addCaretListener(tracker);
}
/**
- * deinstall
- * @param component TODO
+ * Deinstalls this <code>EditorKit</code> from the specified
+ * {@link JEditorPane}. This basically involves removing all listeners from
+ * <code>JEditorPane</code> that have been set up by this
+ * <code>EditorKit</code>.
+ *
+ * @param component the <code>JEditorPane</code> from which to deinstall this
+ * <code>EditorKit</code>
*/
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 <code>EditorKit</code>,
+ * namely the following types of <code>Element</code>s:
+ *
+ * <ul>
+ * <li>{@link AbstractDocument.ContentElementName}</li>
+ * <li>{@link AbstractDocument.ParagraphElementName}</li>
+ * <li>{@link AbstractDocument.SectionElementName}</li>
+ * <li>{@link StyleContext.ComponentElementName}</li>
+ * <li>{@link StyleContext.IconElementName}</li>
+ * </ul>
+ *
+ * @return a {@link ViewFactory} that is able to create {@link View}s
+ * for {@link Element}s that are supported by this <code>EditorKit</code>
*/
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 <code>element</code> to <code>set</code>.
+ * This is called everytime when the caret position changes to keep
+ * track of the current input attributes. The attributes in <code>set</code>
+ * are cleaned before adding the attributes of <code>element</code>.
+ *
+ * This method filters out attributes for element names, <code>Icon</code>s
+ * and <code>Component</code>s.
+ *
+ * @param element the <code>Element</code> 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 4d9ed7b3122..24efba9a1bc 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 <code>View</code> instance.
*
* @param elem an <code>Element</code> 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 <code>null</code> this defaults to
+ * <code>Position.Bias.Forward</code>
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> 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 <code>p1</code> or <code>p2</code> 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 <code>View</code>'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 <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ 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 7ae78ec0725..c0182fe6ac9 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 &lt;/table&gt;)
* 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 63d03eaccf0..f17ca011ea0 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;
* <p>
* 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}.
+ * <a href="http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html"
+ * >http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html</a>.
* We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
* Oxford University Press, 688 p, ISBN: 0198537379.
* </p>
@@ -402,7 +403,7 @@ public class DTD
* placed to the field
* {@link javax.swing.text.html.parser.AttributeList#next },
* creating a linked list.
- * @return
+ * @return The attributes.
*/
protected AttributeList defAttributeList(String name, int type, int modifier,
String default_value,
@@ -541,7 +542,7 @@ public class DTD
* The unknown elements are automatically defined and added
* to the element table.
* @param elements
- * @return
+ * @return The bit set.
*/
private BitSet bitSet(String[] elements)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
index a771264a1ad..75e7afb4db6 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DTDConstants.java
@@ -40,14 +40,16 @@ package javax.swing.text.html.parser;
/**
* <p>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 <a href="http://www.w3.org/TR/html4/types.html"
+ * >http://www.w3.org/TR/html4/types.html</a>. 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.
* </p>
* <p>
* 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}.
+ * <a href="http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html"
+ * >http://www.w3.org/TR/WD-html40-970708/intro/sgmltut.html</a>.
* We also recommend Goldfarb C.F (1991) <i>The SGML Handbook</i>,
* Oxford University Press, 688 p, ISBN: 0198537379.
* </p>
diff --git a/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
index c706f4d0f0b..164297f1882 100644
--- a/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
+++ b/libjava/classpath/javax/swing/text/html/parser/DocumentParser.java
@@ -167,7 +167,7 @@ public class DocumentParser
* to get a default DTD; you must either refer to the implementation -
* specific packages, write your own DTD or obtain the working instance
* of parser in other way, for example, by calling
- * {@link javax.swing.text.html.HTMLEditorKit#getParser() }.
+ * {@link javax.swing.text.html.HTMLEditorKit#getParser()}.
* @param a_dtd a DTD to use.
*/
public DocumentParser(DTD a_dtd)
@@ -180,18 +180,18 @@ public class DocumentParser
* Parses the HTML document, calling methods of the provided
* callback. This method must be multithread - safe.
* @param reader The reader to read the HTML document from
- * @param callback The callback that is notifyed about the presence
+ * @param aCallback The callback that is notifyed about the presence
* of HTML elements in the document.
* @param ignoreCharSet If thrue, any charset changes during parsing
* are ignored.
* @throws java.io.IOException
*/
- public void parse(Reader reader, HTMLEditorKit.ParserCallback a_callback,
+ public void parse(Reader reader, HTMLEditorKit.ParserCallback aCallback,
boolean ignoreCharSet
)
throws IOException
{
- callBack = a_callback;
+ callBack = aCallback;
gnu.parse(reader);
callBack.handleEndOfLineString(gnu.getEndOfLineSequence());
@@ -230,7 +230,7 @@ public class DocumentParser
* The method is called when the HTML closing tag ((like &lt;/table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleEndTag(TagElement tag)
{
@@ -245,7 +245,7 @@ public class DocumentParser
* The method is called when the HTML opening tag ((like &lt;table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleStartTag(TagElement tag)
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/Element.java b/libjava/classpath/javax/swing/text/html/parser/Element.java
index f0a0f3303cb..098983c6923 100644
--- a/libjava/classpath/javax/swing/text/html/parser/Element.java
+++ b/libjava/classpath/javax/swing/text/html/parser/Element.java
@@ -225,7 +225,7 @@ public final class Element
/**
* Get all attributes of this document as an attribute list.
- * @return
+ * @return The attribute list.
*/
public AttributeList getAttributes()
{
diff --git a/libjava/classpath/javax/swing/text/html/parser/Parser.java b/libjava/classpath/javax/swing/text/html/parser/Parser.java
index 5867107cd45..7ff6853da82 100644
--- a/libjava/classpath/javax/swing/text/html/parser/Parser.java
+++ b/libjava/classpath/javax/swing/text/html/parser/Parser.java
@@ -327,7 +327,7 @@ public class Parser
* Handle the tag with no content, like &lt;br&gt;. The method is
* called for the elements that, in accordance with the current DTD,
* has an empty content.
- * @param The tag being handled.
+ * @param tag The tag being handled.
* @throws javax.swing.text.ChangedCharSetException
*/
protected void handleEmptyTag(TagElement tag)
@@ -339,7 +339,7 @@ public class Parser
* The method is called when the HTML closing tag ((like &lt;/table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleEndTag(TagElement tag)
{
@@ -354,7 +354,7 @@ public class Parser
* The method is called when the HTML opening tag ((like &lt;table&gt;)
* is found or if the parser concludes that the one should be present
* in the current position.
- * @param The tag being handled
+ * @param tag The tag being handled
*/
protected void handleStartTag(TagElement tag)
{
@@ -383,7 +383,7 @@ public class Parser
* both title starting and closing tags are already behind.
* The passed argument contains the concatenation of all
* title text sections.
- * @param The title text.
+ * @param title The title text.
*/
protected void handleTitle(char[] title)
{
@@ -402,7 +402,7 @@ public class Parser
/**
* Constructs the tag from the given element.
- * @param the tag base {@link javax.swing.text.html.parser.Element}
+ * @param element the tag base {@link javax.swing.text.html.parser.Element}
* @param isSupposed true if the tag is not actually present in the
* html input, but the parser supposes that it should to occur in
* the current location.
@@ -427,7 +427,7 @@ public class Parser
* is found or if the parser concludes that the one should be present
* in the current position. The method is called immediately before
* calling the handleStartTag.
- * @param The tag
+ * @param tag The tag
*/
protected void startTag(TagElement tag)
throws ChangedCharSetException
diff --git a/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java b/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
index 4b54e8a486c..e5d2db4df7c 100644
--- a/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
+++ b/libjava/classpath/javax/swing/text/html/parser/ParserDelegator.java
@@ -143,7 +143,7 @@ public class ParserDelegator
* Parses the HTML document, calling methods of the provided
* callback. This method must be multithread - safe.
* @param reader The reader to read the HTML document from
- * @param callback The callback that is notifyed about the presence
+ * @param a_callback The callback that is notifyed about the presence
* of HTML elements in the document.
* @param ignoreCharSet If thrue, any charset changes during parsing
* are ignored.
@@ -191,7 +191,7 @@ public class ParserDelegator
* all subsequent calls to the parse(...) . If you need to specify
* your DTD locally, simply {@link javax.swing.text.html.parser.Parser}
* instead.
- * @param dtd The DTD that will be used to parse documents by this class.
+ * @param a_dtd The DTD that will be used to parse documents by this class.
* @param name The name of this DTD.
* @return No standard is specified on which instance of DTD must be
* returned by this method, and it is recommended to leave the returned
diff --git a/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java b/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java
index 9f8e9da5984..adece101deb 100644
--- a/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java
+++ b/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java
@@ -134,11 +134,11 @@ public abstract class AbstractLayoutCache
/**
* getNodeDimensions
*
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
+ * @param value TODO
+ * @param row TODO
+ * @param depth TODO
+ * @param expanded TODO
+ * @param bounds TODO
*
* @return Rectangle
*/
@@ -154,7 +154,7 @@ public abstract class AbstractLayoutCache
/**
* Sets the model that provides the tree data.
*
- * @param the model
+ * @param model the model
*/
public void setModel(TreeModel model)
{
@@ -318,7 +318,7 @@ public abstract class AbstractLayoutCache
*
* @return int
*/
- public abstract int getVisibleChildCount(TreePath value0);
+ public abstract int getVisibleChildCount(TreePath path);
/**
* setExpandedState
diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java b/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java
index e509d2c18e0..7a44e738338 100644
--- a/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java
+++ b/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java
@@ -1,5 +1,5 @@
/* DefaultTreeCellEditor.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,17 +43,30 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
+import javax.swing.CellRendererPane;
+import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.JTree;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.CellEditorListener;
import javax.swing.event.EventListenerList;
@@ -90,29 +103,62 @@ public class DefaultTreeCellEditor
}
/**
- * getPreferredSize
- * @return Dimension
+ * Returns the preferred size for the Container.
+ *
+ * @return Dimension of EditorContainer
*/
public Dimension getPreferredSize()
{
- return null; // TODO
+ Dimension containerSize = super.getPreferredSize();
+ containerSize.width += DefaultTreeCellEditor.this.offset;
+ return containerSize;
}
/**
- * paint
- * @param value0 TODO
+ * Overrides Container.paint to paint the node's icon and use the selection
+ * color for the background.
+ *
+ * @param g -
+ * the specified Graphics window
*/
- public void paint(Graphics value0)
+ public void paint(Graphics g)
{
- // TODO
+ Rectangle tr = tree.getPathBounds(lastPath);
+ if (tr != null)
+ {
+ Insets i = ((DefaultTextField) editingComponent).getBorder()
+ .getBorderInsets(this);
+ int textIconGap = 3;
+ tr.x -= i.left;
+
+ // paints icon
+ if (editingIcon != null)
+ {
+ editingIcon.paintIcon(this, g, tr.x - editingIcon.
+ getIconWidth()/2, tr.y + i.top + i.bottom);
+ tr.x += editingIcon.getIconWidth()/2 + textIconGap;
+ }
+
+ tr.width += offset;
+
+ // paint background
+ g.translate(tr.x, tr.y);
+ editingComponent.setSize(new Dimension(tr.width, tr.height));
+ editingComponent.paint(g);
+ g.translate(-tr.x, -tr.y);
+ }
+ super.paint(g);
}
/**
- * doLayout
+ * Lays out this Container. If editing, the editor will be placed at offset
+ * in the x direction and 0 for y.
*/
public void doLayout()
{
- // TODO
+ if (DefaultTreeCellEditor.this.tree.isEditing())
+ setLocation(offset, 0);
+ super.doLayout();
}
}
@@ -137,12 +183,22 @@ public class DefaultTreeCellEditor
}
/**
- * getFont
- * @return Font
+ * Gets the font of this component.
+ * @return this component's font; if a font has not been set for
+ * this component, the font of its parent is returned (if the parent
+ * is not null, otherwise null is returned).
*/
public Font getFont()
{
- return null; // TODO
+ Font font = super.getFont();
+ if (font == null)
+ {
+ Component parent = getParent();
+ if (parent != null)
+ return parent.getFont();
+ return null;
+ }
+ return font;
}
/**
@@ -156,108 +212,184 @@ public class DefaultTreeCellEditor
}
/**
- * getPreferredSize
- * @return Dimension
+ * Overrides JTextField.getPreferredSize to return the preferred size
+ * based on current font, if set, or else use renderer's font.
+ *
+ * @return the Dimension of this textfield.
*/
public Dimension getPreferredSize()
{
- return null; // TODO
+ String s = getText();
+
+ Font f = getFont();
+
+ if (f != null)
+ {
+ FontMetrics fm = getToolkit().getFontMetrics(f);
+
+ return new Dimension(SwingUtilities.computeStringWidth(fm, s),
+ fm.getHeight());
+ }
+ return renderer.getPreferredSize();
}
}
private EventListenerList listenerList = new EventListenerList();
-
+
/**
- * realEditor
+ * Editor handling the editing.
*/
protected TreeCellEditor realEditor;
/**
- * renderer
+ * Renderer, used to get border and offsets from.
*/
protected DefaultTreeCellRenderer renderer;
/**
- * editingContainer
+ * Editing container, will contain the editorComponent.
*/
protected Container editingContainer;
/**
- * editingComponent
+ * Component used in editing, obtained from the editingContainer.
*/
protected transient Component editingComponent;
/**
- * canEdit
+ * As of Java 2 platform v1.4 this field should no longer be used.
+ * If you wish to provide similar behavior you should directly
+ * override isCellEditable.
*/
protected boolean canEdit;
/**
- * offset
+ * Used in editing. Indicates x position to place editingComponent.
*/
protected transient int offset;
/**
- * tree
+ * JTree instance listening too.
*/
protected transient JTree tree;
/**
- * lastPath
+ * Last path that was selected.
*/
protected transient TreePath lastPath;
/**
- * timer
+ * Used before starting the editing session.
*/
- protected transient javax.swing.Timer timer; // TODO
+ protected transient javax.swing.Timer timer;
/**
- * lastRow
+ * Row that was last passed into getTreeCellEditorComponent.
*/
protected transient int lastRow;
/**
- * borderSelectionColor
+ * True if the border selection color should be drawn.
*/
protected Color borderSelectionColor;
/**
- * editingIcon
+ * Icon to use when editing.
*/
protected transient Icon editingIcon;
/**
- * font
+ * Font to paint with, null indicates font of renderer is to be used.
*/
protected Font font;
-
+
/**
- * Constructor DefaultTreeCellEditor
- * @param value0 TODO
- * @param value1 TODO
+ * Helper field used to save the last path seen while the timer was
+ * running.
*/
- public DefaultTreeCellEditor(JTree value0, DefaultTreeCellRenderer value1)
+ private TreePath tPath;
+
+ /**
+ * Constructs a DefaultTreeCellEditor object for a JTree using the
+ * specified renderer and a default editor. (Use this constructor
+ * for normal editing.)
+ *
+ * @param tree - a JTree object
+ * @param renderer - a DefaultTreeCellRenderer object
+ */
+ public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer)
{
- // TODO
+ this(tree, renderer, null);
}
/**
- * Constructor DefaultTreeCellEditor
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * Constructs a DefaultTreeCellEditor object for a JTree using the specified
+ * renderer and the specified editor. (Use this constructor
+ * for specialized editing.)
+ *
+ * @param tree - a JTree object
+ * @param renderer - a DefaultTreeCellRenderer object
+ * @param editor - a TreeCellEditor object
*/
- public DefaultTreeCellEditor(JTree value0, DefaultTreeCellRenderer value1,
- TreeCellEditor value2)
+ public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
+ TreeCellEditor editor)
{
- // TODO
+ setTree(tree);
+ this.renderer = renderer;
+
+ if (editor == null)
+ editor = createTreeCellEditor();
+ realEditor = editor;
+
+ lastPath = tree.getLeadSelectionPath();
+ tree.addTreeSelectionListener(this);
+ editingContainer = createContainer();
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ setFont(defaults.getFont("Tree.font"));
+ setBorderSelectionColor(defaults.getColor("Tree.selectionBorderColor"));
+ editingIcon = renderer.getIcon();
+ timer = new javax.swing.Timer(1200, this);
}
/**
+ * Configures the editing component whenever it is null.
+ *
+ * @param tree- the tree to configure to component for.
+ * @param renderer- the renderer used to set up the nodes
+ * @param editor- the editor used
+ */
+ private void configureEditingComponent(JTree tree,
+ DefaultTreeCellRenderer renderer,
+ TreeCellEditor editor)
+ {
+ if (tree != null && lastPath != null)
+ {
+ Object val = lastPath.getLastPathComponent();
+ boolean isLeaf = tree.getModel().isLeaf(val);
+ boolean expanded = tree.isExpanded(lastPath);
+ determineOffset(tree, val, true, expanded, isLeaf, lastRow);
+
+ // set up icon
+ if (isLeaf)
+ renderer.setIcon(renderer.getLeafIcon());
+ else if (expanded)
+ renderer.setIcon(renderer.getOpenIcon());
+ else
+ renderer.setIcon(renderer.getClosedIcon());
+ editingIcon = renderer.getIcon();
+
+ editingComponent = getTreeCellEditorComponent(tree, val, true,
+ expanded, isLeaf, lastRow);
+ }
+ }
+
+ /**
* writeObject
- * @param value0 TODO
- * @exception IOException TODO
+ *
+ * @param value0
+ * TODO
+ * @exception IOException
+ * TODO
*/
private void writeObject(ObjectOutputStream value0) throws IOException
{
@@ -277,102 +409,152 @@ public class DefaultTreeCellEditor
}
/**
- * setBorderSelectionColor
- * @param value0 TODO
+ * Sets the color to use for the border.
+ * @param newColor - the new border color
*/
- public void setBorderSelectionColor(Color value0)
+ public void setBorderSelectionColor(Color newColor)
{
- // TODO
+ this.borderSelectionColor = newColor;
}
/**
- * getBorderSelectionColor
+ * Returns the color the border is drawn.
* @return Color
*/
public Color getBorderSelectionColor()
{
- return null; // TODO
+ return borderSelectionColor;
}
/**
- * setFont
- * @param value0 TODO
+ * Sets the font to edit with. null indicates the renderers
+ * font should be used. This will NOT override any font you have
+ * set in the editor the receiver was instantied with. If null for
+ * an editor was passed in, a default editor will be created that
+ * will pick up this font.
+ *
+ * @param font - the editing Font
*/
- public void setFont(Font value0)
+ public void setFont(Font font)
{
- // TODO
+ if (font != null)
+ this.font = font;
+ else
+ this.font = renderer.getFont();
}
/**
- * getFont
- * @return Font
+ * Gets the font used for editing.
+ *
+ * @return the editing font
*/
public Font getFont()
{
- return null; // TODO
+ return font;
}
/**
- * getTreeCellEditorComponent
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- * @param value5 TODO
- * @return Component
- */
- public Component getTreeCellEditorComponent(JTree value0, Object value1,
- boolean value2, boolean value3,
- boolean value4, int value5)
+ * Configures the editor. Passed onto the realEditor.
+ * 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 - 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 rendered 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
+ *
+ * @return the component for editing
+ */
+ public Component getTreeCellEditorComponent(JTree tree, Object value,
+ boolean isSelected, boolean expanded,
+ boolean leaf, int row)
{
- return null; // TODO
+ if (realEditor == null)
+ createTreeCellEditor();
+
+ return realEditor.getTreeCellEditorComponent(tree, value, isSelected,
+ expanded, leaf, row);
}
/**
- * getCellEditorValue
- * @return Object
+ * Returns the value currently being edited.
+ *
+ * @return the value currently being edited
*/
public Object getCellEditorValue()
{
- return null; // TODO
+ return editingComponent;
}
-
- /**
- * isCellEditable
- * @param value0 TODO
- * @return boolean
- */
- public boolean isCellEditable(EventObject value0)
- {
- return false; // TODO
+
+ /**
+ * If the realEditor returns true to this message, prepareForEditing
+ * is messaged and true is returned.
+ *
+ * @param event - the event the editor should use to consider whether to begin editing or not
+ * @return true if editing can be started
+ */
+ public boolean isCellEditable(EventObject event)
+ {
+ if (editingComponent == null)
+ configureEditingComponent(tree, renderer, realEditor);
+
+ if (editingComponent != null && realEditor.isCellEditable(event))
+ {
+ prepareForEditing();
+ return true;
+ }
+
+ // Cell may not be currently editable, but may need to start timer.
+ if (shouldStartEditingTimer(event))
+ startEditingTimer();
+ return false;
}
/**
- * shouldSelectCell
- * @param value0 TODO
- * @return boolean
+ * Messages the realEditor for the return value.
+ *
+ * @param event -
+ * the event the editor should use to start editing
+ * @return true if the editor would like the editing cell to be selected;
+ * otherwise returns false
*/
- public boolean shouldSelectCell(EventObject value0)
+ public boolean shouldSelectCell(EventObject event)
{
- return false; // TODO
+ return true;
}
/**
- * stopCellEditing
- * @return boolean
+ * If the realEditor will allow editing to stop, the realEditor
+ * is removed and true is returned, otherwise false is returned.
+ * @return true if editing was stopped; false otherwise
*/
public boolean stopCellEditing()
{
- return false; // TODO
+ if (editingComponent != null && realEditor.stopCellEditing())
+ {
+ timer.stop();
+ return true;
+ }
+ return false;
}
/**
- * cancelCellEditing
+ * Messages cancelCellEditing to the realEditor and removes it
+ * from this instance.
*/
public void cancelCellEditing()
{
- // TODO
+ if (editingComponent != null)
+ {
+ timer.stop();
+ realEditor.cancelCellEditing();
+ }
}
/**
@@ -382,7 +564,7 @@ public class DefaultTreeCellEditor
*/
public void addCellEditorListener(CellEditorListener listener)
{
- listenerList.add(CellEditorListener.class, listener);
+ realEditor.addCellEditorListener(listener);
}
/**
@@ -392,7 +574,7 @@ public class DefaultTreeCellEditor
*/
public void removeCellEditorListener(CellEditorListener listener)
{
- listenerList.remove(CellEditorListener.class, listener);
+ realEditor.removeCellEditorListener(listener);
}
/**
@@ -408,109 +590,157 @@ public class DefaultTreeCellEditor
}
/**
- * valueChanged
- * @param value0 TODO
+ * Resets lastPath.
+ *
+ * @param e - the event that characterizes the change.
*/
- public void valueChanged(TreeSelectionEvent value0)
+ public void valueChanged(TreeSelectionEvent e)
{
- // TODO
+ tPath = lastPath;
+ lastPath = e.getNewLeadSelectionPath();
+ lastRow = tree.getRowForPath(lastPath);
+ configureEditingComponent(tree, renderer, realEditor);
}
-
+
/**
- * actionPerformed
- * @param value0 TODO
+ * Messaged when the timer fires, this will start the editing session.
+ *
+ * @param @param e - the event that characterizes the action.
*/
- public void actionPerformed(ActionEvent value0)
+ public void actionPerformed(ActionEvent e)
{
- // TODO
+ if (lastPath != null && tPath != null && tPath.equals(lastPath))
+ {
+ tree.startEditingAtPath(lastPath);
+ timer.stop();
+ }
}
/**
- * setTree
- * @param value0 TODO
+ * Sets the tree currently editing for. This is needed to add a selection
+ * listener.
+ *
+ * @param newTree -
+ * the new tree to be edited
*/
- protected void setTree(JTree value0)
+ protected void setTree(JTree newTree)
{
- // TODO
+ tree = newTree;
}
/**
- * shouldStartEditingTimer
- * @param value0 TODO
- * @return boolean
+ * Returns true if event is a MouseEvent and the click count is 1.
+ *
+ * @param event - the event being studied
+ * @return true if editing should start
*/
- protected boolean shouldStartEditingTimer(EventObject value0)
+ protected boolean shouldStartEditingTimer(EventObject event)
{
- return false; // TODO
+ if ((event instanceof MouseEvent) &&
+ ((MouseEvent) event).getClickCount() == 1)
+ return true;
+ return false;
}
/**
- * startEditingTimer
+ * Starts the editing timer.
*/
protected void startEditingTimer()
{
- // TODO
+ if (timer == null)
+ timer = new javax.swing.Timer(1200, this);
+ if (!timer.isRunning())
+ timer.start();
}
/**
- * canEditImmediately
- * @param value0 TODO
- * @return boolean
+ * Returns true if event is null, or it is a MouseEvent with
+ * a click count > 2 and inHitRegion returns true.
+ *
+ * @param event - the event being studied
+ * @return true if event is null, or it is a MouseEvent with
+ * a click count > 2 and inHitRegion returns true
*/
- protected boolean canEditImmediately(EventObject value0)
+ protected boolean canEditImmediately(EventObject event)
{
- return false; // TODO
+ if (event == null || !(event instanceof MouseEvent) || (((MouseEvent) event).
+ getClickCount() > 2 && inHitRegion(((MouseEvent) event).getX(),
+ ((MouseEvent) event).getY())))
+ return true;
+ return false;
}
/**
- * inHitRegion
- * @param value0 TODO
- * @param value1 TODO
- * @return boolean
+ * Returns true if the passed in location is a valid mouse location
+ * to start editing from. This is implemented to return false if x is
+ * less than or equal to the width of the icon and icon
+ * gap displayed by the renderer. In other words this returns true if
+ * the user clicks over the text part displayed by the renderer, and
+ * false otherwise.
+ *
+ * @param x - the x-coordinate of the point
+ * @param y - the y-coordinate of the point
+ *
+ * @return true if the passed in location is a valid mouse location
*/
- protected boolean inHitRegion(int value0, int value1)
+ protected boolean inHitRegion(int x, int y)
{
- return false; // TODO
+ Rectangle bounds = tree.getPathBounds(lastPath);
+
+ return bounds.contains(x, y);
}
/**
* determineOffset
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- * @param value5 TODO
- */
- protected void determineOffset(JTree value0, Object value1, boolean value2,
- boolean value3, boolean value4, int value5)
+ * @param tree -
+ * @param value -
+ * @param isSelected -
+ * @param expanded -
+ * @param leaf -
+ * @param row -
+ */
+ protected void determineOffset(JTree tree, Object value, boolean isSelected,
+ boolean expanded, boolean leaf, int row)
{
- // TODO
+ renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded,
+ leaf, row, true);
+ Icon c = renderer.getIcon();
+ if (c != null)
+ offset = renderer.getIconTextGap() + c.getIconWidth();
+ else
+ offset = 0;
}
/**
- * prepareForEditing
+ * Invoked just before editing is to start. Will add the
+ * editingComponent to the editingContainer.
*/
protected void prepareForEditing()
{
- // TODO
+ editingContainer.add(editingComponent);
}
/**
- * createContainer
- * @return Container
+ * Creates the container to manage placement of editingComponent.
+ *
+ * @return the container to manage the placement of the editingComponent.
*/
protected Container createContainer()
{
- return null; // TODO
+ return new DefaultTreeCellEditor.EditorContainer();
}
/**
- * createTreeCellEditor
- * @return TreeCellEditor
+ * This is invoked if a TreeCellEditor is not supplied in the constructor.
+ * It returns a TextField editor.
+ *
+ * @return a new TextField editor
*/
protected TreeCellEditor createTreeCellEditor()
{
- return null; // TODO
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ realEditor = new DefaultCellEditor(new DefaultTreeCellEditor.DefaultTextField(
+ defaults.getBorder("Tree.selectionBorder")));
+ return realEditor;
}
}
diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java b/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java
index db69c605554..4a353b30176 100644
--- a/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java
+++ b/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java
@@ -1,39 +1,40 @@
/* DefaultTreeCellRenderer.java
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ 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. */
+ 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.tree;
@@ -41,14 +42,18 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.Rectangle;
+import javax.swing.border.Border;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
+import javax.swing.SwingUtilities;
import javax.swing.plaf.UIResource;
/**
@@ -57,535 +62,626 @@ import javax.swing.plaf.UIResource;
* @author Andrew Selkirk
*/
public class DefaultTreeCellRenderer
- extends JLabel
- implements TreeCellRenderer
+ extends JLabel
+ implements TreeCellRenderer
{
- // -------------------------------------------------------------
- // Variables --------------------------------------------------
- // -------------------------------------------------------------
-
- /**
- * selected
- */
- protected boolean selected;
-
- /**
- * hasFocus
- */
- protected boolean hasFocus;
-
- /**
- * drawsFocusBorderAroundIcon
- */
- private boolean drawsFocusBorderAroundIcon;
-
- /**
- * closedIcon
- */
- protected transient Icon closedIcon;
-
- /**
- * leafIcon
- */
- protected transient Icon leafIcon;
-
- /**
- * openIcon
- */
- protected transient Icon openIcon;
-
- /**
- * textSelectionColor
- */
- protected Color textSelectionColor;
-
- /**
- * textNonSelectionColor
- */
- protected Color textNonSelectionColor;
-
- /**
- * backgroundSelectionColor
- */
- protected Color backgroundSelectionColor;
-
- /**
- * backgroundNonSelectionColor
- */
- protected Color backgroundNonSelectionColor;
-
- /**
- * borderSelectionColor
- */
- protected Color borderSelectionColor;
-
-
- // -------------------------------------------------------------
- // Initialization ---------------------------------------------
- // -------------------------------------------------------------
-
- /**
- * Constructor DefaultTreeCellRenderer
- */
- public DefaultTreeCellRenderer()
- {
- UIDefaults defaults = UIManager.getLookAndFeelDefaults();
-
- setLeafIcon(getDefaultLeafIcon());
- setOpenIcon(getDefaultOpenIcon());
- setClosedIcon(getDefaultClosedIcon());
-
- setTextNonSelectionColor(defaults.getColor("Tree.textForeground"));
- setTextSelectionColor(defaults.getColor("Tree.selectionForeground"));
- setBackgroundNonSelectionColor(defaults
- .getColor("Tree.nonSelectionBackground"));
- setBackgroundSelectionColor(defaults
- .getColor("Tree.selectionBackground"));
- setBorderSelectionColor(defaults
- .getColor("Tree.selectionBorderColor"));
- }
-
- // -------------------------------------------------------------
- // Methods ----------------------------------------------------
- // -------------------------------------------------------------
-
- /**
- * getDefaultOpenIcon
- *
- * @returns Icon
- */
- public Icon getDefaultOpenIcon()
- {
- return UIManager.getLookAndFeelDefaults().getIcon("Tree.openIcon");
- }
-
- /**
- * getDefaultClosedIcon
- *
- * @returns Icon
- */
- public Icon getDefaultClosedIcon()
- {
- return UIManager.getLookAndFeelDefaults().getIcon("Tree.closedIcon");
- }
-
- /**
- * getDefaultLeafIcon
- *
- * @returns Icon
- */
- public Icon getDefaultLeafIcon()
- {
- return UIManager.getLookAndFeelDefaults().getIcon("Tree.leafIcon");
- }
-
- /**
- * setOpenIcon
- *
- * @param value0 TODO
- */
- public void setOpenIcon(Icon i)
- {
- openIcon = i;
- }
-
- /**
- * getOpenIcon
- *
- * @returns Icon
- */
- public Icon getOpenIcon()
- {
- return openIcon;
- }
-
- /**
- * setClosedIcon
- *
- * @param value0 TODO
- */
- public void setClosedIcon(Icon i)
- {
- closedIcon = i;
- }
-
- /**
- * getClosedIcon
- *
- * @returns Icon
- */
- public Icon getClosedIcon()
- {
- return closedIcon;
- }
-
- /**
- * setLeafIcon
- *
- * @param value0 TODO
- */
- public void setLeafIcon(Icon i)
- {
- leafIcon = i;
- }
-
- /**
- * getLeafIcon
- *
- * @returns Icon
- */
- public Icon getLeafIcon()
- {
- return leafIcon;
- }
-
- /**
- * setTextSelectionColor
- *
- * @param value0 TODO
- */
- public void setTextSelectionColor(Color c)
- {
- textSelectionColor = c;
- }
-
- /**
- * getTextSelectionColor
- *
- * @returns Color
- */
- public Color getTextSelectionColor()
- {
- return textSelectionColor;
- }
-
- /**
- * setTextNonSelectionColor
- *
- * @param value0 TODO
- */
- public void setTextNonSelectionColor(Color c)
- {
- textNonSelectionColor = c;
- }
-
- /**
- * getTextNonSelectionColor
- *
- * @returns Color
- */
- public Color getTextNonSelectionColor()
- {
- return textNonSelectionColor;
- }
-
- /**
- * setBackgroundSelectionColor
- *
- * @param value0 TODO
- */
- public void setBackgroundSelectionColor(Color c)
- {
- backgroundSelectionColor = c;
- }
-
- /**
- * getBackgroundSelectionColor
- *
- * @returns Color
- */
- public Color getBackgroundSelectionColor()
- {
- return backgroundSelectionColor;
- }
-
- /**
- * setBackgroundNonSelectionColor
- *
- * @param value0 TODO
- */
- public void setBackgroundNonSelectionColor(Color c)
- {
- backgroundNonSelectionColor = c;
- }
-
- /**
- * getBackgroundNonSelectionColor
- *
- * @returns Color
- */
- public Color getBackgroundNonSelectionColor()
- {
- return backgroundNonSelectionColor;
- }
-
- /**
- * setBorderSelectionColor
- *
- * @param value0 TODO
- */
- public void setBorderSelectionColor(Color c)
- {
- borderSelectionColor = c;
- }
-
- /**
- * getBorderSelectionColor
- *
- * @returns Color
- */
- public Color getBorderSelectionColor()
- {
- return borderSelectionColor;
- }
-
- /**
- * setFont
- *
- * @param value0 TODO
- */
- public void setFont(Font f)
- {
- if (f != null && f instanceof UIResource)
- f = null;
- super.setFont(f);
- }
-
- /**
- * setBackground
- *
- * @param value0 TODO
- */
- public void setBackground(Color c)
- {
- if (c != null && c instanceof UIResource)
- c = null;
- super.setBackground(c);
- }
-
- /**
- * getTreeCellRendererComponent
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- * @param value5 TODO
- * @param value6 TODO
- * @returns Component
- */
- public Component getTreeCellRendererComponent(JTree tree, Object val,
- boolean selected, boolean expanded, boolean leaf, int row,
- boolean hasFocus)
- {
- if (val instanceof Icon)
- setIcon((Icon) val);
- else
+ // -------------------------------------------------------------
+ // Variables --------------------------------------------------
+ // -------------------------------------------------------------
+
+ /**
+ * selected
+ */
+ protected boolean selected;
+
+ /**
+ * hasFocus
+ */
+ protected boolean hasFocus;
+
+ /**
+ * drawsFocusBorderAroundIcon
+ */
+ private boolean drawsFocusBorderAroundIcon;
+
+ /**
+ * closedIcon
+ */
+ protected transient Icon closedIcon;
+
+ /**
+ * leafIcon
+ */
+ protected transient Icon leafIcon;
+
+ /**
+ * openIcon
+ */
+ protected transient Icon openIcon;
+
+ /**
+ * textSelectionColor
+ */
+ protected Color textSelectionColor;
+
+ /**
+ * textNonSelectionColor
+ */
+ protected Color textNonSelectionColor;
+
+ /**
+ * backgroundSelectionColor
+ */
+ protected Color backgroundSelectionColor;
+
+ /**
+ * backgroundNonSelectionColor
+ */
+ protected Color backgroundNonSelectionColor;
+
+ /**
+ * borderSelectionColor
+ */
+ protected Color borderSelectionColor;
+
+ // -------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ // -------------------------------------------------------------
+
+ /**
+ * Constructor DefaultTreeCellRenderer
+ */
+ public DefaultTreeCellRenderer()
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+ setLeafIcon(getDefaultLeafIcon());
+ setOpenIcon(getDefaultOpenIcon());
+ setClosedIcon(getDefaultClosedIcon());
+
+ setTextNonSelectionColor(defaults.getColor("Tree.textForeground"));
+ setTextSelectionColor(defaults.getColor("Tree.selectionForeground"));
+ setBackgroundNonSelectionColor(defaults.getColor("Tree.nonSelectionBackground"));
+ setBackgroundSelectionColor(defaults.getColor("Tree.selectionBackground"));
+ setBorderSelectionColor(defaults.getColor("Tree.selectionBorderColor"));
+ }
+
+ // -------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ // -------------------------------------------------------------
+
+ /**
+ * getDefaultOpenIcon
+ *
+ * @returns Icon
+ */
+ public Icon getDefaultOpenIcon()
+ {
+ return UIManager.getLookAndFeelDefaults().getIcon("Tree.openIcon");
+ }
+
+ /**
+ * getDefaultClosedIcon
+ *
+ * @returns Icon
+ */
+ public Icon getDefaultClosedIcon()
+ {
+ return UIManager.getLookAndFeelDefaults().getIcon("Tree.closedIcon");
+ }
+
+ /**
+ * getDefaultLeafIcon
+ *
+ * @returns Icon
+ */
+ public Icon getDefaultLeafIcon()
+ {
+ return UIManager.getLookAndFeelDefaults().getIcon("Tree.leafIcon");
+ }
+
+ /**
+ * setOpenIcon
+ *
+ * @param i
+ * the icon.
+ */
+ public void setOpenIcon(Icon i)
+ {
+ openIcon = i;
+ }
+
+ /**
+ * getOpenIcon
+ *
+ * @returns Icon
+ */
+ public Icon getOpenIcon()
+ {
+ return openIcon;
+ }
+
+ /**
+ * setClosedIcon
+ *
+ * @param i
+ * the icon.
+ */
+ public void setClosedIcon(Icon i)
+ {
+ closedIcon = i;
+ }
+
+ /**
+ * getClosedIcon
+ *
+ * @returns Icon
+ */
+ public Icon getClosedIcon()
+ {
+ return closedIcon;
+ }
+
+ /**
+ * setLeafIcon
+ *
+ * @param i
+ * the icon.
+ */
+ public void setLeafIcon(Icon i)
+ {
+ leafIcon = i;
+ }
+
+ /**
+ * getLeafIcon
+ *
+ * @returns Icon
+ */
+ public Icon getLeafIcon()
+ {
+ return leafIcon;
+ }
+
+ /**
+ * setTextSelectionColor
+ *
+ * @param c
+ * the color.
+ */
+ public void setTextSelectionColor(Color c)
+ {
+ textSelectionColor = c;
+ }
+
+ /**
+ * getTextSelectionColor
+ *
+ * @returns Color
+ */
+ public Color getTextSelectionColor()
+ {
+ return textSelectionColor;
+ }
+
+ /**
+ * setTextNonSelectionColor
+ *
+ * @param c
+ * the color.
+ */
+ public void setTextNonSelectionColor(Color c)
+ {
+ textNonSelectionColor = c;
+ }
+
+ /**
+ * getTextNonSelectionColor
+ *
+ * @returns Color
+ */
+ public Color getTextNonSelectionColor()
+ {
+ return textNonSelectionColor;
+ }
+
+ /**
+ * setBackgroundSelectionColor
+ *
+ * @param c
+ * the color.
+ */
+ public void setBackgroundSelectionColor(Color c)
+ {
+ backgroundSelectionColor = c;
+ }
+
+ /**
+ * getBackgroundSelectionColor
+ *
+ * @returns Color
+ */
+ public Color getBackgroundSelectionColor()
+ {
+ return backgroundSelectionColor;
+ }
+
+ /**
+ * setBackgroundNonSelectionColor
+ *
+ * @param c
+ * the color.
+ */
+ public void setBackgroundNonSelectionColor(Color c)
+ {
+ backgroundNonSelectionColor = c;
+ }
+
+ /**
+ * getBackgroundNonSelectionColor
+ *
+ * @returns Color
+ */
+ public Color getBackgroundNonSelectionColor()
+ {
+ return backgroundNonSelectionColor;
+ }
+
+ /**
+ * setBorderSelectionColor
+ *
+ * @param c
+ * the color.
+ */
+ public void setBorderSelectionColor(Color c)
+ {
+ borderSelectionColor = c;
+ }
+
+ /**
+ * getBorderSelectionColor
+ *
+ * @returns Color
+ */
+ public Color getBorderSelectionColor()
+ {
+ return borderSelectionColor;
+ }
+
+ /**
+ * setFont
+ *
+ * @param f
+ * the font.
+ */
+ public void setFont(Font f)
+ {
+ if (f != null && f instanceof UIResource)
+ f = null;
+ super.setFont(f);
+ }
+
+ /**
+ * setBackground
+ *
+ * @param c
+ * the color.
+ */
+ public void setBackground(Color c)
+ {
+ if (c != null && c instanceof UIResource)
+ c = null;
+ super.setBackground(c);
+ }
+
+ /**
+ * getTreeCellRendererComponent
+ *
+ * @param tree
+ * TODO
+ * @param val
+ * TODO
+ * @param selected
+ * TODO
+ * @param expanded
+ * TODO
+ * @param leaf
+ * TODO
+ * @param row
+ * TODO
+ * @param hasFocus
+ * TODO
+ * @returns Component
+ */
+ public Component getTreeCellRendererComponent(JTree tree, Object val,
+ boolean selected,
+ boolean expanded, boolean leaf,
+ int row, boolean hasFocus)
+ {
+ if (leaf)
+ setIcon(getLeafIcon());
+ else if (expanded)
+ setIcon(getOpenIcon());
+ else
+ setIcon(getClosedIcon());
+
+ setText(val.toString());
+ this.selected = selected;
+ this.hasFocus = hasFocus;
+ setHorizontalAlignment(LEFT);
+ setOpaque(false);
+ setVerticalAlignment(TOP);
+ setEnabled(true);
+ super.setFont(UIManager.getLookAndFeelDefaults().getFont("Tree.font"));
+
+ if (selected)
+ {
+ super.setBackground(getBackgroundSelectionColor());
+ setForeground(getTextSelectionColor());
+
+ if (tree.getLeadSelectionPath() == null ||
+ (tree.getLeadSelectionPath().getLastPathComponent()).equals(val))
+ setBorderSelectionColor(UIManager.getLookAndFeelDefaults().
+ getColor("Tree.selectionBorderColor"));
+ else
+ setBorderSelectionColor(null);
+ }
+ else
{
- setText(val.toString());
- setIcon(null);
- this.selected = selected;
- this.hasFocus = hasFocus;
- setHorizontalAlignment(LEFT);
- setOpaque(true);
- setVerticalAlignment(TOP);
- setEnabled(true);
- super.setFont(UIManager.getLookAndFeelDefaults().getFont("Tree.font"));
+ super.setBackground(getBackgroundNonSelectionColor());
+ setForeground(getTextNonSelectionColor());
+ setBorderSelectionColor(null);
}
- if (selected)
- {
- super.setBackground(getBackgroundSelectionColor());
- setForeground(getTextSelectionColor());
- }
- else
- {
- super.setBackground(getBackgroundNonSelectionColor());
- setForeground(getTextNonSelectionColor());
- }
-
- return this;
- }
-
- /**
- * getFont
- *
- * @return the current Font
- */
- public Font getFont()
- {
- return super.getFont();
- }
-
- /**
- * paint
- *
- * @param value0 TODO
- */
- public void paint(Graphics g)
- {
- super.paint(g);
- }
-
- /**
- * getPreferredSize
- *
- * @returns Dimension
- */
- public Dimension getPreferredSize()
- {
- return null; // TODO
- } // getPreferredSize()
-
- /**
- * validate
- */
- public void validate()
- {
- // Overridden for performance reasons.
- } // validate()
-
- /**
- * revalidate
- */
- public void revalidate()
- {
- // Overridden for performance reasons.
- } // revalidate()
-
- /**
- * repaint
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- */
- public void repaint(long value0, int value1, int value2, int value3,
- int value4)
- {
- // Overridden for performance reasons.
- } // repaint()
-
- /**
- * repaint
- *
- * @param value0 TODO
- */
- public void repaint(Rectangle value0)
- {
- // Overridden for performance reasons.
- } // repaint()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- protected void firePropertyChange(String value0, Object value1,
- Object value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, byte value1, byte value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, char value1, char value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, short value1, short value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, int value1, int value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, long value1, long value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, float value1, float value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, double value1, double value2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
-
- /**
- * firePropertyChange
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void firePropertyChange(String value0, boolean v1, boolean v2)
- {
- // Overridden for performance reasons.
- } // firePropertyChange()
+ return this;
+ }
+
+ /**
+ * getFont
+ *
+ * @return the current Font
+ */
+ public Font getFont()
+ {
+ return super.getFont();
+ }
+
+ /**
+ * Paints the value. The background is filled based on selected.
+ *
+ * @param g
+ * the graphics device.
+ */
+ public void paint(Graphics g)
+ {
+ // paint background
+ Rectangle vr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+
+ Insets insets = new Insets(0, 0, 0, 0);
+ Border border = UIManager.getLookAndFeelDefaults().getBorder(
+ "Tree.selectionBorder");
+ if (border != null)
+ insets = border.getBorderInsets(this);
+
+ FontMetrics fm = getToolkit().getFontMetrics(getFont());
+ SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(),
+ getIcon(), getVerticalAlignment(),
+ getHorizontalAlignment(),
+ getVerticalTextPosition(),
+ getHorizontalTextPosition(), vr, ir, tr,
+ getIconTextGap());
+
+ g.setColor(super.getBackground());
+ g.fillRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+
+ // paint border
+ Color b = getBorderSelectionColor();
+ if (b != null)
+ {
+ g.setColor(b);
+ g.drawRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+ }
+ super.paint(g);
+ }
+
+ /**
+ * returns the preferred size of the cell.
+ *
+ * @returns Dimension
+ */
+ public Dimension getPreferredSize()
+ {
+ Rectangle vr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+
+ FontMetrics fm = getToolkit().getFontMetrics(getFont());
+ SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(),
+ getIcon(), getVerticalAlignment(),
+ getHorizontalAlignment(),
+ getVerticalTextPosition(),
+ getHorizontalTextPosition(), vr, ir, tr,
+ getIconTextGap());
+ Rectangle cr = ir.union(tr);
+ return new Dimension(cr.width, cr.height);
+ } // getPreferredSize()
+
+ /**
+ * validate
+ */
+ public void validate()
+ {
+ // Overridden for performance reasons.
+ } // validate()
+
+ /**
+ * revalidate
+ */
+ public void revalidate()
+ {
+ // Overridden for performance reasons.
+ } // revalidate()
+
+ /**
+ * repaint
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ * @param value3
+ * TODO
+ * @param value4
+ * TODO
+ */
+ public void repaint(long value0, int value1, int value2, int value3,
+ int value4)
+ {
+ // Overridden for performance reasons.
+ } // repaint()
+
+ /**
+ * repaint
+ *
+ * @param value0
+ * TODO
+ */
+ public void repaint(Rectangle value0)
+ {
+ // Overridden for performance reasons.
+ } // repaint()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ protected void firePropertyChange(String value0, Object value1, Object value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, byte value1, byte value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, char value1, char value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, short value1, short value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, int value1, int value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, long value1, long value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0
+ * TODO
+ * @param value1
+ * TODO
+ * @param value2
+ * TODO
+ */
+ public void firePropertyChange(String value0, float value1, float value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param value0 TODO
+ * @param value1 TODO
+ * @param value2 TODO
+ */
+ public void firePropertyChange(String value0, double value1, double value2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
+
+ /**
+ * firePropertyChange
+ *
+ * @param name the property name.
+ * @param v1 the old value.
+ * @param v2 the new value.
+ */
+ public void firePropertyChange(String name, boolean v1, boolean v2)
+ {
+ // Overridden for performance reasons.
+ } // firePropertyChange()
} // DefaultTreeCellRenderer
diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java
index 3278ffadc77..5b5e0391478 100644
--- a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java
+++ b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java
@@ -1,6 +1,6 @@
-/* DefaultTreeModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
-
+/* DefaultTreeModel.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
@@ -10,16 +10,16 @@ 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
+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
+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
+making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
@@ -29,13 +29,12 @@ 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
+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
+obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package javax.swing.tree;
import java.io.IOException;
@@ -51,405 +50,516 @@ import javax.swing.tree.DefaultMutableTreeNode;
/**
* DefaultTreeModel
+ *
* @author Andrew Selkirk
*/
public class DefaultTreeModel
- implements Serializable, TreeModel
+ implements Serializable, TreeModel
{
- static final long serialVersionUID = -2621068368932566998L;
-
- /**
- * root
- */
- protected TreeNode root = null;
-
- /**
- * listenerList
- */
- protected EventListenerList listenerList = new EventListenerList();
-
- /**
- * asksAllowsChildren
- */
- protected boolean asksAllowsChildren;
-
- /**
- * Constructor DefaultTreeModel
- * @param value0 TODO
- */
- public DefaultTreeModel(TreeNode root)
- {
- if (root == null)
- root = new DefaultMutableTreeNode();
- setRoot(root);
- }
-
- /**
- * Constructor DefaultTreeModel
- * @param value0 TODO
- * @param value1 TODO
- */
- public DefaultTreeModel(TreeNode root, boolean asksAllowsChildren)
- {
- setRoot(root);
- this.asksAllowsChildren = asksAllowsChildren;
- }
-
- /**
- * writeObject
- * @param value0 TODO
- * @exception IOException TODO
- */
- private void writeObject(ObjectOutputStream value0) 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 value0 TODO
- */
- public void setAsksAllowsChildren(boolean value)
- {
- asksAllowsChildren = value; // TODO
- }
-
- /**
- * setRoot
- * @param value0 TODO
- */
- public void setRoot(TreeNode root)
- {
- // Sanity Check
- if (root == null)
- {
- throw new IllegalArgumentException("null root");
- }
- // Set new root
- this.root = root;
-
- // TODO
- }
-
- /**
- * getRoot
- * @return Object
- */
- public Object getRoot()
- {
- return root;
- }
-
- /**
- * getIndexOfChild
- * @param value0 TODO
- * @param value1 TODO
- * @return int
- */
- public int getIndexOfChild(Object parent, Object child)
- {
- return 0; // TODO
- }
-
- /**
- * getChild
- * @param value0 TODO
- * @param value1 TODO
- * @return Object
- */
- public Object getChild(Object node, int idx)
- {
- if (node instanceof TreeNode)
- return ((TreeNode) node).getChildAt(idx);
- else
- return null;
- }
-
- /**
- * getChildCount
- * @param value0 TODO
- * @return int
- */
- public int getChildCount(Object node)
- {
- if (node instanceof TreeNode)
- return ((TreeNode) node).getChildCount();
- else
- return 0;
- }
-
- /**
- * isLeaf
- * @param value0 TODO
- * @return boolean
- */
- public boolean isLeaf(Object node)
- {
- if (node instanceof TreeNode)
- return ((TreeNode) node).isLeaf();
- else
- return true;
- }
-
- /**
- * reload
- */
- public void reload()
- {
- // TODO
- }
-
- /**
- * reload
- * @param value0 TODO
- */
- public void reload(TreeNode value0)
- {
- // TODO
- }
-
- /**
- * valueForPathChanged
- * @param value0 TODO
- * @param value1 TODO
- */
- public void valueForPathChanged(TreePath value0, Object value1)
- {
- // TODO
- }
-
- /**
- * insertNodeInto
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void insertNodeInto(MutableTreeNode value0, MutableTreeNode value1,
- int value2)
- {
- // TODO
- }
-
- /**
- * removeNodeFromParent
- * @param value0 TODO
- */
- public void removeNodeFromParent(MutableTreeNode value0)
- {
- // TODO
- }
-
- /**
- * nodeChanged
- * @param value0 TODO
- */
- public void nodeChanged(TreeNode value0)
- {
- // TODO
- }
-
- /**
- * nodesWereInserted
- * @param value0 TODO
- * @param value1 TODO
- */
- public void nodesWereInserted(TreeNode value0, int[] value1)
- {
- // TODO
- }
-
- /**
- * nodesWereRemoved
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- */
- public void nodesWereRemoved(TreeNode value0, int[] value1, Object[] value2)
- {
- // TODO
- }
-
- /**
- * nodesChanged
- * @param value0 TODO
- * @param value1 TODO
- */
- public void nodesChanged(TreeNode value0, int[] value1)
- {
- // TODO
- }
-
- /**
- * nodeStructureChanged
- * @param value0 TODO
- */
- public void nodeStructureChanged(TreeNode value0)
- {
- // TODO
- }
-
- /**
- * getPathToRoot
- * @param value0 TODO
- * @return TreeNode[]
- */
- public TreeNode[] getPathToRoot(TreeNode value0)
- {
- return null; // TODO
- }
-
- /**
- * getPathToRoot
- * @param value0 TODO
- * @param value1 TODO
- * @return TreeNode[]
- */
- protected TreeNode[] getPathToRoot(TreeNode value0, int value1)
- {
- return null; // TODO
- }
-
- /**
- * 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 <code>TreeModelListener</code> 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 <code>TreeModelListener</code> 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 de27dad04f9..75b76a9e8c6 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 67a21f0205a..535417ec389 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)
OpenPOWER on IntegriCloud