summaryrefslogtreecommitdiff
path: root/javax
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-05-01 21:45:41 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-05-01 21:45:41 +0000
commit480ccb4bfcc622c1ce320c20ce992188187f7573 (patch)
treeaebfd0e230d0370ec1ac1a9b1a99b478abdc6854 /javax
parent4d80ae24073737202d4c51bf9efd2466fea8696d (diff)
downloadclasspath-480ccb4bfcc622c1ce320c20ce992188187f7573.tar.gz
2006-05-01 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge HEAD-->generics-branch for the period 2006-04-13 to 2006-05-01.
Diffstat (limited to 'javax')
-rw-r--r--javax/accessibility/AccessibleAction.java22
-rw-r--r--javax/accessibility/AccessibleRole.java50
-rw-r--r--javax/accessibility/AccessibleState.java31
-rw-r--r--javax/net/ssl/HttpsURLConnection.java8
-rw-r--r--javax/swing/ActionMap.java5
-rw-r--r--javax/swing/DefaultListSelectionModel.java13
-rw-r--r--javax/swing/ImageIcon.java94
-rw-r--r--javax/swing/JButton.java66
-rw-r--r--javax/swing/JComboBox.java35
-rw-r--r--javax/swing/JComponent.java45
-rw-r--r--javax/swing/JDesktopPane.java32
-rw-r--r--javax/swing/JInternalFrame.java49
-rw-r--r--javax/swing/JLabel.java1
-rw-r--r--javax/swing/JList.java180
-rw-r--r--javax/swing/JMenu.java14
-rw-r--r--javax/swing/JMenuItem.java34
-rw-r--r--javax/swing/JPanel.java83
-rw-r--r--javax/swing/JProgressBar.java23
-rw-r--r--javax/swing/JRadioButtonMenuItem.java35
-rw-r--r--javax/swing/JScrollPane.java1
-rw-r--r--javax/swing/JSeparator.java83
-rw-r--r--javax/swing/JSlider.java30
-rw-r--r--javax/swing/JSpinner.java4
-rw-r--r--javax/swing/JSplitPane.java130
-rw-r--r--javax/swing/JTabbedPane.java16
-rw-r--r--javax/swing/JTable.java28
-rw-r--r--javax/swing/JToolBar.java30
-rw-r--r--javax/swing/JToolTip.java2
-rw-r--r--javax/swing/JTree.java113
-rw-r--r--javax/swing/ProgressMonitor.java6
-rw-r--r--javax/swing/RepaintManager.java60
-rw-r--r--javax/swing/ScrollPaneLayout.java2
-rw-r--r--javax/swing/SpinnerDateModel.java96
-rw-r--r--javax/swing/SpinnerNumberModel.java30
-rw-r--r--javax/swing/UIManager.java4
-rw-r--r--javax/swing/ViewportLayout.java14
-rw-r--r--javax/swing/border/AbstractBorder.java55
-rw-r--r--javax/swing/border/BevelBorder.java18
-rw-r--r--javax/swing/border/CompoundBorder.java4
-rw-r--r--javax/swing/border/EtchedBorder.java10
-rw-r--r--javax/swing/border/LineBorder.java16
-rw-r--r--javax/swing/border/MatteBorder.java4
-rw-r--r--javax/swing/border/TitledBorder.java10
-rw-r--r--javax/swing/event/ChangeEvent.java33
-rw-r--r--javax/swing/event/ChangeListener.java32
-rw-r--r--javax/swing/event/TableColumnModelListener.java88
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicComboPopup.java4
-rw-r--r--javax/swing/plaf/basic/BasicInternalFrameUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicLabelUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicListUI.java3
-rw-r--r--javax/swing/plaf/basic/BasicMenuBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicMenuUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicOptionPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicPopupMenuUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicScrollBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicScrollPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicSliderUI.java169
-rw-r--r--javax/swing/plaf/basic/BasicSpinnerUI.java9
-rw-r--r--javax/swing/plaf/basic/BasicSplitPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java40
-rw-r--r--javax/swing/plaf/basic/BasicTableHeaderUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTableUI.java3
-rw-r--r--javax/swing/plaf/basic/BasicTextAreaUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTextFieldUI.java15
-rw-r--r--javax/swing/plaf/basic/BasicTextUI.java12
-rw-r--r--javax/swing/plaf/basic/BasicToolBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTreeUI.java319
-rw-r--r--javax/swing/table/DefaultTableCellRenderer.java3
-rw-r--r--javax/swing/table/DefaultTableColumnModel.java346
-rw-r--r--javax/swing/table/TableColumnModel.java95
-rw-r--r--javax/swing/text/AbstractDocument.java92
-rw-r--r--javax/swing/text/AsyncBoxView.java2
-rw-r--r--javax/swing/text/CompositeView.java98
-rw-r--r--javax/swing/text/DefaultCaret.java68
-rw-r--r--javax/swing/text/DefaultHighlighter.java22
-rw-r--r--javax/swing/text/FieldView.java7
-rw-r--r--javax/swing/text/FlowView.java2
-rw-r--r--javax/swing/text/Utilities.java74
-rw-r--r--javax/swing/text/View.java29
-rw-r--r--javax/swing/text/WrappedPlainView.java76
-rw-r--r--javax/swing/tree/AbstractLayoutCache.java89
-rw-r--r--javax/swing/tree/DefaultMutableTreeNode.java2
-rw-r--r--javax/swing/tree/DefaultTreeCellEditor.java20
-rw-r--r--javax/swing/tree/DefaultTreeCellRenderer.java29
-rw-r--r--javax/swing/tree/DefaultTreeModel.java68
-rw-r--r--javax/swing/tree/DefaultTreeSelectionModel.java366
-rw-r--r--javax/swing/tree/FixedHeightLayoutCache.java239
-rw-r--r--javax/swing/tree/TreePath.java14
-rw-r--r--javax/swing/tree/VariableHeightLayoutCache.java48
-rw-r--r--javax/xml/datatype/DatatypeFactory.java37
91 files changed, 3130 insertions, 1061 deletions
diff --git a/javax/accessibility/AccessibleAction.java b/javax/accessibility/AccessibleAction.java
index 2ca683e45..a7cf05e4a 100644
--- a/javax/accessibility/AccessibleAction.java
+++ b/javax/accessibility/AccessibleAction.java
@@ -55,6 +55,28 @@ package javax.accessibility;
*/
public interface AccessibleAction
{
+
+ /**
+ * The name of an action which decrements a value.
+ *
+ * @since 1.5
+ */
+ static final String DECREMENT = "decrement";
+
+ /**
+ * The name of an action which increments a value.
+ *
+ * @since 1.5
+ */
+ static final String INCREMENT = "increment";
+
+ /**
+ * The name of an action which toggles the expansion of a tree node.
+ *
+ * @since 1.5
+ */
+ static final String TOGGLE_EXPAND = "toggle expand";
+
/**
* Get the number possible actions for this object, with the zeroth
* representing the default action.
diff --git a/javax/accessibility/AccessibleRole.java b/javax/accessibility/AccessibleRole.java
index f386ad0e9..a5396f147 100644
--- a/javax/accessibility/AccessibleRole.java
+++ b/javax/accessibility/AccessibleRole.java
@@ -467,6 +467,56 @@ public class AccessibleRole extends AccessibleBundle
= new AccessibleRole("groupbox");
/**
+ * A formula for creating a value.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole EDITBAR
+ = new AccessibleRole("editbar");
+
+ /**
+ * A text-based footer.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole FOOTER
+ = new AccessibleRole("footer");
+
+ /**
+ * A text-based header.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole HEADER
+ = new AccessibleRole("header");
+
+
+ /**
+ * A text-based paragraph.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole PARAGRAPH
+ = new AccessibleRole("paragraph");
+
+ /**
+ * Represents the current level of progress on a particular task.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole PROGRESS_MONITOR
+ = new AccessibleRole("progress monitor");
+
+ /**
+ * A ruler is a method of measuring the distance between two
+ * points.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole RULER
+ = new AccessibleRole("ruler");
+
+ /**
* Create a new constant with a locale independent key. Follow the example,
* keep the constructor private and make public constants instead.
*
diff --git a/javax/accessibility/AccessibleState.java b/javax/accessibility/AccessibleState.java
index a630354b0..e4d00bd70 100644
--- a/javax/accessibility/AccessibleState.java
+++ b/javax/accessibility/AccessibleState.java
@@ -177,6 +177,28 @@ public class AccessibleState extends AccessibleBundle
= new AccessibleState("iconified");
/**
+ * Indicates that the state of this particular object is
+ * indeterminate. This commonly occurs when an object is incapable
+ * of representing the state by a single value.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState INDETERMINATE
+ = new AccessibleState("indeterminate");
+
+ /**
+ * Indicates that this particular object manages a number of
+ * subcomponents. This is a common property of structures such as
+ * trees and tables, which have a number of sub-elements such as
+ * rows and columns. The subcomponents should be left to the
+ * object, and not managed by the application.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState MANAGES_DESCENDANTS
+ = new AccessibleState("manages descendants");
+
+ /**
* Indicates that something must be done in the current object before
* interaction is allowed on other windows, usually for dialogs.
*
@@ -250,6 +272,15 @@ public class AccessibleState extends AccessibleBundle
= new AccessibleState("showing");
/**
+ * Indicates that this particular object is truncated when displayed
+ * visually.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState TRUNCATED
+ = new AccessibleState("truncated");
+
+ /**
* Indicates that this object intends to be visible. However, if its
* parent is invisible, this object is as well.
*
diff --git a/javax/net/ssl/HttpsURLConnection.java b/javax/net/ssl/HttpsURLConnection.java
index 4c73edbcd..3f30dc1b8 100644
--- a/javax/net/ssl/HttpsURLConnection.java
+++ b/javax/net/ssl/HttpsURLConnection.java
@@ -1,5 +1,5 @@
/* HttpsURLConnection.java -- an HTTPS connection.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.net.ssl;
-import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.Certificate;
@@ -90,9 +89,10 @@ public abstract class HttpsURLConnection extends HttpURLConnection
* Creates a new HTTPS URL connection.
*
* @param url The URL of the connection being established.
- * @throws IOException If the connection cannot be established.
+ * @specnote This was marked as throwing IOException in 1.4,
+ * but this was removed in 1.5.
*/
- protected HttpsURLConnection(URL url) throws IOException
+ protected HttpsURLConnection(URL url)
{
super(url);
}
diff --git a/javax/swing/ActionMap.java b/javax/swing/ActionMap.java
index 2a8c78d66..0d6706c3b 100644
--- a/javax/swing/ActionMap.java
+++ b/javax/swing/ActionMap.java
@@ -1,5 +1,5 @@
/* ActionMap.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,9 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/javax/swing/DefaultListSelectionModel.java b/javax/swing/DefaultListSelectionModel.java
index 003513a23..b6d3e079e 100644
--- a/javax/swing/DefaultListSelectionModel.java
+++ b/javax/swing/DefaultListSelectionModel.java
@@ -162,11 +162,14 @@ public class DefaultListSelectionModel implements Cloneable,
/**
* Sets the value of the {@link #selectionMode} property.
*
- * @param a The new value of the property
+ * @param mode The new value of the property
*/
- public void setSelectionMode(int a)
+ public void setSelectionMode(int mode)
{
- selectionMode = a;
+ if (mode < ListSelectionModel.SINGLE_SELECTION
+ || mode > ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ throw new IllegalArgumentException("Unrecognised mode: " + mode);
+ selectionMode = mode;
}
/**
@@ -552,9 +555,10 @@ public class DefaultListSelectionModel implements Cloneable,
int i;
- Up: for (i = from; i>=0; i=sel.nextSetBit(i+1))
+ for (i = from; i>=0; i=sel.nextSetBit(i+1))
to = i;
+ sel.clear();
fireValueChanged(from, to, valueIsAdjusting);
}
@@ -776,6 +780,7 @@ public class DefaultListSelectionModel implements Cloneable,
DefaultListSelectionModel model =
(DefaultListSelectionModel) super.clone();
model.sel = (BitSet) sel.clone();
+ model.listenerList = new EventListenerList();
return model;
}
}
diff --git a/javax/swing/ImageIcon.java b/javax/swing/ImageIcon.java
index 0baaf6f60..7347985eb 100644
--- a/javax/swing/ImageIcon.java
+++ b/javax/swing/ImageIcon.java
@@ -1,5 +1,5 @@
/* ImageIcon.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package javax.swing;
import java.awt.Component;
import java.awt.Graphics;
+import java.awt.IllegalComponentStateException;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
@@ -60,7 +61,8 @@ public class ImageIcon
implements Icon, Serializable, Accessible
{
/**
- * Accessibility support for ImageIcon.
+ * Provides the accessibility features for the <code>ImageIcon</code>
+ * class.
*/
protected class AccessibleImageIcon
extends AccessibleContext
@@ -69,7 +71,7 @@ public class ImageIcon
private static final long serialVersionUID = 2113430526551336564L;
/**
- * Creates a new instance of AccessibleImageIcon.
+ * Creates a new instance of <code>AccessibleImageIcon</code>.
*/
protected AccessibleImageIcon()
{
@@ -77,10 +79,9 @@ public class ImageIcon
}
/**
- * Returns the AccessibleRole of ImageIcon, which is
- * {@link AccessibleRole#ICON}.
+ * Returns the accessible role for the <code>ImageIcon</code>.
*
- * @return {@link AccessibleRole#ICON}
+ * @return {@link AccessibleRole#ICON}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -88,45 +89,47 @@ public class ImageIcon
}
/**
- * Returns the accessible state of this ImageIcon.
+ * Returns the accessible state for the <code>ImageIcon</code>. To
+ * match the reference implementation, this method always returns
+ * <code>null</code>.
*
- * @return the accessible state of this ImageIcon
+ * @return <code>null</code>.
*/
public AccessibleStateSet getAccessibleStateSet()
{
- // TODO: which state information from ImageIcon is returned here??
- return new AccessibleStateSet();
+ // refer to Sun's bug report 4269253
+ return null;
}
/**
- * Returns the accessible parent of this object, which is <code>null</code>
- * in this case, because ImageIcons have no parent.
+ * Returns the accessible parent of this object. To match the reference
+ * implementation, this method always returns <code>null</code>.
*
- * @return <code>null</code>, because ImageIcons have no parent
+ * @return <code>null</code>.
*/
public Accessible getAccessibleParent()
{
- // TODO: ImageIcons have no parent, have they ??
+ // refer to Sun's bug report 4269253
return null;
}
/**
- * Returns the index of this object in its accessible parent, which is
- * -1 here, because ImageIcons have no accessible parent.
+ * Returns the index of this object in its accessible parent. To match
+ * the reference implementation, this method always returns <code>-1</code>.
*
- * @return -1 because ImageIcons have no parent
+ * @return <code>-1</code>.
*/
public int getAccessibleIndexInParent()
{
- // TODO: do ImageIcons have parents??
+ // refer to Sun's bug report 4269253
return -1;
}
/**
* Returns the number of accessible children of this component,
- * which is 0, because ImageIcons have no children.
+ * which is 0, because an {@link ImageIcon} has no children.
*
- * @return 0 because ImageIcons have no children
+ * @return <code>0</code>.
*/
public int getAccessibleChildrenCount()
{
@@ -135,11 +138,12 @@ public class ImageIcon
/**
* Returns the accessible child at index <code>i</code>, which is
- * <code>null</code> in this case because ImageIcons have no children.
+ * <code>null</code> in this case because an {@link ImageIcon} has no
+ * children.
*
* @param i the index of the child to be fetched
*
- * @return <code>null</code> because ImageIcons have no children
+ * @return <code>null</code>.
*/
public Accessible getAccessibleChild(int i)
{
@@ -147,21 +151,25 @@ public class ImageIcon
}
/**
- * Returns the locale of this object. This returns the default locale
- * that is set for the current VM.
+ * Returns the locale of this object. To match the reference
+ * implementation, this method always returns <code>null</code>.
*
- * @return the locale of this object
+ * @return <code>null</code>.
*/
- public Locale getLocale()
+ public Locale getLocale()
+ throws IllegalComponentStateException
{
- return Locale.getDefault();
+ // refer to Sun's bug report 4269253
+ return null;
}
/**
- * Returns the accessible Icon description. This returns the
- * actual 'description' property of the ImageIcon.
+ * Returns the accessible icon description. This returns the
+ * <code>description</code> property of the underlying {@link ImageIcon}.
*
- * @return the accessible Icon description
+ * @return The description (possibly <code>null</code>).
+ *
+ * @see #setAccessibleIconDescription(String)
*/
public String getAccessibleIconDescription()
{
@@ -169,10 +177,12 @@ public class ImageIcon
}
/**
- * Sets the accessible Icon description. This sets the
- * actual 'description' property of the ImageIcon.
+ * Sets the accessible icon description. This sets the
+ * <code>description</code> property of the underlying {@link ImageIcon}.
*
- * @param newDescr the description to be set
+ * @param newDescr the description (<code>null</code> permitted).
+ *
+ * @see #getAccessibleIconDescription()
*/
public void setAccessibleIconDescription(String newDescr)
{
@@ -180,10 +190,10 @@ public class ImageIcon
}
/**
- * Returns the icon height. This returns the iconHeight property of
- * the underlying Icon.
+ * Returns the icon height. This returns the <code>iconHeight</code>
+ * property of the underlying {@link ImageIcon}.
*
- * @return the icon height
+ * @return The icon height.
*/
public int getAccessibleIconHeight()
{
@@ -191,10 +201,10 @@ public class ImageIcon
}
/**
- * Returns the icon width. This returns the iconWidth property of
- * the underlying Icon.
+ * Returns the icon width. This returns the <code>iconWidth</code> property
+ * of the underlying {@link ImageIcon}.
*
- * @return the icon width
+ * @return The icon width.
*/
public int getAccessibleIconWidth()
{
@@ -446,9 +456,11 @@ public class ImageIcon
}
/**
- * Returns the AccessibleContext for this ImageIcon.
+ * Returns the object that provides accessibility features for this
+ * <code>ImageIcon</code> instance.
*
- * @return the AccessibleContext for this ImageIcon
+ * @return The accessible context (an instance of
+ * {@link AccessibleImageIcon}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JButton.java b/javax/swing/JButton.java
index c1340bbc2..787adb87c 100644
--- a/javax/swing/JButton.java
+++ b/javax/swing/JButton.java
@@ -1,5 +1,5 @@
/* JButton.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -78,27 +78,57 @@ public class JButton extends AbstractButton
*/
private boolean defaultCapable;
+ /**
+ * Creates a new button with an empty string for the button text and no
+ * icon.
+ */
public JButton()
{
this(null, null);
}
+ /**
+ * Creates a new button from the specified action.
+ *
+ * @param a the action (<code>null</code> permitted).
+ *
+ * @see AbstractButton#setAction(Action)
+ */
public JButton(Action a)
{
this();
setAction(a);
}
+ /**
+ * Creates a new button with the specified icon (and an empty string for
+ * the button text).
+ *
+ * @param icon the icon (<code>null</code> permitted).
+ */
public JButton(Icon icon)
{
this(null, icon);
}
+ /**
+ * Creates a new button with the specified text and no icon.
+ *
+ * @param text the button text (<code>null</code> permitted, will be
+ * substituted by an empty string).
+ */
public JButton(String text)
{
this(text, null);
}
+ /**
+ * Creates a new button with the specified text and icon.
+ *
+ * @param text the button text (<code>null</code> permitted, will be
+ * substituted by an empty string).
+ * @param icon the icon (<code>null</code> permitted).
+ */
public JButton(String text, Icon icon)
{
super();
@@ -108,12 +138,16 @@ public class JButton extends AbstractButton
}
protected void configurePropertiesFromAction(Action a)
- {
- // Factory method which sets the AbstractButton's properties according to
- // values from the Action instance.
+ {
super.configurePropertiesFromAction(a);
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JButton</code> component.
+ *
+ * @return The accessible context (an instance of {@link AccessibleJButton}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -121,6 +155,13 @@ public class JButton extends AbstractButton
return accessibleContext;
}
+ /**
+ * Returns the suffix (<code>"ButtonUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JButton</code>.
+ *
+ * @return <code>"ButtonUI"</code>.
+ */
public String getUIClassID()
{
// Returns a string that specifies the name of the L&F class that renders
@@ -138,7 +179,7 @@ public class JButton extends AbstractButton
* its <code>JRootPane</code>
*
* @see #isDefaultCapable()
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
*/
@@ -160,7 +201,7 @@ public class JButton extends AbstractButton
*
* @return <code>true</code> if this button can act as the default button
*
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see #isDefaultButton()
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
@@ -172,6 +213,13 @@ public class JButton extends AbstractButton
return defaultCapable;
}
+ /**
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JButton</code>.
+ *
+ * @return A string describing the attributes of this <code>JButton</code>
+ * (never <code>null</code>).
+ */
protected String paramString()
{
String superParam = super.paramString();
@@ -205,7 +253,7 @@ public class JButton extends AbstractButton
* @param defaultCapable <code>true</code> if this button can become the
* default button in its JRootPane, <code>false</code> otherwise
*
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see #isDefaultButton()
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
@@ -215,6 +263,10 @@ public class JButton extends AbstractButton
this.defaultCapable = defaultCapable;
}
+ /**
+ * Sets this button's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
+ */
public void updateUI()
{
setUI((ButtonUI) UIManager.getUI(this));
diff --git a/javax/swing/JComboBox.java b/javax/swing/JComboBox.java
index f995e114a..17bcf1f99 100644
--- a/javax/swing/JComboBox.java
+++ b/javax/swing/JComboBox.java
@@ -1,5 +1,5 @@
/* JComboBox.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -1102,15 +1102,33 @@ public class JComboBox extends JComponent implements ItemSelectable,
}
/**
- * A string that describes this JComboBox. Normally only used for debugging.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JComboBox</code>.
*
- * @return A string describing this JComboBox
+ * @return A string describing the attributes of this <code>JComboBox</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JComboBox";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isEditable=").append(isEditable());
+ sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
+ sb.append(",maximumRowCount=").append(getMaximumRowCount());
+
+ sb.append(",selectedItemReminder=");
+ if (selectedItemReminder != null)
+ sb.append(selectedItemReminder);
+ return superParamStr + sb.toString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JComboBox</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJComboBox}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -1219,6 +1237,10 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
private static final long serialVersionUID = 8217828307256675666L;
+ /**
+ * @specnote This constructor was protected in 1.4, but made public
+ * in 1.5.
+ */
public AccessibleJComboBox()
{
// Nothing to do here.
@@ -1254,6 +1276,11 @@ public class JComboBox extends JComponent implements ItemSelectable,
return false;
}
+ /**
+ * Returns the accessible role for the <code>JComboBox</code> component.
+ *
+ * @return {@link AccessibleRole#COMBO_BOX}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.COMBO_BOX;
diff --git a/javax/swing/JComponent.java b/javax/swing/JComponent.java
index eba05d03c..8838dda0a 100644
--- a/javax/swing/JComponent.java
+++ b/javax/swing/JComponent.java
@@ -1862,8 +1862,8 @@ public abstract class JComponent extends Container implements Serializable
// Go through children from top to bottom and find out their paint
// rectangles.
- int index = 0;
- while (paintRectangles.size() > 0 && index < children.length)
+ for (int index = 0; paintRectangles.size() > 0 &&
+ index < children.length; index++)
{
Component comp = children[index];
if (! comp.isVisible())
@@ -1936,6 +1936,12 @@ public abstract class JComponent extends Container implements Serializable
newPaintRects.add(rect);
}
}
+ else
+ {
+ // Not opaque, need to reuse the current paint rectangles
+ // for the next component.
+ newPaintRects.add(r);
+ }
}
else
@@ -1958,8 +1964,6 @@ public abstract class JComponent extends Container implements Serializable
paintRegions.add(componentRectangles);
componentRectangles = new ArrayList();
}
-
- index++;
}
// paintingTile becomes true just before we start painting the component's
@@ -2024,34 +2028,10 @@ public abstract class JComponent extends Container implements Serializable
g.clipRect(inner.x, inner.y, inner.width, inner.height);
Component[] children = getComponents();
- // Find the bottommost component that needs to be painted. This is the
- // component that - together with the rectangles of the components that
- // are painted above it - covers the whole clip area.
- Rectangle rect = new Rectangle();
- int startIndex = children.length - 1;
- for (int i = 0; i < children.length; i++)
- {
- Rectangle b = children[i].getBounds();
- if (children[i].isOpaque() && children[i].isVisible()
- && g.hitClip(b.x, b.y, b.width, b.height))
- {
- if (rect.isEmpty())
- rect.setBounds(b);
- else
- SwingUtilities.computeUnion(b.x, b.y, b.width, b.height, rect);
-
- if (SwingUtilities.isRectangleContainingRectangle(rect, inner))
- {
- startIndex = i;
- break;
- }
- }
- }
-
// paintingTile becomes true just before we start painting the component's
// children.
paintingTile = true;
- for (int i = startIndex; i >= 0; i--) //children.length; i++)
+ for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
{
// paintingTile must be set to false before we begin to start painting
// the last tile.
@@ -2942,9 +2922,12 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #opaque} property.
+ * Set if the component should paint all pixels withing its bounds.
+ * If this property is set to false, the component expects the cleared
+ * background.
*
- * @param isOpaque The new value of the property
+ * @param isOpaque if true, paint all pixels. If false, expect the clean
+ * background.
*
* @see ComponentUI#update
*/
diff --git a/javax/swing/JDesktopPane.java b/javax/swing/JDesktopPane.java
index 92b25f979..454870ea6 100644
--- a/javax/swing/JDesktopPane.java
+++ b/javax/swing/JDesktopPane.java
@@ -56,7 +56,6 @@ import javax.swing.plaf.DesktopPaneUI;
*/
public class JDesktopPane extends JLayeredPane implements Accessible
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = 766333777224038726L;
/**
@@ -94,15 +93,15 @@ public class JDesktopPane extends JLayeredPane implements Accessible
private boolean clientDragModeSet = false;
/**
- * AccessibleJDesktopPane
+ * Provides the accessibility features for the <code>JDesktopPane</code>
+ * component.
*/
protected class AccessibleJDesktopPane extends AccessibleJComponent
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = 6079388927946077570L;
/**
- * Constructor AccessibleJDesktopPane
+ * Creates a new <code>AccessibleJDesktopPane</code> instance.
*/
protected AccessibleJDesktopPane()
{
@@ -110,9 +109,9 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JSlider</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#DESKTOP_PANE}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -298,13 +297,22 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * This method returns a String that describes the JDesktopPane.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JDesktopPane</code>.
*
- * @return A String that describes the JDesktopPane.
+ * @return A string describing the attributes of this <code>JDesktopPane</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JDesktopPane";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isOptimizedDrawingPossible=");
+ sb.append(isOptimizedDrawingEnabled());
+ sb.append(",desktopManager=");
+ if (desktopManager != null)
+ sb.append(desktopManager);
+ return superParamStr + sb.toString();
}
/**
@@ -330,9 +338,11 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JDesktopPane</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of
+ * {@link AccessibleJDesktopPane}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JInternalFrame.java b/javax/swing/JInternalFrame.java
index 937212562..79dcc7326 100644
--- a/javax/swing/JInternalFrame.java
+++ b/javax/swing/JInternalFrame.java
@@ -280,15 +280,17 @@ public class JInternalFrame extends JComponent implements Accessible,
updateUI();
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JDesktopIcon</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJDesktopIcon}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
- accessibleContext = new AccessibleJDesktopIcon();
+ accessibleContext = new AccessibleJDesktopIcon();
return accessibleContext;
}
@@ -773,10 +775,16 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method returns the default action taken when this JInternalFrame is
- * closed.
+ * Returns a code for the default action taken when this
+ * <code>JInternalFrame</code> is closed.
*
- * @return The default action taken when this JInternalFrame is closed.
+ * @return The action code (usually one of
+ * {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE}, or
+ * {@link WindowConstants#DISPOSE_ON_CLOSE}).
+ *
+ * @see #setDefaultCloseOperation(int)
+ * @see #doDefaultCloseAction()
*/
public int getDefaultCloseOperation()
{
@@ -1202,13 +1210,15 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method returns a String describing this JInternalFrame.
+ * An implementation dependent string describing the current state of this
+ * <code>JInternalFrame</code> instance.
*
- * @return A String describing this JInternalFrame.
+ * @return A string describing the current state of this
+ * <code>JInternalFrame</code> instance.
*/
protected String paramString()
{
- return super.paramString();
+ return super.paramString() + ",title=" + getTitle();
}
/**
@@ -1322,12 +1332,17 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method sets the action taken when this JInternalFrame is closed.
- *
- * @param operation One of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE or
- * DISPOSE_ON_CLOSE.
+ * Sets a code for the action to be taken when this
+ * <code>JInternalFrame</code> is closed. Note that no validation is
+ * performed on the <code>operation</code> code, any integer will be
+ * accepted (nevertheless, you should pass in one of the listed values).
*
- * @throws Error If the given operation is not one of the allowed modes.
+ * @param operation one of {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE} or
+ * {@link WindowConstants#DISPOSE_ON_CLOSE}.
+ *
+ * @see #getDefaultCloseOperation()
+ * @see #doDefaultCloseAction()
*/
public void setDefaultCloseOperation(int operation)
{
diff --git a/javax/swing/JLabel.java b/javax/swing/JLabel.java
index 7c552469e..65b1e6fcd 100644
--- a/javax/swing/JLabel.java
+++ b/javax/swing/JLabel.java
@@ -512,6 +512,7 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
Icon oldIcon = icon;
icon = newIcon;
firePropertyChange("icon", oldIcon, newIcon);
+ repaint();
}
}
diff --git a/javax/swing/JList.java b/javax/swing/JList.java
index 04f658361..04f3881a2 100644
--- a/javax/swing/JList.java
+++ b/javax/swing/JList.java
@@ -1,5 +1,5 @@
/* JList.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -1022,48 +1022,56 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*/
public JList()
{
- init();
+ init(new DefaultListModel());
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param items the initial list items.
*/
- public JList(Object[] listData)
+ public JList(Object[] items)
{
- init();
- setListData(listData);
+ init(createListModel(items));
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param items the initial list items.
*/
- public JList(Vector<?> listData)
+ public JList(Vector<?> items)
{
- init();
- setListData(listData);
+ init(createListModel(items));
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param model a model containing the list items (<code>null</code> not
+ * permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
*/
- public JList(ListModel listData)
+ public JList(ListModel model)
{
- init();
- setModel(listData);
+ init(model);
}
- void init()
+ /**
+ * Initializes the list.
+ *
+ * @param m the list model (<code>null</code> not permitted).
+ */
+ private void init(ListModel m)
{
+ if (m == null)
+ throw new IllegalArgumentException("Null model not permitted.");
dragEnabled = false;
fixedCellHeight = -1;
fixedCellWidth = -1;
@@ -1075,9 +1083,17 @@ public class JList extends JComponent implements Accessible, Scrollable
cellRenderer = new DefaultListCellRenderer();
listListener = new ListListener();
- setModel(new DefaultListModel());
- setSelectionModel(createSelectionModel());
- setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ model = m;
+ if (model != null)
+ model.addListDataListener(listListener);
+
+ selectionModel = createSelectionModel();
+ if (selectionModel != null)
+ {
+ selectionModel.addListSelectionListener(listListener);
+ selectionModel.setSelectionMode
+ (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ }
setLayout(null);
updateUI();
@@ -1117,6 +1133,8 @@ public class JList extends JComponent implements Accessible, Scrollable
* #prototypeCellValue} property is set, but setting it explicitly
* overrides the height computed from {@link #prototypeCellValue}.
*
+ * @param h the height.
+ *
* @see #getFixedCellHeight
* @see #getPrototypeCellValue
*/
@@ -1127,7 +1145,7 @@ public class JList extends JComponent implements Accessible, Scrollable
int old = fixedCellHeight;
fixedCellHeight = h;
- firePropertyChange("fixedCellWidth", old, h);
+ firePropertyChange("fixedCellHeight", old, h);
}
@@ -1549,20 +1567,39 @@ public class JList extends JComponent implements Accessible, Scrollable
* @param listData The object array to build a new list model on
* @see #setModel
*/
- public void setListData(final Object[] listData)
+ public void setListData(Object[] listData)
{
- setModel(new AbstractListModel()
- {
- public int getSize()
- {
- return listData.length;
- }
+ setModel(createListModel(listData));
+ }
- public Object getElementAt(int i)
- {
- return listData[i];
- }
- });
+ private ListModel createListModel(final Object[] items)
+ {
+ return new AbstractListModel()
+ {
+ public int getSize()
+ {
+ return items.length;
+ }
+ public Object getElementAt(int i)
+ {
+ return items[i];
+ }
+ };
+ }
+
+ private ListModel createListModel(final Vector items)
+ {
+ return new AbstractListModel()
+ {
+ public int getSize()
+ {
+ return items.size();
+ }
+ public Object getElementAt(int i)
+ {
+ return items.get(i);
+ }
+ };
}
/**
@@ -1576,17 +1613,17 @@ public class JList extends JComponent implements Accessible, Scrollable
public void setListData(final Vector<?> listData)
{
setModel(new AbstractListModel()
- {
- public int getSize()
- {
- return listData.size();
- }
-
- public Object getElementAt(int i)
- {
- return listData.elementAt(i);
- }
- });
+ {
+ public int getSize()
+ {
+ return listData.size();
+ }
+
+ public Object getElementAt(int i)
+ {
+ return listData.elementAt(i);
+ }
+ });
}
/**
@@ -2022,11 +2059,27 @@ public class JList extends JComponent implements Accessible, Scrollable
return selectionModel.getLeadSelectionIndex();
}
+ /**
+ * Returns the lowest item index in the current selection, or <code>-1</code>
+ * if there is no selection.
+ *
+ * @return The index.
+ *
+ * @see #getMaxSelectionIndex()
+ */
public int getMinSelectionIndex()
{
- return selectionModel.getMaxSelectionIndex();
+ return selectionModel.getMinSelectionIndex();
}
+ /**
+ * Returns the highest item index in the current selection, or
+ * <code>-1</code> if there is no selection.
+ *
+ * @return The index.
+ *
+ * @see #getMinSelectionIndex()
+ */
public int getMaxSelectionIndex()
{
return selectionModel.getMaxSelectionIndex();
@@ -2140,7 +2193,14 @@ public class JList extends JComponent implements Accessible, Scrollable
*/
public Rectangle getCellBounds(int index0, int index1)
{
- return getUI().getCellBounds(this, index0, index1);
+ ListUI ui = getUI();
+ Rectangle bounds = null;
+ if (ui != null)
+ {
+ bounds = ui.getCellBounds(this, index0, index1);
+ }
+ // When the UI is null, this method also returns null in the RI.
+ return bounds;
}
/**
@@ -2203,4 +2263,28 @@ public class JList extends JComponent implements Accessible, Scrollable
}
return index;
}
+
+ /**
+ * Returns a string describing the attributes for the <code>JList</code>
+ * component, for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format of the string may vary between
+ * implementations.
+ *
+ * @return A string describing the attributes of the <code>JList</code>.
+ */
+ protected String paramString()
+ {
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",fixedCellHeight=").append(getFixedCellHeight());
+ sb.append(",fixedCellWidth=").append(getFixedCellWidth());
+ sb.append(",selectionBackground=");
+ if (getSelectionBackground() != null)
+ sb.append(getSelectionBackground());
+ sb.append(",selectionForeground=");
+ if (getSelectionForeground() != null)
+ sb.append(getSelectionForeground());
+ sb.append(",visibleRowCount=").append(getVisibleRowCount());
+ sb.append(",layoutOrientation=").append(getLayoutOrientation());
+ return sb.toString();
+ }
}
diff --git a/javax/swing/JMenu.java b/javax/swing/JMenu.java
index 438fc49f1..37ed14854 100644
--- a/javax/swing/JMenu.java
+++ b/javax/swing/JMenu.java
@@ -1,5 +1,5 @@
/* JMenu.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Point;
import java.awt.event.KeyEvent;
@@ -821,26 +823,31 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
}
public int getAccessibleChildrenCount()
+ throws NotImplementedException
{
return 0;
}
public Accessible getAccessibleChild(int value0)
+ throws NotImplementedException
{
return null;
}
public AccessibleSelection getAccessibleSelection()
+ throws NotImplementedException
{
return null;
}
public Accessible getAccessibleSelection(int value0)
+ throws NotImplementedException
{
return null;
}
public boolean isAccessibleChildSelected(int value0)
+ throws NotImplementedException
{
return false;
}
@@ -851,26 +858,31 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
}
public int getAccessibleSelectionCount()
+ throws NotImplementedException
{
return 0;
}
public void addAccessibleSelection(int value0)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void removeAccessibleSelection(int value0)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void clearAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void selectAllAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/JMenuItem.java b/javax/swing/JMenuItem.java
index 643fe8fd5..272c1cfe6 100644
--- a/javax/swing/JMenuItem.java
+++ b/javax/swing/JMenuItem.java
@@ -1,5 +1,5 @@
/* JMenuItem.java --
- Copyright (C) 2002, 2004, 2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -671,16 +673,26 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
/**
- * A string that describes this JMenuItem. Normally only used
- * for debugging.
+ * Returns a string describing the attributes for the <code>JToolTip</code>
+ * component, for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format of the string may vary between
+ * implementations.
*
- * @return A string describing this JMenuItem
+ * @return A string describing the attributes of the <code>JMenuItem</code>.
*/
protected String paramString()
{
+ // calling super seems to be sufficient here...
return super.paramString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JMenuItem</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJMenuItem}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -689,13 +701,19 @@ public class JMenuItem extends AbstractButton implements Accessible,
return accessibleContext;
}
+ /**
+ * Provides the accessibility features for the <code>JMenuItem</code>
+ * component.
+ *
+ * @see JMenuItem#getAccessibleContext()
+ */
protected class AccessibleJMenuItem extends AccessibleAbstractButton
implements ChangeListener
{
private static final long serialVersionUID = 6748924232082076534L;
/**
- * Creates a new AccessibleJMenuItem object.
+ * Creates a new <code>AccessibleJMenuItem</code> instance.
*/
AccessibleJMenuItem()
{
@@ -703,10 +721,16 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
public void stateChanged(ChangeEvent event)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
+ /**
+ * Returns the accessible role for the <code>JMenuItem</code> component.
+ *
+ * @return {@link AccessibleRole#MENU_ITEM}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.MENU_ITEM;
diff --git a/javax/swing/JPanel.java b/javax/swing/JPanel.java
index 815e452dc..3bd71d1c2 100644
--- a/javax/swing/JPanel.java
+++ b/javax/swing/JPanel.java
@@ -1,5 +1,5 @@
/* JPanel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -80,54 +80,108 @@ public class JPanel extends JComponent implements Accessible
}
}
+ /**
+ * Creates a new panel with a new instance of {@link FlowLayout} as the
+ * layout manager and double-buffering enabled.
+ */
public JPanel()
{
this(new FlowLayout(), true);
}
- public JPanel(boolean double_buffered)
+ /**
+ * Creates a new panel with double-buffering enabled or disabled as
+ * specified. The default layout manager is an instance of
+ * {@link FlowLayout}.
+ *
+ * @param isDoubleBuffered a flag that controls whether or not
+ * double-buffering is enabled.
+ */
+ public JPanel(boolean isDoubleBuffered)
{
- this(new FlowLayout(), double_buffered);
+ this(new FlowLayout(), isDoubleBuffered);
}
+ /**
+ * Creates a new panel with the specified layout manager. Double-buffering
+ * is enabled by default.
+ *
+ * @param layout the layout manager (<code>null</code> permitted).
+ */
public JPanel(LayoutManager layout)
{
this(layout, true);
}
+ /**
+ * Creates a new panel with the specified layout manager and
+ * double-buffering.
+ *
+ * @param layout the layout manager (<code>null</code> permitted).
+ * @param isDoubleBuffered a flag that controls whether or not
+ * double-buffering is enabled.
+ */
public JPanel(LayoutManager layout, boolean isDoubleBuffered)
{
- if (layout == null)
- {
- // TODO: Is this correct? Or should we throw a NPE?
- layout = new FlowLayout();
- }
setLayout(layout);
- setOpaque(true);
-
+ setOpaque(true);
+ setDoubleBuffered(isDoubleBuffered);
updateUI();
}
+ /**
+ * Returns the suffix (<code>"PanelUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JPanel</code>.
+ *
+ * @return <code>"PanelUI"</code>.
+ */
public String getUIClassID()
{
return "PanelUI";
}
+ /**
+ * Sets the UI delegate for the <code>JPanel</code> component.
+ *
+ * @param ui the UI delegate.
+ *
+ * @since 1.4
+ * @see #getUI()
+ */
public void setUI(PanelUI ui)
{
super.setUI(ui);
}
+ /**
+ * Returns the UI delegate for the <code>JPanel</code> component.
+ *
+ * @return The UI delegate.
+ *
+ * @since 1.4
+ * @see #setUI(PanelUI)
+ */
public PanelUI getUI()
{
return (PanelUI) ui;
}
+ /**
+ * Sets this panel's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
+ */
public void updateUI()
{
setUI((PanelUI) UIManager.getUI(this));
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JPanel</code> component.
+ *
+ * @return The accessible context (an instance of {@link AccessibleJPanel}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -135,7 +189,14 @@ public class JPanel extends JComponent implements Accessible
return accessibleContext;
}
- protected String paramString()
+ /**
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JPanel</code>.
+ *
+ * @return A string describing the attributes of this <code>JPanel</code>
+ * (never <code>null</code>).
+ */
+ protected String paramString()
{
return super.paramString();
}
diff --git a/javax/swing/JProgressBar.java b/javax/swing/JProgressBar.java
index 2f61ac305..db936f64a 100644
--- a/javax/swing/JProgressBar.java
+++ b/javax/swing/JProgressBar.java
@@ -634,15 +634,28 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns a string that can be used to
- * describe this JProgressBar. This method is usually
- * only used for debugging purposes.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JProgressBar</code>.
*
- * @return A string that describes this JProgressBar.
+ * @return A string describing the attributes of this
+ * <code>JProgressBar</code> (never <code>null</code>).
*/
protected String paramString()
{
- return "JProgressBar";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL)
+ sb.append("HORIZONTAL");
+ else
+ sb.append("VERTICAL");
+ sb.append(",paintBorder=").append(isBorderPainted());
+ sb.append(",paintString=").append(isStringPainted());
+ sb.append(",progressString=");
+ if (progressString != null)
+ sb.append(progressString);
+ sb.append(",indeterminateString=").append(isIndeterminate());
+ return superParamStr + sb.toString();
}
/**
diff --git a/javax/swing/JRadioButtonMenuItem.java b/javax/swing/JRadioButtonMenuItem.java
index 61a8dbab3..0d7c1d105 100644
--- a/javax/swing/JRadioButtonMenuItem.java
+++ b/javax/swing/JRadioButtonMenuItem.java
@@ -1,5 +1,5 @@
/* JRadioButtonMenuItem.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -168,16 +168,27 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
}
/**
- * A string that describes this JRadioButtonMenuItem. Normally only used
- * for debugging.
+ * Returns a string describing the attributes for the
+ * <code>JRadioButtonMenuItem</code> component, for use in debugging. The
+ * return value is guaranteed to be non-<code>null</code>, but the format of
+ * the string may vary between implementations.
*
- * @return A string describing this JRadioButtonMenuItem
+ * @return A string describing the attributes of the
+ * <code>JRadioButtonMenuItem</code>.
*/
protected String paramString()
{
- return "JRadioButtonMenuItem";
+ // calling super seems to be sufficient here...
+ return super.paramString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JRadioButtonMenuItem</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJRadioButtonMenuItem}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -186,18 +197,30 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
return accessibleContext;
}
+ /**
+ * Provides the accessibility features for the
+ * <code>JRadioButtonMenuItem</code> component.
+ *
+ * @see JRadioButtonMenuItem#getAccessibleContext()
+ */
protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem
{
private static final long serialVersionUID = 4381471510145292179L;
/**
- * Creates a new AccessibleJRadioButtonMenuItem object.
+ * Creates a new <code>AccessibleJRadioButtonMenuItem</code> instance.
*/
protected AccessibleJRadioButtonMenuItem()
{
// Nothing to do here.
}
+ /**
+ * Returns the accessible role for the <code>JRadioButtonMenuItem</code>
+ * component.
+ *
+ * @return {@link AccessibleRole#RADIO_BUTTON}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.RADIO_BUTTON;
diff --git a/javax/swing/JScrollPane.java b/javax/swing/JScrollPane.java
index b1e16a681..09e37378b 100644
--- a/javax/swing/JScrollPane.java
+++ b/javax/swing/JScrollPane.java
@@ -51,7 +51,6 @@ import javax.accessibility.AccessibleContext;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.plaf.ScrollBarUI;
import javax.swing.plaf.ScrollPaneUI;
import javax.swing.plaf.UIResource;
diff --git a/javax/swing/JSeparator.java b/javax/swing/JSeparator.java
index 602af6a38..c87783b73 100644
--- a/javax/swing/JSeparator.java
+++ b/javax/swing/JSeparator.java
@@ -37,12 +37,13 @@ exception statement from your version. */
package javax.swing;
+import java.beans.PropertyChangeEvent;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.plaf.SeparatorUI;
-
/**
* The JSeparator. It is mostly used to divide/space out
* components.
@@ -51,14 +52,15 @@ public class JSeparator extends JComponent implements SwingConstants,
Accessible
{
/**
- * AccessibleJSeparator
+ * Provides the accessibility features for the <code>JSeparator</code>
+ * component.
*/
protected class AccessibleJSeparator extends AccessibleJComponent
{
private static final long serialVersionUID = 916332890553201095L;
/**
- * Constructor AccessibleJSeparator
+ * Creates a new <code>AccessibleJSeparator</code> instance.
*/
protected AccessibleJSeparator()
{
@@ -66,9 +68,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JSeparator</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#SEPARATOR}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -82,7 +84,7 @@ public class JSeparator extends JComponent implements SwingConstants,
private transient int orientation = HORIZONTAL;
/**
- * Creates a new horizontal JSeparator object.
+ * Creates a new horizontal <code>JSeparator</code> object.
*/
public JSeparator()
{
@@ -90,9 +92,13 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * Creates a new JSeparator object with the given orientation.
+ * Creates a new <code>JSeparator</code> object with the given orientation.
*
- * @param orientation The orientation of the JSeparator.
+ * @param orientation the orientation (either {@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if <code>orientation</code> is not
+ * one of the specified values.
*/
public JSeparator(int orientation)
{
@@ -104,10 +110,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the UI delegate being
- * used with the JSeparator.
+ * Returns the UI delegate being used with the <code>JSeparator</code>.
*
- * @return SeparatorUI The JSeparator's UI delegate.
+ * @return The JSeparator's UI delegate.
*/
public SeparatorUI getUI()
{
@@ -115,10 +120,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method sets the UI delegate to use
- * with the JSeparator.
+ * Sets the separator's UI delegate.
*
- * @param ui The UI delegate to use.
+ * @param ui the UI delegate.
*/
public void setUI(SeparatorUI ui)
{
@@ -126,8 +130,8 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method resets the UI delegate to the
- * default for the current look and feel.
+ * Sets this separator's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
*/
public void updateUI()
{
@@ -135,11 +139,11 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the identifier string
- * that is used to determine the UI delegate
- * from the current look and feel.
+ * Returns the suffix (<code>"SeparatorUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JSeparator</code>.
*
- * @return String The identifier string for the UI.
+ * @return <code>"SeparatorUI"</code>.
*/
public String getUIClassID()
{
@@ -147,9 +151,11 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the JSeparator's orientation.
+ * Returns the orientation of the <code>JSeparator</code>.
*
- * @return int The JSeparator's orientation.
+ * @return The orientation (one of {@link #HORIZONTAL} and {@link #VERTICAL}).
+ *
+ * @see #setOrientation(int)
*/
public int getOrientation()
{
@@ -157,33 +163,50 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method changes the JSeparator's orientation.
+ * Sets the orientation for the <code>JSeparator</code> and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * <code>orientation</code>) to all registered listeners.
*
- * @param orientation The JSeparator's orientation.
+ * @param orientation the orientation (either {@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if <code>orientation</code> is not
+ * one of the specified values.
+ *
+ * @see #getOrientation()
*/
public void setOrientation(int orientation)
{
if (orientation != HORIZONTAL && orientation != VERTICAL)
throw new IllegalArgumentException(orientation
+ " is not a valid orientation.");
+ int old = this.orientation;
this.orientation = orientation;
+ firePropertyChange("orientation", old, orientation);
}
/**
- * This method returns a string desribing the JSeparator.
- * Normally only used in debugging.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSeparator</code>.
*
- * @return String A string describing the JSeparator.
+ * @return A string describing the attributes of this <code>JSeparator</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSeparator";
+ String superParamStr = super.paramString();
+ if (orientation == HORIZONTAL)
+ return superParamStr + ",orientation=HORIZONTAL";
+ else
+ return superParamStr + ",orientation=VERTICAL";
}
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JSeparator</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of
+ * {@link AccessibleJSeparator}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JSlider.java b/javax/swing/JSlider.java
index f298cbebf..ed94c4ecc 100644
--- a/javax/swing/JSlider.java
+++ b/javax/swing/JSlider.java
@@ -1068,15 +1068,35 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
}
/**
- * Returns a string describing the attributes of this slider, for debugging
- * purposes. According to the specification, this method is implementation
- * specific, we just return "JSlider" at present.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSlider</code>.
*
- * @return Returns a string describing the attributes of this slider.
+ * @return A string describing the attributes of this <code>JSlider</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSlider";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isInverted=").append(getInverted());
+ sb.append(",majorTickSpacing=").append(getMajorTickSpacing());
+ sb.append(",minorTickSpacing=").append(getMinorTickSpacing());
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL)
+ sb.append("HORIZONTAL");
+ else
+ sb.append("VERTICAL");
+ sb.append(",paintLabels=").append(getPaintLabels());
+ sb.append(",paintTicks=").append(getPaintTicks());
+ sb.append(",paintTrack=").append(getPaintTrack());
+ sb.append(",snapToTicks=").append(getSnapToTicks());
+
+ // the following is output by the reference implementation. We don't
+ // strictly need to replicate this. Perhaps it has some meaning, but
+ // I couldn't determine it yet...
+ sb.append(",snapToValue=true");
+
+ return superParamStr + sb.toString();
}
/**
diff --git a/javax/swing/JSpinner.java b/javax/swing/JSpinner.java
index 882d216e1..70045ed53 100644
--- a/javax/swing/JSpinner.java
+++ b/javax/swing/JSpinner.java
@@ -106,6 +106,10 @@ public class JSpinner extends JComponent
add(ftf);
ftf.setValue(spinner.getValue());
ftf.addPropertyChangeListener(this);
+ if(getComponentOrientation().isLeftToRight())
+ ftf.setHorizontalAlignment(JTextField.RIGHT);
+ else
+ ftf.setHorizontalAlignment(JTextField.LEFT);
spinner.addChangeListener(this);
}
diff --git a/javax/swing/JSplitPane.java b/javax/swing/JSplitPane.java
index cb2640570..4e18b7cda 100644
--- a/javax/swing/JSplitPane.java
+++ b/javax/swing/JSplitPane.java
@@ -1,5 +1,5 @@
/* JSplitPane.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,10 +40,12 @@ package javax.swing;
import java.awt.Component;
import java.awt.Graphics;
+import java.beans.PropertyChangeEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
import javax.swing.plaf.SplitPaneUI;
@@ -56,18 +58,18 @@ import javax.swing.plaf.SplitPaneUI;
*/
public class JSplitPane extends JComponent implements Accessible
{
+
/**
- * DOCUMENT ME!
+ * Provides the accessibility features for the <code>JSplitPane</code>
+ * component.
*/
- // FIXME: This inner class is a complete stub and must be implemented
- // properly.
protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
implements AccessibleValue
{
private static final long serialVersionUID = -1788116871416305366L;
/**
- * Creates a new AccessibleJSplitPane object.
+ * Creates a new <code>AccessibleJSplitPane</code> instance.
*/
protected AccessibleJSplitPane()
{
@@ -75,75 +77,101 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns a set containing the current state of the {@link JSplitPane}
+ * component.
*
- * @return DOCUMENT ME!
+ * @return The accessible state set.
*/
public AccessibleStateSet getAccessibleStateSet()
{
- return null;
+ AccessibleStateSet result = super.getAccessibleStateSet();
+ if (getOrientation() == HORIZONTAL_SPLIT)
+ {
+ result.add(AccessibleState.HORIZONTAL);
+ }
+ else if (getOrientation() == VERTICAL_SPLIT)
+ {
+ result.add(AccessibleState.VERTICAL);
+ }
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns the accessible role for the <code>JSplitPane</code> component.
*
- * @return DOCUMENT ME!
+ * @return {@link AccessibleRole#SPLIT_PANE}.
*/
public AccessibleRole getAccessibleRole()
{
- return null;
+ return AccessibleRole.SPLIT_PANE;
}
/**
- * DOCUMENT ME!
+ * Returns an object that provides access to the current, minimum and
+ * maximum values for the {@link JSlider}. Since this class implements
+ * {@link AccessibleValue}, it returns itself.
*
- * @return DOCUMENT ME!
+ * @return The accessible value.
*/
public AccessibleValue getAccessibleValue()
{
- return null;
+ return this;
}
/**
- * DOCUMENT ME!
+ * Returns the current divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The current divider location.
*/
public Number getCurrentAccessibleValue()
{
- return null;
+ return new Integer(getDividerLocation());
}
/**
- * DOCUMENT ME!
+ * Sets the divider location for the {@link JSplitPane} component and sends
+ * a {@link PropertyChangeEvent} (with the property name
+ * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+ * listeners. If the supplied value is <code>null</code>, this method
+ * does nothing and returns <code>false</code>.
*
- * @param value0 DOCUMENT ME!
+ * @param value the new slider value (<code>null</code> permitted).
*
- * @return DOCUMENT ME!
+ * @return <code>true</code> if the slider value is updated, and
+ * <code>false</code> otherwise.
*/
- public boolean setCurrentAccessibleValue(Number value0)
+ public boolean setCurrentAccessibleValue(Number value)
{
- return false;
+ if (value == null)
+ return false;
+ Number oldValue = getCurrentAccessibleValue();
+ setDividerLocation(value.intValue());
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue,
+ new Integer(value.intValue()));
+ return true;
}
/**
- * DOCUMENT ME!
+ * Returns the minimum divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The minimum divider location.
*/
public Number getMinimumAccessibleValue()
{
- return null;
+ return new Integer(getMinimumDividerLocation());
}
/**
- * DOCUMENT ME!
+ * Returns the maximum divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The maximum divider location.
*/
public Number getMaximumAccessibleValue()
{
- return null;
+ return new Integer(getMaximumDividerLocation());
}
}
@@ -371,9 +399,11 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the object that provides accessibility features for this
+ * <code>JSplitPane</code> component.
*
- * @return DOCUMENT ME!
+ * @return The accessible context (an instance of
+ * {@link AccessibleJSplitPane}).
*/
public AccessibleContext getAccessibleContext()
{
@@ -559,14 +589,27 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * This method returns a String that describes this JSplitPane. The string
- * is primarily used for debugging purposes.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSplitPane</code>.
*
- * @return A String used for debugging purposes.
+ * @return A string describing the attributes of this <code>JSplitPane</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSplitPane";
+ // FIXME: the next line can be restored once PR27208 is fixed
+ String superParamStr = ""; //super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",continuousLayout=").append(isContinuousLayout());
+ sb.append(",dividerSize=").append(getDividerSize());
+ sb.append(",lastDividerLocation=").append(getLastDividerLocation());
+ sb.append(",oneTouchExpandable=").append(isOneTouchExpandable());
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL_SPLIT)
+ sb.append("HORIZONTAL_SPLIT");
+ else
+ sb.append("VERTICAL_SPLIT");
+ return superParamStr + sb.toString();
}
/**
@@ -753,11 +796,15 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * This method sets the orientation of the JSplitPane.
+ * Sets the orientation for the <code>JSplitPane</code> and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #ORIENTATION_PROPERTY}) to all registered listeners.
*
- * @param orientation The orientation of the JSplitPane.
+ * @param orientation the orientation (either {@link #HORIZONTAL_SPLIT}
+ * or {@link #VERTICAL_SPLIT}).
*
- * @throws IllegalArgumentException DOCUMENT ME!
+ * @throws IllegalArgumentException if <code>orientation</code> is not one of
+ * the listed values.
*/
public void setOrientation(int orientation)
{
@@ -784,7 +831,14 @@ public class JSplitPane extends JComponent implements Accessible
*/
public void setResizeWeight(double value)
{
- resizeWeight = value;
+ if (value < 0.0 || value > 1.0)
+ throw new IllegalArgumentException("Value outside permitted range.");
+ if (this.resizeWeight != value)
+ {
+ double old = resizeWeight;
+ resizeWeight = value;
+ firePropertyChange(RESIZE_WEIGHT_PROPERTY, old, value);
+ }
}
/**
diff --git a/javax/swing/JTabbedPane.java b/javax/swing/JTabbedPane.java
index 0c2180969..34ab8eeaa 100644
--- a/javax/swing/JTabbedPane.java
+++ b/javax/swing/JTabbedPane.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
@@ -102,6 +104,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param e the change event describing the change
*/
public void stateChanged(ChangeEvent e)
+ throws NotImplementedException
{
// Implement this properly.
}
@@ -113,6 +116,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the accessible role of the <code>JTabbedPane</code>
*/
public AccessibleRole getAccessibleRole()
+ throws NotImplementedException
{
return null;
}
@@ -125,6 +129,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* <code>JTabbedPane</code>
*/
public int getAccessibleChildrenCount()
+ throws NotImplementedException
{
return 0;
}
@@ -153,6 +158,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the current selection state of the <code>JTabbedPane</code>
*/
public AccessibleSelection getAccessibleSelection()
+ throws NotImplementedException
{
return null;
}
@@ -169,6 +175,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* this location
*/
public Accessible getAccessibleAt(Point p)
+ throws NotImplementedException
{
return null;
}
@@ -183,6 +190,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* <code>JTabbedPane</code>
*/
public int getAccessibleSelectionCount()
+ throws NotImplementedException
{
return 0;
}
@@ -195,6 +203,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return DOCUMENT ME!
*/
public Accessible getAccessibleSelection(int i)
+ throws NotImplementedException
{
return null;
}
@@ -207,6 +216,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return DOCUMENT ME!
*/
public boolean isAccessibleChildSelected(int i)
+ throws NotImplementedException
{
return false;
}
@@ -217,6 +227,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param i DOCUMENT ME!
*/
public void addAccessibleSelection(int i)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -227,6 +238,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param i DOCUMENT ME!
*/
public void removeAccessibleSelection(int i)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -235,6 +247,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* DOCUMENT ME!
*/
public void clearAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -243,6 +256,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* DOCUMENT ME!
*/
public void selectAllAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -595,12 +609,14 @@ public class JTabbedPane extends JComponent implements Serializable,
}
public AccessibleStateSet getAccessibleStateSet()
+ throws NotImplementedException
{
// FIXME: Implement this properly.
return null;
}
public int getAccessibleIndexInParent()
+ throws NotImplementedException
{
// FIXME: Implement this properly.
return 0;
diff --git a/javax/swing/JTable.java b/javax/swing/JTable.java
index 89272451e..3463ac26f 100644
--- a/javax/swing/JTable.java
+++ b/javax/swing/JTable.java
@@ -2053,9 +2053,6 @@ public class JTable
int column,
boolean includeSpacing)
{
- // moveToCellBeingEdited expects the cached value and clones it.
- // If the caching would be removed later, uplate moveToCellBeingEdited
- // as well.
int height = getRowHeight(row);
int width = columnModel.getColumn(column).getWidth();
int x_gap = columnModel.getColumnMargin();
@@ -2069,12 +2066,14 @@ public class JTable
for (int i = 0; i < column; ++i)
x += columnModel.getColumn(i).getWidth();
+
+ Rectangle rect = new Rectangle();
if (includeSpacing)
- rectCache.setBounds(x, y, width, height +y_gap);
+ rect.setBounds(x, y, width, height +y_gap);
else
- rectCache.setBounds(x, y, width - x_gap, height);
- return rectCache;
+ rect.setBounds(x, y, width - x_gap, height);
+ return rect;
}
public void clearSelection()
@@ -2434,7 +2433,7 @@ public class JTable
/**
* Get the value of the <code>columnCount</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the columnCount property
*/
@@ -2445,7 +2444,7 @@ public class JTable
/**
* Get the value of the <code>rowCount</code> property by
- * delegation to the @{link #dataModel} field.
+ * delegation to the {@link #dataModel} field.
*
* @return The current value of the rowCount property
*/
@@ -2466,7 +2465,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumn</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumn property
*/
@@ -2535,7 +2534,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumnCount</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumnCount property
*/
@@ -2546,7 +2545,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumns</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumns property
*/
@@ -2567,7 +2566,7 @@ public class JTable
/**
* Get the value of the <code>selectedRowCount</code> property by
- * delegation to the @{link #selectionModel} field.
+ * delegation to the {@link #selectionModel} field.
*
* @return The current value of the selectedRowCount property
*/
@@ -2578,7 +2577,7 @@ public class JTable
/**
* Get the value of the <code>selectedRows</code> property by
- * delegation to the @{link #selectionModel} field.
+ * delegation to the {@link #selectionModel} field.
*
* @return The current value of the selectedRows property
*/
@@ -3722,8 +3721,7 @@ public class JTable
private void moveToCellBeingEdited(Component component)
{
Rectangle r = getCellRect(editingRow, editingColumn, true);
- // Clone rectangle as getCellRect returns the cached value.
- component.setBounds(new Rectangle(r));
+ component.setBounds(r);
}
/**
diff --git a/javax/swing/JToolBar.java b/javax/swing/JToolBar.java
index bc97f9ecd..b576b4f2a 100644
--- a/javax/swing/JToolBar.java
+++ b/javax/swing/JToolBar.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
@@ -67,17 +65,15 @@ import javax.swing.plaf.ToolBarUI;
public class JToolBar extends JComponent implements SwingConstants, Accessible
{
/**
- * AccessibleJToolBar
+ * Provides the accessibility features for the <code>JToolBar</code>
+ * component.
*/
- // FIXME: This inner class is a complete stub and must be implemented
- // properly.
protected class AccessibleJToolBar extends AccessibleJComponent
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = -5516888265903814215L;
/**
- * Constructor AccessibleJToolBar
+ * Creates a new <code>AccessibleJToolBar</code> instance.
*/
protected AccessibleJToolBar()
{
@@ -85,20 +81,23 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
}
/**
- * getAccessibleStateSet
+ * Returns a set containing the current state of the {@link JToolBar}
+ * component. The current implementation simply calls the superclass.
*
- * @return AccessibleStateSet
+ * @return The accessible state set.
*/
public AccessibleStateSet getAccessibleStateSet()
- throws NotImplementedException
{
- return null; // TODO
+ // running tests against the reference implementation, I was unable
+ // to find any state information that is set specifically by the
+ // tool bar...
+ return super.getAccessibleStateSet();
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JToolBar</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#TOOL_BAR}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -768,9 +767,10 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
} // paramString()
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JToolBar</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of {@link AccessibleJToolBar}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JToolTip.java b/javax/swing/JToolTip.java
index 1a4a0f205..836c122c6 100644
--- a/javax/swing/JToolTip.java
+++ b/javax/swing/JToolTip.java
@@ -127,7 +127,7 @@ public class JToolTip extends JComponent implements Accessible
* Returns the object that provides accessibility features for this
* <code>JToolTip</code> component.
*
- * @return The accessible context (an instance of {@link AccessibleJToolTip}.
+ * @return The accessible context (an instance of {@link AccessibleJToolTip}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JTree.java b/javax/swing/JTree.java
index f4b37e106..eb54523e2 100644
--- a/javax/swing/JTree.java
+++ b/javax/swing/JTree.java
@@ -1276,10 +1276,16 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public void valueChanged(TreeSelectionEvent ev)
{
- TreeSelectionEvent rewritten =
+ TreeSelectionEvent rewritten =
(TreeSelectionEvent) ev.cloneWithSource(JTree.this);
fireValueChanged(rewritten);
- JTree.this.repaint();
+
+ // Only repaint the changed nodes.
+ TreePath[] changed = ev.getPaths();
+ for (int i = 0; i < changed.length; i++)
+ {
+ repaint(getPathBounds(changed[i]));
+ }
}
}
@@ -1396,8 +1402,6 @@ public class JTree extends JComponent implements Scrollable, Accessible
private TreePath anchorSelectionPath;
- private TreePath leadSelectionPath;
-
/**
* This contains the state of all nodes in the tree. Al/ entries map the
* TreePath of a note to to its state. Valid states are EXPANDED and
@@ -1504,8 +1508,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public JTree(TreeModel model)
{
- updateUI();
setRootVisible(true);
+ // The setModel also calls the updateUI
setModel(model);
setSelectionModel(new EmptySelectionModel());
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
@@ -1562,7 +1566,15 @@ public class JTree extends JComponent implements Scrollable, Accessible
TreeUI ui = getUI();
return ui != null ? ui.getPathForRow(this, row) : null;
}
-
+
+ /**
+ * Get the pathes that are displayes between the two given rows.
+ *
+ * @param index0 the starting row, inclusive
+ * @param index1 the ending row, inclusive
+ *
+ * @return the array of the tree pathes
+ */
protected TreePath[] getPathBetweenRows(int index0, int index1)
{
TreeUI ui = getUI();
@@ -1941,9 +1953,19 @@ public class JTree extends JComponent implements Scrollable, Accessible
if (rootVisible == flag)
return;
+ // If the root is currently selected, unselect it
+ if (rootVisible && !flag)
+ {
+ TreeSelectionModel model = getSelectionModel();
+ // The root is always shown in the first row
+ TreePath rootPath = getPathForRow(0);
+ model.removeSelectionPath(rootPath);
+ }
+
boolean oldValue = rootVisible;
rootVisible = flag;
firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
+
}
public boolean getShowsRootHandles()
@@ -2110,27 +2132,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
{
if (path == null)
return;
-
- Object[] oPath = path.getPath();
- TreePath temp = new TreePath(oPath[0]);
- boolean stop = false;
- int i = 1;
- while (!stop)
- {
- while (isVisible(temp))
- if (i < oPath.length)
- temp = temp.pathByAddingChild(oPath[i++]);
- else
- {
- stop = true;
- break;
- }
- makeVisible(temp);
- }
Rectangle rect = getPathBounds(path);
scrollRectToVisible(rect);
- revalidate();
- repaint();
}
public void scrollRowToVisible(int row)
@@ -2225,7 +2228,15 @@ public class JTree extends JComponent implements Scrollable, Accessible
addSelectionPaths(paths);
}
-
+
+ /**
+ * Select all rows between the two given indexes, inclusive. The method
+ * will not select the inner leaves and braches of the currently collapsed
+ * nodes in this interval.
+ *
+ * @param index0 the starting row, inclusive
+ * @param index1 the ending row, inclusive
+ */
public void addSelectionInterval(int index0, int index1)
{
TreePath[] paths = getPathBetweenRows(index0, index1);
@@ -2281,7 +2292,10 @@ public class JTree extends JComponent implements Scrollable, Accessible
public TreePath getLeadSelectionPath()
{
- return leadSelectionPath;
+ if (selectionModel == null)
+ return null;
+ else
+ return selectionModel.getLeadSelectionPath();
}
/**
@@ -2289,12 +2303,24 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public void setLeadSelectionPath(TreePath path)
{
- if (leadSelectionPath == path)
- return;
-
- TreePath oldValue = leadSelectionPath;
- leadSelectionPath = path;
- firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
+ if (selectionModel != null)
+ {
+ TreePath oldValue = selectionModel.getLeadSelectionPath();
+ if (path.equals(oldValue))
+ return;
+
+ // Repaint the previous and current rows with the lead selection path.
+ if (path != null)
+ {
+ repaint(getPathBounds(path));
+ selectionModel.addSelectionPath(path);
+ }
+
+ if (oldValue!=null)
+ repaint(getPathBounds(oldValue));
+
+ firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
+ }
}
/**
@@ -2430,7 +2456,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
public void expandPath(TreePath path)
{
// Don't expand if path is null
- if (path == null)
+ // or is already expanded.
+ if (path == null || isExpanded(path))
return;
try
@@ -2967,10 +2994,20 @@ public class JTree extends JComponent implements Scrollable, Accessible
}
/**
- * Sent when the tree has changed enough that we need to resize the bounds,
- * but not enough that we need to remove the expanded node set (e.g nodes
- * were expanded or collapsed, or nodes were inserted into the tree). You
- * should never have to invoke this, the UI will invoke this as it needs to.
+ * <p>
+ * Sent when the tree has changed enough that we need to resize the bounds,
+ * but not enough that we need to remove the expanded node set (e.g nodes were
+ * expanded or collapsed, or nodes were inserted into the tree). You should
+ * never have to invoke this, the UI will invoke this as it needs to.
+ * </p>
+ * <p>
+ * If the tree uses {@link DefaultTreeModel}, you must call
+ * {@link DefaultTreeModel#reload(TreeNode)} or
+ * {@link DefaultTreeModel#reload()} after adding or removing nodes. Following
+ * the official Java 1.5 API standard, just calling treeDidChange, repaint()
+ * or revalidate() does <i>not</i> update the tree appearance properly.
+ *
+ * @see DefaultTreeModel#reload()
*/
public void treeDidChange()
{
diff --git a/javax/swing/ProgressMonitor.java b/javax/swing/ProgressMonitor.java
index dc0c6434c..73e36b9ca 100644
--- a/javax/swing/ProgressMonitor.java
+++ b/javax/swing/ProgressMonitor.java
@@ -398,7 +398,11 @@ public class ProgressMonitor
if (( now - timestamp ) > millisToDecideToPopup )
{
first = false;
- long expected = ( now - timestamp ) * ( max - min ) / ( progress - min );
+
+
+ long expected = ( progress - min == 0 ) ?
+ ( now - timestamp ) * ( max - min ) :
+ ( now - timestamp ) * ( max - min ) / ( progress - min );
if ( expected > millisToPopup )
{
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index a5e0379f6..9e246ee1e 100644
--- a/javax/swing/RepaintManager.java
+++ b/javax/swing/RepaintManager.java
@@ -160,9 +160,9 @@ public class RepaintManager
if (o1 instanceof JComponent && o2 instanceof JComponent)
{
JComponent c1 = (JComponent) o1;
- Rectangle d1 = (Rectangle) dirtyComponents.get(c1);
+ Rectangle d1 = (Rectangle) dirtyComponentsWork.get(c1);
JComponent c2 = (JComponent) o2;
- Rectangle d2 = (Rectangle) dirtyComponents.get(c2);
+ Rectangle d2 = (Rectangle) dirtyComponentsWork.get(c2);
return d2.width * d2.height - d1.width * d1.height;
}
throw new ClassCastException("This comparator can only be used with "
@@ -188,6 +188,12 @@ public class RepaintManager
HashMap dirtyComponents;
/**
+ * The dirtyComponents which is used in paintDiryRegions to avoid unnecessary
+ * locking.
+ */
+ HashMap dirtyComponentsWork;
+
+ /**
* The comparator used for ordered inserting into the repaintOrder list.
*/
private transient Comparator comparator;
@@ -262,6 +268,7 @@ public class RepaintManager
public RepaintManager()
{
dirtyComponents = new HashMap();
+ dirtyComponentsWork = new HashMap();
invalidComponents = new ArrayList();
repaintWorker = new RepaintWorker();
doubleBufferMaximumSize = new Dimension(2000,2000);
@@ -554,31 +561,36 @@ public class RepaintManager
if (dirtyComponents.size() == 0)
return;
+ // Swap dirtyRegions with dirtyRegionsWork to avoid locking.
synchronized (dirtyComponents)
{
- // We sort the components by their size here. This way we have a good
- // chance that painting the bigger components also paints the smaller
- // components and we don't need to paint them twice.
- ArrayList repaintOrder = new ArrayList(dirtyComponents.size());
- repaintOrder.addAll(dirtyComponents.keySet());
- if (comparator == null)
- comparator = new ComponentComparator();
- Collections.sort(repaintOrder, comparator);
- repaintUnderway = true;
- for (Iterator i = repaintOrder.iterator(); i.hasNext();)
- {
- JComponent comp = (JComponent) i.next();
- // If a component is marked completely clean in the meantime, then skip
- // it.
- Rectangle damaged = (Rectangle) dirtyComponents.get(comp);
- if (damaged == null || damaged.isEmpty())
- continue;
- comp.paintImmediately(damaged);
- dirtyComponents.remove(comp);
- }
- repaintUnderway = false;
- commitRemainingBuffers();
+ HashMap swap = dirtyComponents;
+ dirtyComponents = dirtyComponentsWork;
+ dirtyComponentsWork = swap;
}
+
+ ArrayList repaintOrder = new ArrayList(dirtyComponentsWork.size());;
+ // We sort the components by their size here. This way we have a good
+ // chance that painting the bigger components also paints the smaller
+ // components and we don't need to paint them twice.
+ repaintOrder.addAll(dirtyComponentsWork.keySet());
+
+ if (comparator == null)
+ comparator = new ComponentComparator();
+ Collections.sort(repaintOrder, comparator);
+ repaintUnderway = true;
+ for (Iterator i = repaintOrder.iterator(); i.hasNext();)
+ {
+ JComponent comp = (JComponent) i.next();
+ // If a component is marked completely clean in the meantime, then skip
+ // it.
+ Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
+ if (damaged == null || damaged.isEmpty())
+ continue;
+ comp.paintImmediately(damaged);
+ }
+ repaintUnderway = false;
+ commitRemainingBuffers();
}
/**
diff --git a/javax/swing/ScrollPaneLayout.java b/javax/swing/ScrollPaneLayout.java
index 9f6829f4d..da8f03afb 100644
--- a/javax/swing/ScrollPaneLayout.java
+++ b/javax/swing/ScrollPaneLayout.java
@@ -328,7 +328,7 @@ public class ScrollPaneLayout
// parent is no JScrollPane, so do we.
JScrollPane sc = (JScrollPane) parent;
JViewport viewport = sc.getViewport();
- Dimension viewSize = viewport.getViewSize();
+ Dimension viewSize = viewport.getView().getPreferredSize();
int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
diff --git a/javax/swing/SpinnerDateModel.java b/javax/swing/SpinnerDateModel.java
index a92f5a49e..e5ff76f1a 100644
--- a/javax/swing/SpinnerDateModel.java
+++ b/javax/swing/SpinnerDateModel.java
@@ -59,13 +59,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
private Calendar date;
/**
- * The start or earliest permitted date (<code>null</code> for no
- * minimum).
+ * A constraint on the start or earliest permitted date (<code>null</code>
+ * for no minimum).
*/
private Comparable start;
/**
- * The end or latest permitted date (<code>null</code> for no
+ * A constraint on the end or latest permitted date (<code>null</code> for no
* maximum).
*/
private Comparable end;
@@ -77,7 +77,6 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* For compatability with Sun's JDK
- * FIXME: Which fields should be serialized?
*/
private static final long serialVersionUID = -4802518107105940612L;
@@ -92,14 +91,21 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Constructs a SpinnerDateModel which spins a given calendar field,
- * using a given date and start and end date limits.
- * @param value - the initial Date value
- * @param start - start limit, as a Date object, or <code>null</code>
- * for no lower limit.
- * @param end - end limit, or <code>null</code> for no upper limit.
- * @param calendarField - the <code>Calendar</code> field to spin,
- * (Calendar.ZONE_OFFSET and Calendar.DST_OFFSET are invalid)
+ * Constructs a <code>SpinnerDateModel</code> with the specified value, lower
+ * and upper bounds, and which spins the specified calendar field.
+ * <p>
+ * The <code>start</code> and <code>end</code> limits must have a
+ * <code>compareTo</code> method that supports instances of {@link Date}, but
+ * do not themselves need to be instances of {@link Date} (although typically
+ * they are).
+ *
+ * @param value the initial value/date (<code>null</code> not permitted).
+ * @param start a constraint that specifies the earliest permitted date
+ * value, or <code>null</code> for no lower limit.
+ * @param end a constraint that specifies the latest permitted date value,
+ * or <code>null</code> for no upper limit.
+ * @param calendarField the <code>Calendar</code> field to spin,
+ * (Calendar.ZONE_OFFSET and Calendar.DST_OFFSET are invalid)
*/
public SpinnerDateModel(Date value, Comparable start, Comparable end,
int calendarField)
@@ -129,9 +135,11 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the current date.
+ * Returns the current date/time.
+ *
+ * @return The current date/time (never <code>null</code>).
*
- * @return The current date.
+ * @see #getValue()
*/
public Date getDate()
{
@@ -139,9 +147,12 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the start date, or <code>null</code> if there is no minimum date.
+ * Returns the lower limit on the date/time value, or <code>null</code> if
+ * there is no minimum date/time.
*
- * @return The start date.
+ * @return The lower limit.
+ *
+ * @see #setStart(Comparable)
*/
public Comparable getStart()
{
@@ -149,9 +160,12 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the end date, or <code>null</code> if there is no maximum date.
+ * Returns the upper limit on the date/time value, or <code>null</code> if
+ * there is no maximum date/time.
+ *
+ * @return The upper limit.
*
- * @return The end date.
+ * @see #setEnd(Comparable)
*/
public Comparable getEnd()
{
@@ -160,9 +174,9 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the current date in the sequence (this method returns the same as
- * {@link #getDate()}.
+ * {@link #getDate()}).
*
- * @return The current date.
+ * @return The current date (never <code>null</code>).
*/
public Object getValue()
{
@@ -171,10 +185,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the next date in the sequence, or <code>null</code> if the
- * next date is after the end date. The current date is not changed.
+ * next date is past the upper limit (if one is specified). The current date
+ * is not changed.
*
* @return The next date, or <code>null</code> if the current value is
* the latest date represented by the model.
+ *
+ * @see #getEnd()
*/
public Object getNextValue()
{
@@ -190,11 +207,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the previous date in the sequence, or <code>null</code> if the
- * previous date is prior to the start date. The current date is not
- * changed.
+ * previous date is prior to the lower limit (if one is specified). The
+ * current date is not changed.
*
* @return The previous date, or <code>null</code> if the current value is
* the earliest date represented by the model.
+ *
+ * @see #getStart()
*/
public Object getPreviousValue()
{
@@ -233,14 +252,16 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Sets the start date and, if the new date is different to the old date,
- * sends a {@link ChangeEvent} to all registered listeners. A
- * <code>null</code> date is interpreted as "no start date". No check
- * is made to ensure that the new start date is on or before the current
- * date - the caller is responsible for ensuring that this relationship
- * holds.
+ * Sets the lower limit for the date/time value and, if the new limit is
+ * different to the old limit, sends a {@link ChangeEvent} to all registered
+ * listeners. A <code>null</code> value is interpreted as "no lower limit".
+ * No check is made to ensure that the current date/time is on or after the
+ * new lower limit - the caller is responsible for ensuring that this
+ * relationship holds. In addition, the caller should ensure that
+ * <code>start</code> is {@link Serializable}.
*
- * @param start the new start date (<code>null</code> permitted).
+ * @param start the new lower limit for the date/time value
+ * (<code>null</code> permitted).
*/
public void setStart(Comparable start)
{
@@ -252,13 +273,16 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Sets the end date and, if the new date is different to the old date,
- * sends a {@link ChangeEvent} to all registered listeners. A
- * <code>null</code> date is interpreted as "no end date". No check
- * is made to ensure that the new end date is on or after the current date -
- * the caller is responsible for ensuring that this relationship holds.
+ * Sets the upper limit for the date/time value and, if the new limit is
+ * different to the old limit, sends a {@link ChangeEvent} to all registered
+ * listeners. A <code>null</code> value is interpreted as "no upper limit".
+ * No check is made to ensure that the current date/time is on or before the
+ * new upper limit - the caller is responsible for ensuring that this
+ * relationship holds. In addition, the caller should ensure that
+ * <code>end</code> is {@link Serializable}.
*
- * @param end the new end date (<code>null</code> permitted).
+ * @param end the new upper limit for the date/time value (<code>null</code>
+ * permitted).
*/
public void setEnd(Comparable end)
{
diff --git a/javax/swing/SpinnerNumberModel.java b/javax/swing/SpinnerNumberModel.java
index 389c536e4..1abbbe377 100644
--- a/javax/swing/SpinnerNumberModel.java
+++ b/javax/swing/SpinnerNumberModel.java
@@ -110,12 +110,14 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
}
/**
- * Creates a <code>SpinnerNumberModel</code> with the given attributes.
+ * Creates a <code>SpinnerNumberModel</code> with the given attributes. The
+ * caller should ensure that both <code>minimum</code> and
+ * <code>maximum</code> are serializable.
*
- * @param value the initial value.
+ * @param value the initial value (<code>null</code> not permitted).
* @param minimum the minimum value (<code>null</code> permitted).
* @param maximum the maximum value (<code>null</code> permitted).
- * @param stepSize the step size.
+ * @param stepSize the step size (<code>null</code> not permitted).
*
* @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
* does not hold
@@ -171,9 +173,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
}
/**
- * Returns the current value.
+ * Returns the current value, which for this class is always an instance of
+ * {@link Number}.
*
* @return The current value.
+ *
+ * @see #getNumber()
*/
public Object getValue()
{
@@ -258,6 +263,8 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* Returns the minimum value, or <code>null</code> if there is no minimum.
*
* @return The minimum value.
+ *
+ * @see #setMinimum(Comparable)
*/
public Comparable getMinimum()
{
@@ -270,9 +277,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* <code>null</code> value is interpreted as "no minimum value". No check
* is made to ensure that the new minimum is less than or equal to the
* current value, the caller is responsible for ensuring that this
- * relationship holds.
+ * relationship holds. In addition, the caller should ensure that
+ * <code>newMinimum</code> is {@link Serializable}.
*
* @param newMinimum the new minimum value (<code>null</code> permitted).
+ *
+ * @see #getMinimum()
*/
public void setMinimum(Comparable newMinimum)
{
@@ -287,6 +297,9 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* Returns the maximum value, or <code>null</code> if there is no maximum.
*
* @return The maximum value.
+ *
+ * @see #getMinimum()
+ * @see #setMaximum(Comparable)
*/
public Comparable getMaximum()
{
@@ -299,9 +312,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* <code>null</code> value is interpreted as "no maximum value". No check
* is made to ensure that the new maximum is greater than or equal to the
* current value, the caller is responsible for ensuring that this
- * relationship holds.
+ * relationship holds. In addition, the caller should ensure that
+ * <code>newMaximum</code> is {@link Serializable}.
*
* @param newMaximum the new maximum (<code>null</code> permitted).
+ *
+ * @see #getMaximum()
*/
public void setMaximum(Comparable newMaximum)
{
@@ -315,7 +331,7 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
/**
* Returns the step size.
*
- * @return The step size.
+ * @return The step size (never <code>null</code>).
*/
public Number getStepSize()
{
diff --git a/javax/swing/UIManager.java b/javax/swing/UIManager.java
index 3b9166261..e1ee28b3f 100644
--- a/javax/swing/UIManager.java
+++ b/javax/swing/UIManager.java
@@ -1,5 +1,5 @@
/* UIManager.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
diff --git a/javax/swing/ViewportLayout.java b/javax/swing/ViewportLayout.java
index 67b69eb28..b61834e9e 100644
--- a/javax/swing/ViewportLayout.java
+++ b/javax/swing/ViewportLayout.java
@@ -158,7 +158,7 @@ public class ViewportLayout implements LayoutManager, Serializable
// the viewport require inputs in view space.
Rectangle portBounds = port.getViewRect();
- Dimension viewPref = view.getPreferredSize();
+ Dimension viewPref = new Dimension(view.getPreferredSize());
Point portLowerRight = new Point(portBounds.x + portBounds.width,
portBounds.y + portBounds.height);
@@ -182,14 +182,10 @@ public class ViewportLayout implements LayoutManager, Serializable
}
}
- // The scroll pane manages the view size itself.
- if (! (port.getParent() instanceof JScrollPane) )
- {
- if (viewPref.width < portBounds.width)
- viewPref.width = portBounds.width;
- if (viewPref.height < portBounds.height)
- viewPref.height = portBounds.height;
- }
+ if (viewPref.width < portBounds.width)
+ viewPref.width = portBounds.width;
+ if (viewPref.height < portBounds.height)
+ viewPref.height = portBounds.height;
// If the view is larger than the port, the port is top and right
// aligned.
diff --git a/javax/swing/border/AbstractBorder.java b/javax/swing/border/AbstractBorder.java
index 7cbbcdaa8..c995de1c2 100644
--- a/javax/swing/border/AbstractBorder.java
+++ b/javax/swing/border/AbstractBorder.java
@@ -1,5 +1,5 @@
/* AbstractBorder.java --
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -68,7 +68,7 @@ public abstract class AbstractBorder implements Border, Serializable
* Performs nothing, because the default implementation provided by
* this class is an invisible, zero-width border. Subclasses will
* likely want to override this method, but they are not required
- * for doing so.
+ * to do so.
*
* @param c the component whose border is to be painted.
* @param g the graphics for painting.
@@ -87,9 +87,11 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Measures the width of this border.
+ * Returns the insets required for drawing this border around the specified
+ * component.
*
- * @param c the component whose border is to be measured.
+ * @param c the component that the border applies to (ignored here,
+ * subclasses may use it).
*
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> fields indicate the
@@ -104,16 +106,23 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Determines the insets of this border. The implementation provided
- * by AbstractButton sets the <code>left</code>, <code>right</code>,
- * <code>top</code> and <code>bottom</code> fields of the passed
- * <code>insets</code> parameter to zero.
+ * Returns the insets required for drawing this border around the specified
+ * component. The default implementation provided here sets the
+ * <code>left</code>, <code>right</code>, <code>top</code> and
+ * <code>bottom</code> fields of the passed <code>insets</code> parameter to
+ * zero.
*
- * @param c the component whose border is to be measured
+ * @param c the component that the border applies to (ignored here,
+ * subclasses may use it).
+ * @param insets an instance that will be overwritten and returned as the
+ * result (<code>null</code> not permitted).
*
- * @return the same object that was passed for <code>insets</code>
+ * @return The border insets (the same object that was passed as the
+ * <code>insets</code> argument).
*
* @see #getBorderInsets(Component)
+ *
+ * @throws NullPointerException if <code>insets</code> is <code>null</code>.
*/
public Insets getBorderInsets(Component c, Insets insets)
{
@@ -126,7 +135,7 @@ public abstract class AbstractBorder implements Border, Serializable
* fills every pixel in its area when painting. Partially
* translucent borders must return <code>false</code>, or ugly
* artifacts can appear on screen. The default implementation
- * provided by AbstractBorder always returns <code>false</code>.
+ * provided here always returns <code>false</code>.
*
* @return <code>false</code>.
*/
@@ -136,9 +145,9 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Returns a rectangle that covers the specified area minus this
- * border. Components that wish to determine an area into which
- * they can safely draw without intersecting with a border might
+ * Returns a rectangle that covers the specified area minus the insets
+ * required to draw this border. Components that wish to determine an area
+ * into which they can safely draw without intersecting with a border might
* want to use this helper method.
*
* @param c the component in the center of this border.
@@ -146,24 +155,30 @@ public abstract class AbstractBorder implements Border, Serializable
* @param y the vertical position of the border.
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
+ *
+ * @return The interior rectangle.
*/
public Rectangle getInteriorRectangle(Component c, int x, int y, int width,
int height)
{
- return getInteriorRectangle (c, this, x, y, width, height);
+ return getInteriorRectangle(c, this, x, y, width, height);
}
/**
- * Returns a rectangle that covers the specified area minus a
- * border. Components that wish to determine an area into which
- * they can safely draw without intersecting with a border might
- * want to use this helper method.
+ * Returns a rectangle that covers the specified area minus the insets
+ * required to draw the specified border (if the border is <code>null</code>,
+ * zero insets are assumed). Components that wish to determine an area into
+ * which they can safely draw without intersecting with a border might want
+ * to use this helper method.
*
* @param c the component in the center of this border.
+ * @param b the border (<code>null</code> permitted).
* @param x the horizontal position of the border.
* @param y the vertical position of the border.
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
+ *
+ * @return The interior rectangle.
*/
public static Rectangle getInteriorRectangle(Component c, Border b, int x,
int y, int width, int height)
@@ -172,7 +187,7 @@ public abstract class AbstractBorder implements Border, Serializable
if (b != null)
{
- borderInsets = b.getBorderInsets (c);
+ borderInsets = b.getBorderInsets(c);
x += borderInsets.left;
y += borderInsets.top;
width -= borderInsets.left + borderInsets.right;
diff --git a/javax/swing/border/BevelBorder.java b/javax/swing/border/BevelBorder.java
index 45b758cae..403c35c04 100644
--- a/javax/swing/border/BevelBorder.java
+++ b/javax/swing/border/BevelBorder.java
@@ -305,6 +305,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see #getHighlightInnerColor(java.awt.Component)
* @see java.awt.Color#brighter()
*/
@@ -326,6 +328,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#brighter()
*/
@@ -347,6 +351,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#darker()
*/
@@ -367,6 +373,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see #getShadowInnerColor(java.awt.Component)
* @see java.awt.Color#darker()
*/
@@ -384,6 +392,8 @@ public class BevelBorder extends AbstractBorder
* highlighted edges when painting the border, or <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getHighlightOuterColor()
{
@@ -396,6 +406,8 @@ public class BevelBorder extends AbstractBorder
* highlighted edges when painting the border, or <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getHighlightInnerColor()
{
@@ -408,6 +420,8 @@ public class BevelBorder extends AbstractBorder
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getShadowInnerColor()
{
@@ -420,6 +434,8 @@ public class BevelBorder extends AbstractBorder
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getShadowOuterColor()
{
@@ -430,6 +446,8 @@ public class BevelBorder extends AbstractBorder
/**
* Returns the appearance of this border, which is either {@link
* #RAISED} or {@link #LOWERED}.
+ *
+ * @return The bevel type ({@link #RAISED} or {@link #LOWERED}).
*/
public int getBevelType()
{
diff --git a/javax/swing/border/CompoundBorder.java b/javax/swing/border/CompoundBorder.java
index 998a9bab3..a69c5e20a 100644
--- a/javax/swing/border/CompoundBorder.java
+++ b/javax/swing/border/CompoundBorder.java
@@ -224,6 +224,8 @@ public class CompoundBorder extends AbstractBorder
* Returns the outside border, which is painted outside both the
* bordered Component and the inside border. It is valid for the
* result to be <code>null</code>.
+ *
+ * @return The outside border (possibly <code>null</code>).
*/
public Border getOutsideBorder()
{
@@ -234,6 +236,8 @@ public class CompoundBorder extends AbstractBorder
* Returns the inside border, which is painted between the bordered
* Component and the outside border. It is valid for the result to
* be <code>null</code>.
+ *
+ * @return The inside border (possibly <code>null</code>).
*/
public Border getInsideBorder ()
{
diff --git a/javax/swing/border/EtchedBorder.java b/javax/swing/border/EtchedBorder.java
index 22882b78c..cd48b18da 100644
--- a/javax/swing/border/EtchedBorder.java
+++ b/javax/swing/border/EtchedBorder.java
@@ -281,6 +281,8 @@ public class EtchedBorder extends AbstractBorder
/**
* Returns the appearance of this EtchedBorder, which is either
* {@link #RAISED} or {@link #LOWERED}.
+ *
+ * @return The type ({@link #RAISED} or {@link #LOWERED}).
*/
public int getEtchType()
{
@@ -297,6 +299,8 @@ public class EtchedBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#brighter()
*/
@@ -312,6 +316,8 @@ public class EtchedBorder extends AbstractBorder
* Returns the color that will be used for highlighted parts when
* painting the border, or <code>null</code> if that color will be
* derived from the background of the enclosed Component.
+ *
+ * @return The highlight color (possibly <code>null</code>).
*/
public Color getHighlightColor()
{
@@ -328,6 +334,8 @@ public class EtchedBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The shadow color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#darker()
*/
@@ -344,6 +352,8 @@ public class EtchedBorder extends AbstractBorder
* Returns the color that will be used for shadowed parts when
* painting the border, or <code>null</code> if that color will be
* derived from the background of the enclosed Component.
+ *
+ * @return The shadow color (possibly <code>null</code>).
*/
public Color getShadowColor()
{
diff --git a/javax/swing/border/LineBorder.java b/javax/swing/border/LineBorder.java
index 36abddd91..31e19fe1f 100644
--- a/javax/swing/border/LineBorder.java
+++ b/javax/swing/border/LineBorder.java
@@ -162,8 +162,10 @@ public class LineBorder extends AbstractBorder
/**
- * Returns a black, one pixel thick, plain LineBorder. The method
- * may always return the same (singleton) LineBorder instance.
+ * Returns a black, one pixel thick, plain {@link LineBorder}. The method
+ * may always return the same (singleton) {@link LineBorder} instance.
+ *
+ * @return The border.
*/
public static Border createBlackLineBorder()
{
@@ -178,8 +180,10 @@ public class LineBorder extends AbstractBorder
/**
- * Returns a gray, one pixel thick, plain LineBorder. The method
- * may always return the same (singleton) LineBorder instance.
+ * Returns a gray, one pixel thick, plain {@link LineBorder}. The method
+ * may always return the same (singleton) {@link LineBorder} instance.
+ *
+ * @return The border.
*/
public static Border createGrayLineBorder()
{
@@ -295,6 +299,8 @@ public class LineBorder extends AbstractBorder
/**
* Returns the color of the line.
+ *
+ * @return The line color (never <code>null</code>).
*/
public Color getLineColor()
{
@@ -304,6 +310,8 @@ public class LineBorder extends AbstractBorder
/**
* Returns the thickness of the line in pixels.
+ *
+ * @return The line thickness (in pixels).
*/
public int getThickness()
{
diff --git a/javax/swing/border/MatteBorder.java b/javax/swing/border/MatteBorder.java
index 4d5b8c253..114cac623 100644
--- a/javax/swing/border/MatteBorder.java
+++ b/javax/swing/border/MatteBorder.java
@@ -299,6 +299,8 @@ public class MatteBorder extends EmptyBorder
* Returns the color that is used for filling the border, or
* <code>null</code> if the border is filled with repetitions of a
* tile icon.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getMatteColor()
{
@@ -310,6 +312,8 @@ public class MatteBorder extends EmptyBorder
* Returns the icon is used for tiling the border, or
* <code>null</code> if the border is filled with a color instead of
* an icon.
+ *
+ * @return The icon (possibly <code>null</code>).
*/
public Icon getTileIcon()
{
diff --git a/javax/swing/border/TitledBorder.java b/javax/swing/border/TitledBorder.java
index 8d3ee13d4..38b575423 100644
--- a/javax/swing/border/TitledBorder.java
+++ b/javax/swing/border/TitledBorder.java
@@ -912,8 +912,10 @@ public class TitledBorder extends AbstractBorder
* Calculates the minimum size needed for displaying the border
* and its title.
*
- * @param c the Component for which this TitledBorder consitutes
+ * @param c the Component for which this TitledBorder constitutes
* a border.
+ *
+ * @return The minimum size.
*/
public Dimension getMinimumSize(Component c)
{
@@ -980,6 +982,10 @@ public class TitledBorder extends AbstractBorder
/**
* Performs various measurements for the current state of this TitledBorder
* and the given Component.
+ *
+ * @param c the component (<code>null</code> not permitted).
+ *
+ * @return Various measurements.
*/
private Measurements getMeasurements(Component c)
{
@@ -1172,6 +1178,8 @@ public class TitledBorder extends AbstractBorder
/**
* Calculates the minimum size needed for displaying the border
* and its title. Used by {@link TitledBorder#getMinimumSize(Component)}.
+ *
+ * @return The minimum size.
*/
public Dimension getMinimumSize()
{
diff --git a/javax/swing/event/ChangeEvent.java b/javax/swing/event/ChangeEvent.java
index f75c15aac..8854282a9 100644
--- a/javax/swing/event/ChangeEvent.java
+++ b/javax/swing/event/ChangeEvent.java
@@ -1,5 +1,5 @@
/* ChangeEvent.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,23 +37,30 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventObject;
/**
- * ChangeEvent
+ * An event used to signal a state change for an object.
+ *
+ * @see ChangeListener
+ * @see CellEditorListener
+ * @see TableColumnModelListener
+ *
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public class ChangeEvent extends EventObject {
+public class ChangeEvent
+ extends EventObject
+{
- /**
- * ChangeEvent constructor
- * @param source Source object
- */
- public ChangeEvent(Object source) {
- super(source);
- } // ChangeEvent()
+ /**
+ * Creates a new <code>ChangeEvent</code> instance for the specified source.
+ *
+ * @param source the source for the event (<code>null</code> not permitted).
+ */
+ public ChangeEvent(Object source)
+ {
+ super(source);
+ }
-
-} // ChangeEvent
+}
diff --git a/javax/swing/event/ChangeListener.java b/javax/swing/event/ChangeListener.java
index 1e58b1d82..75809707b 100644
--- a/javax/swing/event/ChangeListener.java
+++ b/javax/swing/event/ChangeListener.java
@@ -1,5 +1,5 @@
/* ChangeListener.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,21 +37,27 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventListener;
/**
- * ChangeListener interface
+ * A <code>ChangeListener</code> can register with an object to receive
+ * notification of state changes (for objects that support this mechanism).
+ *
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public interface ChangeListener extends EventListener {
-
- /**
- * State changed
- * @param event Change Event
- */
- void stateChanged(ChangeEvent event);
-
-
-} // ChangeListener
+public interface ChangeListener
+ extends EventListener
+{
+
+ /**
+ * Called by an object to notify the listener that the object's state has
+ * changed. The incoming <code>event</code> identifies the
+ * <code>source</code> of the event, allowing the listener to differentiate
+ * when it is listening for changes in multiple sources.
+ *
+ * @param event the change event.
+ */
+ void stateChanged(ChangeEvent event);
+
+}
diff --git a/javax/swing/event/TableColumnModelListener.java b/javax/swing/event/TableColumnModelListener.java
index 90e1b29cc..522e0a8c6 100644
--- a/javax/swing/event/TableColumnModelListener.java
+++ b/javax/swing/event/TableColumnModelListener.java
@@ -1,5 +1,5 @@
/* TableColumnModelListener.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,44 +37,58 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventListener;
+import javax.swing.table.TableColumnModel;
+
/**
- * TableColumnModelListener public interface
+ * A <code>TableColumnModelListener</code> can register with a
+ * {@link TableColumnModel} to receive notification of changes to the model.
+ *
* @author Andrew Selkirk
*/
-public interface TableColumnModelListener extends EventListener {
-
- /**
- * Column added
- * @param event Table Column Model Event
- */
- void columnAdded(TableColumnModelEvent event);
-
- /**
- * Column margin changed
- * @param event Change Event
- */
- void columnMarginChanged(ChangeEvent event);
-
- /**
- * Column moved
- * @param event Table Column Model Event
- */
- void columnMoved(TableColumnModelEvent event);
-
- /**
- * Column removed
- * @param event Table Column Model Event
- */
- void columnRemoved(TableColumnModelEvent event);
-
- /**
- * Column selection changed
- * @param event List Selection Event
- */
- void columnSelectionChanged(ListSelectionEvent event);
-
-
-} // TableColumnModelListener
+public interface TableColumnModelListener
+ extends EventListener
+{
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * added to the model.
+ *
+ * @param event information about the column addition.
+ */
+ void columnAdded(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that the model's
+ * column margin has changed.
+ *
+ * @param event the event (identifies the source).
+ */
+ void columnMarginChanged(ChangeEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * moved.
+ *
+ * @param event information about the column move.
+ */
+ void columnMoved(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * removed from the model.
+ *
+ * @param event information about the column removal.
+ */
+ void columnRemoved(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that the column
+ * selection state has changed.
+ *
+ * @param event information about the column selection state.
+ */
+ void columnSelectionChanged(ListSelectionEvent event);
+
+}
diff --git a/javax/swing/plaf/basic/BasicComboBoxUI.java b/javax/swing/plaf/basic/BasicComboBoxUI.java
index e62432f10..557eea93f 100644
--- a/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -972,6 +974,7 @@ public class BasicComboBoxUI extends ComboBoxUI
* by the look and feel.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement.
}
@@ -981,6 +984,7 @@ public class BasicComboBoxUI extends ComboBoxUI
* installed by in {@link #installListeners}.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement.
}
diff --git a/javax/swing/plaf/basic/BasicComboPopup.java b/javax/swing/plaf/basic/BasicComboPopup.java
index 90b0585c4..d4eabc602 100644
--- a/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/javax/swing/plaf/basic/BasicComboPopup.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
@@ -292,6 +294,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -559,6 +562,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
* DOCUMENT ME!
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicInternalFrameUI.java b/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 75aab2fe7..0a330e776 100644
--- a/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
@@ -1209,6 +1211,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method installs the keyboard actions for the JInternalFrame.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1291,6 +1294,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method uninstalls the keyboard actions for the JInternalFrame.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
diff --git a/javax/swing/plaf/basic/BasicLabelUI.java b/javax/swing/plaf/basic/BasicLabelUI.java
index d0964f473..60e3a9868 100644
--- a/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/javax/swing/plaf/basic/BasicLabelUI.java
@@ -37,6 +37,8 @@
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
@@ -372,6 +374,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param l The {@link JLabel} to install keyboard actions for.
*/
protected void installKeyboardActions(JLabel l)
+ throws NotImplementedException
{
//FIXME: implement.
}
@@ -382,6 +385,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param l The {@link JLabel} to uninstall keyboard actions for.
*/
protected void uninstallKeyboardActions(JLabel l)
+ throws NotImplementedException
{
//FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicListUI.java b/javax/swing/plaf/basic/BasicListUI.java
index 6892833b2..e5dcd1c4f 100644
--- a/javax/swing/plaf/basic/BasicListUI.java
+++ b/javax/swing/plaf/basic/BasicListUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -1025,6 +1027,7 @@ public class BasicListUI extends ListUI
* Uninstalls keyboard actions for this UI in the {@link JList}.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicMenuBarUI.java b/javax/swing/plaf/basic/BasicMenuBarUI.java
index a21514467..f258ebe30 100644
--- a/javax/swing/plaf/basic/BasicMenuBarUI.java
+++ b/javax/swing/plaf/basic/BasicMenuBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Dimension;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
@@ -176,6 +178,7 @@ public class BasicMenuBarUI extends MenuBarUI
* This method installs the keyboard actions for the JMenuBar.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement
}
@@ -223,6 +226,7 @@ public class BasicMenuBarUI extends MenuBarUI
* This method reverses the work done in installKeyboardActions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicMenuUI.java b/javax/swing/plaf/basic/BasicMenuUI.java
index 4fb250d24..f8936be5b 100644
--- a/javax/swing/plaf/basic/BasicMenuUI.java
+++ b/javax/swing/plaf/basic/BasicMenuUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
@@ -218,6 +220,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -262,6 +265,7 @@ public class BasicMenuUI extends BasicMenuItemUI
* Basic look and feel's defaults.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicOptionPaneUI.java b/javax/swing/plaf/basic/BasicOptionPaneUI.java
index 005a3b394..88bca3b53 100644
--- a/javax/swing/plaf/basic/BasicOptionPaneUI.java
+++ b/javax/swing/plaf/basic/BasicOptionPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@@ -1204,6 +1206,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
* This method installs keyboard actions for the JOptionpane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1336,6 +1339,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
* This method uninstalls keyboard actions for the JOptionPane.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicPopupMenuUI.java b/javax/swing/plaf/basic/BasicPopupMenuUI.java
index 6ecd06b39..a26a5c7c4 100644
--- a/javax/swing/plaf/basic/BasicPopupMenuUI.java
+++ b/javax/swing/plaf/basic/BasicPopupMenuUI.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
@@ -137,6 +139,7 @@ public class BasicPopupMenuUI extends PopupMenuUI
* This method installs the keyboard actions for this {@link JPopupMenu}.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -179,6 +182,7 @@ public class BasicPopupMenuUI extends PopupMenuUI
* Uninstalls any keyboard actions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicScrollBarUI.java b/javax/swing/plaf/basic/BasicScrollBarUI.java
index 0ab2914ea..f24485484 100644
--- a/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -763,6 +765,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
* This method installs the keyboard actions for the scrollbar.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1141,6 +1144,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
* during install.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicScrollPaneUI.java b/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 1e982008f..e6a4eaf4f 100644
--- a/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -484,6 +486,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
* @param sp the scrollpane to install keyboard actions on
*/
protected void installKeyboardActions(JScrollPane sp)
+ throws NotImplementedException
{
// TODO: Is this only a hook method or should we actually do something
// here? If the latter, than figure out what and implement this.
@@ -579,6 +582,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
* @param sp the scrollpane to uninstall keyboard actions from
*/
protected void uninstallKeyboardActions(JScrollPane sp)
+ throws NotImplementedException
{
// TODO: Is this only a hook method or should we actually do something
// here? If the latter, than figure out what and implement this.
diff --git a/javax/swing/plaf/basic/BasicSliderUI.java b/javax/swing/plaf/basic/BasicSliderUI.java
index 9137ae9dc..137ab55a6 100644
--- a/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/javax/swing/plaf/basic/BasicSliderUI.java
@@ -63,7 +63,9 @@ import java.util.Dictionary;
import java.util.Enumeration;
import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
import javax.swing.BoundedRangeModel;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
@@ -74,6 +76,7 @@ import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
+import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SliderUI;
@@ -871,9 +874,11 @@ public class BasicSliderUI extends SliderUI
* installed.
*/
protected void installKeyboardActions(JSlider slider)
- throws NotImplementedException
{
- // FIXME: implement.
+ InputMap keyMap = getInputMap(JComponent.WHEN_FOCUSED);
+ SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, keyMap);
+ ActionMap map = getActionMap();
+ SwingUtilities.replaceUIActionMap(slider, map);
}
/**
@@ -884,9 +889,9 @@ public class BasicSliderUI extends SliderUI
* uninstalled.
*/
protected void uninstallKeyboardActions(JSlider slider)
- throws NotImplementedException
{
- // FIXME: implement.
+ SwingUtilities.replaceUIActionMap(slider, null);
+ SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, null);
}
/* XXX: This is all after experimentation with SUN's implementation.
@@ -2073,18 +2078,22 @@ public class BasicSliderUI extends SliderUI
}
/**
- * This method is used to move the thumb one block in the direction
- * specified. If the slider snaps to ticks, this method is responsible for
- * snapping it to a tick after the thumb has been moved.
+ * Moves the thumb one block in the direction specified (a block is 1/10th
+ * of the slider range). If the slider snaps to ticks, this method is
+ * responsible for snapping it to a tick after the thumb has been moved.
*
- * @param direction The direction to move in.
+ * @param direction the direction (positive values increment the thumb
+ * position by one block, zero/negative values decrement the thumb position
+ * by one block).
*/
public void scrollByBlock(int direction)
{
- // The direction is -1 for backwards and 1 for forwards.
- int unit = direction * (slider.getMaximum() - slider.getMinimum()) / 10;
-
- int moveTo = slider.getValue() + unit;
+ int unit = (slider.getMaximum() - slider.getMinimum()) / 10;
+ int moveTo = slider.getValue();
+ if (direction > 0)
+ moveTo += unit;
+ else
+ moveTo -= unit;
if (slider.getSnapToTicks())
moveTo = findClosestTick(moveTo);
@@ -2093,16 +2102,21 @@ public class BasicSliderUI extends SliderUI
}
/**
- * This method is used to move the thumb one unit in the direction
- * specified. If the slider snaps to ticks, this method is responsible for
- * snapping it to a tick after the thumb has been moved.
+ * Moves the thumb one unit in the specified direction. If the slider snaps
+ * to ticks, this method is responsible for snapping it to a tick after the
+ * thumb has been moved.
*
- * @param direction The direction to move in.
+ * @param direction the direction (positive values increment the thumb
+ * position by one, zero/negative values decrement the thumb position by
+ * one).
*/
public void scrollByUnit(int direction)
{
- // The direction is -1 for backwards and 1 for forwards.
- int moveTo = slider.getValue() + direction;
+ int moveTo = slider.getValue();
+ if (direction > 0)
+ moveTo++;
+ else
+ moveTo--;
if (slider.getSnapToTicks())
moveTo = findClosestTick(moveTo);
@@ -2316,4 +2330,123 @@ public class BasicSliderUI extends SliderUI
else
return value + minor;
}
+
+ InputMap getInputMap(int condition)
+ {
+ if (condition == JComponent.WHEN_FOCUSED)
+ return (InputMap) UIManager.get("Slider.focusInputMap");
+ return null;
+ }
+
+ /**
+ * Returns the action map for the {@link JSlider}. All sliders share
+ * a single action map which is created the first time this method is
+ * called, then stored in the UIDefaults table for subsequent access.
+ *
+ * @return The shared action map.
+ */
+ ActionMap getActionMap()
+ {
+ ActionMap map = (ActionMap) UIManager.get("Slider.actionMap");
+
+ if (map == null) // first time here
+ {
+ map = createActionMap();
+ if (map != null)
+ UIManager.put("Slider.actionMap", map);
+ }
+ return map;
+ }
+
+ /**
+ * Creates the action map shared by all {@link JSlider} instances.
+ * This method is called once by {@link #getActionMap()} when it
+ * finds no action map in the UIDefaults table...after the map is
+ * created, it gets added to the defaults table so that subsequent
+ * calls to {@link #getActionMap()} will return the same shared
+ * instance.
+ *
+ * @return The action map.
+ */
+ ActionMap createActionMap()
+ {
+ ActionMap map = new ActionMapUIResource();
+ map.put("positiveUnitIncrement",
+ new AbstractAction("positiveUnitIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
+ else
+ ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
+ }
+ }
+ );
+ map.put("negativeUnitIncrement",
+ new AbstractAction("negativeUnitIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
+ else
+ ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
+ }
+ }
+ );
+ map.put("positiveBlockIncrement",
+ new AbstractAction("positiveBlockIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
+ else
+ ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
+ }
+ }
+ );
+ map.put("negativeBlockIncrement",
+ new AbstractAction("negativeBlockIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
+ else
+ ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
+ }
+ }
+ );
+ map.put("minScroll",
+ new AbstractAction("minScroll") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ if (slider.getInverted())
+ slider.setValue(slider.getMaximum());
+ else
+ slider.setValue(slider.getMinimum());
+ }
+ }
+ );
+ map.put("maxScroll",
+ new AbstractAction("maxScroll") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ if (slider.getInverted())
+ slider.setValue(slider.getMinimum());
+ else
+ slider.setValue(slider.getMaximum());
+ }
+ }
+ );
+ return map;
+ }
}
diff --git a/javax/swing/plaf/basic/BasicSpinnerUI.java b/javax/swing/plaf/basic/BasicSpinnerUI.java
index 6f7a41a1d..465374bfd 100644
--- a/javax/swing/plaf/basic/BasicSpinnerUI.java
+++ b/javax/swing/plaf/basic/BasicSpinnerUI.java
@@ -41,7 +41,6 @@ package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
-import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
@@ -365,9 +364,9 @@ public class BasicSpinnerUI extends SpinnerUI
private class DefaultLayoutManager implements LayoutManager
{
/**
- * DOCUMENT ME!
+ * Layout the spinners inner parts.
*
- * @param parent DOCUMENT ME!
+ * @param parent The parent container
*/
public void layoutContainer(Container parent)
{
@@ -385,12 +384,12 @@ public class BasicSpinnerUI extends SpinnerUI
Dimension e = prefSize(editor);
Dimension n = prefSize(next);
Dimension p = prefSize(previous);
- Dimension s = spinner.getPreferredSize();
+ Dimension s = parent.getSize();
int x = l2r ? i.left : i.right;
int y = i.top;
int w = Math.max(p.width, n.width);
- int h = e.height / 2;
+ int h = (s.height - i.bottom) / 2;
int e_width = s.width - w - i.left - i.right;
if (l2r)
diff --git a/javax/swing/plaf/basic/BasicSplitPaneUI.java b/javax/swing/plaf/basic/BasicSplitPaneUI.java
index 906acfe16..694baadda 100644
--- a/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
@@ -1047,6 +1049,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
* This method installs the keyboard actions for the JSplitPane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1055,6 +1058,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
* This method reverses the work done in installKeyboardActions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index dd27b7d2d..6d9bed331 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -1734,6 +1736,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method installs keyboard actions for the JTabbedPane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1742,6 +1745,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method uninstalls keyboard actions for the JTabbedPane.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1950,6 +1954,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
return;
}
+ int ascent = metrics.getAscent();
+
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex))
{
@@ -1966,10 +1972,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x,
- textRect.y
- + metrics.getAscent());
+ textRect.y + ascent);
else
- g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
+ g.drawString(title, textRect.x, textRect.y + ascent);
}
else
{
@@ -1977,17 +1982,19 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
g.setColor(bg.brighter());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
- textRect.x, textRect.y);
+ textRect.x, textRect.y
+ + ascent);
else
- g.drawString(title, textRect.x, textRect.y);
+ g.drawString(title, textRect.x, textRect.y + ascent);
g.setColor(bg.darker());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x + 1,
- textRect.y + 1);
+ textRect.y + 1
+ + ascent);
else
- g.drawString(title, textRect.x + 1, textRect.y + 1);
+ g.drawString(title, textRect.x + 1, textRect.y + 1 + ascent);
}
}
@@ -2552,10 +2559,23 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected int lastTabInRun(int tabCount, int run)
{
- if (tabRuns[run] == 0)
- return tabCount - 1;
+ int lastTab;
+ if (runCount == 1)
+ lastTab = tabCount - 1;
else
- return tabRuns[run] - 1;
+ {
+ int nextRun;
+ if (run == runCount - 1)
+ nextRun = 0;
+ else
+ nextRun = run + 1;
+
+ if (tabRuns[nextRun] == 0)
+ lastTab = tabCount - 1;
+ else
+ lastTab = tabRuns[nextRun] - 1;
+ }
+ return lastTab;
}
/**
diff --git a/javax/swing/plaf/basic/BasicTableHeaderUI.java b/javax/swing/plaf/basic/BasicTableHeaderUI.java
index c6f9e37df..fbef6e69f 100644
--- a/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
@@ -415,6 +417,7 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void installKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -447,6 +450,7 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicTableUI.java b/javax/swing/plaf/basic/BasicTableUI.java
index 9ddaeb2e9..0711ce385 100644
--- a/javax/swing/plaf/basic/BasicTableUI.java
+++ b/javax/swing/plaf/basic/BasicTableUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
@@ -1168,6 +1170,7 @@ public class BasicTableUI extends TableUI
}
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicTextAreaUI.java b/javax/swing/plaf/basic/BasicTextAreaUI.java
index e9f566e9a..93e119b31 100644
--- a/javax/swing/plaf/basic/BasicTextAreaUI.java
+++ b/javax/swing/plaf/basic/BasicTextAreaUI.java
@@ -1,5 +1,5 @@
/* BasicTextAreaUI.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,11 +45,9 @@ import javax.swing.JComponent;
import javax.swing.JTextArea;
import javax.swing.UIDefaults;
import javax.swing.plaf.ComponentUI;
-import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.PlainView;
import javax.swing.text.View;
-import javax.swing.text.ViewFactory;
import javax.swing.text.WrappedPlainView;
public class BasicTextAreaUI extends BasicTextUI
diff --git a/javax/swing/plaf/basic/BasicTextFieldUI.java b/javax/swing/plaf/basic/BasicTextFieldUI.java
index 4e2ca9f93..89c4e5a75 100644
--- a/javax/swing/plaf/basic/BasicTextFieldUI.java
+++ b/javax/swing/plaf/basic/BasicTextFieldUI.java
@@ -1,5 +1,5 @@
/* BasicTextFieldUI.java
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,7 @@ import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
import javax.swing.UIDefaults;
+import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.Element;
import javax.swing.text.FieldView;
@@ -83,6 +84,9 @@ public class BasicTextFieldUI extends BasicTextUI
* Receives notification whenever one of the text component's bound
* properties changes. Here we check for the editable and enabled
* properties and adjust the background color accordingly.
+ *
+ * <p>The colors are only changed if they are not a
+ * <code>ColorUIResource</code>.</p>
*
* @param event the property change event
*/
@@ -91,10 +95,11 @@ public class BasicTextFieldUI extends BasicTextUI
if (event.getPropertyName().equals("editable"))
{
boolean editable = ((Boolean) event.getNewValue()).booleanValue();
- if (editable)
- textComponent.setBackground(background);
- else
- textComponent.setBackground(inactiveBackground);
+
+ // Changing the color only if the current background is an instance of
+ // ColorUIResource is the behavior of the RI.
+ if (textComponent.getBackground() instanceof ColorUIResource)
+ textComponent.setBackground(editable ? background : inactiveBackground);
}
}
}
diff --git a/javax/swing/plaf/basic/BasicTextUI.java b/javax/swing/plaf/basic/BasicTextUI.java
index 6a45969cc..66c0da284 100644
--- a/javax/swing/plaf/basic/BasicTextUI.java
+++ b/javax/swing/plaf/basic/BasicTextUI.java
@@ -61,7 +61,6 @@ import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
-import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
@@ -69,7 +68,6 @@ import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ActionMapUIResource;
-import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.AbstractDocument;
@@ -824,6 +822,7 @@ public abstract class BasicTextUI extends TextUI
* this UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Uninstall keyboard actions here.
}
@@ -1139,9 +1138,14 @@ public abstract class BasicTextUI extends TextUI
public int getNextVisualPositionFrom(JTextComponent t, int pos,
Position.Bias b, int direction,
Position.Bias[] biasRet)
- throws BadLocationException, NotImplementedException
+ throws BadLocationException
{
- return 0; // TODO: Implement me.
+ // A comment in the spec of NavigationFilter.getNextVisualPositionFrom()
+ // suggests that this method should be implemented by forwarding the call
+ // the root view.
+ return rootView.getNextVisualPositionFrom(pos, b,
+ getVisibleEditorRect(),
+ direction, biasRet);
}
/**
diff --git a/javax/swing/plaf/basic/BasicToolBarUI.java b/javax/swing/plaf/basic/BasicToolBarUI.java
index 5d718876f..80fec6a77 100644
--- a/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@@ -604,6 +606,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
* by the look and feel.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -900,6 +903,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java
index 78d0a586a..fb09ac998 100644
--- a/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/javax/swing/plaf/basic/BasicTreeUI.java
@@ -1,5 +1,5 @@
/* BasicTreeUI.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,6 +57,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.KeyListener;
@@ -252,25 +253,25 @@ public class BasicTreeUI
int maxHeight = 0;
/** Listeners */
- private PropertyChangeListener propertyChangeListener;
+ PropertyChangeListener propertyChangeListener;
- private FocusListener focusListener;
+ FocusListener focusListener;
- private TreeSelectionListener treeSelectionListener;
+ TreeSelectionListener treeSelectionListener;
- private MouseListener mouseListener;
+ MouseListener mouseListener;
- private KeyListener keyListener;
+ KeyListener keyListener;
- private PropertyChangeListener selectionModelPropertyChangeListener;
+ PropertyChangeListener selectionModelPropertyChangeListener;
- private ComponentListener componentListener;
+ ComponentListener componentListener;
CellEditorListener cellEditorListener;
- private TreeExpansionListener treeExpansionListener;
+ TreeExpansionListener treeExpansionListener;
- private TreeModelListener treeModelListener;
+ TreeModelListener treeModelListener;
/**
* This timer fires the editing action after about 1200 ms if not reset during
@@ -668,7 +669,8 @@ public class BasicTreeUI
maxHeight = Math.max(maxHeight, iconHeight + gap);
}
-
+
+ treeState.setRowHeight(maxHeight);
return maxHeight;
}
@@ -1313,10 +1315,11 @@ public class BasicTreeUI
public void installUI(JComponent c)
{
tree = (JTree) c;
+ treeModel = tree.getModel();
+
prepareForUIInstall();
super.installUI(c);
installDefaults();
-
installComponents();
installKeyboardActions();
installListeners();
@@ -1384,25 +1387,11 @@ public class BasicTreeUI
int endIndex = tree.getClosestRowForLocation(clip.x + clip.width,
clip.y + clip.height);
- for (int i = startIndex; i <= endIndex; i++)
- {
- TreePath path = treeState.getPathForRow(i);
- boolean isLeaf = treeModel.isLeaf(path.getLastPathComponent());
- boolean isExpanded = tree.isExpanded(path);
-
- Rectangle bounds = getPathBounds(tree, path);
-
- paintHorizontalPartOfLeg(g, clip, insets, bounds, path, i,
- isExpanded, false, isLeaf);
- paintRow(g, clip, insets, bounds, path, i, isExpanded, false,
- isLeaf);
- if (isLastChild(path))
- paintVerticalPartOfLeg(g, clip, insets, path);
- }
-
// Also paint dashes to the invisible nodes below:
int rows = treeState.getRowCount();
+ // These should be painted first, otherwise they may cover
+ // the control icons.
if (endIndex < rows)
for (int i = endIndex + 1; i < rows; i++)
{
@@ -1410,6 +1399,37 @@ public class BasicTreeUI
if (isLastChild(path))
paintVerticalPartOfLeg(g, clip, insets, path);
}
+
+ // The two loops are required to ensure that the lines are not
+ // painted over the other tree components.
+
+ int n = endIndex - startIndex + 1;
+ Rectangle[] bounds = new Rectangle[n];
+ boolean[] isLeaf = new boolean[n];
+ boolean[] isExpanded = new boolean[n];
+ TreePath[] path = new TreePath[n];
+ int k;
+
+ k = 0;
+ for (int i = startIndex; i <= endIndex; i++, k++)
+ {
+ path[k] = treeState.getPathForRow(i);
+ isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
+ isExpanded[k] = tree.isExpanded(path[k]);
+ bounds[k] = getPathBounds(tree, path[k]);
+
+ paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k], i,
+ isExpanded[k], false, isLeaf[k]);
+ if (isLastChild(path[k]))
+ paintVerticalPartOfLeg(g, clip, insets, path[k]);
+ }
+
+ k = 0;
+ for (int i = startIndex; i <= endIndex; i++, k++)
+ {
+ paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
+ false, isLeaf[k]);
+ }
}
}
@@ -1508,8 +1528,9 @@ public class BasicTreeUI
{
if (! validCachedPreferredSize)
{
+ Rectangle size = tree.getBounds();
// Add the scrollbar dimensions to the preferred size.
- preferredSize = new Dimension(treeState.getPreferredWidth(null),
+ preferredSize = new Dimension(treeState.getPreferredWidth(size),
treeState.getPreferredHeight());
validCachedPreferredSize = true;
}
@@ -1598,12 +1619,6 @@ public class BasicTreeUI
*/
protected boolean startEditing(TreePath path, MouseEvent event)
{
- // Force to recalculate the maximal row height.
- maxHeight = 0;
-
- // Force to recalculate the cached preferred size.
- validCachedPreferredSize = false;
-
updateCellEditor();
TreeCellEditor ed = getCellEditor();
@@ -1720,7 +1735,10 @@ public class BasicTreeUI
/**
* Returning true signifies a mouse event on the node should toggle the
- * selection of only the row under the mouse.
+ * selection of only the row under the mouse. The BasisTreeUI treats the
+ * event as "toggle selection event" if the CTRL button was pressed while
+ * clicking. The event is not counted as toggle event if the associated
+ * tree does not support the multiple selection.
*
* @param event is the MouseEvent performed on the row.
* @return true signifies a mouse event on the node should toggle the
@@ -1728,12 +1746,18 @@ public class BasicTreeUI
*/
protected boolean isToggleSelectionEvent(MouseEvent event)
{
- return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION);
+ return
+ (tree.getSelectionModel().getSelectionMode() !=
+ TreeSelectionModel.SINGLE_TREE_SELECTION) &&
+ ((event.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0);
}
/**
* Returning true signifies a mouse event on the node should select from the
- * anchor point.
+ * anchor point. The BasisTreeUI treats the event as "multiple selection
+ * event" if the SHIFT button was pressed while clicking. The event is not
+ * counted as multiple selection event if the associated tree does not support
+ * the multiple selection.
*
* @param event is the MouseEvent performed on the node.
* @return true signifies a mouse event on the node should select from the
@@ -1741,7 +1765,10 @@ public class BasicTreeUI
*/
protected boolean isMultiSelectEvent(MouseEvent event)
{
- return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
+ return
+ (tree.getSelectionModel().getSelectionMode() !=
+ TreeSelectionModel.SINGLE_TREE_SELECTION) &&
+ ((event.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0);
}
/**
@@ -1763,15 +1790,19 @@ public class BasicTreeUI
* 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.
+ * and the previous selection is cleared.</p>
*
* @param path is the path selected for an event
* @param event is the MouseEvent performed on the path.
+ *
+ * @see #isToggleSelectionEvent(MouseEvent)
+ * @see #isMultiSelectEvent(MouseEvent)
*/
protected void selectPathForEvent(TreePath path, MouseEvent event)
{
if (isToggleSelectionEvent(event))
{
+ // The event selects or unselects the clicked row.
if (tree.isPathSelected(path))
tree.removeSelectionPath(path);
else
@@ -1782,6 +1813,7 @@ public class BasicTreeUI
}
else if (isMultiSelectEvent(event))
{
+ // The event extends selection form anchor till the clicked row.
TreePath anchor = tree.getAnchorSelectionPath();
if (anchor != null)
{
@@ -1792,7 +1824,11 @@ public class BasicTreeUI
tree.addSelectionPath(path);
}
else
- tree.addSelectionPath(path);
+ {
+ // This is an ordinary event that just selects the clicked row.
+ tree.setSelectionPath(path);
+ tree.setAnchorSelectionPath(path);
+ }
}
/**
@@ -1865,7 +1901,7 @@ public class BasicTreeUI
if (tree.isEditing() && ! command.equals("startEditing"))
tree.stopEditing();
- tree.scrollPathToVisible(lead);
+ tree.scrollPathToVisible(tree.getLeadSelectionPath());
}
}
@@ -2017,24 +2053,38 @@ public class BasicTreeUI
/**
* Invoked when focus is activated on the tree we're in, redraws the lead
- * row. Invoked when a component gains the keyboard focus.
+ * row. Invoked when a component gains the keyboard focus. The method
+ * repaints the lead row that is shown differently when the tree is in
+ * focus.
*
* @param e is the focus event that is activated
*/
public void focusGained(FocusEvent e)
{
- // TODO: Implement this properly.
+ repaintLeadRow();
}
/**
* Invoked when focus is deactivated on the tree we're in, redraws the lead
- * row. Invoked when a component loses the keyboard focus.
+ * row. Invoked when a component loses the keyboard focus. The method
+ * repaints the lead row that is shown differently when the tree is in
+ * focus.
*
* @param e is the focus event that is deactivated
*/
public void focusLost(FocusEvent e)
{
- // TODO: Implement this properly.
+ repaintLeadRow();
+ }
+
+ /**
+ * Repaint the lead row.
+ */
+ void repaintLeadRow()
+ {
+ TreePath lead = tree.getLeadSelectionPath();
+ if (lead!=null)
+ tree.repaint(tree.getPathBounds(lead));
}
}
@@ -2131,6 +2181,11 @@ public class BasicTreeUI
{
Rectangle bounds = getPathBounds(tree, path);
int row = getRowForPath(tree, path);
+
+ // Cancel the editing session if clicked on the different row.
+ if (tree.isEditing() && row != editingRow)
+ cancelEditing(tree);
+
boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);
boolean isLeaf = isLeaf(row);
@@ -2171,23 +2226,22 @@ public class BasicTreeUI
startEditTimer.stop();
startEditTimer = new Timer(WAIT_TILL_EDITING,
- new ActionListener()
- {
- public void actionPerformed(
- ActionEvent e)
- {
- startEditing(editPath,
- EDIT);
- }
- });
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ startEditing(editPath, EDIT);
+ }
+ });
startEditTimer.setRepeats(false);
startEditTimer.start();
}
else
{
- selectPath(tree, path);
if (e.getClickCount() == 2 && ! isLeaf(row))
toggleExpandState(path);
+ else
+ selectPathForEvent(path, e);
}
}
@@ -2410,12 +2464,13 @@ public class BasicTreeUI
*/
protected int getRowX(int row, int depth)
{
- return depth * rightChildIndent;
+ int iw = getCurrentControlIcon(null).getIconWidth();
+ return depth * (rightChildIndent + iw/2);
}
}// NodeDimensionsHandler
/**
- * PropertyChangeListener for the tree. Updates the appropriate varaible, or
+ * PropertyChangeListener for the tree. Updates the appropriate variable, or
* TreeState, based on what changes.
*/
public class PropertyChangeHandler
@@ -2438,12 +2493,23 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
- if ((event.getPropertyName()).equals("rootVisible"))
+ String property = event.getPropertyName();
+ if (property.equals(JTree.ROOT_VISIBLE_PROPERTY))
{
validCachedPreferredSize = false;
treeState.setRootVisible(tree.isRootVisible());
tree.repaint();
}
+ else if (property.equals(JTree.SELECTION_MODEL_PROPERTY))
+ {
+ treeSelectionModel = tree.getSelectionModel();
+ treeSelectionModel.setRowMapper(treeState);
+ }
+ else if (property.equals(JTree.TREE_MODEL_PROPERTY))
+ {
+ treeModel = tree.getModel();
+ treeModel.addTreeModelListener(treeModelListener);
+ }
}
}
@@ -2536,6 +2602,8 @@ public class BasicTreeUI
{
validCachedPreferredSize = false;
treeState.setExpandedState(event.getPath(), true);
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -2547,6 +2615,8 @@ public class BasicTreeUI
{
validCachedPreferredSize = false;
treeState.setExpandedState(event.getPath(), false);
+ tree.revalidate();
+ tree.repaint();
}
}// TreeExpansionHandler
@@ -2643,35 +2713,54 @@ public class BasicTreeUI
if (command.equals("selectPreviousChangeLead") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
+ tree.setAnchorSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectPreviousExtendSelection") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
+
+ // If the new path is already selected, the selection shrinks,
+ // unselecting the previously current path.
+ if (tree.isPathSelected(newPath))
+ tree.getSelectionModel().removeSelectionPath(currentPath);
+
+ // This must be called in any case because it updates the model
+ // lead selection index.
tree.addSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectPrevious") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
}
else if (command.equals("selectNext") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
}
else if (command.equals("selectNextExtendSelection") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
+
+ // If the new path is already selected, the selection shrinks,
+ // unselecting the previously current path.
+ if (tree.isPathSelected(newPath))
+ tree.getSelectionModel().removeSelectionPath(currentPath);
+
+ // This must be called in any case because it updates the model
+ // lead selection index.
tree.addSelectionPath(newPath);
+
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectNextChangeLead") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
+ tree.setAnchorSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
}
@@ -2837,7 +2926,24 @@ public class BasicTreeUI
public void valueChanged(TreeSelectionEvent event)
{
if (tree.isEditing())
- tree.stopEditing();
+ tree.cancelEditing();
+
+ TreePath op = event.getOldLeadSelectionPath();
+ TreePath np = event.getNewLeadSelectionPath();
+
+ // Repaint of the changed lead selection path.
+ if (op != np)
+ {
+ Rectangle o = treeState.getBounds(event.getOldLeadSelectionPath(),
+ new Rectangle());
+ Rectangle n = treeState.getBounds(event.getNewLeadSelectionPath(),
+ new Rectangle());
+
+ if (o!=null)
+ tree.repaint(o);
+ if (n!=null)
+ tree.repaint(n);
+ }
}
}// TreeSelectionHandler
@@ -2913,16 +3019,41 @@ public class BasicTreeUI
return;
if (e.getActionCommand().equals("selectParent"))
- selectPath(tree, current.getParentPath());
+ {
+ if (current == null)
+ return;
+
+ if (tree.isExpanded(current))
+ {
+ tree.collapsePath(current);
+ }
+ else
+ {
+ // If the node is not expanded (also, if it is a leaf node),
+ // we just select the parent. We do not select the root if it
+ // is not visible.
+ TreePath parent = current.getParentPath();
+ if (parent != null &&
+ !(parent.getPathCount()==1 && !tree.isRootVisible()) )
+ tree.setSelectionPath(parent);
+ }
+ }
else if (e.getActionCommand().equals("selectChild"))
{
Object node = current.getLastPathComponent();
int nc = treeModel.getChildCount(node);
- if (nc > 0)
- node = treeModel.getChild(node, 0);
-
- TreePath path = current.pathByAddingChild(node);
- selectPath(tree, path);
+ if (nc == 0 || treeState.isExpanded(current))
+ {
+ // If the node is leaf or it is already expanded,
+ // we just select the next row.
+ int nextRow = tree.getLeadSelectionRow() + 1;
+ if (nextRow <= tree.getRowCount())
+ tree.setSelectionRow(nextRow);
+ }
+ else
+ {
+ tree.expandPath(current);
+ }
}
}
@@ -3018,23 +3149,9 @@ public class BasicTreeUI
{
if (path != null)
{
- 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.addSelectionPath(path);
- tree.setLeadSelectionPath(path);
- tree.getSelectionModel().setSelectionMode(
- TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
- }
+ tree.setSelectionPath(path);
+ tree.setLeadSelectionPath(path);
+ tree.makeVisible(path);
tree.scrollPathToVisible(path);
}
}
@@ -3172,9 +3289,7 @@ public class BasicTreeUI
{
Icon icon = getCurrentControlIcon(path);
int iconW = icon.getIconWidth();
- int x = bounds.x - rightChildIndent + iconW / 2;
- if (x + iconW > bounds.x)
- x = bounds.x - rightChildIndent - gap;
+ int x = bounds.x - iconW - gap;
icon.paintIcon(tree, g, x, bounds.y + bounds.height / 2
- icon.getIconHeight() / 2);
}
@@ -3203,8 +3318,12 @@ public class BasicTreeUI
boolean isLeaf)
{
if (row != 0)
- paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, bounds.x - gap
- - 2, bounds.x);
+ {
+ Icon icon = getCurrentControlIcon(path);
+ int iconW = icon.getIconWidth();
+ paintHorizontalLine(g, tree, bounds.y + bounds.height / 2,
+ bounds.x - iconW/2 - gap, bounds.x - gap);
+ }
}
/**
@@ -3224,7 +3343,7 @@ public class BasicTreeUI
if (parent != null)
{
Rectangle parentBounds = getPathBounds(tree, parent);
- paintVerticalLine(g, tree, parentBounds.x + gap + 2,
+ paintVerticalLine(g, tree, parentBounds.x + 2* gap,
parentBounds.y + parentBounds.height / 2,
bounds.y + bounds.height / 2);
}
@@ -3260,9 +3379,15 @@ public class BasicTreeUI
if (dtcr == null)
dtcr = createDefaultCellRenderer();
+ boolean focused = false;
+ if (treeSelectionModel!= null)
+ focused = treeSelectionModel.getLeadSelectionRow() == row
+ && tree.isFocusOwner();
+
Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
isExpanded, isLeaf, row,
- tree.hasFocus());
+ focused);
+
rendererPane.paintComponent(g, c, c.getParent(), bounds);
}
@@ -3298,15 +3423,17 @@ public class BasicTreeUI
*/
void finish()
{
+ treeState.invalidatePathBounds(treeState.getPathForRow(editingRow));
editingPath = null;
editingRow = - 1;
stopEditingInCompleteEditing = false;
isEditing = false;
+ Rectangle bounds = editingComponent.getParent().getBounds();
tree.removeAll();
validCachedPreferredSize = false;
-
// Repaint the region, where was the editing component.
- tree.repaint(editingComponent.getParent().getBounds());
+ tree.repaint(bounds);
editingComponent = null;
+ tree.requestFocus();
}
} // BasicTreeUI
diff --git a/javax/swing/table/DefaultTableCellRenderer.java b/javax/swing/table/DefaultTableCellRenderer.java
index 0d9b62567..f56fd4f0e 100644
--- a/javax/swing/table/DefaultTableCellRenderer.java
+++ b/javax/swing/table/DefaultTableCellRenderer.java
@@ -1,5 +1,5 @@
/* DefaultTableCellRenderer.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -49,7 +49,6 @@ import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
-import javax.swing.JTextField;
/**
* Class to display every cells.
diff --git a/javax/swing/table/DefaultTableColumnModel.java b/javax/swing/table/DefaultTableColumnModel.java
index cd04a6979..6ed6331c2 100644
--- a/javax/swing/table/DefaultTableColumnModel.java
+++ b/javax/swing/table/DefaultTableColumnModel.java
@@ -1,5 +1,5 @@
/* DefaultTableColumnModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,6 +46,7 @@ import java.util.EventListener;
import java.util.Vector;
import javax.swing.DefaultListSelectionModel;
+import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
@@ -55,9 +56,11 @@ import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
/**
- * DefaultTableColumnModel
+ * A model that stores information about the columns used in a {@link JTable}.
+ *
+ * @see JTable#setColumnModel(TableColumnModel)
+ *
* @author Andrew Selkirk
- * @version 1.0
*/
public class DefaultTableColumnModel
implements TableColumnModel, PropertyChangeListener, ListSelectionListener,
@@ -66,88 +69,116 @@ public class DefaultTableColumnModel
private static final long serialVersionUID = 6580012493508960512L;
/**
- * Columns that this model keeps track of.
+ * Storage for the table columns.
*/
protected Vector<TableColumn> tableColumns;
/**
- * Selection Model that keeps track of columns selection
+ * A selection model that keeps track of column selections.
*/
protected ListSelectionModel selectionModel;
/**
- * Space between two columns. By default it is set to 1
+ * The space between the columns (the default value is <code>1</code>).
*/
protected int columnMargin;
/**
- * listenerList keeps track of all listeners registered with this model
+ * Storage for the listeners registered with the model.
*/
protected EventListenerList listenerList = new EventListenerList();
/**
- * changeEvent is fired when change occurs in one of the columns properties
+ * A change event used when notifying listeners of a change to the
+ * <code>columnMargin</code> field. This single event is reused for all
+ * notifications.
*/
+ // FIXME: use lazy instantiation
protected transient ChangeEvent changeEvent = new ChangeEvent(this);
/**
- * Indicates whether columns can be selected
+ * A flag that indicates whether or not columns can be selected.
*/
protected boolean columnSelectionAllowed;
/**
- * Total width of all the columns in this model
+ * The total width of all the columns in this model.
*/
protected int totalColumnWidth;
/**
- * Constructor DefaultTableColumnModel
+ * Creates a new table column model with zero columns. A default column
+ * selection model is created by calling {@link #createSelectionModel()}.
+ * The default value for <code>columnMargin</code> is <code>1</code> and
+ * the default value for <code>columnSelectionAllowed</code> is
+ * <code>false</code>.
*/
public DefaultTableColumnModel()
{
tableColumns = new Vector();
- setSelectionModel(createSelectionModel());
+ selectionModel = createSelectionModel();
+ selectionModel.addListSelectionListener(this);
columnMargin = 1;
columnSelectionAllowed = false;
}
/**
- * addColumn adds column to the model. This method fires ColumnAdded
- * event to model's registered TableColumnModelListeners.
+ * Adds a column to the model then calls
+ * {@link #fireColumnAdded(TableColumnModelEvent)} to notify the registered
+ * listeners. The model registers itself with the column as a
+ * {@link PropertyChangeListener} so that changes to the column width will
+ * invalidate the cached {@link #totalColumnWidth} value.
*
- * @param col column to add
+ * @param column the column (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>column</code> is
+ * <code>null</code>.
+ *
+ * @see #removeColumn(TableColumn)
*/
- public void addColumn(TableColumn col)
+ public void addColumn(TableColumn column)
{
- if (col == null)
+ if (column == null)
throw new IllegalArgumentException("Null 'col' argument.");
- tableColumns.add(col);
+ tableColumns.add(column);
+ column.addPropertyChangeListener(this);
invalidateWidthCache();
- fireColumnAdded(new TableColumnModelEvent(this, 0, tableColumns.size() - 1));
+ fireColumnAdded(new TableColumnModelEvent(this, 0,
+ tableColumns.size() - 1));
}
/**
- * removeColumn removes table column from the model. This method fires
- * ColumnRemoved event to model's registered TableColumnModelListeners.
+ * Removes a column from the model then calls
+ * {@link #fireColumnRemoved(TableColumnModelEvent)} to notify the registered
+ * listeners. If the specified column does not belong to the model, or is
+ * <code>null</code>, this method does nothing.
*
- * @param col column to be removed
+ * @param column the column to be removed (<code>null</code> permitted).
+ *
+ * @see #addColumn(TableColumn)
*/
- public void removeColumn(TableColumn col)
+ public void removeColumn(TableColumn column)
{
- int index = this.tableColumns.indexOf(col);
+ int index = this.tableColumns.indexOf(column);
if (index < 0)
return;
+ tableColumns.remove(column);
fireColumnRemoved(new TableColumnModelEvent(this, index, 0));
- tableColumns.remove(col);
+ column.removePropertyChangeListener(this);
invalidateWidthCache();
}
/**
- * moveColumn moves column at index i to index j. This method fires
- * ColumnMoved event to model's registered TableColumnModelListeners.
+ * Moves the column at index i to the position specified by index j, then
+ * calls {@link #fireColumnMoved(TableColumnModelEvent)} to notify registered
+ * listeners.
*
- * @param i index of the column that will be moved
- * @param j index of column's new location
+ * @param i index of the column that will be moved.
+ * @param j index of the column's new location.
+ *
+ * @throws IllegalArgumentException if <code>i</code> or <code>j</code> are
+ * outside the range <code>0</code> to <code>N-1</code>, where
+ * <code>N</code> is the column count.
*/
public void moveColumn(int i, int j)
{
@@ -158,22 +189,27 @@ public class DefaultTableColumnModel
throw new IllegalArgumentException("Index 'j' out of range.");
TableColumn column = tableColumns.remove(i);
tableColumns.add(j, column);
- fireColumnAdded(new TableColumnModelEvent(this, i, j));
+ fireColumnMoved(new TableColumnModelEvent(this, i, j));
}
/**
- * setColumnMargin sets margin of the columns.
- * @param m new column margin
+ * Sets the column margin then calls {@link #fireColumnMarginChanged()} to
+ * notify the registered listeners.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
*/
- public void setColumnMargin(int m)
+ public void setColumnMargin(int margin)
{
- columnMargin = m;
+ columnMargin = margin;
fireColumnMarginChanged();
}
/**
- * getColumnCount returns number of columns in the model
- * @return int number of columns in the model
+ * Returns the number of columns in the model.
+ *
+ * @return The column count.
*/
public int getColumnCount()
{
@@ -181,8 +217,9 @@ public class DefaultTableColumnModel
}
/**
- * getColumns
- * @return Enumeration
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
*/
public Enumeration<TableColumn> getColumns()
{
@@ -214,18 +251,28 @@ public class DefaultTableColumnModel
}
/**
- * getColumn returns column at the specified index
- * @param i index of the column
- * @return TableColumn column at the specified index
+ * Returns the column at the specified index.
+ *
+ * @param columnIndex the column index (in the range from <code>0</code> to
+ * <code>N-1</code>, where <code>N</code> is the number of columns in
+ * the model).
+ *
+ * @return The column at the specified index.
+ *
+ * @throws ArrayIndexOutOfBoundsException if <code>i</code> is not within
+ * the specified range.
*/
- public TableColumn getColumn(int i)
+ public TableColumn getColumn(int columnIndex)
{
- return (TableColumn) tableColumns.get(i);
+ return (TableColumn) tableColumns.get(columnIndex);
}
/**
- * getColumnMargin returns column margin
- * @return int column margin
+ * Returns the column margin.
+ *
+ * @return The column margin.
+ *
+ * @see #setColumnMargin(int)
*/
public int getColumnMargin()
{
@@ -233,16 +280,26 @@ public class DefaultTableColumnModel
}
/**
- * getColumnIndexAtX returns column that contains specified x-coordinate.
- * @param x x-coordinate that column should contain
- * @return int index of the column that contains specified x-coordinate relative
- * to this column model
+ * Returns the index of the column that contains the specified x-coordinate.
+ * This method assumes that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param x the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
*/
public int getColumnIndexAtX(int x)
{
for (int i = 0; i < tableColumns.size(); ++i)
{
- int w = ((TableColumn)tableColumns.get(i)).getWidth();
+ int w = ((TableColumn) tableColumns.get(i)).getWidth();
if (0 <= x && x < w)
return i;
else
@@ -252,10 +309,10 @@ public class DefaultTableColumnModel
}
/**
- * getTotalColumnWidth returns total width of all the columns including
- * column's margins.
+ * Returns total width of all the columns in the model, ignoring the
+ * {@link #columnMargin}.
*
- * @return total width of all the columns
+ * @return The total width of all the columns.
*/
public int getTotalColumnWidth()
{
@@ -265,24 +322,32 @@ public class DefaultTableColumnModel
}
/**
- * setSelectionModel sets selection model that will be used by this ColumnTableModel
- * to keep track of currently selected columns
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
*
- * @param model new selection model
- * @exception IllegalArgumentException if model is null
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
+ *
+ * @see #getSelectionModel()
*/
public void setSelectionModel(ListSelectionModel model)
{
if (model == null)
throw new IllegalArgumentException();
+ selectionModel.removeListSelectionListener(this);
selectionModel = model;
selectionModel.addListSelectionListener(this);
}
/**
- * getSelectionModel returns selection model
- * @return ListSelectionModel selection model
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
*/
public ListSelectionModel getSelectionModel()
{
@@ -290,10 +355,11 @@ public class DefaultTableColumnModel
}
/**
- * setColumnSelectionAllowed sets whether column selection is allowed
- * or not.
+ * Sets the flag that indicates whether or not column selection is allowed.
*
- * @param flag true if column selection is allowed and false otherwise
+ * @param flag the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
*/
public void setColumnSelectionAllowed(boolean flag)
{
@@ -301,10 +367,12 @@ public class DefaultTableColumnModel
}
/**
- * getColumnSelectionAllowed indicates whether column selection is
- * allowed or not.
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
*
- * @return boolean true if column selection is allowed and false otherwise.
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
*/
public boolean getColumnSelectionAllowed()
{
@@ -312,10 +380,9 @@ public class DefaultTableColumnModel
}
/**
- * getSelectedColumns returns array containing indexes of currently
- * selected columns
+ * Returns an array containing the indices of the selected columns.
*
- * @return int[] array containing indexes of currently selected columns
+ * @return An array containing the indices of the selected columns.
*/
public int[] getSelectedColumns()
{
@@ -356,8 +423,11 @@ public class DefaultTableColumnModel
}
/**
- * getSelectedColumnCount returns number of currently selected columns
- * @return int number of currently selected columns
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
*/
public int getSelectedColumnCount()
{
@@ -395,10 +465,10 @@ public class DefaultTableColumnModel
}
/**
- * addColumnModelListener adds specified listener to the model's
- * listener list
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
*
- * @param listener the listener to add
+ * @param listener the listener (<code>null</code> ignored).
*/
public void addColumnModelListener(TableColumnModelListener listener)
{
@@ -406,10 +476,10 @@ public class DefaultTableColumnModel
}
/**
- * removeColumnModelListener removes specified listener from the model's
- * listener list.
+ * Deregisters a listener so that it no longer receives notification of
+ * changes to this model.
*
- * @param listener the listener to remove
+ * @param listener the listener to remove
*/
public void removeColumnModelListener(TableColumnModelListener listener)
{
@@ -417,6 +487,13 @@ public class DefaultTableColumnModel
}
/**
+ * Returns an array containing the listeners that are registered with the
+ * model. If there are no listeners, an empty array is returned.
+ *
+ * @return An array containing the listeners that are registered with the
+ * model.
+ *
+ * @see #addColumnModelListener(TableColumnModelListener)
* @since 1.4
*/
public TableColumnModelListener[] getColumnModelListeners()
@@ -426,78 +503,97 @@ public class DefaultTableColumnModel
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was added
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been added to the model. The
+ * event's <code>toIndex</code> attribute should contain the index of the
+ * added column.
+ *
+ * @param e the event.
+ *
+ * @see #addColumn(TableColumn)
*/
protected void fireColumnAdded(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnAdded(e);
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was removed
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been removed from the model. The
+ * event's <code>fromIndex</code> attribute should contain the index of the
+ * removed column.
+ *
+ * @param e the event.
+ *
+ * @see #removeColumn(TableColumn)
*/
protected void fireColumnRemoved(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnRemoved(e);
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was moved
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column in the model has been moved. The
+ * event's <code>fromIndex</code> attribute should contain the old column
+ * index, and the <code>toIndex</code> attribute should contain the new
+ * column index.
+ *
+ * @param e the event.
+ *
+ * @see #moveColumn(int, int)
*/
protected void fireColumnMoved(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnMoved(e);
}
/**
- * fireColumnSelectionChanged fires TableColumnModelEvent to model's
- * registered TableColumnModelListeners to indicate that different column
- * was selected.
+ * Sends the specified {@link ListSelectionEvent} to all registered listeners,
+ * to indicate that the column selections have changed.
*
- * @param evt ListSelectionEvent
+ * @param e the event.
+ *
+ * @see #valueChanged(ListSelectionEvent)
*/
- protected void fireColumnSelectionChanged(ListSelectionEvent evt)
+ protected void fireColumnSelectionChanged(ListSelectionEvent e)
{
EventListener [] listeners = getListeners(TableColumnModelListener.class);
for (int i = 0; i < listeners.length; ++i)
- ((TableColumnModelListener)listeners[i]).columnSelectionChanged(evt);
+ ((TableColumnModelListener) listeners[i]).columnSelectionChanged(e);
}
/**
- * fireColumnMarginChanged fires TableColumnModelEvent to model's
- * registered TableColumnModelListeners to indicate that column margin
- * was changed.
+ * Sends a {@link ChangeEvent} to the model's registered listeners to
+ * indicate that the column margin was changed.
+ *
+ * @see #setColumnMargin(int)
*/
protected void fireColumnMarginChanged()
{
EventListener [] listeners = getListeners(TableColumnModelListener.class);
for (int i = 0; i < listeners.length; ++i)
- ((TableColumnModelListener)listeners[i]).columnMarginChanged(changeEvent);
+ ((TableColumnModelListener) listeners[i]).columnMarginChanged(changeEvent);
}
/**
- * getListeners returns currently registered listeners with this model.
- * @param listenerType type of listeners to return
+ * Returns an array containing the listeners (of the specified type) that
+ * are registered with this model.
+ *
+ * @param listenerType the listener type (must indicate a subclass of
+ * {@link EventListener}, <code>null</code> not permitted).
*
- * @return EventListener[] array of model's listeners of the specified type
+ * @return An array containing the listeners (of the specified type) that
+ * are registered with this model.
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
@@ -505,20 +601,26 @@ public class DefaultTableColumnModel
}
/**
- * propertyChange handles changes occuring in the properties of the
- * model's columns.
+ * Receives notification of property changes for the columns in the model.
+ * If the <code>width</code> property for any column changes, we invalidate
+ * the {@link #totalColumnWidth} value here.
*
- * @param evt PropertyChangeEvent
+ * @param event the event.
*/
- public void propertyChange(PropertyChangeEvent evt)
+ public void propertyChange(PropertyChangeEvent event)
{
- if (evt.getPropertyName().equals(TableColumn.COLUMN_WIDTH_PROPERTY))
- invalidateWidthCache();
+ if (event.getPropertyName().equals("width"))
+ invalidateWidthCache();
}
/**
- * valueChanged handles changes in the selectionModel.
- * @param e ListSelectionEvent
+ * Receives notification of the change to the list selection model, and
+ * responds by calling
+ * {@link #fireColumnSelectionChanged(ListSelectionEvent)}.
+ *
+ * @param e the list selection event.
+ *
+ * @see #getSelectionModel()
*/
public void valueChanged(ListSelectionEvent e)
{
@@ -526,10 +628,11 @@ public class DefaultTableColumnModel
}
/**
- * createSelectionModel creates selection model that will keep track
- * of currently selected column(s)
+ * Creates a default selection model to track the currently selected
+ * column(s). This method is called by the constructor and returns a new
+ * instance of {@link DefaultListSelectionModel}.
*
- * @return ListSelectionModel selection model of the columns
+ * @return A new default column selection model.
*/
protected ListSelectionModel createSelectionModel()
{
@@ -537,9 +640,10 @@ public class DefaultTableColumnModel
}
/**
- * recalcWidthCache calculates total width of the columns.
- * If the current cache of the total width is in invalidated state,
- * then width is recalculated. Otherwise nothing is done.
+ * Recalculates the total width of the columns, if the cached value is
+ * <code>-1</code>. Otherwise this method does nothing.
+ *
+ * @see #getTotalColumnWidth()
*/
protected void recalcWidthCache()
{
@@ -548,13 +652,15 @@ public class DefaultTableColumnModel
totalColumnWidth = 0;
for (int i = 0; i < tableColumns.size(); ++i)
{
- totalColumnWidth += ((TableColumn)tableColumns.get(i)).getWidth();
+ totalColumnWidth += ((TableColumn) tableColumns.get(i)).getWidth();
}
}
}
/**
- * invalidateWidthCache
+ * Sets the {@link #totalColumnWidth} field to <code>-1</code>.
+ *
+ * @see #recalcWidthCache()
*/
private void invalidateWidthCache()
{
diff --git a/javax/swing/table/TableColumnModel.java b/javax/swing/table/TableColumnModel.java
index 66f52e619..7e8a70c3a 100644
--- a/javax/swing/table/TableColumnModel.java
+++ b/javax/swing/table/TableColumnModel.java
@@ -1,5 +1,5 @@
/* TableColumnModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,8 @@ import java.util.Enumeration;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
/**
@@ -50,7 +52,6 @@ import javax.swing.event.TableColumnModelListener;
*
* @author Andrew Selkirk
*/
-// FIXME: The API documentation in this class is incomplete.
public interface TableColumnModel
{
/**
@@ -80,21 +81,26 @@ public interface TableColumnModel
void moveColumn(int columnIndex, int newIndex);
/**
- * setColumnMargin
- * @param margin Margin of column
+ * Sets the column margin and sends a {@link ChangeEvent} to all registered
+ * {@link TableColumnModelListener}s registered with the model.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
*/
void setColumnMargin(int margin);
/**
* Returns the number of columns in the model.
*
- * @return The column count
+ * @return The column count.
*/
int getColumnCount();
/**
- * getColumns
- * @return Enumeration of columns
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
*/
Enumeration<TableColumn> getColumns();
@@ -123,30 +129,53 @@ public interface TableColumnModel
* Returns the column margin.
*
* @return The column margin.
+ *
+ * @see #setColumnMargin(int)
*/
int getColumnMargin();
/**
- * getColumnIndexAtX
- * @return Column index as position x
+ * Returns the index of the column that contains the specified x-coordinate,
+ * assuming that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param xPosition the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
*/
int getColumnIndexAtX(int xPosition);
/**
- * getTotalColumnWidth
- * @return Total column width
+ * Returns total width of all the columns in the model, ignoring the
+ * column margin (see {@link #getColumnMargin()}).
+ *
+ * @return The total width of all the columns.
*/
int getTotalColumnWidth();
/**
- * setColumnSelectionAllowed
- * @param value Set column selection
+ * Sets the flag that indicates whether or not column selection is allowed.
+ *
+ * @param allowed the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
*/
- void setColumnSelectionAllowed(boolean value);
+ void setColumnSelectionAllowed(boolean allowed);
/**
- * getColumnSelectionAllowed
- * @return true if column selection allowed, false otherwise
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
+ *
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
*/
boolean getColumnSelectionAllowed();
@@ -157,31 +186,47 @@ public interface TableColumnModel
int[] getSelectedColumns();
/**
- * getSelectedColumnCount
- * @return Count of selected columns
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
*/
int getSelectedColumnCount();
/**
- * setSelectionModel
- * @param model ListSelectionModel
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
+ *
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
*/
void setSelectionModel(ListSelectionModel model);
/**
- * getSelectionModel
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
*/
ListSelectionModel getSelectionModel();
/**
- * addColumnModelListener
- * @param listener TableColumnModelListener
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener (<code>null</code> ignored).
*/
void addColumnModelListener(TableColumnModelListener listener);
/**
- * removeColumnModelListener
- * @param listener TableColumnModelListener
+ * Deregisters a listener, so that it will no longer receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener.
*/
void removeColumnModelListener(TableColumnModelListener listener);
}
diff --git a/javax/swing/text/AbstractDocument.java b/javax/swing/text/AbstractDocument.java
index e656e7e9c..bb065044d 100644
--- a/javax/swing/text/AbstractDocument.java
+++ b/javax/swing/text/AbstractDocument.java
@@ -51,6 +51,7 @@ import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
+import javax.swing.text.DocumentFilter;
import javax.swing.tree.TreeNode;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CompoundEdit;
@@ -148,6 +149,11 @@ public abstract class AbstractDocument implements Document, Serializable
*/
Object documentCV = new Object();
+ /** An instance of a DocumentFilter.FilterBypass which allows calling
+ * the insert, remove and replace method without checking for an installed
+ * document filter.
+ */
+ DocumentFilter.FilterBypass bypass;
/**
* Creates a new <code>AbstractDocument</code> with the specified
@@ -180,6 +186,19 @@ public abstract class AbstractDocument implements Document, Serializable
content = doc;
context = ctx;
}
+
+ /** Returns the DocumentFilter.FilterBypass instance for this
+ * document and create it if it does not exist yet.
+ *
+ * @return This document's DocumentFilter.FilterBypass instance.
+ */
+ private DocumentFilter.FilterBypass getBypass()
+ {
+ if (bypass == null)
+ bypass = new Bypass();
+
+ return bypass;
+ }
/**
* Returns the paragraph {@link Element} that holds the specified position.
@@ -521,6 +540,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Inserts a String into this <code>Document</code> at the specified
* position and assigning the specified attributes to it.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the location at which the string should be inserted
* @param text the content to be inserted
@@ -532,6 +554,15 @@ public abstract class AbstractDocument implements Document, Serializable
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
+ if (documentFilter != null)
+ documentFilter.insertString(getBypass(), offset, text, attributes);
+ else
+ insertStringImpl(offset, text, attributes);
+ }
+
+ void insertStringImpl(int offset, String text, AttributeSet attributes)
+ throws BadLocationException
+ {
// Just return when no text to insert was given.
if (text == null || text.length() == 0)
return;
@@ -673,6 +704,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Removes a piece of content from this <code>Document</code>.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -683,6 +717,14 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void remove(int offset, int length) throws BadLocationException
{
+ if (documentFilter != null)
+ documentFilter.remove(getBypass(), offset, length);
+ else
+ removeImpl(offset, length);
+ }
+
+ void removeImpl(int offset, int length) throws BadLocationException
+ {
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.REMOVE);
@@ -707,6 +749,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Replaces a piece of content in this <code>Document</code> with
* another piece of content.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -720,11 +765,21 @@ public abstract class AbstractDocument implements Document, Serializable
* @since 1.4
*/
public void replace(int offset, int length, String text,
+ AttributeSet attributes)
+ throws BadLocationException
+ {
+ if (documentFilter != null)
+ documentFilter.replace(getBypass(), offset, length, text, attributes);
+ else
+ replaceImpl(offset, length, text, attributes);
+ }
+
+ void replaceImpl(int offset, int length, String text,
AttributeSet attributes)
throws BadLocationException
{
- remove(offset, length);
- insertString(offset, text, attributes);
+ removeImpl(offset, length);
+ insertStringImpl(offset, text, attributes);
}
/**
@@ -2239,4 +2294,37 @@ public abstract class AbstractDocument implements Document, Serializable
+ getStartOffset() + "," + getEndOffset() + "\n");
}
}
+
+ /** A class whose methods delegate to the insert, remove and replace methods
+ * of this document which do not check for an installed DocumentFilter.
+ */
+ class Bypass extends DocumentFilter.FilterBypass
+ {
+
+ public Document getDocument()
+ {
+ return AbstractDocument.this;
+ }
+
+ public void insertString(int offset, String string, AttributeSet attr)
+ throws BadLocationException
+ {
+ AbstractDocument.this.insertStringImpl(offset, string, attr);
+ }
+
+ public void remove(int offset, int length)
+ throws BadLocationException
+ {
+ AbstractDocument.this.removeImpl(offset, length);
+ }
+
+ public void replace(int offset, int length, String string,
+ AttributeSet attrs)
+ throws BadLocationException
+ {
+ AbstractDocument.this.replaceImpl(offset, length, string, attrs);
+ }
+
+ }
+
}
diff --git a/javax/swing/text/AsyncBoxView.java b/javax/swing/text/AsyncBoxView.java
index 863c409ed..90447f86e 100644
--- a/javax/swing/text/AsyncBoxView.java
+++ b/javax/swing/text/AsyncBoxView.java
@@ -1367,7 +1367,7 @@ public class AsyncBoxView
/**
* Updates the layout for this view. This is implemented to trigger
- * {link ChildLocator#childChanged} for the changed view, if there is
+ * {@link ChildLocator#childChanged} for the changed view, if there is
* any.
*
* @param ec the element change, may be <code>null</code> if there were
diff --git a/javax/swing/text/CompositeView.java b/javax/swing/text/CompositeView.java
index 9195602ce..17f13dbed 100644
--- a/javax/swing/text/CompositeView.java
+++ b/javax/swing/text/CompositeView.java
@@ -633,8 +633,51 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is NORTH chose the View preceding the one that contains the
+ // offset 'pos' (imagine the views are stacked on top of each other where
+ // the top is 0 and the bottom is getViewCount()-1.
+ // Consecutively when the direction is SOUTH the View following the one
+ // the offset 'pos' lies in is questioned.
+ //
+ // This limitation is described as PR 27345.
+ int index = getViewIndex(pos, b);
+ View v = null;
+
+ if (index == -1)
+ return pos;
+
+ switch (direction)
+ {
+ case NORTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index <= 0)
+ return pos;
+
+ v = getView(index - 1);
+ break;
+ case SOUTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index >= getViewCount() - 1)
+ return pos;
+
+ v = getView(index + 1);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos, b, a, direction, biasRet);
}
/**
@@ -667,8 +710,55 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is EAST increase the offset by one and ask the View to
+ // which that index belong to calculate the 'next visual position'.
+ // If the direction is WEST do the same with offset 'pos' being decreased
+ // by one.
+ // This behavior will fail in a right-to-left or bidi environment!
+ //
+ // This limitation is described as PR 27346.
+ int index;
+
+ View v = null;
+
+ switch (direction)
+ {
+ case EAST:
+ index = getViewIndex(pos + 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ case WEST:
+ index = getViewIndex(pos - 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos,
+ b,
+ a,
+ direction,
+ biasRet);
}
/**
diff --git a/javax/swing/text/DefaultCaret.java b/javax/swing/text/DefaultCaret.java
index 9b6cd6b07..fc2aca0a0 100644
--- a/javax/swing/text/DefaultCaret.java
+++ b/javax/swing/text/DefaultCaret.java
@@ -59,6 +59,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
+import javax.swing.text.Position.Bias;
/**
* The default implementation of the {@link Caret} interface.
@@ -75,6 +76,31 @@ public class DefaultCaret extends Rectangle
*/
static JTextComponent componentWithSelection;
+ /** An implementation of NavigationFilter.FilterBypass which delegates
+ * to the corresponding methods of the <code>DefaultCaret</code>.
+ *
+ * @author Robert Schuster (robertschuster@fsfe.org)
+ */
+ class Bypass extends NavigationFilter.FilterBypass
+ {
+
+ public Caret getCaret()
+ {
+ return DefaultCaret.this;
+ }
+
+ public void moveDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.moveDotImpl(dot);
+ }
+
+ public void setDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.setDotImpl(dot);
+ }
+
+ }
+
/**
* Controls the blinking of the caret.
*
@@ -299,12 +325,29 @@ public class DefaultCaret extends Rectangle
private BlinkTimerListener blinkListener;
/**
+ * A <code>NavigationFilter.FilterBypass</code> instance which
+ * is provided to the a <code>NavigationFilter</code> to
+ * unconditionally set or move the caret.
+ */
+ NavigationFilter.FilterBypass bypass;
+
+ /**
* Creates a new <code>DefaultCaret</code> instance.
*/
public DefaultCaret()
{
// Nothing to do here.
}
+
+ /** Returns the caret's <code>NavigationFilter.FilterBypass</code> instance
+ * and creates it if it does not yet exist.
+ *
+ * @return The caret's <code>NavigationFilter.FilterBypass</code> instance.
+ */
+ private NavigationFilter.FilterBypass getBypass()
+ {
+ return (bypass == null) ? bypass = new Bypass() : bypass;
+ }
/**
* Sets the Caret update policy.
@@ -946,12 +989,24 @@ public class DefaultCaret extends Rectangle
* Moves the <code>dot</code> location without touching the
* <code>mark</code>. This is used when making a selection.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot the location where to move the dot
*
* @see #setDot(int)
*/
public void moveDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.moveDot(getBypass(), dot, Bias.Forward);
+ else
+ moveDotImpl(dot);
+ }
+
+ void moveDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -970,12 +1025,24 @@ public class DefaultCaret extends Rectangle
* <code>Document</code>. This also sets the <code>mark</code> to the new
* location.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot
* the new position to be set
* @see #moveDot(int)
*/
public void setDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.setDot(getBypass(), dot, Bias.Forward);
+ else
+ setDotImpl(dot);
+ }
+
+ void setDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -1135,4 +1202,5 @@ public class DefaultCaret extends Rectangle
blinkTimer = new Timer(getBlinkRate(), blinkListener);
blinkTimer.setRepeats(true);
}
+
}
diff --git a/javax/swing/text/DefaultHighlighter.java b/javax/swing/text/DefaultHighlighter.java
index 58602c249..59f77316e 100644
--- a/javax/swing/text/DefaultHighlighter.java
+++ b/javax/swing/text/DefaultHighlighter.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
@@ -45,6 +47,7 @@ import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
+import javax.swing.SwingUtilities;
import javax.swing.plaf.TextUI;
public class DefaultHighlighter extends LayeredHighlighter
@@ -91,8 +94,18 @@ public class DefaultHighlighter extends LayeredHighlighter
Rectangle l0 = ui.modelToView(t, p0, null);
Rectangle l1 = ui.modelToView(t, p1, null);
+ // Note: The computed locations may lie outside of the allocation
+ // area if the text is scrolled.
+
if (l0.y == l1.y)
- paintHighlight(g, l0.union(l1));
+ {
+ SwingUtilities.computeUnion(l0.x, l0.y, l0.width, l0.height, l1);
+
+ // Paint only inside the allocation area.
+ SwingUtilities.computeIntersection(rect.x, rect.y, rect.width, rect.height, l1);
+
+ paintHighlight(g, l1);
+ }
else
{
// 1. The line of p0 is painted from the position of p0
@@ -104,7 +117,11 @@ public class DefaultHighlighter extends LayeredHighlighter
// position of p1.
// Highlight first line until the end.
- l0.width = rect.width - l0.x;
+ // If rect.x is non-zero the calculation will properly adjust the
+ // area to be painted.
+ l0.x -= rect.x;
+ l0.width = rect.width - l0.x - rect.x;
+
paintHighlight(g, l0);
int posBelow = Utilities.getPositionBelow(t, p0, l0.x);
@@ -358,6 +375,7 @@ public class DefaultHighlighter extends LayeredHighlighter
public void paintLayeredHighlights(Graphics g, int p0, int p1,
Shape viewBounds, JTextComponent editor,
View view)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/text/FieldView.java b/javax/swing/text/FieldView.java
index 928949b56..127f32f53 100644
--- a/javax/swing/text/FieldView.java
+++ b/javax/swing/text/FieldView.java
@@ -236,8 +236,13 @@ public class FieldView extends PlainView
checkContainer();
Shape newAlloc = adjustAllocation(s);
-
+
+ // Set a clip to prevent drawing outside of the allocation area.
+ // TODO: Is there a better way to achieve this?
+ Shape clip = g.getClip();
+ g.setClip(s);
super.paint(g, newAlloc);
+ g.setClip(clip);
}
public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
diff --git a/javax/swing/text/FlowView.java b/javax/swing/text/FlowView.java
index 8be8f41e9..8ca55d834 100644
--- a/javax/swing/text/FlowView.java
+++ b/javax/swing/text/FlowView.java
@@ -433,7 +433,7 @@ public abstract class FlowView extends BoxView
/**
* Loads the children of this view. The <code>FlowView</code> does not
* directly load its children. Instead it creates a logical view
- * (@{link #layoutPool}) which is filled by the logical child views.
+ * ({@link #layoutPool}) which is filled by the logical child views.
* The real children are created at layout time and each represent one
* row.
*
diff --git a/javax/swing/text/Utilities.java b/javax/swing/text/Utilities.java
index 3149048f7..f154e55aa 100644
--- a/javax/swing/text/Utilities.java
+++ b/javax/swing/text/Utilities.java
@@ -48,6 +48,7 @@ import java.text.BreakIterator;
* inside this package.
*
* @author Roman Kennke (roman@ontographics.com)
+ * @author Robert Schuster (robertschuster@fsfe.org)
*/
public class Utilities
{
@@ -238,34 +239,39 @@ public class Utilities
// At the end of the for loop, this holds the requested model location
int pos;
int currentX = x0;
+ int width = 0;
for (pos = 0; pos < s.count; pos++)
{
char nextChar = s.array[s.offset+pos];
if (nextChar == 0)
- {
- if (! round && pos > 0)
- pos--;
break;
- }
+
if (nextChar != '\t')
- currentX += fm.charWidth(nextChar);
+ width = fm.charWidth(nextChar);
else
{
if (te == null)
- currentX += fm.charWidth(' ');
+ width = fm.charWidth(' ');
else
- currentX = (int) te.nextTabStop(currentX, pos);
+ width = ((int) te.nextTabStop(currentX, pos)) - currentX;
}
- if (currentX >= x)
+ if (round)
{
- if (! round && pos > 0)
- pos--;
- break;
+ if (currentX + (width>>1) > x)
+ break;
}
+ else
+ {
+ if (currentX + width > x)
+ break;
+ }
+
+ currentX += width;
}
+
return pos + p0;
}
@@ -316,21 +322,31 @@ public class Utilities
String text = c.getText();
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
+
int last = wb.following(offs);
int current = wb.next();
+ int cp;
+
while (current != BreakIterator.DONE)
{
for (int i = last; i < current; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ cp = text.codePointAt(i);
+
+ // Return the last found bound if there is a letter at the current
+ // location or is not whitespace (meaning it is a number or
+ // punctuation). The first case means that 'last' denotes the
+ // beginning of a word while the second case means it is the start
+ // of some else.
+ if (Character.isLetter(cp)
+ || !Character.isWhitespace(cp))
return last;
}
last = current;
current = wb.next();
}
- return BreakIterator.DONE;
+
+ throw new BadLocationException("no more word", offs);
}
/**
@@ -359,9 +375,7 @@ public class Utilities
{
for (int i = last; i < offs; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ if (Character.isLetter(text.codePointAt(i)))
return last;
}
last = current;
@@ -511,24 +525,28 @@ public class Utilities
int x0, int x, TabExpander e,
int startOffset)
{
- int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset);
+ int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset, false);
BreakIterator breaker = BreakIterator.getWordInstance();
breaker.setText(s);
- // If mark is equal to the end of the string, just use that position
- if (mark >= s.count)
+ // If startOffset and s.offset differ then we need to use
+ // that difference two convert the offset between the two metrics.
+ int shift = startOffset - s.offset;
+
+ // If mark is equal to the end of the string, just use that position.
+ if (mark >= shift + s.count)
return mark;
// Try to find a word boundary previous to the mark at which we
- // can break the text
- int preceding = breaker.preceding(mark + 1);
+ // can break the text.
+ int preceding = breaker.preceding(mark + 1 - shift);
if (preceding != 0)
- return preceding;
- else
- // If preceding is 0 we couldn't find a suitable word-boundary so
- // just break it on the character boundary
- return mark;
+ return preceding + shift;
+
+ // If preceding is 0 we couldn't find a suitable word-boundary so
+ // just break it on the character boundary
+ return mark;
}
/**
diff --git a/javax/swing/text/View.java b/javax/swing/text/View.java
index 2feaf29a4..d8ad5f585 100644
--- a/javax/swing/text/View.java
+++ b/javax/swing/text/View.java
@@ -1,5 +1,5 @@
/* View.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -733,23 +733,38 @@ public abstract class View implements SwingConstants
throws BadLocationException
{
int ret = pos;
+ Rectangle r;
+ View parent;
+
switch (d)
{
- case WEST:
- ret = pos - 1;
- break;
case EAST:
- ret = pos + 1;
+ // TODO: take component orientation into account?
+ // Note: If pos is below zero the implementation will return
+ // pos + 1 regardless of whether that value is a correct offset
+ // in the document model. However this is what the RI does.
+ ret = Math.min(pos + 1, getEndOffset());
+ break;
+ case WEST:
+ // TODO: take component orientation into account?
+ ret = Math.max(pos - 1, getStartOffset());
break;
case NORTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area above.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x, r.y - 1, a, biasRet);
break;
case SOUTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area below.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
break;
default:
throw new IllegalArgumentException("Illegal value for d");
}
+
return ret;
}
}
diff --git a/javax/swing/text/WrappedPlainView.java b/javax/swing/text/WrappedPlainView.java
index 9477f23f7..1cd85b515 100644
--- a/javax/swing/text/WrappedPlainView.java
+++ b/javax/swing/text/WrappedPlainView.java
@@ -275,7 +275,17 @@ public class WrappedPlainView extends BoxView implements TabExpander
protected int calculateBreakPosition(int p0, int p1)
{
Container c = getContainer();
- Rectangle alloc = new Rectangle(0, 0, getWidth(), getHeight());
+
+ int li = getLeftInset();
+ int ti = getTopInset();
+
+ Rectangle alloc = new Rectangle(li, ti,
+ getWidth()-getRightInset()-li,
+ getHeight()-getBottomInset()-ti);
+
+ // Mimic a behavior observed in the RI.
+ if (alloc.isEmpty())
+ return 0;
updateMetrics();
@@ -288,10 +298,10 @@ public class WrappedPlainView extends BoxView implements TabExpander
// this shouldn't happen
throw new InternalError("Invalid offsets p0: " + p0 + " - p1: " + p1);
}
- // FIXME: Should we account for the insets of the container?
+
if (wordWrap)
- return p0 + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
- alloc.x + alloc.width, this, 0);
+ return Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, p0);
else
return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
alloc.x + alloc.width, this, 0,
@@ -419,7 +429,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
class WrappedLine extends View
{
/** Used to cache the number of lines for this View **/
- int numLines;
+ int numLines = 1;
public WrappedLine(Element elem)
{
@@ -437,17 +447,30 @@ public class WrappedPlainView extends BoxView implements TabExpander
int end = getEndOffset();
int currStart = getStartOffset();
- int currEnd;
+ int currEnd;
+ int count = 0;
while (currStart < end)
{
currEnd = calculateBreakPosition(currStart, end);
+
drawLine(currStart, currEnd, g, rect.x, rect.y + metrics.getAscent());
+
rect.y += lineHeight;
if (currEnd == currStart)
currStart ++;
else
- currStart = currEnd;
+ currStart = currEnd;
+
+ count++;
+
+ }
+
+ if (count != numLines)
+ {
+ numLines = count;
+ preferenceChanged(this, false, true);
}
+
}
/**
@@ -470,6 +493,9 @@ public class WrappedPlainView extends BoxView implements TabExpander
// depending on which position calculateBreakPosition returns
breakPoint = calculateBreakPosition(i, end);
+ if (breakPoint == 0)
+ return;
+
// If breakPoint is equal to the current index no further
// line is needed and we can end the loop.
if (breakPoint == i)
@@ -492,7 +518,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
if (axis == X_AXIS)
return getWidth();
else if (axis == Y_AXIS)
- return numLines * metrics.getHeight();
+ return numLines * metrics.getHeight();
throw new IllegalArgumentException("Invalid axis for getPreferredSpan: "
+ axis);
@@ -578,13 +604,15 @@ public class WrappedPlainView extends BoxView implements TabExpander
Rectangle rect = a.getBounds();
int currLineStart = getStartOffset();
- // WrappedLine does not represent the last possible offset in a line.
- // So we should never return that offset. Behavior observed in the RI.
- int end = getEndOffset() - 1;
+ // Although calling modelToView with the last possible offset will
+ // cause a BadLocationException in CompositeView it is allowed
+ // to return that offset in viewToModel.
+ int end = getEndOffset();
int lineHeight = metrics.getHeight();
if (y < rect.y)
return currLineStart;
+
if (y > rect.y + rect.height)
return end;
@@ -592,9 +620,10 @@ public class WrappedPlainView extends BoxView implements TabExpander
// text but the area where text *may* be painted. This means the width
// is most of the time identical to the component's width.
- while (true)
+ while (currLineStart != end)
{
int currLineEnd = calculateBreakPosition(currLineStart, end);
+
// If we're at the right y-position that means we're on the right
// logical line and we should look for the character
if (y >= rect.y && y < rect.y + lineHeight)
@@ -608,18 +637,27 @@ public class WrappedPlainView extends BoxView implements TabExpander
// Shouldn't happen
}
- return Utilities.getTabbedTextOffset(s, metrics, rect.x,
+ int offset = Utilities.getTabbedTextOffset(s, metrics, rect.x,
(int) x,
WrappedPlainView.this,
currLineStart);
+ // If the calculated offset is the end of the line (in the
+ // document (= start of the next line) return the preceding
+ // offset instead. This makes sure that clicking right besides
+ // the last character in a line positions the cursor after the
+ // last character and not in the beginning of the next line.
+ return (offset == currLineEnd) ? offset - 1 : offset;
}
// Increment rect.y so we're checking the next logical line
rect.y += lineHeight;
// Increment currLineStart to the model position of the start
- // of the next logical line
+ // of the next logical line.
currLineStart = currLineEnd;
+
}
+
+ return end;
}
/**
@@ -632,6 +670,16 @@ public class WrappedPlainView extends BoxView implements TabExpander
*/
void updateDamage (Rectangle a)
{
+ // If the allocation area is empty we can't do anything useful.
+ // As determining the number of lines is impossible in that state we
+ // reset it to an invalid value which can then be recalculated at a
+ // later point.
+ if (a.isEmpty())
+ {
+ numLines = 1;
+ return;
+ }
+
int oldNumLines = numLines;
determineNumLines();
diff --git a/javax/swing/tree/AbstractLayoutCache.java b/javax/swing/tree/AbstractLayoutCache.java
index 445aa233e..713c9cae7 100644
--- a/javax/swing/tree/AbstractLayoutCache.java
+++ b/javax/swing/tree/AbstractLayoutCache.java
@@ -44,6 +44,7 @@ import java.awt.Rectangle;
import java.util.Enumeration;
import javax.swing.event.TreeModelEvent;
+import javax.swing.tree.VariableHeightLayoutCache.NodeRecord;
/**
* class AbstractLayoutCache
@@ -66,19 +67,21 @@ public abstract class AbstractLayoutCache
// Do nothing here.
}
- /**
- * getNodeDimensions
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- * @return Rectangle
- */
- public abstract Rectangle getNodeDimensions(Object value0, int value1,
- int value2, boolean value3,
- Rectangle value4);
+ /**
+ * Get the node dimensions. The NodeDimensions property must be set (unless
+ * the method is overridden, like if {@link FixedHeightLayoutCache}. If the
+ * method is not overridden and the property is not set, the InternalError is
+ * thrown.
+ *
+ * @param value the last node in the path
+ * @param row the node row
+ * @param depth the indentation depth
+ * @param expanded true if this node is expanded, false otherwise
+ * @param bounds the area where the tree is displayed
+ */
+ public abstract Rectangle getNodeDimensions(Object value, int row,
+ int depth, boolean expanded,
+ Rectangle bounds);
}
/**
@@ -204,6 +207,7 @@ public abstract class AbstractLayoutCache
public void setRowHeight(int height)
{
rowHeight = height;
+ invalidateSizes();
}
/**
@@ -237,29 +241,51 @@ public abstract class AbstractLayoutCache
}
/**
- * getPreferredHeight
- *
- * @return int
+ * Get the sum of heights for all rows. This class provides a general not
+ * optimized implementation that is overridded in derived classes
+ * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for
+ * the better performance.
*/
- public int getPreferredHeight()
- throws NotImplementedException
+ public int getPreferredHeight()
{
- return 0; // TODO
+ int height = 0;
+ int n = getRowCount();
+ Rectangle r = new Rectangle();
+ for (int i = 0; i < n; i++)
+ {
+ TreePath path = getPathForRow(i);
+ height += getBounds(path, r).height;
+ }
+ return height;
}
/**
- * getPreferredWidth
+ * Get the maximal width. This class provides a general not
+ * optimized implementation that is overridded in derived classes
+ * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for
+ * the better performance.
*
- * @param value0 TODO
- *
- * @return int
+ * @param rect the rectangle that is used during the method work
*/
- public int getPreferredWidth(Rectangle value0)
- throws NotImplementedException
+ public int getPreferredWidth(Rectangle rect)
{
- return 0; // TODO
+ int maximalWidth = 0;
+ Rectangle r = new Rectangle();
+ int n = getRowCount();
+ for (int i = 0; i < n; i++)
+ {
+ TreePath path = getPathForRow(i);
+ r.setBounds(0,0,0,0);
+ r = getBounds(path, r);
+ if (r.x + r.width > maximalWidth)
+ maximalWidth = r.x + r.width;
+ // Invalidate the cached value as this may be the very early call
+ // before the heigth is properly set (the vertical coordinate may
+ // not be correct).
+ invalidatePathBounds(path);
+ }
+ return maximalWidth;
}
-
/**
* isExpanded
*
@@ -409,13 +435,14 @@ public abstract class AbstractLayoutCache
}
/**
- * isFixedRowHeight
+ * Returns true if this layout supposes that all rows have the fixed
+ * height.
*
- * @return boolean
+ * @return boolean true if all rows in the tree must have the fixed
+ * height (false by default).
*/
protected boolean isFixedRowHeight()
- throws NotImplementedException
{
- return false; // TODO
+ return false;
}
}
diff --git a/javax/swing/tree/DefaultMutableTreeNode.java b/javax/swing/tree/DefaultMutableTreeNode.java
index 3569ebdbb..389101be1 100644
--- a/javax/swing/tree/DefaultMutableTreeNode.java
+++ b/javax/swing/tree/DefaultMutableTreeNode.java
@@ -154,6 +154,8 @@ public class DefaultMutableTreeNode
/**
* Adds a new child node to this node and sets this node as the parent of
* the child node. The child node must not be an ancestor of this node.
+ * If the tree uses the {@link DefaultTreeModel}, you must subsequently
+ * call {@link DefaultTreeModel#reload(TreeNode)}.
*
* @param child the child node (<code>null</code> not permitted).
*
diff --git a/javax/swing/tree/DefaultTreeCellEditor.java b/javax/swing/tree/DefaultTreeCellEditor.java
index e28c9261b..cc19501d2 100644
--- a/javax/swing/tree/DefaultTreeCellEditor.java
+++ b/javax/swing/tree/DefaultTreeCellEditor.java
@@ -77,17 +77,6 @@ public class DefaultTreeCellEditor
implements ActionListener, TreeCellEditor, TreeSelectionListener
{
/**
- * The gap between the icon and editing component during editing.
- */
- static int ICON_TEXT_GAP = 3;
-
- /**
- * The left margin of the editing container (the gap between the tree and
- * the editing component of the editing icon.
- */
- static int TREE_ICON_GAP = ICON_TEXT_GAP;
-
- /**
* The number of the fast mouse clicks, required to start the editing
* session.
*/
@@ -141,7 +130,7 @@ public class DefaultTreeCellEditor
{
// From the previous version, the left margin is taken as half
// of the icon width.
- editingIcon.paintIcon(this, g, TREE_ICON_GAP, 0);
+ editingIcon.paintIcon(this, g, 0, 0);
}
super.paint(g);
}
@@ -157,7 +146,7 @@ public class DefaultTreeCellEditor
// Move the component to the left, leaving room for the editing icon:
if (editingIcon != null)
- eOffset = TREE_ICON_GAP + editingIcon.getIconWidth() + ICON_TEXT_GAP;
+ eOffset = editingIcon.getIconWidth();
else
eOffset = 0;
@@ -166,7 +155,7 @@ public class DefaultTreeCellEditor
c.setLocation(eOffset, 0);
// Span the editing component near over all window width.
- c.setSize(bounds.width - eOffset - TREE_ICON_GAP, bounds.height);
+ c.setSize(bounds.width - eOffset, bounds.height);
/*
* @specnote the Sun sets some more narrow editing component width (it is
* not documented how does it is calculated). However as our text field is
@@ -542,7 +531,8 @@ public class DefaultTreeCellEditor
* 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
+ * @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)
diff --git a/javax/swing/tree/DefaultTreeCellRenderer.java b/javax/swing/tree/DefaultTreeCellRenderer.java
index df70ba7fb..5e93145ae 100644
--- a/javax/swing/tree/DefaultTreeCellRenderer.java
+++ b/javax/swing/tree/DefaultTreeCellRenderer.java
@@ -407,7 +407,7 @@ public class DefaultTreeCellRenderer
this.hasFocus = hasFocus;
setHorizontalAlignment(LEFT);
setOpaque(false);
- setVerticalAlignment(TOP);
+ setVerticalAlignment(CENTER);
setEnabled(true);
super.setFont(UIManager.getFont("Tree.font"));
@@ -445,8 +445,7 @@ public class DefaultTreeCellRenderer
/**
* Paints the value. The background is filled based on selected.
*
- * @param g
- * the graphics device.
+ * @param g the graphics device.
*/
public void paint(Graphics g)
{
@@ -468,17 +467,27 @@ public class DefaultTreeCellRenderer
getHorizontalTextPosition(), vr, ir, tr,
getIconTextGap());
+ // Reusing one rectangle.
+ Rectangle bounds = getBounds(ir);
+
+ bounds.x = tr.x - insets.left;
+ bounds.width = tr.width + insets.left+insets.right;
+
g.setColor(super.getBackground());
- g.fillRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
- // paint border
- Color b = getBorderSelectionColor();
- if (b != null)
+ super.paint(g);
+
+ // Paint the border of the focused element only (lead selection)
+ if (hasFocus)
{
- g.setColor(b);
- g.drawRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+ Color b = getBorderSelectionColor();
+ if (b != null)
+ {
+ g.setColor(b);
+ g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
+ }
}
- super.paint(g);
}
/**
diff --git a/javax/swing/tree/DefaultTreeModel.java b/javax/swing/tree/DefaultTreeModel.java
index e462b1c8b..713343811 100644
--- a/javax/swing/tree/DefaultTreeModel.java
+++ b/javax/swing/tree/DefaultTreeModel.java
@@ -223,27 +223,60 @@ public class DefaultTreeModel
}
/**
- * 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.
+ * <p>
+ * 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. It will fire the events, necessary to update the layout caches and
+ * repaint the tree. The tree will <i>not</i> be properly refreshed if you
+ * call the JTree.repaint instead.
+ * </p>
+ * <p>
+ * This method will refresh the information about whole tree from the root. If
+ * only part of the tree should be refreshed, it is more effective to call
+ * {@link #reload(TreeNode)}.
+ * </p>
*/
public void reload()
- throws NotImplementedException
{
- // TODO
+ // Need to duplicate the code because the root can formally be
+ // no an instance of the TreeNode.
+ int n = getChildCount(root);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(root, i);
+ }
+
+ fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
}
/**
- * 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.
+ * 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. It will fire the events, necessary to update the layout caches and
+ * repaint the tree. The tree will <i>not</i> be properly refreshed if you
+ * call the JTree.repaint instead.
*
- * @param node - TODO
+ * @param node - the tree node, from which the tree nodes have changed
+ * (inclusive). If you do not know this node, call {@link #reload()}
+ * instead.
*/
public void reload(TreeNode node)
- throws NotImplementedException
{
- // TODO
+ int n = getChildCount(node);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(node, i);
+ }
+
+ fireTreeStructureChanged(this, getPathToRoot(node), childIdx, children);
}
/**
@@ -392,9 +425,18 @@ public class DefaultTreeModel
* @param node that had its children and grandchildren changed.
*/
public void nodeStructureChanged(TreeNode node)
- throws NotImplementedException
{
- // TODO
+ int n = getChildCount(root);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(root, i);
+ }
+
+ fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
}
/**
diff --git a/javax/swing/tree/DefaultTreeSelectionModel.java b/javax/swing/tree/DefaultTreeSelectionModel.java
index f0e8f4932..e38850af8 100644
--- a/javax/swing/tree/DefaultTreeSelectionModel.java
+++ b/javax/swing/tree/DefaultTreeSelectionModel.java
@@ -38,14 +38,15 @@ exception statement from your version. */
package javax.swing.tree;
-import gnu.classpath.NotImplementedException;
-
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Vector;
import javax.swing.DefaultListSelectionModel;
@@ -61,6 +62,7 @@ import javax.swing.event.TreeSelectionListener;
* expansion events.
*
* @author Andrew Selkirk
+ * @author Audrius Meskauskas
*/
public class DefaultTreeSelectionModel
implements Cloneable, Serializable, TreeSelectionModel
@@ -145,19 +147,33 @@ public class DefaultTreeSelectionModel
// Clone the selection and the list selection model.
cloned.selection = (TreePath[]) selection.clone();
- cloned.listSelectionModel =
- (DefaultListSelectionModel) listSelectionModel.clone();
+ if (listSelectionModel!=null)
+ cloned.listSelectionModel =
+ (DefaultListSelectionModel) listSelectionModel.clone();
return cloned;
}
/**
* Returns a string that shows this object's properties.
+ * The returned string lists the selected tree rows, if any.
*
* @return a string that shows this object's properties
*/
- public String toString() throws NotImplementedException
+ public String toString()
{
- return null; // TODO
+ if (isSelectionEmpty())
+ return "[selection empty]";
+ else
+ {
+ StringBuffer b = new StringBuffer("selected rows: [");
+ for (int i = 0; i < selection.length; i++)
+ {
+ b.append(getRow(selection[i]));
+ b.append(' ');
+ }
+ b.append(", lead "+getLeadSelectionRow());
+ return b.toString();
+ }
}
/**
@@ -221,6 +237,7 @@ public class DefaultTreeSelectionModel
public void setSelectionMode(int mode)
{
selectionMode = mode;
+ insureRowContinuity();
}
/**
@@ -245,7 +262,60 @@ public class DefaultTreeSelectionModel
*/
public void setSelectionPath(TreePath path)
{
+ // The most frequently only one cell in the tree is selected.
+ TreePath[] ose = selection;
selection = new TreePath[] { path };
+ TreePath oldLead = leadPath;
+ leadIndex = 0;
+ leadRow = getRow(path);
+ leadPath = path;
+
+ TreeSelectionEvent event;
+
+ if (ose != null && ose.length > 0)
+ {
+ // The first item in the path list is the selected path.
+ // The remaining items are unselected pathes.
+ TreePath[] changed = new TreePath[ose.length + 1];
+ boolean[] news = new boolean[changed.length];
+ news[0] = true;
+ changed[0] = path;
+ System.arraycopy(ose, 0, changed, 1, ose.length);
+ event = new TreeSelectionEvent(this, changed, news, oldLead, path);
+ }
+ else
+ {
+ event = new TreeSelectionEvent(this, path, true, oldLead, path);
+ }
+ fireValueChanged(event);
+ }
+
+ /**
+ * Get the number of the tree row for the given path.
+ *
+ * @param path the tree path
+ * @return the tree row for this path or -1 if the path is not visible.
+ */
+ int getRow(TreePath path)
+ {
+ RowMapper mapper = getRowMapper();
+
+ if (mapper instanceof AbstractLayoutCache)
+ {
+ // The absolute majority of cases, unless the TreeUI is very
+ // seriously rewritten
+ AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
+ return ama.getRowForPath(path);
+ }
+ else
+ {
+ // Generic non optimized implementation.
+ int[] rows = mapper.getRowsForPaths(new TreePath[] { path });
+ if (rows.length == 0)
+ return - 1;
+ else
+ return rows[0];
+ }
}
/**
@@ -256,11 +326,11 @@ public class DefaultTreeSelectionModel
* @param paths the paths to set as selection
*/
public void setSelectionPaths(TreePath[] paths)
- throws NotImplementedException
{
// Must be called, as defined in JDK API 1.4.
insureUniqueness();
- // TODO
+ clearSelection();
+ addSelectionPaths(paths);
}
/**
@@ -268,13 +338,17 @@ public class DefaultTreeSelectionModel
* is already selected and doesn't add the same path twice. If this changes
* the selection the registered TreeSelectionListeners are notified.
*
+ * The lead path is changed to the added path. This also happen if the
+ * passed path was already selected before.
+ *
* @param path the path to add to the selection
*/
public void addSelectionPath(TreePath path)
{
if (! isPathSelected(path))
{
- if (isSelectionEmpty())
+ if (selectionMode == SINGLE_TREE_SELECTION || isSelectionEmpty()
+ || ! canPathBeAdded(path))
setSelectionPath(path);
else
{
@@ -284,9 +358,16 @@ public class DefaultTreeSelectionModel
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
}
+ }
+
+ if (path!=leadPath)
+ {
+ TreePath oldLead = leadPath;
leadPath = path;
- fireValueChanged(new TreeSelectionEvent(this, path, true, leadPath,
- path));
+ leadRow = getRow(path);
+ leadIndex = selection.length - 1;
+ fireValueChanged(new TreeSelectionEvent(this, path, true, oldLead,
+ leadPath));
}
}
@@ -301,7 +382,7 @@ public class DefaultTreeSelectionModel
{
// Must be called, as defined in JDK API 1.4.
insureUniqueness();
-
+
if (paths != null)
{
TreePath v0 = null;
@@ -320,11 +401,16 @@ public class DefaultTreeSelectionModel
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
}
+ TreePath oldLead = leadPath;
leadPath = paths[paths.length - 1];
+ leadRow = getRow(leadPath);
+ leadIndex = selection.length - 1;
+
fireValueChanged(new TreeSelectionEvent(this, v0, true,
- leadPath, paths[0]));
+ oldLead, leadPath));
}
}
+ insureRowContinuity();
}
}
@@ -336,6 +422,9 @@ public class DefaultTreeSelectionModel
*/
public void removeSelectionPath(TreePath path)
{
+ if (isSelectionEmpty())
+ return;
+
int index = - 1;
if (isPathSelected(path))
{
@@ -353,9 +442,15 @@ public class DefaultTreeSelectionModel
- index - 1);
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
-
- fireValueChanged(new TreeSelectionEvent(this, path, false, leadPath,
- path));
+
+ // If the removed path was the lead path, set the lead path to null.
+ TreePath oldLead = leadPath;
+ if (path!=null && leadPath!=null && path.equals(leadPath))
+ leadPath = null;
+
+ fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead,
+ leadPath));
+ insureRowContinuity();
}
}
@@ -367,10 +462,13 @@ public class DefaultTreeSelectionModel
*/
public void removeSelectionPaths(TreePath[] paths)
{
+ if (isSelectionEmpty())
+ return;
if (paths != null)
{
int index = - 1;
TreePath v0 = null;
+ TreePath oldLead = leadPath;
for (int i = 0; i < paths.length; i++)
{
v0 = paths[i];
@@ -383,6 +481,8 @@ public class DefaultTreeSelectionModel
index = x;
break;
}
+ if (leadPath != null && leadPath.equals(v0))
+ leadPath = null;
}
TreePath[] temp = new TreePath[selection.length - 1];
System.arraycopy(selection, 0, temp, 0, index);
@@ -392,9 +492,10 @@ public class DefaultTreeSelectionModel
System.arraycopy(temp, 0, selection, 0, temp.length);
fireValueChanged(new TreeSelectionEvent(this, v0, false,
- leadPath, paths[0]));
+ oldLead, leadPath));
}
}
+ insureRowContinuity();
}
}
@@ -467,12 +568,23 @@ public class DefaultTreeSelectionModel
}
/**
- * Removes all paths from the selection.
+ * Removes all paths from the selection. Fire the unselection event.
*/
public void clearSelection()
{
- leadPath = null;
- selection = null;
+ if (! isSelectionEmpty())
+ {
+ TreeSelectionEvent event = new TreeSelectionEvent(
+ this, selection, new boolean[selection.length], leadPath, null);
+ leadPath = null;
+ selection = null;
+ fireValueChanged(event);
+ }
+ else
+ {
+ leadPath = null;
+ selection = null;
+ }
}
/**
@@ -588,18 +700,43 @@ public class DefaultTreeSelectionModel
* @param row the index of the row to check
* @return <code>true</code> if the row is in this selection,
* <code>false</code> otherwise
+ * @throws NullPointerException if the row mapper is not set (can only happen
+ * if the user has plugged in the custom incorrect TreeUI
+ * implementation.
*/
- public boolean isRowSelected(int row) throws NotImplementedException
+ public boolean isRowSelected(int row)
{
- return false; // TODO
+ // Return false if nothing is selected.
+ if (isSelectionEmpty())
+ return false;
+
+ RowMapper mapper = getRowMapper();
+
+ if (mapper instanceof AbstractLayoutCache)
+ {
+ // The absolute majority of cases, unless the TreeUI is very
+ // seriously rewritten
+ AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
+ TreePath path = ama.getPathForRow(row);
+ return isPathSelected(path);
+ }
+ else
+ {
+ // Generic non optimized implementation.
+ int[] rows = mapper.getRowsForPaths(selection);
+ for (int i = 0; i < rows.length; i++)
+ if (rows[i] == row)
+ return true;
+ return false;
+ }
}
/**
* Updates the mappings from TreePaths to row indices.
*/
- public void resetRowSelection() throws NotImplementedException
+ public void resetRowSelection()
{
- // TODO
+ // Nothing to do here.
}
/**
@@ -609,10 +746,7 @@ public class DefaultTreeSelectionModel
*/
public int getLeadSelectionRow()
{
- if ((rowMapper == null) || (leadPath == null))
- return - 1;
- else
- return rowMapper.getRowsForPaths(new TreePath[] { leadPath })[0];
+ return leadRow;
}
/**
@@ -665,23 +799,93 @@ public class DefaultTreeSelectionModel
* has more than one path, the selection is reset to the contain only the
* first path.
*/
- protected void insureRowContinuity() throws NotImplementedException
+ protected void insureRowContinuity()
{
- // TODO
+ if (selection == null || selection.length < 2)
+ return;
+ else if (selectionMode == CONTIGUOUS_TREE_SELECTION)
+ {
+ if (rowMapper == null)
+ // This is the best we can do without the row mapper:
+ selectOne();
+ else
+ {
+ int[] rows = rowMapper.getRowsForPaths(selection);
+ Arrays.sort(rows);
+ int i;
+ for (i = 1; i < rows.length; i++)
+ {
+ if (rows[i - 1] != rows[i] - 1)
+ // Break if no longer continuous.
+ break;
+ }
+
+ if (i < rows.length)
+ {
+ TreePath[] ns = new TreePath[i];
+ for (int j = 0; j < ns.length; j++)
+ ns[i] = getPath(j);
+ setSelectionPaths(ns);
+ }
+ }
+ }
+ else if (selectionMode == SINGLE_TREE_SELECTION)
+ selectOne();
+ }
+
+ /**
+ * Keep only one (normally last or leading) path in the selection.
+ */
+ private void selectOne()
+ {
+ if (leadIndex > 0 && leadIndex < selection.length)
+ setSelectionPath(selection[leadIndex]);
+ else
+ setSelectionPath(selection[selection.length -1]);
+ }
+
+ /**
+ * Get path for the given row that must be in the current selection.
+ */
+ private TreePath getPath(int row)
+ {
+ if (rowMapper instanceof AbstractLayoutCache)
+ return ((AbstractLayoutCache) rowMapper).getPathForRow(row);
+ else
+ {
+ int[] rows = rowMapper.getRowsForPaths(selection);
+ for (int i = 0; i < rows.length; i++)
+ if (rows[i] == row)
+ return selection[i];
+ }
+ throw new InternalError(row + " not in selection");
}
/**
- * Returns <code>true</code> if the paths are contiguous or we have no
- * RowMapper assigned.
+ * Returns <code>true</code> if the paths are contiguous (take subsequent
+ * rows in the diplayed tree view. The method returns <code>true</code> if
+ * we have no RowMapper assigned.
*
* @param paths the paths to check for continuity
* @return <code>true</code> if the paths are contiguous or we have no
* RowMapper assigned
*/
protected boolean arePathsContiguous(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || paths.length < 2)
+ return true;
+
+ int[] rows = rowMapper.getRowsForPaths(paths);
+
+ // The patches may not be sorted.
+ Arrays.sort(rows);
+
+ for (int i = 1; i < rows.length; i++)
+ {
+ if (rows[i-1] != rows[i] - 1)
+ return false;
+ }
+ return true;
}
/**
@@ -699,9 +903,32 @@ public class DefaultTreeSelectionModel
* selectionMode
*/
protected boolean canPathsBeAdded(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ TreePath [] all = new TreePath[paths.length + selection.length];
+ System.arraycopy(paths, 0, all, 0, paths.length);
+ System.arraycopy(selection, 0, all, paths.length, selection.length);
+
+ return arePathsContiguous(all);
+ }
+
+ /**
+ * Checks if the single path can be added to selection.
+ */
+ private boolean canPathBeAdded(TreePath path)
+ {
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ TreePath[] all = new TreePath[selection.length + 1];
+ System.arraycopy(selection, 0, all, 0, selection.length);
+ all[all.length - 1] = path;
+
+ return arePathsContiguous(all);
}
/**
@@ -713,29 +940,74 @@ public class DefaultTreeSelectionModel
* selectionMode
*/
protected boolean canPathsBeRemoved(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ HashSet set = new HashSet();
+ for (int i = 0; i < selection.length; i++)
+ set.add(selection[i]);
+
+ for (int i = 0; i < paths.length; i++)
+ set.remove(paths[i]);
+
+ TreePath[] remaining = new TreePath[set.size()];
+ Iterator iter = set.iterator();
+
+ for (int i = 0; i < remaining.length; i++)
+ remaining[i] = (TreePath) iter.next();
+
+ return arePathsContiguous(remaining);
}
/**
- * notifyPathChange
+ * Notify the installed listeners that the given patches have changed. This
+ * method will call listeners if invoked, but it is not called from the
+ * implementation of this class.
*
- * @param value0 TODO
- * @param value1 TODO
+ * @param vPathes the vector of the changed patches
+ * @param oldLeadSelection the old selection index
*/
- protected void notifyPathChange(Vector value0, TreePath value1)
- throws NotImplementedException
+ protected void notifyPathChange(Vector vPathes, TreePath oldLeadSelection)
{
- // STUB
+ TreePath[] pathes = new TreePath[vPathes.size()];
+ for (int i = 0; i < pathes.length; i++)
+ pathes[i] = (TreePath) vPathes.get(i);
+
+ boolean[] news = new boolean[pathes.length];
+ for (int i = 0; i < news.length; i++)
+ news[i] = isPathSelected(pathes[i]);
+
+ TreeSelectionEvent event = new TreeSelectionEvent(this, pathes, news,
+ oldLeadSelection,
+ leadPath);
+ fireValueChanged(event);
}
/**
- * Updates the lead index instance field.
+ * Updates the lead selection row number after changing the lead selection
+ * path.
*/
- protected void updateLeadIndex() throws NotImplementedException
+ protected void updateLeadIndex()
{
- // STUB
+ if (isSelectionEmpty())
+ {
+ leadRow = leadIndex = - 1;
+ }
+ else
+ {
+ leadRow = getRow(leadPath);
+ for (int i = 0; i < selection.length; i++)
+ {
+ if (selection[i].equals(leadPath))
+ {
+ leadIndex = i;
+ break;
+ }
+ }
+ leadIndex = leadRow;
+ }
}
/**
diff --git a/javax/swing/tree/FixedHeightLayoutCache.java b/javax/swing/tree/FixedHeightLayoutCache.java
index c4cc560fc..b8192211d 100644
--- a/javax/swing/tree/FixedHeightLayoutCache.java
+++ b/javax/swing/tree/FixedHeightLayoutCache.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package javax.swing.tree;
+import gnu.javax.swing.tree.GnuPath;
+
import java.awt.Rectangle;
import java.util.Enumeration;
import java.util.HashSet;
@@ -45,22 +47,21 @@ import java.util.LinkedList;
import java.util.Set;
import java.util.Vector;
-import javax.swing.UIManager;
import javax.swing.event.TreeModelEvent;
+
/**
* The fixed height tree layout. This class assumes that all cells in the tree
* have the same fixed height. This may be not the case, for instance, if leaves
* and branches have different height, of if the tree rows may have arbitrary
* variable height. This class will also work if the NodeDimensions are not
- * set. If they are set, the size calculations are just forwarded to the set
- * instance.
+ * set.
*
* @author Audrius Meskauskas
* @author Andrew Selkirk
*/
public class FixedHeightLayoutCache
- extends AbstractLayoutCache
+ extends VariableHeightLayoutCache
{
/**
* The cached node record.
@@ -114,26 +115,61 @@ public class FixedHeightLayoutCache
*/
private TreePath path;
+ /**
+ * Get the path for this node. The derived class is returned,
+ * making check for the last child of some parent easier.
+ */
TreePath getPath()
{
if (path == null)
{
+ boolean lastChild = false;
+ if (parent != null)
+ {
+ int nc = treeModel.getChildCount(parent);
+ if (nc > 0)
+ {
+ int n = treeModel.getIndexOfChild(parent, node);
+ if (n == nc - 1)
+ lastChild = true;
+ }
+ }
+
LinkedList lpath = new LinkedList();
NodeRecord rp = this;
while (rp != null)
{
lpath.addFirst(rp.node);
if (rp.parent != null)
- rp = (NodeRecord) nodes.get(rp.parent);
+ {
+ Object parent = rp.parent;
+ rp = (NodeRecord) nodes.get(parent);
+ // Add the root node, even if it is not visible.
+ if (rp == null)
+ lpath.addFirst(parent);
+ }
else
rp = null;
}
- path = new TreePath(lpath.toArray());
+ path = new GnuPath(lpath.toArray(), lastChild);
}
return path;
}
+
+ /**
+ * Get the rectangle bounds (compute, if required).
+ */
+ Rectangle getBounds()
+ {
+ // This method may be called in the context when the tree rectangle is
+ // not known. To work around this, it is assumed near infinitely large.
+ if (bounds==null)
+ bounds = getNodeDimensions(node, row, depth, isExpanded,
+ new Rectangle());
+ return bounds;
+ }
}
-
+
/**
* The set of all expanded tree nodes.
*/
@@ -153,6 +189,16 @@ public class FixedHeightLayoutCache
* If true, the row map must be recomputed before using.
*/
boolean dirty;
+
+ /**
+ * The cumulative height of all rows.
+ */
+ int totalHeight;
+
+ /**
+ * The maximal width.
+ */
+ int maximalWidth;
/**
* Creates the unitialised instance. Before using the class, the row height
@@ -184,6 +230,8 @@ public class FixedHeightLayoutCache
{
nodes.clear();
row2node.clear();
+
+ totalHeight = maximalWidth = 0;
Object root = treeModel.getRoot();
@@ -197,7 +245,7 @@ public class FixedHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 1);
+ countRows(child, root, 0);
}
}
dirty = false;
@@ -211,9 +259,11 @@ public class FixedHeightLayoutCache
Integer n = new Integer(row2node.size());
row2node.put(n, node);
- nodes.put(node, new NodeRecord(n.intValue(), depth, node, parent));
-
- if (expanded.contains(node) || parent == null)
+ NodeRecord nr = new NodeRecord(n.intValue(), depth, node, parent);
+ nodes.put(node, nr);
+
+ // For expanded nodes and for the root node.
+ if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
@@ -226,14 +276,15 @@ public class FixedHeightLayoutCache
}
/**
- * This should invalidate the width of the last path component, but
- * following the JDK 1.4 API it is not cached and the method should return
- * without action.
- * @param path the path being invalidated, ignored.
+ * Discard the bound information for the given path.
+ *
+ * @param path the path, for that the bound information must be recomputed.
*/
public void invalidatePathBounds(TreePath path)
{
- // Following JDK 1.4 API, should return without action.
+ NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
+ if (r!=null)
+ r.bounds = null;
}
/**
@@ -277,29 +328,34 @@ public class FixedHeightLayoutCache
* Get bounds for the given tree path.
*
* @param path the tree path
- * @param rect the rectangle, specifying the area where the path should be
- * displayed.
+ * @param rect the rectangle that will be reused to return the result.
* @return Rectangle the bounds of the last line, defined by the given path.
*/
public Rectangle getBounds(TreePath path, Rectangle rect)
{
+ if (path == null)
+ return null;
if (dirty)
update();
Object last = path.getLastPathComponent();
NodeRecord r = (NodeRecord) nodes.get(last);
if (r == null)
- // This node is not visible.
- return new Rectangle();
+ // This node is not visible.
+ {
+ rect.x = rect.y = rect.width = rect.height = 0;
+ }
else
{
if (r.bounds == null)
{
- Rectangle dim = getNodeDimensions(last, r.row, r.depth, r.isExpanded,
- rect);
+ Rectangle dim = getNodeDimensions(last, r.row, r.depth,
+ r.isExpanded, rect);
r.bounds = dim;
}
- return r.bounds;
+
+ rect.setRect(r.bounds);
}
+ return rect;
}
/**
@@ -330,6 +386,9 @@ public class FixedHeightLayoutCache
*/
public int getRowForPath(TreePath path)
{
+ if (path == null)
+ return -1;
+
if (dirty) update();
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
@@ -351,28 +410,59 @@ public class FixedHeightLayoutCache
if (dirty)
update();
- // We do not need to iterate because all rows have the same height.
- int row = y / rowHeight;
- if (row < 0)
- row = 0;
- if (row > getRowCount())
- row = getRowCount() - 1;
+ // As the rows have arbitrary height, we need to iterate.
+ NodeRecord best = null;
+ NodeRecord r;
+ Enumeration en = nodes.elements();
- if (row < 0)
- return null; // Empty tree - nothing to return.
-
- Object node = row2node.get(new Integer(row));
- NodeRecord nr = (NodeRecord) nodes.get(node);
- return nr.getPath();
+ int dist = Integer.MAX_VALUE;
+
+ while (en.hasMoreElements() && dist > 0)
+ {
+ r = (NodeRecord) en.nextElement();
+ if (best == null)
+ {
+ best = r;
+ dist = distance(r.getBounds(), x, y);
+ }
+ else
+ {
+ int rr = distance(r.getBounds(), x, y);
+ if (rr < dist)
+ {
+ best = r;
+ dist = rr;
+ }
+ }
+ }
+
+ if (best == null)
+ return null;
+ else
+ return best.getPath();
}
+
+ /**
+ * Get the closest distance from this point till the given rectangle. Only
+ * vertical distance is taken into consideration.
+ */
+ int distance(Rectangle r, int x, int y)
+ {
+ if (y < r.y)
+ return r.y - y;
+ else if (y > r.y + r.height)
+ return y - (r.y + r.height);
+ else
+ return 0;
+ }
/**
- * Get the number of the visible childs for the given tree path. If the
- * node is not expanded, 0 is returned. Otherwise, the number of children
- * is obtained from the model as the number of children for the last path
+ * Get the number of the visible childs for the given tree path. If the node
+ * is not expanded, 0 is returned. Otherwise, the number of children is
+ * obtained from the model as the number of children for the last path
* component.
*
- * @param path the tree path
+ * @param path the tree path
* @return int the number of the visible childs (for row).
*/
public int getVisibleChildCount(TreePath path)
@@ -466,7 +556,9 @@ public class FixedHeightLayoutCache
*/
public void setModel(TreeModel newModel)
{
- super.setModel(newModel);
+ treeModel = newModel;
+ // The root node is expanded by default.
+ expanded.add(treeModel.getRoot());
dirty = true;
}
@@ -484,32 +576,53 @@ public class FixedHeightLayoutCache
}
/**
- * Get the node dimensions. If the NodeDimensions are not set, this method
- * calculates dimensions assuming the fixed row height.
- *
- * @param value the last node in the path
- * @param row the node row
- * @param depth the indentation depth
- * @param expanded true if this node is expanded, false otherwise
- * @param bounds the area where the tree is displayed
- */
- protected Rectangle getNodeDimensions(Object value, int row, int depth,
- boolean expanded, Rectangle bounds)
+ * Get the sum of heights for all rows.
+ */
+ public int getPreferredHeight()
{
- if (nodeDimensions != null)
- return nodeDimensions.getNodeDimensions(value, row, depth, expanded,
- bounds);
- else
+ if (dirty)
+ update();
+ totalHeight = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
{
- Rectangle r = new Rectangle(bounds);
-
- int indent = depth * UIManager.getInt("Tree.rightChildIndent");
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ totalHeight += r.height;
+ }
+ return totalHeight;
+ }
- r.x = indent;
- r.y = row * getRowHeight();
- r.width = bounds.width = r.x;
- r.height = getRowHeight();
- return r;
+ /**
+ * Get the maximal width.
+ */
+ public int getPreferredWidth(Rectangle value)
+ {
+ if (dirty)
+ update();
+
+ maximalWidth = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
+ {
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ if (r.x + r.width > maximalWidth)
+ maximalWidth = r.x + r.width;
}
+ return maximalWidth;
+ }
+
+ /**
+ * Returns true if this layout supposes that all rows have the fixed
+ * height.
+ *
+ * @return boolean true if all rows in the tree must have the fixed
+ * height (true by default).
+ */
+ protected boolean isFixedRowHeight()
+ {
+ return true;
}
+
}
diff --git a/javax/swing/tree/TreePath.java b/javax/swing/tree/TreePath.java
index 89f36f0ff..4671c4be5 100644
--- a/javax/swing/tree/TreePath.java
+++ b/javax/swing/tree/TreePath.java
@@ -57,6 +57,11 @@ public class TreePath implements Serializable
* assumes that the TreePath is immutable, so it is marked final here.
*/
private final Object[] path;
+
+ /**
+ * The parent path (to be reused).
+ */
+ private transient TreePath parentPath;
/**
@@ -294,7 +299,12 @@ public class TreePath implements Serializable
// is what the JDK does.
if (path.length <= 1)
return null;
-
- return new TreePath(this.getPath(), path.length - 1);
+
+ // Reuse the parent path, if possible. The parent path is requested
+ // during the tree repainting, so reusing generates a lot less garbage.
+ if (parentPath == null)
+ parentPath = new TreePath(this.getPath(), path.length - 1);
+
+ return parentPath;
}
}
diff --git a/javax/swing/tree/VariableHeightLayoutCache.java b/javax/swing/tree/VariableHeightLayoutCache.java
index 3758a4fc0..302fb0e45 100644
--- a/javax/swing/tree/VariableHeightLayoutCache.java
+++ b/javax/swing/tree/VariableHeightLayoutCache.java
@@ -115,31 +115,38 @@ public class VariableHeightLayoutCache
private TreePath path;
/**
- * Get the path for this node. The derived class is returned,
- * making check for the last child of some parent easier.
+ * Get the path for this node. The derived class is returned, making check
+ * for the last child of some parent easier.
*/
TreePath getPath()
{
- boolean lastChild = false;
- if (parent!=null)
+ if (path == null)
{
- int nc = treeModel.getChildCount(parent);
- if (nc > 0)
+ boolean lastChild = false;
+ if (parent != null)
{
- int n = treeModel.getIndexOfChild(parent, node);
- if (n == nc-1)
- lastChild = true;
+ int nc = treeModel.getChildCount(parent);
+ if (nc > 0)
+ {
+ int n = treeModel.getIndexOfChild(parent, node);
+ if (n == nc - 1)
+ lastChild = true;
+ }
}
- }
- if (path == null)
- {
+
LinkedList lpath = new LinkedList();
NodeRecord rp = this;
while (rp != null)
{
lpath.addFirst(rp.node);
if (rp.parent != null)
- rp = (NodeRecord) nodes.get(rp.parent);
+ {
+ Object parent = rp.parent;
+ rp = (NodeRecord) nodes.get(parent);
+ // Add the root node, even if it is not visible.
+ if (rp == null)
+ lpath.addFirst(parent);
+ }
else
rp = null;
}
@@ -157,8 +164,7 @@ public class VariableHeightLayoutCache
// not known. To work around this, it is assumed near infinitely large.
if (bounds==null)
bounds = getNodeDimensions(node, row, depth, isExpanded,
- new Rectangle(Integer.MAX_VALUE/2,
- Integer.MAX_VALUE/2));
+ new Rectangle());
return bounds;
}
}
@@ -238,7 +244,7 @@ public class VariableHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 1);
+ countRows(child, root, 0);
}
}
dirty = false;
@@ -255,8 +261,8 @@ public class VariableHeightLayoutCache
NodeRecord nr = new NodeRecord(n.intValue(), depth, node, parent);
nodes.put(node, nr);
- // For expanded nodes and for the root node.
- if (expanded.contains(node) || parent == null)
+ // For expanded nodes
+ if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
@@ -326,6 +332,8 @@ public class VariableHeightLayoutCache
*/
public Rectangle getBounds(TreePath path, Rectangle rect)
{
+ if (path == null)
+ return null;
if (dirty)
update();
Object last = path.getLastPathComponent();
@@ -377,6 +385,8 @@ public class VariableHeightLayoutCache
*/
public int getRowForPath(TreePath path)
{
+ if (path == null)
+ return -1;
if (dirty) update();
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
@@ -545,6 +555,8 @@ public class VariableHeightLayoutCache
public void setModel(TreeModel newModel)
{
treeModel = newModel;
+ // The root node is expanded by default.
+ expanded.add(treeModel.getRoot());
dirty = true;
}
diff --git a/javax/xml/datatype/DatatypeFactory.java b/javax/xml/datatype/DatatypeFactory.java
index c5bc96ed2..14f507416 100644
--- a/javax/xml/datatype/DatatypeFactory.java
+++ b/javax/xml/datatype/DatatypeFactory.java
@@ -37,15 +37,23 @@ exception statement from your version. */
package javax.xml.datatype;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.Properties;
+import gnu.classpath.ServiceFactory;
/**
* Factory class to create new datatype objects mapping XML to and from Java
* objects.
*
- * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
+ * @author Chris Burdess
* @since 1.5
*/
public abstract class DatatypeFactory
@@ -59,7 +67,7 @@ public abstract class DatatypeFactory
/**
* JAXP 1.3 default implementation class name.
*/
- public static final java.lang.String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
+ public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
protected DatatypeFactory()
{
@@ -73,12 +81,35 @@ public abstract class DatatypeFactory
{
try
{
+ // 1. system property
+ String className = System.getProperty(DATATYPEFACTORY_PROPERTY);
+ if (className != null)
+ return (DatatypeFactory) Class.forName(className).newInstance();
+ // 2. jaxp.properties property
+ File javaHome = new File(System.getProperty("java.home"));
+ File javaHomeLib = new File(javaHome, "lib");
+ File jaxpProperties = new File(javaHomeLib, "jaxp.properties");
+ if (jaxpProperties.exists())
+ {
+ FileInputStream in = new FileInputStream(jaxpProperties);
+ Properties p = new Properties();
+ p.load(in);
+ in.close();
+ className = p.getProperty(DATATYPEFACTORY_PROPERTY);
+ if (className != null)
+ return (DatatypeFactory) Class.forName(className).newInstance();
+ }
+ // 3. services
+ Iterator i = ServiceFactory.lookupProviders(DatatypeFactory.class);
+ if (i.hasNext())
+ return (DatatypeFactory) i.next();
+ // 4. fallback
Class t = Class.forName(DATATYPEFACTORY_IMPLEMENTATION_CLASS);
return (DatatypeFactory) t.newInstance();
}
catch (Exception e)
{
- throw new DatatypeConfigurationException (e);
+ throw new DatatypeConfigurationException(e);
}
}