#! /bin/sh -e

# DP: Michael Koch <konqueror@gmx.de>
# DP: Backport AWT, Swing and GTK peer from java-gui-branch (20040906).

dir=libjava
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3/libjava"
    dir="$3/libjava"
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p0 < $0
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
        #rm ${dir}/configure
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

? gnu/regexp
? gnu/java/awt/doc-files
? gnu/java/nio/channels
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.354.2.3
diff -u -r1.354.2.3 Makefile.am
--- Makefile.am	24 Jan 2004 20:47:28 -0000	1.354.2.3
+++ Makefile.am	6 Sep 2004 16:35:34 -0000
@@ -182,11 +182,13 @@
 ## Gtk JNI sources.
 gtk_c_source_files = \
 $(gtk_cairo_c_source_files) \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c \
@@ -195,11 +197,13 @@
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c \
@@ -219,15 +223,16 @@
 
 ## Java sources for Gtk peers.
 gtk_awt_peer_sources = \
+gnu/java/awt/peer/gtk/GThreadMutex.java \
+gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java \
 gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java \
 gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java \
 gnu/java/awt/peer/gtk/GdkFontMetrics.java \
 gnu/java/awt/peer/gtk/GdkGlyphVector.java \
 gnu/java/awt/peer/gtk/GdkGraphics.java \
 gnu/java/awt/peer/gtk/GdkGraphics2D.java \
+gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java \
 gnu/java/awt/peer/gtk/GdkPixbufDecoder.java \
-gnu/java/awt/peer/gtk/GtkArg.java \
-gnu/java/awt/peer/gtk/GtkArgList.java \
 gnu/java/awt/peer/gtk/GtkButtonPeer.java \
 gnu/java/awt/peer/gtk/GtkCanvasPeer.java \
 gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java	\
@@ -1074,24 +1079,32 @@
 java/awt/geom/FlatteningPathIterator.java \
 java/awt/geom/GeneralPath.java \
 java/awt/geom/QuadCurve2D.java \
+java/awt/image/AffineTransformOp.java \
+java/awt/image/ByteLookupTable.java \
 java/awt/image/BufferedImage.java \
 java/awt/image/ColorModel.java \
 java/awt/image/ComponentColorModel.java \
 java/awt/image/ComponentSampleModel.java \
 java/awt/image/DataBuffer.java \
 java/awt/image/DataBufferByte.java \
+java/awt/image/DataBufferDouble.java \
+java/awt/image/DataBufferFloat.java \
 java/awt/image/DataBufferInt.java \
+java/awt/image/DataBufferShort.java \
 java/awt/image/DataBufferUShort.java \
 java/awt/image/DirectColorModel.java \
 java/awt/image/ImageConsumer.java \
 java/awt/image/ImageObserver.java \
 java/awt/image/ImageProducer.java \
 java/awt/image/IndexColorModel.java \
+java/awt/image/Kernel.java \
+java/awt/image/LookupTable.java \
 java/awt/image/PackedColorModel.java \
 java/awt/image/Raster.java \
 java/awt/image/RasterOp.java \
 java/awt/image/SampleModel.java \
 java/awt/image/SinglePixelPackedSampleModel.java \
+java/awt/image/ShortLookupTable.java \
 java/awt/image/WritableRaster.java \
 java/awt/image/AreaAveragingScaleFilter.java \
 java/awt/image/CropImageFilter.java \
@@ -1099,6 +1112,7 @@
 java/awt/image/ImageFilter.java \
 java/awt/image/MemoryImageSource.java \
 java/awt/image/PixelGrabber.java \
+java/awt/image/PixelInterleavedSampleModel.java \
 java/awt/image/RGBImageFilter.java \
 java/awt/image/ReplicateScaleFilter.java \
 java/awt/image/BufferStrategy.java \
@@ -1293,26 +1307,59 @@
 javax/swing/GrayFilter.java \
 javax/swing/AbstractAction.java \
 javax/swing/AbstractButton.java \
+javax/swing/plaf/basic/BasicArrowButton.java \
+javax/swing/plaf/basic/BasicButtonListener.java \
 javax/swing/plaf/basic/BasicButtonUI.java \
+javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java \
 javax/swing/plaf/basic/BasicCheckBoxUI.java \
-javax/swing/plaf/basic/BasicDefaults.java \
+javax/swing/plaf/basic/BasicColorChooserUI.java \
+javax/swing/plaf/basic/BasicComboBoxEditor.java \
+javax/swing/plaf/basic/BasicComboBoxRenderer.java \
+javax/swing/plaf/basic/BasicComboBoxUI.java \
+javax/swing/plaf/basic/BasicComboPopup.java \
+javax/swing/plaf/basic/BasicDesktopIconUI.java \
+javax/swing/plaf/basic/BasicDesktopPaneUI.java \
+javax/swing/plaf/basic/BasicFormattedTextFieldUI.java \
 javax/swing/plaf/basic/BasicGraphicsUtils.java \
+javax/swing/plaf/basic/BasicInternalFrameTitlePane.java \
+javax/swing/plaf/basic/BasicInternalFrameUI.java \
+javax/swing/plaf/basic/BasicMenuBarUI.java \
+javax/swing/plaf/basic/BasicMenuItemUI.java \
+javax/swing/plaf/basic/BasicMenuUI.java \
 javax/swing/plaf/basic/BasicLabelUI.java \
 javax/swing/plaf/basic/BasicListUI.java \
 javax/swing/plaf/basic/BasicOptionPaneUI.java \
 javax/swing/plaf/basic/BasicPanelUI.java \
+javax/swing/plaf/basic/BasicPasswordFieldUI.java \
+javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java \
+javax/swing/plaf/basic/BasicPopupMenuUI.java \
+javax/swing/plaf/basic/BasicProgressBarUI.java \
+javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java \
 javax/swing/plaf/basic/BasicRadioButtonUI.java \
+javax/swing/plaf/basic/BasicRootPaneUI.java \
+javax/swing/plaf/basic/BasicScrollBarUI.java \
 javax/swing/plaf/basic/BasicScrollPaneUI.java \
+javax/swing/plaf/basic/BasicSeparatorUI.java \
+javax/swing/plaf/basic/BasicSliderUI.java \
+javax/swing/plaf/basic/BasicSpinnerUI.java \
 javax/swing/plaf/basic/BasicSplitPaneDivider.java \
 javax/swing/plaf/basic/BasicSplitPaneUI.java \
 javax/swing/plaf/basic/BasicTabbedPaneUI.java \
+javax/swing/plaf/basic/BasicTableHeaderUI.java \
+javax/swing/plaf/basic/BasicTableUI.java \
+javax/swing/plaf/basic/BasicTextAreaUI.java \
+javax/swing/plaf/basic/BasicTextFieldUI.java \
 javax/swing/plaf/basic/BasicTextUI.java \
 javax/swing/plaf/basic/BasicToggleButtonUI.java \
+javax/swing/plaf/basic/BasicToolBarSeparatorUI.java \
+javax/swing/plaf/basic/BasicToolBarUI.java \
+javax/swing/plaf/basic/BasicToolTipUI.java \
 javax/swing/plaf/basic/BasicTreeUI.java \
 javax/swing/plaf/basic/BasicViewportUI.java \
 javax/swing/plaf/basic/BasicLookAndFeel.java \
 javax/swing/plaf/basic/BasicBorders.java \
 javax/swing/plaf/basic/BasicIconFactory.java \
+javax/swing/plaf/basic/ComboPopup.java \
 javax/swing/plaf/BorderUIResource.java \
 javax/swing/plaf/UIResource.java \
 javax/swing/plaf/ButtonUI.java \
@@ -1357,10 +1404,15 @@
 javax/swing/plaf/ToolTipUI.java \
 javax/swing/AbstractListModel.java \
 javax/swing/AbstractSet.java \
+javax/swing/AbstractSpinnerModel.java \
 javax/swing/colorchooser/AbstractColorChooserPanel.java \
 javax/swing/colorchooser/ColorChooserComponentFactory.java \
 javax/swing/colorchooser/ColorSelectionModel.java \
 javax/swing/colorchooser/DefaultColorSelectionModel.java \
+javax/swing/colorchooser/DefaultHSBChooserPanel.java \
+javax/swing/colorchooser/DefaultPreviewPanel.java \
+javax/swing/colorchooser/DefaultRGBChooserPanel.java \
+javax/swing/colorchooser/DefaultSwatchChooserPanel.java \
 javax/swing/filechooser/FileFilter.java \
 javax/swing/filechooser/FileSystemView.java \
 javax/swing/filechooser/FileView.java \
@@ -1406,7 +1458,9 @@
 javax/swing/JRootPane.java \
 javax/swing/JScrollBar.java \
 javax/swing/JScrollPane.java \
+javax/swing/JSpinner.java \
 javax/swing/JTabbedPane.java \
+javax/swing/JTextArea.java \
 javax/swing/JTextField.java \
 javax/swing/JToggleButton.java \
 javax/swing/JToolTip.java \
@@ -1419,10 +1473,12 @@
 javax/swing/ListSelectionModel.java \
 javax/swing/LookAndFeel.java \
 javax/swing/Scrollable.java \
+javax/swing/SpinnerModel.java \
+javax/swing/SpinnerNumberModel.java \
 javax/swing/SwingConstants.java \
 javax/swing/SwingUtilities.java \
 javax/swing/Timer.java \
-javax/swing/ToggleButtonModel.java \
+javax/swing/TransferHandler.java \
 javax/swing/UIDefaults.java \
 javax/swing/UIManager.java \
 javax/swing/UnsupportedLookAndFeelException.java \
@@ -1474,22 +1530,33 @@
 javax/swing/text/AttributeSet.java \
 javax/swing/text/BadLocationException.java \
 javax/swing/text/Caret.java \
-javax/swing/text/CharacterIterator.java \
 javax/swing/text/ComponentView.java \
 javax/swing/text/DefaultCaret.java \
 javax/swing/text/DefaultEditorKit.java \
+javax/swing/text/DefaultHighlighter.java \
 javax/swing/text/Document.java \
 javax/swing/text/DocumentFilter.java \
 javax/swing/text/EditorKit.java \
 javax/swing/text/Element.java \
+javax/swing/text/FieldView.java \
 javax/swing/text/GapContent.java \
+javax/swing/text/Highlighter.java \
 javax/swing/text/JTextComponent.java \
 javax/swing/text/Keymap.java \
+javax/swing/text/LayeredHighlighter.java \
 javax/swing/text/PlainDocument.java \
-javax/swing/text/PlainEditorKit.java \
+javax/swing/text/PlainView.java \
 javax/swing/text/Position.java \
 javax/swing/text/Segment.java \
+javax/swing/text/SimpleAttributeSet.java \
 javax/swing/text/Style.java \
+javax/swing/text/StyleConstants.java \
+javax/swing/text/StyleContext.java \
+javax/swing/text/TabExpander.java \
+javax/swing/text/TabableView.java \
+javax/swing/text/TabSet.java \
+javax/swing/text/TabStop.java \
+javax/swing/text/Utilities.java \
 javax/swing/text/View.java \
 javax/swing/text/ViewFactory.java \
 javax/swing/text/MutableAttributeSet.java \
@@ -1577,6 +1644,8 @@
 javax/swing/ProgressMonitorInputStream.java \
 javax/swing/RepaintManager.java \
 javax/swing/ScrollPaneLayout.java \
+javax/swing/Spring.java \
+javax/swing/SpringLayout.java \
 javax/swing/ToolTipManager.java \
 javax/swing/ViewportLayout.java
 
@@ -2351,6 +2420,8 @@
 gnu/java/nio/charset/UTF_8.java \
 gnu/java/security/Engine.java \
 gnu/java/security/OID.java \
+gnu/java/security/action/GetPropertyAction.java \
+gnu/java/security/action/SetAccessibleAction.java \
 gnu/java/security/der/BitString.java \
 gnu/java/security/der/DER.java \
 gnu/java/security/der/DEREncodingException.java \
@@ -2800,7 +2871,6 @@
 gnu/gcj/runtime/natStackTrace.cc \
 gnu/gcj/runtime/natStringBuffer.cc \
 gnu/gcj/runtime/natVMClassLoader.cc \
-gnu/java/awt/natEmbeddedWindow.cc \
 gnu/java/net/natPlainDatagramSocketImpl.cc \
 gnu/java/net/natPlainSocketImpl.cc \
 gnu/java/net/protocol/core/natCoreInputStream.cc \
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.in,v
retrieving revision 1.378.2.3
diff -u -r1.378.2.3 Makefile.in
--- Makefile.in	24 Jan 2004 20:47:28 -0000	1.378.2.3
+++ Makefile.in	6 Sep 2004 16:35:36 -0000
@@ -274,11 +274,13 @@
 
 gtk_c_source_files = \
 $(gtk_cairo_c_source_files) \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c \
@@ -287,11 +289,13 @@
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c \
 jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c \
@@ -311,15 +315,16 @@
 
 
 gtk_awt_peer_sources = \
+gnu/java/awt/peer/gtk/GThreadMutex.java \
+gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java \
 gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java \
 gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java \
 gnu/java/awt/peer/gtk/GdkFontMetrics.java \
 gnu/java/awt/peer/gtk/GdkGlyphVector.java \
 gnu/java/awt/peer/gtk/GdkGraphics.java \
 gnu/java/awt/peer/gtk/GdkGraphics2D.java \
+gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java \
 gnu/java/awt/peer/gtk/GdkPixbufDecoder.java \
-gnu/java/awt/peer/gtk/GtkArg.java \
-gnu/java/awt/peer/gtk/GtkArgList.java \
 gnu/java/awt/peer/gtk/GtkButtonPeer.java \
 gnu/java/awt/peer/gtk/GtkCanvasPeer.java \
 gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java	\
@@ -772,24 +777,32 @@
 java/awt/geom/FlatteningPathIterator.java \
 java/awt/geom/GeneralPath.java \
 java/awt/geom/QuadCurve2D.java \
+java/awt/image/AffineTransformOp.java \
+java/awt/image/ByteLookupTable.java \
 java/awt/image/BufferedImage.java \
 java/awt/image/ColorModel.java \
 java/awt/image/ComponentColorModel.java \
 java/awt/image/ComponentSampleModel.java \
 java/awt/image/DataBuffer.java \
 java/awt/image/DataBufferByte.java \
+java/awt/image/DataBufferDouble.java \
+java/awt/image/DataBufferFloat.java \
 java/awt/image/DataBufferInt.java \
+java/awt/image/DataBufferShort.java \
 java/awt/image/DataBufferUShort.java \
 java/awt/image/DirectColorModel.java \
 java/awt/image/ImageConsumer.java \
 java/awt/image/ImageObserver.java \
 java/awt/image/ImageProducer.java \
 java/awt/image/IndexColorModel.java \
+java/awt/image/Kernel.java \
+java/awt/image/LookupTable.java \
 java/awt/image/PackedColorModel.java \
 java/awt/image/Raster.java \
 java/awt/image/RasterOp.java \
 java/awt/image/SampleModel.java \
 java/awt/image/SinglePixelPackedSampleModel.java \
+java/awt/image/ShortLookupTable.java \
 java/awt/image/WritableRaster.java \
 java/awt/image/AreaAveragingScaleFilter.java \
 java/awt/image/CropImageFilter.java \
@@ -797,6 +810,7 @@
 java/awt/image/ImageFilter.java \
 java/awt/image/MemoryImageSource.java \
 java/awt/image/PixelGrabber.java \
+java/awt/image/PixelInterleavedSampleModel.java \
 java/awt/image/RGBImageFilter.java \
 java/awt/image/ReplicateScaleFilter.java \
 java/awt/image/BufferStrategy.java \
@@ -991,26 +1005,59 @@
 javax/swing/GrayFilter.java \
 javax/swing/AbstractAction.java \
 javax/swing/AbstractButton.java \
+javax/swing/plaf/basic/BasicArrowButton.java \
+javax/swing/plaf/basic/BasicButtonListener.java \
 javax/swing/plaf/basic/BasicButtonUI.java \
+javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java \
 javax/swing/plaf/basic/BasicCheckBoxUI.java \
-javax/swing/plaf/basic/BasicDefaults.java \
+javax/swing/plaf/basic/BasicColorChooserUI.java \
+javax/swing/plaf/basic/BasicComboBoxEditor.java \
+javax/swing/plaf/basic/BasicComboBoxRenderer.java \
+javax/swing/plaf/basic/BasicComboBoxUI.java \
+javax/swing/plaf/basic/BasicComboPopup.java \
+javax/swing/plaf/basic/BasicDesktopIconUI.java \
+javax/swing/plaf/basic/BasicDesktopPaneUI.java \
+javax/swing/plaf/basic/BasicFormattedTextFieldUI.java \
 javax/swing/plaf/basic/BasicGraphicsUtils.java \
+javax/swing/plaf/basic/BasicInternalFrameTitlePane.java \
+javax/swing/plaf/basic/BasicInternalFrameUI.java \
+javax/swing/plaf/basic/BasicMenuBarUI.java \
+javax/swing/plaf/basic/BasicMenuItemUI.java \
+javax/swing/plaf/basic/BasicMenuUI.java \
 javax/swing/plaf/basic/BasicLabelUI.java \
 javax/swing/plaf/basic/BasicListUI.java \
 javax/swing/plaf/basic/BasicOptionPaneUI.java \
 javax/swing/plaf/basic/BasicPanelUI.java \
+javax/swing/plaf/basic/BasicPasswordFieldUI.java \
+javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java \
+javax/swing/plaf/basic/BasicPopupMenuUI.java \
+javax/swing/plaf/basic/BasicProgressBarUI.java \
+javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java \
 javax/swing/plaf/basic/BasicRadioButtonUI.java \
+javax/swing/plaf/basic/BasicRootPaneUI.java \
+javax/swing/plaf/basic/BasicScrollBarUI.java \
 javax/swing/plaf/basic/BasicScrollPaneUI.java \
+javax/swing/plaf/basic/BasicSeparatorUI.java \
+javax/swing/plaf/basic/BasicSliderUI.java \
+javax/swing/plaf/basic/BasicSpinnerUI.java \
 javax/swing/plaf/basic/BasicSplitPaneDivider.java \
 javax/swing/plaf/basic/BasicSplitPaneUI.java \
 javax/swing/plaf/basic/BasicTabbedPaneUI.java \
+javax/swing/plaf/basic/BasicTableHeaderUI.java \
+javax/swing/plaf/basic/BasicTableUI.java \
+javax/swing/plaf/basic/BasicTextAreaUI.java \
+javax/swing/plaf/basic/BasicTextFieldUI.java \
 javax/swing/plaf/basic/BasicTextUI.java \
 javax/swing/plaf/basic/BasicToggleButtonUI.java \
+javax/swing/plaf/basic/BasicToolBarSeparatorUI.java \
+javax/swing/plaf/basic/BasicToolBarUI.java \
+javax/swing/plaf/basic/BasicToolTipUI.java \
 javax/swing/plaf/basic/BasicTreeUI.java \
 javax/swing/plaf/basic/BasicViewportUI.java \
 javax/swing/plaf/basic/BasicLookAndFeel.java \
 javax/swing/plaf/basic/BasicBorders.java \
 javax/swing/plaf/basic/BasicIconFactory.java \
+javax/swing/plaf/basic/ComboPopup.java \
 javax/swing/plaf/BorderUIResource.java \
 javax/swing/plaf/UIResource.java \
 javax/swing/plaf/ButtonUI.java \
@@ -1055,10 +1102,15 @@
 javax/swing/plaf/ToolTipUI.java \
 javax/swing/AbstractListModel.java \
 javax/swing/AbstractSet.java \
+javax/swing/AbstractSpinnerModel.java \
 javax/swing/colorchooser/AbstractColorChooserPanel.java \
 javax/swing/colorchooser/ColorChooserComponentFactory.java \
 javax/swing/colorchooser/ColorSelectionModel.java \
 javax/swing/colorchooser/DefaultColorSelectionModel.java \
+javax/swing/colorchooser/DefaultHSBChooserPanel.java \
+javax/swing/colorchooser/DefaultPreviewPanel.java \
+javax/swing/colorchooser/DefaultRGBChooserPanel.java \
+javax/swing/colorchooser/DefaultSwatchChooserPanel.java \
 javax/swing/filechooser/FileFilter.java \
 javax/swing/filechooser/FileSystemView.java \
 javax/swing/filechooser/FileView.java \
@@ -1104,7 +1156,9 @@
 javax/swing/JRootPane.java \
 javax/swing/JScrollBar.java \
 javax/swing/JScrollPane.java \
+javax/swing/JSpinner.java \
 javax/swing/JTabbedPane.java \
+javax/swing/JTextArea.java \
 javax/swing/JTextField.java \
 javax/swing/JToggleButton.java \
 javax/swing/JToolTip.java \
@@ -1117,10 +1171,12 @@
 javax/swing/ListSelectionModel.java \
 javax/swing/LookAndFeel.java \
 javax/swing/Scrollable.java \
+javax/swing/SpinnerModel.java \
+javax/swing/SpinnerNumberModel.java \
 javax/swing/SwingConstants.java \
 javax/swing/SwingUtilities.java \
 javax/swing/Timer.java \
-javax/swing/ToggleButtonModel.java \
+javax/swing/TransferHandler.java \
 javax/swing/UIDefaults.java \
 javax/swing/UIManager.java \
 javax/swing/UnsupportedLookAndFeelException.java \
@@ -1172,22 +1228,33 @@
 javax/swing/text/AttributeSet.java \
 javax/swing/text/BadLocationException.java \
 javax/swing/text/Caret.java \
-javax/swing/text/CharacterIterator.java \
 javax/swing/text/ComponentView.java \
 javax/swing/text/DefaultCaret.java \
 javax/swing/text/DefaultEditorKit.java \
+javax/swing/text/DefaultHighlighter.java \
 javax/swing/text/Document.java \
 javax/swing/text/DocumentFilter.java \
 javax/swing/text/EditorKit.java \
 javax/swing/text/Element.java \
+javax/swing/text/FieldView.java \
 javax/swing/text/GapContent.java \
+javax/swing/text/Highlighter.java \
 javax/swing/text/JTextComponent.java \
 javax/swing/text/Keymap.java \
+javax/swing/text/LayeredHighlighter.java \
 javax/swing/text/PlainDocument.java \
-javax/swing/text/PlainEditorKit.java \
+javax/swing/text/PlainView.java \
 javax/swing/text/Position.java \
 javax/swing/text/Segment.java \
+javax/swing/text/SimpleAttributeSet.java \
 javax/swing/text/Style.java \
+javax/swing/text/StyleConstants.java \
+javax/swing/text/StyleContext.java \
+javax/swing/text/TabExpander.java \
+javax/swing/text/TabableView.java \
+javax/swing/text/TabSet.java \
+javax/swing/text/TabStop.java \
+javax/swing/text/Utilities.java \
 javax/swing/text/View.java \
 javax/swing/text/ViewFactory.java \
 javax/swing/text/MutableAttributeSet.java \
@@ -1275,6 +1342,8 @@
 javax/swing/ProgressMonitorInputStream.java \
 javax/swing/RepaintManager.java \
 javax/swing/ScrollPaneLayout.java \
+javax/swing/Spring.java \
+javax/swing/SpringLayout.java \
 javax/swing/ToolTipManager.java \
 javax/swing/ViewportLayout.java
 
@@ -2042,6 +2111,8 @@
 gnu/java/nio/charset/UTF_8.java \
 gnu/java/security/Engine.java \
 gnu/java/security/OID.java \
+gnu/java/security/action/GetPropertyAction.java \
+gnu/java/security/action/SetAccessibleAction.java \
 gnu/java/security/der/BitString.java \
 gnu/java/security/der/DER.java \
 gnu/java/security/der/DEREncodingException.java \
@@ -2490,7 +2561,6 @@
 gnu/gcj/runtime/natStackTrace.cc \
 gnu/gcj/runtime/natStringBuffer.cc \
 gnu/gcj/runtime/natVMClassLoader.cc \
-gnu/java/awt/natEmbeddedWindow.cc \
 gnu/java/net/natPlainDatagramSocketImpl.cc \
 gnu/java/net/natPlainSocketImpl.cc \
 gnu/java/net/protocol/core/natCoreInputStream.cc \
@@ -2670,7 +2740,6 @@
 gnu/gcj/runtime/natFirstThread.lo gnu/gcj/runtime/natNameFinder.lo \
 gnu/gcj/runtime/natSharedLibLoader.lo gnu/gcj/runtime/natStackTrace.lo \
 gnu/gcj/runtime/natStringBuffer.lo gnu/gcj/runtime/natVMClassLoader.lo \
-gnu/java/awt/natEmbeddedWindow.lo \
 gnu/java/net/natPlainDatagramSocketImpl.lo \
 gnu/java/net/natPlainSocketImpl.lo \
 gnu/java/net/protocol/core/natCoreInputStream.lo \
@@ -2732,15 +2801,16 @@
 org/w3c/dom/traversal/TreeWalker.lo
 lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = 
 @GTK_CAIRO_FALSE@lib_gnu_java_awt_peer_gtk_la_OBJECTS =  \
+@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GThreadMutex.lo \
+@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkClasspathFontPeer.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkFontMetrics.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGlyphVector.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGraphics.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGraphics2D.lo \
+@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkPixbufDecoder.lo \
-@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkArg.lo \
-@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkArgList.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkButtonPeer.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkCanvasPeer.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.lo \
@@ -2775,11 +2845,13 @@
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkTextFieldPeer.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkToolkit.lo \
 @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkWindowPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.lo \
@@ -2788,11 +2860,13 @@
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.lo \
 @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.lo \
@@ -2808,15 +2882,16 @@
 @GTK_CAIRO_FALSE@jni/classpath/jnilink.lo jni/classpath/native_state.lo \
 @GTK_CAIRO_FALSE@jni/classpath/primlib.lo
 @GTK_CAIRO_TRUE@lib_gnu_java_awt_peer_gtk_la_OBJECTS =  \
+@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GThreadMutex.lo \
+@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkClasspathFontPeer.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkFontMetrics.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGlyphVector.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGraphics.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGraphics2D.lo \
+@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkPixbufDecoder.lo \
-@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkArg.lo \
-@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkArgList.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkButtonPeer.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkCanvasPeer.lo \
 @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.lo \
@@ -2855,11 +2930,13 @@
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.lo \
@@ -2868,11 +2945,13 @@
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.lo \
 @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.lo \
@@ -2930,7 +3009,7 @@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 DIST_SUBDIRS =  @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include
 DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
@@ -3020,19 +3099,19 @@
 .deps/gnu/java/awt/EventModifier.P \
 .deps/gnu/java/awt/image/ImageDecoder.P \
 .deps/gnu/java/awt/image/XBMDecoder.P \
-.deps/gnu/java/awt/natEmbeddedWindow.P \
 .deps/gnu/java/awt/peer/ClasspathFontPeer.P \
 .deps/gnu/java/awt/peer/EmbeddedWindowPeer.P \
 .deps/gnu/java/awt/peer/GLightweightPeer.P \
+.deps/gnu/java/awt/peer/gtk/GThreadMutex.P \
+.deps/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.P \
 .deps/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.P \
 .deps/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.P \
 .deps/gnu/java/awt/peer/gtk/GdkFontMetrics.P \
 .deps/gnu/java/awt/peer/gtk/GdkGlyphVector.P \
 .deps/gnu/java/awt/peer/gtk/GdkGraphics.P \
 .deps/gnu/java/awt/peer/gtk/GdkGraphics2D.P \
+.deps/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.P \
 .deps/gnu/java/awt/peer/gtk/GdkPixbufDecoder.P \
-.deps/gnu/java/awt/peer/gtk/GtkArg.P \
-.deps/gnu/java/awt/peer/gtk/GtkArgList.P \
 .deps/gnu/java/awt/peer/gtk/GtkButtonPeer.P \
 .deps/gnu/java/awt/peer/gtk/GtkCanvasPeer.P \
 .deps/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.P \
@@ -3300,6 +3379,8 @@
 .deps/gnu/java/rmi/server/UnicastServer.P \
 .deps/gnu/java/rmi/server/UnicastServerRef.P \
 .deps/gnu/java/security/Engine.P .deps/gnu/java/security/OID.P \
+.deps/gnu/java/security/action/GetPropertyAction.P \
+.deps/gnu/java/security/action/SetAccessibleAction.P \
 .deps/gnu/java/security/der/BitString.P \
 .deps/gnu/java/security/der/DER.P \
 .deps/gnu/java/security/der/DEREncodingException.P \
@@ -3502,16 +3583,21 @@
 .deps/java/awt/im/spi/InputMethod.P \
 .deps/java/awt/im/spi/InputMethodContext.P \
 .deps/java/awt/im/spi/InputMethodDescriptor.P \
+.deps/java/awt/image/AffineTransformOp.P \
 .deps/java/awt/image/AreaAveragingScaleFilter.P \
 .deps/java/awt/image/BufferStrategy.P \
 .deps/java/awt/image/BufferedImage.P \
 .deps/java/awt/image/BufferedImageOp.P \
+.deps/java/awt/image/ByteLookupTable.P \
 .deps/java/awt/image/ColorModel.P \
 .deps/java/awt/image/ComponentColorModel.P \
 .deps/java/awt/image/ComponentSampleModel.P \
 .deps/java/awt/image/CropImageFilter.P \
 .deps/java/awt/image/DataBuffer.P .deps/java/awt/image/DataBufferByte.P \
+.deps/java/awt/image/DataBufferDouble.P \
+.deps/java/awt/image/DataBufferFloat.P \
 .deps/java/awt/image/DataBufferInt.P \
+.deps/java/awt/image/DataBufferShort.P \
 .deps/java/awt/image/DataBufferUShort.P \
 .deps/java/awt/image/DirectColorModel.P \
 .deps/java/awt/image/FilteredImageSource.P \
@@ -3519,15 +3605,18 @@
 .deps/java/awt/image/ImageObserver.P \
 .deps/java/awt/image/ImageProducer.P \
 .deps/java/awt/image/ImagingOpException.P \
-.deps/java/awt/image/IndexColorModel.P \
+.deps/java/awt/image/IndexColorModel.P .deps/java/awt/image/Kernel.P \
+.deps/java/awt/image/LookupTable.P \
 .deps/java/awt/image/MemoryImageSource.P \
 .deps/java/awt/image/PackedColorModel.P \
 .deps/java/awt/image/PixelGrabber.P \
+.deps/java/awt/image/PixelInterleavedSampleModel.P \
 .deps/java/awt/image/RGBImageFilter.P .deps/java/awt/image/Raster.P \
 .deps/java/awt/image/RasterFormatException.P \
 .deps/java/awt/image/RasterOp.P .deps/java/awt/image/RenderedImage.P \
 .deps/java/awt/image/ReplicateScaleFilter.P \
 .deps/java/awt/image/SampleModel.P \
+.deps/java/awt/image/ShortLookupTable.P \
 .deps/java/awt/image/SinglePixelPackedSampleModel.P \
 .deps/java/awt/image/TileObserver.P \
 .deps/java/awt/image/VolatileImage.P \
@@ -4303,13 +4392,14 @@
 .deps/javax/swing/AbstractAction.P .deps/javax/swing/AbstractButton.P \
 .deps/javax/swing/AbstractCellEditor.P \
 .deps/javax/swing/AbstractListModel.P .deps/javax/swing/AbstractSet.P \
-.deps/javax/swing/Action.P .deps/javax/swing/ActionMap.P \
-.deps/javax/swing/BorderFactory.P .deps/javax/swing/BoundedRangeModel.P \
-.deps/javax/swing/Box.P .deps/javax/swing/BoxLayout.P \
-.deps/javax/swing/ButtonGroup.P .deps/javax/swing/ButtonModel.P \
-.deps/javax/swing/CellEditor.P .deps/javax/swing/CellRendererPane.P \
-.deps/javax/swing/ComboBoxEditor.P .deps/javax/swing/ComboBoxModel.P \
-.deps/javax/swing/ComponentInputMap.P .deps/javax/swing/DebugGraphics.P \
+.deps/javax/swing/AbstractSpinnerModel.P .deps/javax/swing/Action.P \
+.deps/javax/swing/ActionMap.P .deps/javax/swing/BorderFactory.P \
+.deps/javax/swing/BoundedRangeModel.P .deps/javax/swing/Box.P \
+.deps/javax/swing/BoxLayout.P .deps/javax/swing/ButtonGroup.P \
+.deps/javax/swing/ButtonModel.P .deps/javax/swing/CellEditor.P \
+.deps/javax/swing/CellRendererPane.P .deps/javax/swing/ComboBoxEditor.P \
+.deps/javax/swing/ComboBoxModel.P .deps/javax/swing/ComponentInputMap.P \
+.deps/javax/swing/DebugGraphics.P \
 .deps/javax/swing/DefaultBoundedRangeModel.P \
 .deps/javax/swing/DefaultButtonModel.P \
 .deps/javax/swing/DefaultCellEditor.P \
@@ -4341,8 +4431,9 @@
 .deps/javax/swing/JRadioButtonMenuItem.P .deps/javax/swing/JRootPane.P \
 .deps/javax/swing/JScrollBar.P .deps/javax/swing/JScrollPane.P \
 .deps/javax/swing/JSeparator.P .deps/javax/swing/JSlider.P \
-.deps/javax/swing/JSplitPane.P .deps/javax/swing/JTabbedPane.P \
-.deps/javax/swing/JTable.P .deps/javax/swing/JTextField.P \
+.deps/javax/swing/JSpinner.P .deps/javax/swing/JSplitPane.P \
+.deps/javax/swing/JTabbedPane.P .deps/javax/swing/JTable.P \
+.deps/javax/swing/JTextArea.P .deps/javax/swing/JTextField.P \
 .deps/javax/swing/JTextPane.P .deps/javax/swing/JToggleButton.P \
 .deps/javax/swing/JToolBar.P .deps/javax/swing/JToolTip.P \
 .deps/javax/swing/JTree.P .deps/javax/swing/JViewport.P \
@@ -4361,9 +4452,11 @@
 .deps/javax/swing/ScrollPaneLayout.P .deps/javax/swing/Scrollable.P \
 .deps/javax/swing/SingleSelectionModel.P \
 .deps/javax/swing/SizeRequirements.P .deps/javax/swing/SizeSequence.P \
+.deps/javax/swing/SpinnerModel.P .deps/javax/swing/SpinnerNumberModel.P \
+.deps/javax/swing/Spring.P .deps/javax/swing/SpringLayout.P \
 .deps/javax/swing/SwingConstants.P .deps/javax/swing/SwingUtilities.P \
-.deps/javax/swing/Timer.P .deps/javax/swing/ToggleButtonModel.P \
-.deps/javax/swing/ToolTipManager.P .deps/javax/swing/UIDefaults.P \
+.deps/javax/swing/Timer.P .deps/javax/swing/ToolTipManager.P \
+.deps/javax/swing/TransferHandler.P .deps/javax/swing/UIDefaults.P \
 .deps/javax/swing/UIManager.P \
 .deps/javax/swing/UnsupportedLookAndFeelException.P \
 .deps/javax/swing/ViewportLayout.P .deps/javax/swing/WindowConstants.P \
@@ -4381,6 +4474,10 @@
 .deps/javax/swing/colorchooser/ColorChooserComponentFactory.P \
 .deps/javax/swing/colorchooser/ColorSelectionModel.P \
 .deps/javax/swing/colorchooser/DefaultColorSelectionModel.P \
+.deps/javax/swing/colorchooser/DefaultHSBChooserPanel.P \
+.deps/javax/swing/colorchooser/DefaultPreviewPanel.P \
+.deps/javax/swing/colorchooser/DefaultRGBChooserPanel.P \
+.deps/javax/swing/colorchooser/DefaultSwatchChooserPanel.P \
 .deps/javax/swing/event/AncestorEvent.P \
 .deps/javax/swing/event/AncestorListener.P \
 .deps/javax/swing/event/CaretEvent.P \
@@ -4459,26 +4556,59 @@
 .deps/javax/swing/plaf/TextUI.P .deps/javax/swing/plaf/ToolBarUI.P \
 .deps/javax/swing/plaf/ToolTipUI.P .deps/javax/swing/plaf/TreeUI.P \
 .deps/javax/swing/plaf/UIResource.P .deps/javax/swing/plaf/ViewportUI.P \
+.deps/javax/swing/plaf/basic/BasicArrowButton.P \
 .deps/javax/swing/plaf/basic/BasicBorders.P \
+.deps/javax/swing/plaf/basic/BasicButtonListener.P \
 .deps/javax/swing/plaf/basic/BasicButtonUI.P \
+.deps/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.P \
 .deps/javax/swing/plaf/basic/BasicCheckBoxUI.P \
-.deps/javax/swing/plaf/basic/BasicDefaults.P \
+.deps/javax/swing/plaf/basic/BasicColorChooserUI.P \
+.deps/javax/swing/plaf/basic/BasicComboBoxEditor.P \
+.deps/javax/swing/plaf/basic/BasicComboBoxRenderer.P \
+.deps/javax/swing/plaf/basic/BasicComboBoxUI.P \
+.deps/javax/swing/plaf/basic/BasicComboPopup.P \
+.deps/javax/swing/plaf/basic/BasicDesktopIconUI.P \
+.deps/javax/swing/plaf/basic/BasicDesktopPaneUI.P \
+.deps/javax/swing/plaf/basic/BasicFormattedTextFieldUI.P \
 .deps/javax/swing/plaf/basic/BasicGraphicsUtils.P \
 .deps/javax/swing/plaf/basic/BasicIconFactory.P \
+.deps/javax/swing/plaf/basic/BasicInternalFrameTitlePane.P \
+.deps/javax/swing/plaf/basic/BasicInternalFrameUI.P \
 .deps/javax/swing/plaf/basic/BasicLabelUI.P \
 .deps/javax/swing/plaf/basic/BasicListUI.P \
 .deps/javax/swing/plaf/basic/BasicLookAndFeel.P \
+.deps/javax/swing/plaf/basic/BasicMenuBarUI.P \
+.deps/javax/swing/plaf/basic/BasicMenuItemUI.P \
+.deps/javax/swing/plaf/basic/BasicMenuUI.P \
 .deps/javax/swing/plaf/basic/BasicOptionPaneUI.P \
 .deps/javax/swing/plaf/basic/BasicPanelUI.P \
+.deps/javax/swing/plaf/basic/BasicPasswordFieldUI.P \
+.deps/javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.P \
+.deps/javax/swing/plaf/basic/BasicPopupMenuUI.P \
+.deps/javax/swing/plaf/basic/BasicProgressBarUI.P \
+.deps/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.P \
 .deps/javax/swing/plaf/basic/BasicRadioButtonUI.P \
+.deps/javax/swing/plaf/basic/BasicRootPaneUI.P \
+.deps/javax/swing/plaf/basic/BasicScrollBarUI.P \
 .deps/javax/swing/plaf/basic/BasicScrollPaneUI.P \
+.deps/javax/swing/plaf/basic/BasicSeparatorUI.P \
+.deps/javax/swing/plaf/basic/BasicSliderUI.P \
+.deps/javax/swing/plaf/basic/BasicSpinnerUI.P \
 .deps/javax/swing/plaf/basic/BasicSplitPaneDivider.P \
 .deps/javax/swing/plaf/basic/BasicSplitPaneUI.P \
 .deps/javax/swing/plaf/basic/BasicTabbedPaneUI.P \
+.deps/javax/swing/plaf/basic/BasicTableHeaderUI.P \
+.deps/javax/swing/plaf/basic/BasicTableUI.P \
+.deps/javax/swing/plaf/basic/BasicTextAreaUI.P \
+.deps/javax/swing/plaf/basic/BasicTextFieldUI.P \
 .deps/javax/swing/plaf/basic/BasicTextUI.P \
 .deps/javax/swing/plaf/basic/BasicToggleButtonUI.P \
+.deps/javax/swing/plaf/basic/BasicToolBarSeparatorUI.P \
+.deps/javax/swing/plaf/basic/BasicToolBarUI.P \
+.deps/javax/swing/plaf/basic/BasicToolTipUI.P \
 .deps/javax/swing/plaf/basic/BasicTreeUI.P \
 .deps/javax/swing/plaf/basic/BasicViewportUI.P \
+.deps/javax/swing/plaf/basic/ComboPopup.P \
 .deps/javax/swing/plaf/metal/MetalLookAndFeel.P \
 .deps/javax/swing/table/AbstractTableModel.P \
 .deps/javax/swing/table/DefaultTableCellRenderer.P \
@@ -4493,25 +4623,32 @@
 .deps/javax/swing/text/AbstractDocument.P \
 .deps/javax/swing/text/AttributeSet.P \
 .deps/javax/swing/text/BadLocationException.P \
-.deps/javax/swing/text/Caret.P \
-.deps/javax/swing/text/CharacterIterator.P \
-.deps/javax/swing/text/ComponentView.P \
+.deps/javax/swing/text/Caret.P .deps/javax/swing/text/ComponentView.P \
 .deps/javax/swing/text/DefaultCaret.P \
 .deps/javax/swing/text/DefaultEditorKit.P \
+.deps/javax/swing/text/DefaultHighlighter.P \
 .deps/javax/swing/text/Document.P \
 .deps/javax/swing/text/DocumentFilter.P \
 .deps/javax/swing/text/EditorKit.P .deps/javax/swing/text/Element.P \
-.deps/javax/swing/text/GapContent.P \
+.deps/javax/swing/text/FieldView.P .deps/javax/swing/text/GapContent.P \
+.deps/javax/swing/text/Highlighter.P \
 .deps/javax/swing/text/JTextComponent.P .deps/javax/swing/text/Keymap.P \
+.deps/javax/swing/text/LayeredHighlighter.P \
 .deps/javax/swing/text/MutableAttributeSet.P \
 .deps/javax/swing/text/NavigationFilter.P \
 .deps/javax/swing/text/PlainDocument.P \
-.deps/javax/swing/text/PlainEditorKit.P \
-.deps/javax/swing/text/Position.P .deps/javax/swing/text/Segment.P \
-.deps/javax/swing/text/Style.P .deps/javax/swing/text/StyledDocument.P \
+.deps/javax/swing/text/PlainView.P .deps/javax/swing/text/Position.P \
+.deps/javax/swing/text/Segment.P \
+.deps/javax/swing/text/SimpleAttributeSet.P \
+.deps/javax/swing/text/Style.P .deps/javax/swing/text/StyleConstants.P \
+.deps/javax/swing/text/StyleContext.P \
+.deps/javax/swing/text/StyledDocument.P \
 .deps/javax/swing/text/StyledEditorKit.P \
-.deps/javax/swing/text/TextAction.P .deps/javax/swing/text/View.P \
-.deps/javax/swing/text/ViewFactory.P .deps/javax/swing/text/html/HTML.P \
+.deps/javax/swing/text/TabExpander.P .deps/javax/swing/text/TabSet.P \
+.deps/javax/swing/text/TabStop.P .deps/javax/swing/text/TabableView.P \
+.deps/javax/swing/text/TextAction.P .deps/javax/swing/text/Utilities.P \
+.deps/javax/swing/text/View.P .deps/javax/swing/text/ViewFactory.P \
+.deps/javax/swing/text/html/HTML.P \
 .deps/javax/swing/text/html/parser/ParserDelegator.P \
 .deps/javax/swing/tree/AbstractLayoutCache.P \
 .deps/javax/swing/tree/DefaultMutableTreeNode.P \
@@ -4557,6 +4694,7 @@
 .deps/javax/transaction/xa/Xid.P .deps/jni.P .deps/jni/classpath/jcl.P \
 .deps/jni/classpath/jnilink.P .deps/jni/classpath/native_state.P \
 .deps/jni/classpath/primlib.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.P \
@@ -4566,6 +4704,7 @@
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.P \
@@ -4574,11 +4713,13 @@
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.P \
 .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.P \
Index: gnu/awt/LightweightRedirector.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/awt/LightweightRedirector.java,v
retrieving revision 1.1
diff -u -r1.1 LightweightRedirector.java
--- gnu/awt/LightweightRedirector.java	22 Oct 2000 17:46:08 -0000	1.1
+++ gnu/awt/LightweightRedirector.java	6 Sep 2004 16:35:37 -0000
@@ -141,7 +141,7 @@
     
     MouseEvent redirected = new MouseEvent(source, event.getID(),
 					   event.getWhen(),
-					   event.getModifiers(),
+					   event.getModifiersEx(),
 					   x, y,
 					   event.getClickCount(),
 					   event.isPopupTrigger());
@@ -157,20 +157,20 @@
    */
   int getButtonNumber(InputEvent event)
   {
-    int modifiers = event.getModifiers();
+    int modifiers = event.getModifiersEx();
     
     modifiers &=
-      InputEvent.BUTTON1_MASK |
-      InputEvent.BUTTON2_MASK |
-      InputEvent.BUTTON3_MASK;
+      InputEvent.BUTTON1_DOWN_MASK |
+      InputEvent.BUTTON2_DOWN_MASK |
+      InputEvent.BUTTON3_DOWN_MASK;
     
     switch (modifiers)
       {
-      case InputEvent.BUTTON1_MASK:
+      case InputEvent.BUTTON1_DOWN_MASK:
 	return 1;
-      case InputEvent.BUTTON2_MASK:
+      case InputEvent.BUTTON2_DOWN_MASK:
 	return 2;
-      case InputEvent.BUTTON3_MASK:
+      case InputEvent.BUTTON3_DOWN_MASK:
 	return 3;
       case 0:
 	return 0;
Index: gnu/java/awt/BitwiseXORComposite.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/BitwiseXORComposite.java,v
retrieving revision 1.1
diff -u -r1.1 BitwiseXORComposite.java
--- gnu/java/awt/BitwiseXORComposite.java	12 Jan 2004 19:11:00 -0000	1.1
+++ gnu/java/awt/BitwiseXORComposite.java	6 Sep 2004 16:35:37 -0000
@@ -232,7 +232,7 @@
                         WritableRaster dstOut)
     {
       int aX, bX, dstX, aY, bY, dstY, width, height;
-      int xorPixel, transferType;
+      int xorPixel;
       int[] srcLine, dstLine;
 
       aX = src.getMinX();
Index: gnu/java/awt/Buffers.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/Buffers.java,v
retrieving revision 1.2
diff -u -r1.2 Buffers.java
--- gnu/java/awt/Buffers.java	22 Jan 2002 22:39:48 -0000	1.2
+++ gnu/java/awt/Buffers.java	6 Sep 2004 16:35:37 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002  Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004  Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -83,10 +83,16 @@
       {
       case DataBuffer.TYPE_BYTE:
 	return new DataBufferByte(size, numBanks);
+      case DataBuffer.TYPE_SHORT:
+	return new DataBufferShort(size, numBanks);
       case DataBuffer.TYPE_USHORT:
 	return new DataBufferUShort(size, numBanks);
       case DataBuffer.TYPE_INT:
 	return new DataBufferInt(size, numBanks);
+      case DataBuffer.TYPE_FLOAT:
+	return new DataBufferFloat(size, numBanks);
+      case DataBuffer.TYPE_DOUBLE:
+	return new DataBufferDouble(size, numBanks);
       default:
 	throw new UnsupportedOperationException();
       }
@@ -106,10 +112,16 @@
       {
       case DataBuffer.TYPE_BYTE:
 	return new DataBufferByte((byte[]) data, size);
+      case DataBuffer.TYPE_SHORT:
+	return new DataBufferShort((short[]) data, size);
       case DataBuffer.TYPE_USHORT:
 	return new DataBufferUShort((short[]) data, size);
       case DataBuffer.TYPE_INT:
 	return new DataBufferInt((int[]) data, size);
+      case DataBuffer.TYPE_FLOAT:
+	return new DataBufferFloat((float[]) data, size);
+      case DataBuffer.TYPE_DOUBLE:
+	return new DataBufferDouble((double[]) data, size);
       default:
 	throw new UnsupportedOperationException();
       }
@@ -126,10 +138,22 @@
   {
     if (buffer instanceof DataBufferByte)
       return ((DataBufferByte) buffer).getData();
+
+    if (buffer instanceof DataBufferShort)
+      return ((DataBufferShort) buffer).getData();
+
     if (buffer instanceof DataBufferUShort)
       return ((DataBufferUShort) buffer).getData();
+
     if (buffer instanceof DataBufferInt)
       return ((DataBufferInt) buffer).getData();
+
+    if (buffer instanceof DataBufferFloat)
+      return ((DataBufferFloat) buffer).getData();
+
+    if (buffer instanceof DataBufferDouble)
+      return ((DataBufferDouble) buffer).getData();
+
     throw new ClassCastException("Unknown data buffer type");
   }
 
@@ -149,6 +173,11 @@
 	from = ((DataBufferByte) src).getData();
 	if (dest == null) dest = new byte[length+destOffset];
       }
+    else if (src instanceof DataBufferShort)
+      {
+	from = ((DataBufferShort) src).getData();
+	if (dest == null) dest = new short[length+destOffset];
+      }
     else if (src instanceof DataBufferUShort)
       {
 	from = ((DataBufferUShort) src).getData();
@@ -159,6 +188,16 @@
 	from = ((DataBufferInt) src).getData();
 	if (dest == null) dest = new int[length+destOffset];
       }
+    else if (src instanceof DataBufferFloat)
+      {
+	from = ((DataBufferFloat) src).getData();
+	if (dest == null) dest = new float[length+destOffset];
+      }
+    else if (src instanceof DataBufferDouble)
+      {
+	from = ((DataBufferDouble) src).getData();
+	if (dest == null) dest = new double[length+destOffset];
+      }
     else
       {
 	throw new ClassCastException("Unknown data buffer type");
Index: gnu/java/awt/ClasspathToolkit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/ClasspathToolkit.java,v
retrieving revision 1.1
diff -u -r1.1 ClasspathToolkit.java
--- gnu/java/awt/ClasspathToolkit.java	25 Oct 2003 18:41:45 -0000	1.1
+++ gnu/java/awt/ClasspathToolkit.java	6 Sep 2004 16:35:37 -0000
@@ -48,6 +48,7 @@
 import java.awt.HeadlessException;
 import java.awt.Toolkit;
 import java.awt.image.ColorModel;
+import java.awt.image.ImageProducer;
 import java.io.File;
 import java.io.InputStream;
 import java.io.IOException;
@@ -331,4 +332,17 @@
         .initCause(muex);
     }
   }
+  
+  /**
+   * Creates an ImageProducer from the specified URL. The image is assumed
+   * to be in a recognised format. If the toolkit does not implement the
+   * image format or the image format is not recognised, null is returned.
+   * This default implementation is overriden by the Toolkit implementations.
+   *
+   * @param url URL to read image data from.
+   */
+  public ImageProducer createImageProducer(URL url)
+  {
+    return null;
+  }
 }
Index: gnu/java/awt/ComponentDataBlitOp.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/ComponentDataBlitOp.java,v
retrieving revision 1.2
diff -u -r1.2 ComponentDataBlitOp.java
--- gnu/java/awt/ComponentDataBlitOp.java	22 Jan 2002 22:39:48 -0000	1.2
+++ gnu/java/awt/ComponentDataBlitOp.java	6 Sep 2004 16:35:37 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002  Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004  Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -36,9 +36,14 @@
 
 package gnu.java.awt;
 
-import java.awt.geom.*;
-import java.awt.image.*;
 import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.RasterOp;
+import java.awt.image.WritableRaster;
 
 /**
  * This raster copy operation assumes that both source and destination
@@ -52,7 +57,7 @@
  */
 public class ComponentDataBlitOp implements RasterOp
 {
-  public static ComponentDataBlitOp INSTANCE = new ComponentDataBlitOp();
+  public static final ComponentDataBlitOp INSTANCE = new ComponentDataBlitOp();
 
   public WritableRaster filter(Raster src, WritableRaster dest)
   {
Index: gnu/java/awt/EmbeddedWindow.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/EmbeddedWindow.java,v
retrieving revision 1.3
diff -u -r1.3 EmbeddedWindow.java
--- gnu/java/awt/EmbeddedWindow.java	5 Jan 2004 21:41:20 -0000	1.3
+++ gnu/java/awt/EmbeddedWindow.java	6 Sep 2004 16:35:37 -0000
@@ -1,5 +1,5 @@
 /* EmbeddedWindow.java --
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,15 +38,21 @@
 
 package gnu.java.awt;
 
+import gnu.classpath.Configuration;
 import gnu.java.awt.peer.EmbeddedWindowPeer;
+import gnu.java.security.action.SetAccessibleAction;
+
+import java.awt.Component;
 import java.awt.Frame;
 import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.security.AccessController;
 
 /**
  * Represents an AWT window that can be embedded into another
  * application.
  * 
- * @author Michael Koch <konqueror@gmx.de>
+ * @author Michael Koch (konqueror@gmx.de)
  */
 public class EmbeddedWindow extends Frame
 {
@@ -84,16 +90,29 @@
 
     if (! (tk instanceof EmbeddedWindowSupport))
       throw new UnsupportedOperationException
-        ("Embedded windows are not supported by the current peers: " + tk.getClass());
+        ("Embedded windows are not supported by the current peers: "
+	 + tk.getClass());
+
+    // Circumvent the package-privateness of the AWT internal
+    // java.awt.Component.peer member variable.
+    try
+      {
+	Field peerField = Component.class.getDeclaredField("peer");
+	AccessController.doPrivileged(new SetAccessibleAction(peerField));
+	peerField.set(this, ((EmbeddedWindowSupport) tk).createEmbeddedWindow (this));
+      }
+    catch (IllegalAccessException e)
+      {
+	// This should never happen.
+      }
+    catch (NoSuchFieldException e)
+      {
+	// This should never happen.
+      }
 
-    setWindowPeer (((EmbeddedWindowSupport) tk).createEmbeddedWindow (this));
     super.addNotify();
   }
 
-  // This method is only made native to circumvent the package-privateness of
-  // an AWT internal java.awt.Component.peer member variable.
-  native void setWindowPeer (EmbeddedWindowPeer peer);
-
   /**
    * If the native peer for this embedded window has been created,
    * then setHandle will embed the window.  If not, setHandle tells
@@ -108,8 +127,8 @@
       throw new RuntimeException ("EmbeddedWindow is already embedded");
 
     this.handle = handle;
-    if (peer != null)
-      ((EmbeddedWindowPeer) peer).embed (this.handle);
+    if (getPeer() != null)
+      ((EmbeddedWindowPeer) getPeer()).embed (this.handle);
   }
 
   /**
Index: gnu/java/awt/natEmbeddedWindow.cc
===================================================================
RCS file: gnu/java/awt/natEmbeddedWindow.cc
diff -N gnu/java/awt/natEmbeddedWindow.cc
--- gnu/java/awt/natEmbeddedWindow.cc	4 Sep 2003 16:58:13 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,18 +0,0 @@
-/* Copyright (C) 2003  Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-#include <gnu/java/awt/EmbeddedWindow.h>
-#include <gnu/java/awt/peer/EmbeddedWindowPeer.h>
-#include <java/awt/peer/ComponentPeer.h>
-
-void
-gnu::java::awt::EmbeddedWindow::setWindowPeer (gnu::java::awt::peer::EmbeddedWindowPeer* w)
-{
-  if (!peer)
-    peer = reinterpret_cast< ::java::awt::peer::ComponentPeer *> (w);
-}
Index: gnu/java/awt/image/ImageDecoder.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/image/ImageDecoder.java,v
retrieving revision 1.3
diff -u -r1.3 ImageDecoder.java
--- gnu/java/awt/image/ImageDecoder.java	10 Jan 2004 21:32:22 -0000	1.3
+++ gnu/java/awt/image/ImageDecoder.java	6 Sep 2004 16:35:37 -0000
@@ -1,5 +1,5 @@
 /* ImageDecoder.java
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,11 +37,14 @@
 
 package gnu.java.awt.image;
 
-import java.awt.*;
-import java.awt.image.*;
-import java.util.*;
-import java.io.*;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
 import java.net.URL;
+import java.util.Vector;
 
 public abstract class ImageDecoder implements ImageProducer 
 {
@@ -53,8 +56,6 @@
   int length;
   InputStream input;
 
-  public static ColorModel cm;
-
   static
   {
     // FIXME: there was some broken code here that looked like
@@ -97,7 +98,9 @@
 
   public void startProduction (ImageConsumer ic)
   {
+    if (!isConsumer(ic))
     addConsumer (ic);
+
     Vector list = (Vector) consumers.clone ();
     try 
       {
Index: gnu/java/awt/peer/ClasspathFontPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/ClasspathFontPeer.java,v
retrieving revision 1.1
diff -u -r1.1 ClasspathFontPeer.java
--- gnu/java/awt/peer/ClasspathFontPeer.java	25 Oct 2003 18:41:45 -0000	1.1
+++ gnu/java/awt/peer/ClasspathFontPeer.java	6 Sep 2004 16:35:37 -0000
@@ -1,5 +1,5 @@
 /* ClasspathFontPeer.java -- Font peer used by GNU Classpath.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -56,12 +56,12 @@
  * <p><b>State kept by the peer:</b> a peer is generated for each Font
  * object in the default implementation. If you wish to share peers between
  * fonts, you will need to subclass both ClasspathFontPeer and
- * {@link ClasspathToolKit}.
+ * {@link ClasspathToolKit}.</p>
  * 
  * <p><b>Thread Safety:</b> Methods of this interface may be called
  * from arbitrary threads at any time. Implementations of the
  * <code>ClasspathFontPeer</code> interface are required to perform
- * the necessary synchronization.
+ * the necessary synchronization.</p>
  *
  * @see java.awt.Font#getPeer
  * @see java.awt.Toolkit#getFontPeer
@@ -395,6 +395,23 @@
   }
 
   /** 
+   * Implementation of {@link Font#deriveFont(int, float)}
+   *
+   * @param font the font this peer is being called from. This may be
+   * useful if you are sharing peers between Font objects. Otherwise it may
+   * be ignored.
+   */
+
+  public Font deriveFont (Font font, int style, float size)
+  {
+    Map attrs = new HashMap ();
+    getStandardAttributes (attrs);
+    copyStyleToAttrs (style, attrs);
+    copySizeToAttrs (size, attrs);
+    return tk().getFont (logicalName, attrs);
+  }
+
+  /** 
    * Implementation of {@link Font#deriveFont(float)}
    *
    * @param font the font this peer is being called from. This may be
@@ -444,6 +461,22 @@
   }
 
   /** 
+   * Implementation of {@link Font#deriveFont(AffineTransform)}
+   *
+   * @param font the font this peer is being called from. This may be
+   * useful if you are sharing peers between Font objects. Otherwise it may
+   * be ignored.
+   */
+
+  public Font deriveFont (Font font, AffineTransform t)
+  {
+    Map attrs = new HashMap ();
+    getStandardAttributes (attrs);
+    copyTransformToAttrs (t, attrs);
+    return tk().getFont (logicalName, attrs);
+  }
+
+  /** 
    * Implementation of {@link Font#deriveFont(Map)}
    *
    * @param font the font this peer is being called from. This may be
@@ -501,6 +534,8 @@
 
   public AffineTransform getTransform (Font font)
   {
+    if (transform == null)
+      transform = new AffineTransform ();
     return transform;
   }
 
Index: gnu/java/awt/peer/GLightweightPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/GLightweightPeer.java,v
retrieving revision 1.2
diff -u -r1.2 GLightweightPeer.java
--- gnu/java/awt/peer/GLightweightPeer.java	10 Jan 2004 21:32:22 -0000	1.2
+++ gnu/java/awt/peer/GLightweightPeer.java	6 Sep 2004 16:35:37 -0000
@@ -1,5 +1,5 @@
 /* GLightweightPeer.java --
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -45,7 +45,6 @@
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.Font;
-import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
Index: gnu/java/awt/peer/gtk/GThreadMutex.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GThreadMutex.java
diff -N gnu/java/awt/peer/gtk/GThreadMutex.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/awt/peer/gtk/GThreadMutex.java	6 Sep 2004 16:35:37 -0000
@@ -0,0 +1,109 @@
+/* GThreadMutex.java -- Implements a mutex object for glib's gthread
+   abstraction, for use with GNU Classpath's --portable-native-sync option.
+   This is used in gthread-jni.c
+   
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+/** Implements a mutex object for glib's gthread
+    abstraction, for use with GNU Classpath's --portable-native-sync option.
+    This is used in gthread-jni.c.
+
+    We use this object to implement the POSIX semantics for Mutexes.  They are
+    needed are needed for the function vector that is passed to glib's
+    g_thread subpackage's initialization function.
+
+    The GThreadMutex object itself serves as the Real Lock; if code has
+    entered the monitor for this GThreadMutex object (in Java language, if
+    it's synchronized on this object) then it holds the lock that this object
+    represents.
+
+    @author Steven Augart
+    May, 2004
+
+    
+*/
+   
+class GThreadMutex 
+{
+  /** Might "lock" be locked?  Is anyone waiting
+      to get that lock?  How long is the queue?
+
+      If zero, nobody holds a lock on this GThreadMutex object, and nobody is
+      trying to get one.   Before someone attempts to acquire a lock on this
+      object, they must increment potentialLockers.  After they release their
+      lock on this object, they must decrement potentialLockers.
+
+      Access to this field is guarded by synchronizing on the object
+      <code>lockForPotentialLockers</code>.
+
+      After construction, we only access this field via JNI.
+  */
+  volatile int potentialLockers;
+
+  /** An object to synchronize to if you want to examine or modify the
+      <code>potentialLockers</code> field.  Only hold this lock for brief
+      moments, just long enough to check or set the value of
+      <code>lockForPotentialLockers</code>.  
+      
+      We use this representation so that g_thread_mutex_trylock() will work
+      with the POSIX semantics.  This is the only case in which you ever hold a
+      lock on <code>lockForPotentialLockers</code> while trying to get another
+      lock -- if you are the mutex_trylock() implementation, and you have just
+      checked that <code>potentialLockers</code> has the value zero.  In that
+      case, mutex_trylock() holds the lock on lockForPotentialLockers so that
+      another thread calling mutex_trylock() or mutex_lock() won't increment
+      potentialLockers after we've checked it and before we've gained the lock
+      on the POSIX mutex.   Of course, in that case the operation of gaining
+      the POSIX lock itself will succeed immediately, and once it has
+      succeeded, trylock releases lockForPotentialLockers right away,
+      incremented to 1 (one).
+
+      After construction, we only access this field via JNI.
+  */     
+  Object lockForPotentialLockers;
+
+  GThreadMutex() 
+  {
+    potentialLockers = 0;
+    lockForPotentialLockers = new Object();
+  }
+}
+// Local Variables:
+// c-file-style: "gnu"
+// End:
Index: gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
diff -N gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java	6 Sep 2004 16:35:38 -0000
@@ -0,0 +1,302 @@
+/* GThreadNativeMethodRunner.java -- Implements pthread_create(), under
+   glib's gthread abstraction, for use with GNU Classpath's
+   --portable-native-sync option. 
+   This is used by gthread-jni.c
+   
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+import java.lang.ref.WeakReference;
+import java.util.Set;
+import java.util.Collections;
+import java.util.HashSet;
+
+/** Implements pthread_create(), under glib's gthread abstraction, for use
+    with GNU Classpath's --portable-native-sync option.  This is used in
+    gthread-jni.c
+
+    Also implements a registry for threads, mapping Thread objects to small
+    integers.  The registry uses weak references for threads that aren't
+    joinable, so that they will be garbage collected.
+
+    There are a number of possible alternative implementations.
+    
+    
+    The rest of this comment consists of an answer to a question that was
+    raised on the commit-classpath mailing list:
+
+    Mark Wielaard wrote:
+
+    > Can't we assume that jobject and gpointer are both (void *) so we don't
+    > need the int <-> Thread (global jobject ref) mapping?
+    > Maybe there are platforms where jobject and gpointer aren't the same,
+    > but I guess that is pretty unlikely.
+
+
+    I agree with you on the pointer size issues.  A gpointer is a void *, so
+    it's certainly guaranteed to be at least as large as any other
+    pointer. And a jobject is implicitly an opaque pointer (in Jikes RVM, we
+    use small integers, but we coerce them into the representation of a
+    pointer).
+
+    The int <==> Thread mapping addresses a different issue.  I realize that I
+    did not document this properly (two and a half lines in thread_create),
+    and the point is subtle (at least to me; took me a while to figure out).
+
+    The int => Thread mapping always returns jobjects that are local
+    references, not global ones.  This is because Thread objects need to be
+    able to go away and be garbage collected after the thread they refer to
+    has died.
+
+    If we keep a global object reference to a thread, then when do we delete
+    that global object reference?  We have an answer in the case of GThread
+    objects that were explicitly created with the joinable attribute.  It is
+    safe for us to maintain a global reference to any joinable thread, since
+    the joinable thread must linger (even if only in a zombie state)
+    until it's explicitly joined via a g_thread_join() call.  The global ref
+    could be cleaned up at that point too.
+
+    However, in the case of GThreads that were created non-joinable by
+    g_thread_create(), and in the case of Java threads that were created
+    within pure Java code (not via g_thread_create()), we don't want them to
+    linger forever, and there is no way to tell when the last reference
+    to such threads needs to expire.  In the case of this application -- AWT
+    with GTK peers -- it would probably be safe anyway, since there are not
+    very many threads we create, but I was going for correctness even in the
+    case of long-running programs that might set up and tear down AWT
+    interfaces many times.
+
+    So, I duplicated the POSIX thread-ID semantics.  The thread ID of a
+    non-joinable thread remains valid as long as that thread is still alive.
+    Once that thread dies, the old thread ID may be reused at any moment.  And
+    that's why the array indexed by thread ID numbers is an array of weak
+    references.
+
+    That's also why the int => Thread jobject mapping function always returns
+    local references, since global references would lock the Thread in memory
+    forever.
+
+    I would dearly love there to be a cleaner solution.  I dislike the
+    repeated dips from C code into Java that are necessary to look up thread
+    ID numbers.  If anyone can think of one, I'm all ears.
+*/
+
+class GThreadNativeMethodRunner 
+  extends Thread 
+{
+  /** The C function pointer that was passed to g_thread_create().
+      Specifically, this the numeric address of an object of 
+      C type "void *(*funcPtr)(void *funcArg)".   
+  */
+  private final long funcPtr;
+
+  /** The argument for the function "funcPtr(funcArg)". */
+  private final long funcArg;
+  
+  GThreadNativeMethodRunner(long funcPtr, long funcArg, boolean joinable) 
+  {
+    this.funcPtr = funcPtr;
+    this.funcArg = funcArg;
+
+    if (joinable)
+      registerSelfJoinable();
+  }
+
+  public void run() 
+  {
+    nativeRun(funcPtr, funcArg);
+  }
+
+  private native void nativeRun(long funcPtr, long funcArg);
+
+  /** THREADS is an array of threads, indexed by thread ID codes.  Not sure
+      whether this is the "best" approach but it does make it O(1) to look up a
+      thread by its ID. 
+
+      Zero is a valid thread ID code.  Any negative number is invalid.
+
+      Possible future fixes (TODO?)
+
+     - The THREADS array will only grow. probably not a problem.
+        But we could keep count when nulling entries and shrink when we have
+        lots of nulls at the end. Probably not worth it. --mjw
+
+     - Could make this a set of Object; see the comment on "joinable" below.
+
+     The initial size of 17 is just a starting point.  Any number will do,
+     including zero.
+  */ 
+  private static WeakReference[] threads = new WeakReference[17]; 
+
+  /**  Used by threadToThreadID, below.  Returns the registration number of
+       the newly-registered thread.  
+  */
+  private static synchronized int registerThread(Thread t) 
+  {
+    int i;
+
+    for (i = 0; i < threads.length; ++i) 
+      {
+	WeakReference ref = threads[i];
+	if (ref == null)
+	  break;                  // found an empty spot.
+      }
+
+    if (i == threads.length) 
+      {
+	/* expand the array */
+	WeakReference[] bigger = new WeakReference[threads.length * 2];
+        System.arraycopy(threads, 0, bigger, 0, threads.length);
+	threads = bigger;
+      }
+
+    threads[i] = new WeakReference(t);
+
+    return i;
+  }
+  
+  /**  Look up the Thread ID # for a Thread.  Assign a Thread ID # if none
+       exists.  This is a general routine for handling all threads, including
+       the VM's main thread, if appropriate.
+
+
+       Runs in O(n/2) time.
+
+       We can't just issue a threadID upon thread creation.  If we were to do
+       that, not all threads would have a threadID, because not all threads
+       are launched by GThreadNativeMethodRunner.
+  */ 
+  static synchronized int threadToThreadID(Thread t) 
+  {
+    for (int i = 0; i < threads.length; ++i ) 
+      {
+	if (threads[i] == null)
+	  continue;
+	Thread referent = (Thread) threads[i].get();
+	if (referent == null) 
+	  {
+	    threads[i] = null;      // Purge the dead WeakReference.
+	    continue;
+	  }
+	if (referent.equals(t))
+	  return i;
+      } // for()
+
+    /* No match found. */
+    return registerThread(t);
+  }
+
+  /** @param threadID Must be a non-negative integer.
+
+      Used to return null if the thread number was out of range or if
+      the thread was unregistered.   Now we throw an exception.
+
+      Possible Alternative Interface:  We could go back to returning null in
+           some sort of check-free mode, so code that calls this function must
+           be prepared to get null. 
+  */ 
+  static Thread threadIDToThread(int threadID) 
+    throws IllegalArgumentException
+  {
+    if (threadID < 0)
+      throw new IllegalArgumentException("Received a negative threadID, " 
+					 + threadID); 
+    if (threadID >= threads.length)
+      throw new IllegalArgumentException("Received a threadID (" + threadID 
+					 + ") higher than was" 
+					 + " ever issued"); 
+    
+    /* Note: if the user is using a stale reference, things will just
+       break.    We might end up getting a different thread than the one
+       expected. 
+       
+       TODO: Add an error-checking mode where the user's problems with threads
+          are announced.  For instance, if the user asks for the thread
+          associated with a threadID that was never issued, we could print a
+          warning or even abort.
+       
+       TODO: Consider optionally disabling all of the error-checking we
+          already have; it probably slows down the implementation.  We could
+          just return NULL.  This is just the reverse of the above TODO item.
+    */ 
+
+    WeakReference threadRef = threads[threadID];
+
+    if (threadRef == null)
+      throw new IllegalArgumentException("Asked to look up a stale or unissued"
+					 + "threadID (" + threadID + ")" );
+    
+      
+    Thread referent = (Thread) threadRef.get();
+    if (referent == null)
+      throw new IllegalArgumentException ("Asked to look up a stale threadID ("
+					  + threadID + ")");
+    return referent;
+  }
+  
+  /** Joinable threads need a hard reference, so that they won't go away when
+      they die.  That is because their thread IDs need to stay valid until the
+      thread is joined via thread_join(threadID).  Joinable threads have to be
+      explicitly joined before they are allowed to go away completely.
+
+      Possible Alternative Implementation: Eliminate the Joinable set.  When
+          calling getThreadIDFromThread() you know whether or not the thread
+          is joinable.  So just store the Thread itself in the threads array?
+          Make that array an Object array and check with instanceof.  This
+          looks cleaner and more robust to me and it saves a native -> Java
+          call. But instanceof might be expensive.  --mjw
+  */
+  private static final Set joinable = 
+       Collections.synchronizedSet(new HashSet()); 
+  
+  /** Only called from the constructor. */
+  private void registerSelfJoinable() 
+  {
+    joinable.add(this);
+  }
+  
+  /** This method is only called from JNI, and only after we have succeeded in
+      a thread_join() operation.  */
+  static void deRegisterJoinable(Thread thread) 
+  {
+    joinable.remove(thread);
+  }
+}
+
+// Local Variables:
+// c-file-style: "gnu"
+// End:
Index: gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java,v
retrieving revision 1.2
diff -u -r1.2 GdkClasspathFontPeer.java
--- gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java	20 Nov 2003 22:44:01 -0000	1.2
+++ gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java	6 Sep 2004 16:35:38 -0000
@@ -70,7 +70,9 @@
       {
         System.loadLibrary("gtkpeer");
       }
-    initStaticState ();
+
+    if (GtkToolkit.useGraphics2D ())
+      initStaticState ();
   }
   native static void initStaticState ();
   private final int native_state = GtkGenericPeer.getUniqueInteger ();
Index: gnu/java/awt/peer/gtk/GdkFontMetrics.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java,v
retrieving revision 1.3
diff -u -r1.3 GdkFontMetrics.java
--- gnu/java/awt/peer/gtk/GdkFontMetrics.java	1 Dec 2003 23:12:07 -0000	1.3
+++ gnu/java/awt/peer/gtk/GdkFontMetrics.java	6 Sep 2004 16:35:38 -0000
@@ -50,19 +50,21 @@
                        MAX_ADVANCE = 4;
 
   private int[] metrics;
-  private native int[] initState (String fname, int size);
+  private native int[] initState (String fname, int style, int size);
 
   public GdkFontMetrics (Font font)
   {
     super (font);
-    metrics = initState (font.getName (), font.getSize ());
+    metrics = initState (font.getName (), font.getStyle (), font.getSize ());
   }
 
-  native public int stringWidth (String fname, int size, String str);
+  native public int stringWidth (String fname, int style, int size,
+                                 String str);
 
   public int stringWidth (String str)
   {
-    return stringWidth (font.getName (), font.getSize (), str);
+    return stringWidth (font.getName (), font.getStyle (), font.getSize (),
+                        str);
   }
 
   public int charWidth (char ch)
Index: gnu/java/awt/peer/gtk/GdkGlyphVector.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java,v
retrieving revision 1.1
diff -u -r1.1 GdkGlyphVector.java
--- gnu/java/awt/peer/gtk/GdkGlyphVector.java	25 Oct 2003 18:41:45 -0000	1.1
+++ gnu/java/awt/peer/gtk/GdkGlyphVector.java	6 Sep 2004 16:35:38 -0000
@@ -60,7 +60,9 @@
       {
         System.loadLibrary("gtkpeer");
       }
-    initStaticState ();
+
+    if (GtkToolkit.useGraphics2D ())
+      initStaticState ();
   }
   native static void initStaticState ();
   private final int native_state = GtkGenericPeer.getUniqueInteger ();
Index: gnu/java/awt/peer/gtk/GdkGraphics.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java,v
retrieving revision 1.4
diff -u -r1.4 GdkGraphics.java
--- gnu/java/awt/peer/gtk/GdkGraphics.java	22 Aug 2003 20:33:49 -0000	1.4
+++ gnu/java/awt/peer/gtk/GdkGraphics.java	6 Sep 2004 16:35:38 -0000
@@ -46,6 +46,7 @@
 import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Shape;
+import java.awt.SystemColor;
 import java.awt.image.ImageObserver;
 import java.text.AttributedCharacterIterator;
 
@@ -63,7 +64,7 @@
 
   static final int GDK_COPY = 0, GDK_XOR = 2;
 
-  native int[] initState (GtkComponentPeer component);
+  native void initState (GtkComponentPeer component);
   native void initState (int width, int height);
   native void copyState (GdkGraphics g);
 
@@ -83,15 +84,15 @@
     initState (width, height);
     color = Color.black;
     clip = new Rectangle (0, 0, width, height);
-    font = new Font ("Dialog", Font.PLAIN, 10);
+    font = new Font ("Dialog", Font.PLAIN, 12);
   }
 
   GdkGraphics (GtkComponentPeer component)
   {
     this.component = component;
-    int rgb[] = initState (component);
-    color = new Color (rgb[0], rgb[1], rgb[2]);
-    font = new Font ("Dialog", Font.PLAIN, 10);
+    initState (component);
+    color = component.awtComponent.getForeground ();
+    font = component.awtComponent.getFont ();
     Dimension d = component.awtComponent.getSize ();
     clip = new Rectangle (0, 0, d.width, d.height);
   }
@@ -125,6 +126,11 @@
   native public void dispose ();
 
   native void copyPixmap (Graphics g, int x, int y, int width, int height);
+  native void copyAndScalePixmap (Graphics g, boolean flip_x, boolean flip_y,
+                                  int src_x, int src_y, 
+                                  int src_width, int src_height, 
+                                  int dest_x, int dest_y, 
+                                  int dest_width, int dest_height);
   public boolean drawImage (Image img, int x, int y, 
 			    Color bgcolor, ImageObserver observer)
   {
@@ -149,7 +155,10 @@
 	return true;
       }
 
-    return drawImage (img, x, y, component.getBackground (), observer);
+    if (component != null)
+      return drawImage (img, x, y, component.getBackground (), observer);
+    else
+      return drawImage (img, x, y, SystemColor.window, observer);
   }
 
   public boolean drawImage (Image img, int x, int y, int width, int height, 
@@ -157,7 +166,10 @@
   {
     if (img instanceof GtkOffScreenImage)
       {
-	throw new RuntimeException ();
+        copyAndScalePixmap (img.getGraphics (), false, false,
+                            0, 0, img.getWidth (null), img.getHeight (null), 
+                            x, y, width, height);
+        return true;
       }
 
     GtkImage image = (GtkImage) img;
@@ -168,8 +180,12 @@
   public boolean drawImage (Image img, int x, int y, int width, int height, 
 			    ImageObserver observer)
   {
-    return drawImage (img, x, y, width, height, component.getBackground (),
-		      observer);
+    if (component != null)
+      return drawImage (img, x, y, width, height, component.getBackground (),
+                        observer);
+    else
+      return drawImage (img, x, y, width, height, SystemColor.window,
+                        observer);
   }
 
   public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, 
@@ -178,7 +194,60 @@
   {
     if (img instanceof GtkOffScreenImage)
       {
-	throw new RuntimeException ();
+        int dx_start, dy_start, d_width, d_height;
+        int sx_start, sy_start, s_width, s_height;
+        boolean x_flip = false;
+        boolean y_flip = false;
+
+        if (dx1 < dx2)
+        {
+          dx_start = dx1;
+          d_width = dx2 - dx1;
+        }
+        else
+        {
+          dx_start = dx2;
+          d_width = dx1 - dx2;
+          x_flip ^= true;
+        }
+        if (dy1 < dy2)
+        {
+          dy_start = dy1;
+          d_height = dy2 - dy1;
+        }
+        else
+        {
+          dy_start = dy2;
+          d_height = dy1 - dy2;
+          y_flip ^= true;
+        }
+        if (sx1 < sx2)
+        {
+          sx_start = sx1;
+          s_width = sx2 - sx1;
+        }
+        else
+        {
+          sx_start = sx2;
+          s_width = sx1 - sx2;
+          x_flip ^= true;
+        }
+        if (sy1 < sy2)
+        {
+          sy_start = sy1;
+          s_height = sy2 - sy1;
+        }
+        else
+        {
+          sy_start = sy2;
+          s_height = sy1 - sy2;
+          y_flip ^= true;
+        }
+
+        copyAndScalePixmap (img.getGraphics (), x_flip, y_flip,
+                            sx_start, sy_start, s_width, s_height, 
+                            dx_start, dy_start, d_width, d_height);
+        return true;
       }
 
     GtkImage image = (GtkImage) img;
@@ -191,8 +260,12 @@
 			    int sx1, int sy1, int sx2, int sy2, 
 			    ImageObserver observer) 
   {
-    return drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
-		      component.getBackground (), observer);
+    if (component != null)
+      return drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
+                        component.getBackground (), observer);
+    else
+      return drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
+                        SystemColor.window, observer);
   }
 
   native public void drawLine (int x1, int y1, int x2, int y2);
@@ -212,10 +285,10 @@
   native public void drawRect(int x, int y, int width, int height);
   native public void fillRect (int x, int y, int width, int height);
 
-  native void drawString (String str, int x, int y, String fname, int size);
+  native void drawString (String str, int x, int y, String fname, int style, int size);
   public void drawString (String str, int x, int y)
   {
-    drawString (str, x, y, font.getName(), font.getSize());
+    drawString (str, x, y, font.getName(), font.getStyle(), font.getSize());
   }
 
   public void drawString (AttributedCharacterIterator ci, int x, int y)
@@ -226,13 +299,48 @@
   public void drawRoundRect(int x, int y, int width, int height, 
 			    int arcWidth, int arcHeight)
   {
-    // System.out.println ("drawRoundRect called [UNIMPLEMENTED]");
+    if (arcWidth > width)
+      arcWidth = width;
+    if (arcHeight > height)
+      arcHeight = height;
+
+    int xx = x + width - arcWidth;
+    int yy = y + height - arcHeight;
+
+    drawArc (x, y, arcWidth, arcHeight, 90, 90);
+    drawArc (xx, y, arcWidth, arcHeight, 0, 90);
+    drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
+    drawArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+    int y1 = y + arcHeight / 2;
+    int y2 = y + height - arcHeight / 2;
+    drawLine (x, y1, x, y2);
+    drawLine (x + width, y1, x + width, y2);
+
+    int x1 = x + arcWidth / 2;
+    int x2 = x + width - arcWidth / 2;
+    drawLine (x1, y, x2, y);
+    drawLine (x1, y + height, x2, y + height);
   }
 
   public void fillRoundRect (int x, int y, int width, int height, 
 			     int arcWidth, int arcHeight)
   {
-    // System.out.println ("fillRoundRect called [UNIMPLEMENTED]");
+    if (arcWidth > width)
+      arcWidth = width;
+    if (arcHeight > height)
+      arcHeight = height;
+
+    int xx = x + width - arcWidth;
+    int yy = y + height - arcHeight;
+
+    fillArc (x, y, arcWidth, arcHeight, 90, 90);
+    fillArc (xx, y, arcWidth, arcHeight, 0, 90);
+    fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
+    fillArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+    fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
+    fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
   }
 
   public Shape getClip ()
@@ -287,7 +395,10 @@
 
   public void setColor (Color c)
   {
-    color = c;
+    if (c == null)
+      color = new Color (0, 0, 0);
+    else
+      color = c;
 
     if (xorColor == null) /* paint mode */
       setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
Index: gnu/java/awt/peer/gtk/GdkGraphics2D.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java,v
retrieving revision 1.6
diff -u -r1.6 GdkGraphics2D.java
--- gnu/java/awt/peer/gtk/GdkGraphics2D.java	16 Jan 2004 14:22:23 -0000	1.6
+++ gnu/java/awt/peer/gtk/GdkGraphics2D.java	6 Sep 2004 16:35:39 -0000
@@ -1,5 +1,5 @@
 /* GdkGraphics2D.java
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -48,7 +48,6 @@
 import java.util.Map;
 
 import java.text.AttributedCharacterIterator;
-import java.util.Map;
 import java.util.Stack;
 import java.lang.Integer;
 import gnu.java.awt.ClasspathToolkit;
@@ -84,13 +83,16 @@
   private GtkComponentPeer component;
   private Font font;  
   private RenderingHints hints;
+  private BufferedImage bimage;
 
   private Stack stateStack;
   
-  native private int[] initState (GtkComponentPeer component);
+  native private void initState (GtkComponentPeer component);
   native private void initState (int width, int height);
   native private void copyState (GdkGraphics2D g);
   native public void dispose ();
+  native private int[] getImagePixels();
+  native private void cairoSurfaceSetFilter(int filter);
 
   public void finalize ()
   {
@@ -158,7 +160,7 @@
     setFont (new Font("SansSerif", Font.PLAIN, 12));
     setTransform (new AffineTransform ());
     setStroke (new BasicStroke ());
-    setRenderingHints (new HashMap ());
+    setRenderingHints (getDefaultHints());
 
     stateStack = new Stack();
   }
@@ -166,19 +168,41 @@
   GdkGraphics2D (GtkComponentPeer component)
   {
     this.component = component;
-    int rgb[] = initState (component);
+    initState (component);
 
-    setColor (new Color (rgb[0], rgb[1], rgb[2]));
-    setBackground (new Color (rgb[3], rgb[4], rgb[5]));
+    setColor (component.awtComponent.getForeground ());
+    setBackground (component.awtComponent.getBackground ());
     setPaint (getColor());
     setFont (new Font("SansSerif", Font.PLAIN, 12));
     setTransform (new AffineTransform ());
     setStroke (new BasicStroke ());
-    setRenderingHints (new HashMap ());
+    setRenderingHints (getDefaultHints());
 
     stateStack = new Stack ();
   }
 
+  GdkGraphics2D (BufferedImage bimage)
+  {
+    
+    this.bimage = bimage;    
+    initState (bimage.getWidth(), bimage.getHeight());
+
+    setColor(Color.black);
+    setBackground (Color.black);
+    setPaint (getColor());
+    setFont (new Font("SansSerif", Font.PLAIN, 12));
+    setTransform (new AffineTransform ());
+    setStroke (new BasicStroke ());
+    setRenderingHints (getDefaultHints());
+
+    stateStack = new Stack();
+    
+    // draw current buffered image to the pixmap associated 
+    // with it.
+    
+    drawImage (bimage, new AffineTransform (1,0,0,1,0,0), bg, null);
+  }
+
 
   ////////////////////////////////////
   ////// Native Drawing Methods //////
@@ -364,6 +388,121 @@
     
   }
 
+  private void updateBufferedImage()
+  {
+    int[] pixels = getImagePixels();
+    updateImagePixels(pixels);
+  }
+
+  
+  private boolean isBufferedImageGraphics ()
+  {
+
+    if (bimage != null)
+      return true;
+    else
+      return false;
+  }
+    
+  private void updateImagePixels (int[] pixels)
+  {
+
+    // This function can only be used if 
+    // this graphics object is used to draw into 
+    // buffered image 
+	
+    if (! isBufferedImageGraphics ()) 
+      return;
+
+    WritableRaster raster = bimage.getRaster();		      
+    DataBuffer db = raster.getDataBuffer ();
+
+    // update pixels in the bufferedImage
+
+    if (raster.getSampleModel ().getDataType () == DataBuffer.TYPE_INT 
+        && db instanceof DataBufferInt 
+        && db.getNumBanks () == 1)
+      {
+
+        // single bank, ARGB-ints buffer in sRGB space
+        DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer ();
+
+        for (int i=0; i < pixels.length; i++) 
+          dbi.setElem(i, pixels[i]);
+	 			
+      }
+    else 
+      {        
+        bimage.getRaster().setPixels (0, 0, raster.getWidth (),
+                                      raster.getHeight (), pixels);
+      }
+  }
+
+
+  private boolean drawImage(Image img, 
+                            AffineTransform xform,
+                            Color bgcolor,			    
+                            ImageObserver obs)
+  {
+    if (img instanceof GtkOffScreenImage &&
+        img.getGraphics () instanceof GdkGraphics2D &&            
+        (xform == null 
+         || xform.getType () == AffineTransform.TYPE_IDENTITY 
+         || xform.getType () == AffineTransform.TYPE_TRANSLATION)
+        ) 
+      {
+        // we are being asked to flush a double buffer from Gdk
+        GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
+        gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
+        
+        if (isBufferedImageGraphics ()) 
+          updateBufferedImage();   
+	 
+        return true;
+      }
+    else
+      {
+      
+        // In this case, xform is an AffineTransform that transforms bounding
+        // box of the specified image from image space to user space. However
+        // when we pass this transform to cairo, cairo will use this transform
+        // to map "user coordinates" to "pixel" coordinates, which is the 
+        // other way around. Therefore to get the "user -> pixel" transform 
+        // that cairo wants from "image -> user" transform that we currently
+        // have, we will need to invert the transformation matrix.
+	
+        AffineTransform invertedXform = new AffineTransform();
+
+        try
+          {             
+	      invertedXform = xform.createInverse();
+             if (img instanceof BufferedImage)
+               {
+                   // draw an image which has actually been loaded 
+                   // into memory fully
+                   
+		     BufferedImage b = (BufferedImage) img;
+                   return drawRaster (b.getColorModel (), 
+                                      b.getData (), 
+                                      invertedXform,
+                                      bgcolor);
+               }
+             else
+               {
+                   // begin progressive loading in a separate thread
+                   new PainterThread (this, img, invertedXform, bgcolor);
+                   return false;
+               }	       
+          }
+        catch (NoninvertibleTransformException e)
+          {
+              throw new ImagingOpException("Unable to invert transform " 
+                                           + xform.toString());
+          } 	      
+      }
+  }
+
+
   //////////////////////////////////////////////////
   ////// Implementation of Graphics2D Methods //////
   //////////////////////////////////////////////////
@@ -401,6 +540,10 @@
       translate (-0.5,-0.5);
       
     stateRestore ();
+    
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
   }
 
   public void fill (Shape s)
@@ -416,6 +559,10 @@
       walkPath (s.getPathIterator (null));
     cairoFill ();
     stateRestore ();
+    
+   if (isBufferedImageGraphics ()) 
+     updateBufferedImage();   
+
   }
 
   public void clip (Shape s)
@@ -475,11 +622,21 @@
       {
         TexturePaint tp = (TexturePaint) paint;
         BufferedImage img = tp.getImage ();
-        int pixels[] = img.getRGB(0, 0, img.getWidth (), 
-                                  img.getHeight (), null, 
-                                  0, img.getWidth ());
-        setTexturePixels (pixels, img.getWidth (), 
-                          img.getHeight (), img.getWidth ());
+	 
+        // map the image to the anchor rectangle  
+
+        int width = (int) tp.getAnchorRect ().getWidth ();
+        int height = (int) tp.getAnchorRect ().getHeight ();
+	
+        double scaleX = width / (double) img.getWidth ();
+        double scaleY = width / (double) img.getHeight ();
+	 
+        AffineTransform at = new AffineTransform (scaleX, 0, 0, scaleY, 0, 0);
+        AffineTransformOp op = new AffineTransformOp (at, getRenderingHints());
+        BufferedImage texture = op.filter(img, null);
+        int pixels[] = texture.getRGB (0, 0, width, height, null, 0, width);
+        setTexturePixels (pixels, width, height, width);
+
       }
     else if (paint instanceof GradientPaint)
       {
@@ -518,6 +675,26 @@
     else
       transform.concatenate (tx);
     setTransform (transform);
+    if (clip != null)
+      {
+        // FIXME: this should actuall try to transform the shape
+        // rather than degrade to bounds.
+        Rectangle2D r = clip.getBounds2D();
+        double[] coords = new double[] { r.getX(), r.getY(), 
+                                         r.getX() + r.getWidth(),
+                                         r.getY() + r.getHeight() };
+        try 
+          {
+            tx.createInverse().transform(coords, 0, coords, 0, 2);
+            r.setRect(coords[0], coords[1],
+                      coords[2] - coords[0], 
+                      coords[3] - coords[1]);
+            clip = r;
+          }
+        catch (java.awt.geom.NoninvertibleTransformException e)
+          {
+          }
+      }
   }
 
   public void rotate(double theta)
@@ -645,19 +822,29 @@
 
   public void setClip (int x, int y, int width, int height)
   {
-      cairoNewPath ();
-      cairoRectangle (x, y, width, height);
-      cairoClosePath ();
-      cairoClip ();
-      clip = new Rectangle2D.Double ((double)x, (double)y, 
-				     (double)width, (double)height);
+    setClip(new Rectangle2D.Double ((double)x, (double)y, 
+                                    (double)width, (double)height));
   }
-
+  
   public void setClip (Shape s)
   {
-    clip (s);
+    clip = s;
+    if (s != null)
+      {
+        cairoNewPath ();
+        if (s instanceof Rectangle2D)
+          {
+            Rectangle2D r = (Rectangle2D)s;
+            cairoRectangle (r.getX (), r.getY (), 
+                            r.getWidth (), r.getHeight ());
+          }
+        else
+          walkPath (s.getPathIterator (null));
+        cairoClosePath ();
+        cairoClip ();
+      }
   }
-
+  
   public void draw3DRect(int x, int y, int width, 
                          int height, boolean raised)
   {
@@ -708,6 +895,10 @@
     cairoStroke ();
     
     stateRestore ();    
+    
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
   }
 
   public void fill3DRect(int x, int y, int width, 
@@ -734,6 +925,10 @@
     cairoClosePath ();
     cairoFill ();
     stateRestore ();
+    
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
   }
 
 
@@ -759,6 +954,10 @@
     cairoClosePath ();
     cairoFill ();
     stateRestore ();
+       
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
   }
 
   public void setBackground(Color c)
@@ -828,7 +1027,8 @@
   }
 
   private boolean drawRaster (ColorModel cm, Raster r, 
-                              AffineTransform imageToUser)
+                              AffineTransform imageToUser, 
+                              Color bgcolor)
   {
     if (r == null)
       return false;
@@ -849,7 +1049,7 @@
       {
         i2u[0] = 1; i2u[1] = 0;
         i2u[2] = 0; i2u[3] = 1;
-        i2u[2] = 0; i2u[3] = 0;
+        i2u[4] = 0; i2u[5] = 0;
       }
 
     int pixels[] = null;
@@ -875,17 +1075,33 @@
         pixels = pixels2;
       }
     
+    // change all transparent pixels in the image to the 
+    // specified bgcolor
+            
+    if (bgcolor != null) 
+      {
+        for (int i = 0; i < pixels.length; i++) 
+          {
+            if (cm.getAlpha (pixels[i]) == 0) 
+              pixels[i] = bgcolor.getRGB ();	    
+          }
+      } 
+
     stateSave ();
     translate (x, y);
     drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
     stateRestore ();    
+    
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
     return true;
   }
 
   public void drawRenderedImage(RenderedImage image,
                                 AffineTransform xform)
   {
-    drawRaster (image.getColorModel(), image.getData(), xform);
+    drawRaster (image.getColorModel(), image.getData(), xform, bg);
   }
   
   public void drawRenderableImage(RenderableImage image,
@@ -898,33 +1114,7 @@
                            AffineTransform xform,
                            ImageObserver obs)
   {
-    if (img instanceof GtkOffScreenImage &&
-        img.getGraphics () instanceof GdkGraphics2D &&            
-        (xform == null 
-         || xform.getType () == AffineTransform.TYPE_IDENTITY 
-         || xform.getType () == AffineTransform.TYPE_TRANSLATION)
-        ) 
-      {
-        // we are being asked to flush a double buffer from Gdk
-        GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
-        gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
-        return true;
-      }
-    else
-      {
-        if (img instanceof BufferedImage)
-          {
-            // draw an image which has actually been loaded into memory fully
-            BufferedImage b = (BufferedImage) img;
-            return drawRaster (b.getColorModel (), b.getData (), xform);
-          }        
-        else
-          {
-            // begin progressive loading in a separate thread
-            new PainterThread (this, img, xform);
-            return false;
-          }
-      }
+    return drawImage(img, xform, bg, obs); 
   }
 
   public void drawImage(BufferedImage image,
@@ -933,13 +1123,13 @@
                         int y)
   {
     Image filtered = op.filter(image, null);
-    drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), null);
+    drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), bg, null);
   }
 
   public boolean drawImage (Image img, int x, int y, 
                             ImageObserver observer)
   {
-    return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), observer);    
+    return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), bg, observer);    
   }
 
 
@@ -962,11 +1152,14 @@
     Image image;
     ColorModel defaultModel;
     AffineTransform xform;
+    Color bgcolor;
 
-    public PainterThread (GdkGraphics2D g, Image im, AffineTransform xf)
+    public PainterThread (GdkGraphics2D g, Image im, 
+                          AffineTransform xf, Color bg)
     {
       image = im;
       xform = xf;
+      bgcolor = bg;
       this.gr = (GdkGraphics2D) g.create ();
       new Thread (this).start ();
     }
@@ -1016,6 +1209,18 @@
         else
           pixels2 = pixels;
 
+        // change all transparent pixels in the image to the 
+        // specified bgcolor
+            
+        if (bgcolor != null) 
+          {
+            for (int i = 0; i < pixels2.length; i++) 
+              {
+                if (model.getAlpha (pixels2[i]) == 0) 
+                pixels2[i] = bgcolor.getRGB ();	    
+              }
+          } 
+
         double[] xf = new double[6];
         xform.getMatrix(xf);        
         gr.drawPixels (pixels2, w, h, scansize, xf);
@@ -1054,13 +1259,46 @@
 
   public void setComposite(Composite comp)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    if (comp instanceof AlphaComposite)
+      {
+        AlphaComposite a = (AlphaComposite) comp;
+        cairoSetOperator(a.getRule());
+        Color c = getColor();
+        setColor(new Color(c.getRed(),
+                           c.getGreen(),
+                           c.getBlue(),
+                           (int) (a.getAlpha() * ((float) c.getAlpha()))));
+      }
+    else
+      throw new java.lang.UnsupportedOperationException ();
   }
 
   public void setRenderingHint(RenderingHints.Key hintKey,
                                Object hintValue)
   {
     hints.put (hintKey, hintValue);    
+    
+    if (hintKey.equals(RenderingHints.KEY_INTERPOLATION)
+        || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION)) 
+      {
+			
+        if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+           cairoSurfaceSetFilter(0);
+	   
+        else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+           cairoSurfaceSetFilter(1); 
+	   
+        else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
+           cairoSurfaceSetFilter(2);
+	   
+        else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
+           cairoSurfaceSetFilter(3);
+	   
+        else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
+           cairoSurfaceSetFilter(4);
+      
+      } 
+
   }
 
   public Object getRenderingHint(RenderingHints.Key hintKey)
@@ -1072,6 +1310,27 @@
   {
     this.hints = new RenderingHints (getDefaultHints ());
     this.hints.add (new RenderingHints (hints));
+        
+    if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) 
+      {
+         if(hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) 
+            cairoSurfaceSetFilter(0);
+	    
+         else if(hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) 
+            cairoSurfaceSetFilter(1);  
+      }
+          
+    if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) 
+      { 
+         if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) 
+            cairoSurfaceSetFilter(2);
+	    
+         else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) 
+            cairoSurfaceSetFilter(3);
+	    
+         else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) 
+            cairoSurfaceSetFilter(4);
+      }      
   }
 
   public void addRenderingHints(Map hints)
@@ -1104,6 +1363,10 @@
     int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null);
     float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null);
     cairoShowGlyphs (codes, posns);
+    
+    if (isBufferedImageGraphics ()) 
+      updateBufferedImage();   
+
     stateRestore ();
   }
 
@@ -1124,33 +1387,86 @@
   public boolean drawImage (Image img, int x, int y, Color bgcolor, 
                             ImageObserver observer)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return drawImage (img, x, y, img.getWidth (observer), 
+                      img.getHeight (observer), bgcolor, observer);
   }
 
   public boolean drawImage (Image img, int x, int y, int width, int height, 
                             Color bgcolor, ImageObserver observer)
   {
-    throw new java.lang.UnsupportedOperationException ();
+   
+    double scaleX =  width / (double) img.getWidth (observer);           
+    double scaleY =  height / (double) img.getHeight (observer);
+
+    return drawImage (img, 
+                      new AffineTransform(scaleX, 0f, 0f, scaleY, x, y),
+                      bgcolor,
+                      observer);
+
   }
 
   public boolean drawImage (Image img, int x, int y, int width, int height, 
                             ImageObserver observer)
   {
-    throw new java.lang.UnsupportedOperationException ();
+
+    return drawImage (img, x, y, width, height, bg, observer);
+
   }
 
   public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, 
                             int sx1, int sy1, int sx2, int sy2, 
                             Color bgcolor, ImageObserver observer)
   {
-    throw new java.lang.UnsupportedOperationException ();
+  
+    Image subImage;	
+    
+    int sourceWidth = sx2 - sx1;
+    int sourceHeight = sy2 - sy1;     
+    
+    int destWidth = dx2 - dx1;
+    int destHeight = dy2 - dy1;
+    
+    double scaleX = destWidth / (double) sourceWidth;
+    double scaleY = destHeight / (double) sourceHeight;
+
+    // Get the subimage of the source enclosed in the 
+    // rectangle specified by sx1, sy1, sx2, sy2
+	
+    if (img instanceof BufferedImage)
+      {
+
+        BufferedImage b = (BufferedImage) img;
+        subImage = b.getSubimage(sx1,sy1,sx2,sy2);  
+      } 
+    else 
+      {
+
+        // FIXME: This code currently doesn't work. Null Pointer 
+        // exception is thrown in this case. This happens 
+        // because img.getSource() always returns null, since source gets 
+        // never initialized when it is created with the help of 
+        // createImage(int width, int height). 
+             
+	 CropImageFilter filter = new CropImageFilter(sx1,sx2,sx2,sy2);
+        FilteredImageSource src = new FilteredImageSource(img.getSource(), 
+                                                          filter);	
+							  						  
+        subImage = Toolkit.getDefaultToolkit().createImage(src);
+      }
+
+    return drawImage(subImage, new AffineTransform(scaleX, 0, 0,
+                                                   scaleY, dx1, dy1), 
+                                                   bgcolor,
+                                                   observer);
   }
 
   public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, 
                             int sx1, int sy1, int sx2, int sy2, 
                             ImageObserver observer) 
   {
-    throw new java.lang.UnsupportedOperationException ();
+
+    return drawImage (img, dx1, dy1, dx2, dy2, 
+                      sx1, sy1, sx2, sy2, bg, observer);	  
   }
 
   public void drawOval(int x, int y, int width, int height)
@@ -1161,14 +1477,28 @@
   public void drawRoundRect(int x, int y, int width, int height, 
                             int arcWidth, int arcHeight)
   {
-    int x1 = x + arcWidth, x2 = x + width - arcWidth;
-    int y1 = y + arcHeight, y2 = y + height - arcHeight;
-    fillRect (x1, y, x2 - x1, height);
-    fillRect (x, y1, width, y2 - y1);
-    fillArc (x, y, arcWidth, arcHeight, 90, 90);
-    fillArc (x1, y, arcWidth, arcHeight, 0, 90);
-    fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
-    fillArc (x, y2, arcWidth, arcHeight, 180, 90);
+    if (arcWidth > width)
+      arcWidth = width;
+    if (arcHeight > height)
+      arcHeight = height;
+
+    int xx = x + width - arcWidth;
+    int yy = y + height - arcHeight;
+
+    drawArc (x, y, arcWidth, arcHeight, 90, 90);
+    drawArc (xx, y, arcWidth, arcHeight, 0, 90);
+    drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
+    drawArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+    int y1 = y + arcHeight / 2;
+    int y2 = y + height - arcHeight / 2;
+    drawLine (x, y1, x, y2);
+    drawLine (x + width, y1, x + width, y2);
+
+    int x1 = x + arcWidth / 2;
+    int x2 = x + width - arcWidth / 2;
+    drawLine (x1, y, x2, y);
+    drawLine (x1, y + height, x2, y + height);
   }
 
   public void drawString (String str, int x, int y)
@@ -1210,14 +1540,21 @@
   public void fillRoundRect (int x, int y, int width, int height, 
                              int arcWidth, int arcHeight)
   {
-    int x1 = x + arcWidth, x2 = x + width - arcWidth;
-    int y1 = y + arcHeight, y2 = y + height - arcHeight;
-    fillRect (x1, y, x2 - x1, height);
-    fillRect (x, y1, width, y2 - y1);
+    if (arcWidth > width)
+      arcWidth = width;
+    if (arcHeight > height)
+      arcHeight = height;
+
+    int xx = x + width - arcWidth;
+    int yy = y + height - arcHeight;
+
     fillArc (x, y, arcWidth, arcHeight, 90, 90);
-    fillArc (x1, y, arcWidth, arcHeight, 0, 90);
-    fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
-    fillArc (x, y2, arcWidth, arcHeight, 180, 90);
+    fillArc (xx, y, arcWidth, arcHeight, 0, 90);
+    fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
+    fillArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+    fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
+    fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
   }
 
   public Font getFont ()
@@ -1251,7 +1588,9 @@
 
   public String toString()
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return  getClass ().getName () +
+            "[font=" + font.toString () +
+            ",color=" + fg.toString () + "]";
   }
 
 }
Index: gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
diff -N gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java	6 Sep 2004 16:35:39 -0000
@@ -0,0 +1,87 @@
+/* GdkGraphicsEnvironment.java -- information about the graphics environment
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.*;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+
+public class GdkGraphicsEnvironment extends GraphicsEnvironment
+{
+  
+  public GdkGraphicsEnvironment ()
+  {
+  	super();
+  }
+
+  public GraphicsDevice[] getScreenDevices ()
+  {
+    throw new java.lang.UnsupportedOperationException ();
+  }
+
+  public GraphicsDevice getDefaultScreenDevice ()
+  {
+    throw new java.lang.UnsupportedOperationException ();
+  }
+
+  public Graphics2D createGraphics (BufferedImage image)
+  {
+    return new GdkGraphics2D (image);
+  }
+
+  public Font[] getAllFonts ()
+  {
+    throw new java.lang.UnsupportedOperationException ();
+  }
+
+  public String[] getAvailableFontFamilyNames ()
+  {
+    throw new java.lang.UnsupportedOperationException ();
+  }
+
+  public String[] getAvailableFontFamilyNames (Locale l)
+  {
+    throw new java.lang.UnsupportedOperationException ();
+  }
+
+
+} // class GdkGraphicsEnvironment
+
Index: gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java,v
retrieving revision 1.3
diff -u -r1.3 GdkPixbufDecoder.java
--- gnu/java/awt/peer/gtk/GdkPixbufDecoder.java	2 Dec 2003 19:56:30 -0000	1.3
+++ gnu/java/awt/peer/gtk/GdkPixbufDecoder.java	6 Sep 2004 16:35:39 -0000
@@ -77,19 +77,16 @@
   public GdkPixbufDecoder (String filename)
   {
     super (filename);
-    initState ();
   }
   
   public GdkPixbufDecoder (URL url)
   {
     super (url);
-    initState ();
   }
 
   public GdkPixbufDecoder (byte[] imagedata, int imageoffset, int imagelength)
   {
     super (imagedata, imageoffset, imagelength);
-    initState ();
   }
 
   // called back by native side
@@ -135,6 +132,7 @@
 
     byte bytes[] = new byte[4096];
     int len = 0;
+    initState();
     while ((len = is.read (bytes)) != -1)
       pumpBytes (bytes, len);
     
@@ -220,4 +218,31 @@
     dec.startProduction (bb);
     return bb.getBufferedImage ();
   }
+
+  public static BufferedImage createBufferedImage (URL u)
+  {
+    BufferedImageBuilder bb = new BufferedImageBuilder ();
+    GdkPixbufDecoder dec = new GdkPixbufDecoder (u);
+    dec.startProduction (bb);
+    return bb.getBufferedImage ();
+  }
+
+  public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
+                                                   int imagelength)
+  {
+    BufferedImageBuilder bb = new BufferedImageBuilder ();
+    GdkPixbufDecoder dec = new GdkPixbufDecoder (imagedata, imageoffset, imagelength);
+    dec.startProduction (bb);
+    return bb.getBufferedImage ();
+  }
+  
+  public static BufferedImage createBufferedImage (ImageProducer producer)
+  {
+    BufferedImageBuilder bb = new BufferedImageBuilder ();
+    producer.startProduction(bb);
+    return bb.getBufferedImage ();
+  }
+  
+
+
 }
Index: gnu/java/awt/peer/gtk/GtkArg.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GtkArg.java
diff -N gnu/java/awt/peer/gtk/GtkArg.java
--- gnu/java/awt/peer/gtk/GtkArg.java	31 Jan 2003 17:54:13 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,61 +0,0 @@
-/* GtkArg.java
-   Copyright (C) 1999 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.awt.peer.gtk;
-
-public class GtkArg
-{
-  String name;
-  Object value;
-
-  public GtkArg (String name, Object value)
-  {
-    this.name = name;
-    this.value = value;
-  }
-
-  public String getName ()
-  {
-    return name;
-  }
-
-  public Object getValue ()
-  {
-    return value;
-  }
-}
Index: gnu/java/awt/peer/gtk/GtkArgList.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GtkArgList.java
diff -N gnu/java/awt/peer/gtk/GtkArgList.java
--- gnu/java/awt/peer/gtk/GtkArgList.java	31 Jan 2003 17:54:13 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,75 +0,0 @@
-/* GtkArgList.java
-   Copyright (C) 1999 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.awt.peer.gtk;
-import java.util.Vector;
-
-public class GtkArgList extends Vector
-{
-  void add (GtkArg arg)
-  {
-    addElement (arg);
-  }
-
-  void add (String name, boolean value)
-  {
-    addElement (new GtkArg (name, new Boolean (value)));
-  }
-    
-  void add (String name, int value)
-  {
-    addElement (new GtkArg (name, new Integer (value)));
-  }
-
-  void add (String name, float value)
-  {
-    addElement (new GtkArg (name, new Float (value)));
-  }
-
-  void add (String name, Object value)
-  {
-    addElement (new GtkArg (name, value));
-  }
-
-  synchronized void setArgs (GtkComponentPeer cp)
-  {
-    for (int i = 0; i < elementCount; i++)
-      cp.set ((GtkArg)elementData[i]);
-  }
-}
-  
Index: gnu/java/awt/peer/gtk/GtkButtonPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java,v
retrieving revision 1.7
diff -u -r1.7 GtkButtonPeer.java
--- gnu/java/awt/peer/gtk/GtkButtonPeer.java	11 Dec 2003 13:50:50 -0000	1.7
+++ gnu/java/awt/peer/gtk/GtkButtonPeer.java	6 Sep 2004 16:35:39 -0000
@@ -42,6 +42,7 @@
 import java.awt.Button;
 import java.awt.Component;
 import java.awt.Font;
+import java.awt.Point;
 import java.awt.event.MouseEvent;
 import java.awt.event.KeyEvent;
 import java.awt.peer.ButtonPeer;
@@ -49,54 +50,57 @@
 public class GtkButtonPeer extends GtkComponentPeer
     implements ButtonPeer
 {
-  native void create ();
+  native void create (String label);
+
   public native void connectJObject ();
   public native void connectSignals ();
 
-  native void gtkSetFont(String name, int style, int size);
+  native void gtkSetFont (String name, int style, int size);
+  native void gtkSetLabel (String label);
   native void gtkWidgetSetForeground (int red, int green, int blue);
+  native void gtkActivate ();
 
   public GtkButtonPeer (Button b)
   {
     super (b);
   }
 
+  void create ()
+  {
+    create (((Button) awtComponent).getLabel ());
+  }
+
   public void setLabel (String label) 
   {
-    set ("label", label);
+    gtkSetLabel(label);
   }
 
   public void handleEvent (AWTEvent e)
   {
-    if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ())
+    if (e.getID () == MouseEvent.MOUSE_RELEASED && isEnabled ())
       {
 	MouseEvent me = (MouseEvent) e;
+	Point p = me.getPoint();
+	p.translate(((Component) me.getSource()).getX(),
+	            ((Component) me.getSource()).getY());
 	if (!me.isConsumed ()
-	    && (me.getModifiers () & MouseEvent.BUTTON1_MASK) != 0)
+	    && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
+	    && awtComponent.getBounds().contains(p))
 	  postActionEvent (((Button)awtComponent).getActionCommand (), 
-			   me.getModifiers ());
+			   me.getModifiersEx ());
       }
 
     if (e.getID () == KeyEvent.KEY_PRESSED)
       {
 	KeyEvent ke = (KeyEvent) e;
 	if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_SPACE)
-	  postActionEvent (((Button)awtComponent).getActionCommand (),
-			   ke.getModifiers ());
+          {
+            postActionEvent (((Button) awtComponent).getActionCommand (),
+                             ke.getModifiersEx ());
+            gtkActivate ();
+          }
       }
 
     super.handleEvent (e);
   }
-
-  public void getArgs (Component component, GtkArgList args)
-  {
-    super.getArgs (component, args);
-
-    args.add ("label", ((Button)component).getLabel ());
-  }
-
-  public void setFont (Font f)
-  {
-    gtkSetFont(f.getName(), f.getStyle(), f.getSize());
-  }
 }
Index: gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java,v
retrieving revision 1.4
diff -u -r1.4 GtkCheckboxPeer.java
--- gnu/java/awt/peer/gtk/GtkCheckboxPeer.java	11 Dec 2003 13:50:50 -0000	1.4
+++ gnu/java/awt/peer/gtk/GtkCheckboxPeer.java	6 Sep 2004 16:35:39 -0000
@@ -41,6 +41,7 @@
 import java.awt.Checkbox;
 import java.awt.CheckboxGroup;
 import java.awt.Component;
+import java.awt.Font;
 import java.awt.peer.CheckboxPeer;
 
 public class GtkCheckboxPeer extends GtkComponentPeer
@@ -51,37 +52,39 @@
   // The current state of the GTK checkbox.
   private boolean currentState;  
 
-  public native void nativeCreate (GtkCheckboxGroupPeer group,
-                                   boolean state);
+  public native void create (GtkCheckboxGroupPeer group);
   public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group);
   public native void connectSignals ();
+  native void gtkSetFont (String name, int style, int size);
+  native void gtkButtonSetLabel (String label);
+  native void gtkToggleButtonSetActive (boolean is_active);
 
   public GtkCheckboxPeer (Checkbox c)
   {
     super (c);
   }
 
-  // We can't fully use the ordinary getArgs code here, due to
-  // oddities of this particular widget.  In particular we must be
-  // able to switch between a checkbutton and a radiobutton
-  // dynamically.
+  // FIXME: we must be able to switch between a checkbutton and a
+  // radiobutton dynamically.
   public void create ()
   {
-    CheckboxGroup g = ((Checkbox) awtComponent).getCheckboxGroup ();
+    Checkbox checkbox = (Checkbox) awtComponent;
+    CheckboxGroup g = checkbox.getCheckboxGroup ();
     old_group = GtkCheckboxGroupPeer.getCheckboxGroupPeer (g);
-    currentState = ((Checkbox)awtComponent).getState();
-    nativeCreate (old_group, currentState);
+    create (old_group);
+    gtkToggleButtonSetActive (checkbox.getState ());
+    gtkButtonSetLabel (checkbox.getLabel ());
   }
 
   public void setState (boolean state)
   {
     if (currentState != state)
-      set ("active", state);
+      gtkToggleButtonSetActive (state);
   }
 
   public void setLabel (String label)
   {
-    set ("label", label);
+    gtkButtonSetLabel (label);
   }
 
   public void setCheckboxGroup (CheckboxGroup group)
@@ -97,13 +100,6 @@
       }
   }
 
-  public void getArgs (Component component, GtkArgList args)
-  {
-    super.getArgs (component, args);
-    args.add ("active", ((Checkbox) component).getState ());
-    args.add ("label", ((Checkbox) component).getLabel ());
-  }
-
   // Override the superclass postItemEvent so that the peer doesn't
   // need information that we have.
   public void postItemEvent (Object item, int stateChange)
Index: gnu/java/awt/peer/gtk/GtkChoicePeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java,v
retrieving revision 1.5
diff -u -r1.5 GtkChoicePeer.java
--- gnu/java/awt/peer/gtk/GtkChoicePeer.java	5 Jan 2004 21:18:06 -0000	1.5
+++ gnu/java/awt/peer/gtk/GtkChoicePeer.java	6 Sep 2004 16:35:39 -0000
@@ -58,25 +58,22 @@
 	  items[i] = c.getItem (i);
 	  
 	append (items);
-
-        // Must set our state before notifying listeners
-	((Choice) awtComponent).select (c.getItem (0));
-	postItemEvent (c.getItem (0), ItemEvent.SELECTED);
       }
   }
 
   native void create ();
 
   native void append (String items[]);
-  native int getHistory ();
+  native int nativeGetSelected ();
   native void nativeAdd (String item, int index);
   native void nativeRemove (int index);
+  native void nativeRemoveAll ();
 
   native public void select (int position);
  
   public void add (String item, int index)
   {
-    int before = getHistory();
+    int before = nativeGetSelected();
     
     nativeAdd (item, index);
     
@@ -92,11 +89,11 @@
 
   public void remove (int index)
   {
-    int before = getHistory();
+    int before = nativeGetSelected();
     int after;
     
     nativeRemove (index);
-    after = getHistory();
+    after = nativeGetSelected();
     
     /* Generate an ItemEvent if we are removing the currently selected item
        and there are at least one item left. */
@@ -110,7 +107,7 @@
 
   public void removeAll ()
   {
-    nativeRemove (-1);
+    nativeRemoveAll();
   }
   
   public void addItem (String item, int position)
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.13
diff -u -r1.13 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java	13 Jan 2004 20:54:46 -0000	1.13
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java	6 Sep 2004 16:35:39 -0000
@@ -1,5 +1,5 @@
 /* GtkComponentPeer.java -- Implements ComponentPeer with GTK
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,6 +42,7 @@
 import java.awt.BufferCapabilities;
 import java.awt.Color;
 import java.awt.Component;
+import java.awt.Container;
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.Font;
@@ -53,6 +54,7 @@
 import java.awt.Image;
 import java.awt.Insets;
 import java.awt.ItemSelectable;
+import java.awt.KeyboardFocusManager;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
@@ -90,6 +92,15 @@
   native void gtkWidgetSetCursor (int type);
   native void gtkWidgetSetBackground (int red, int green, int blue);
   native void gtkWidgetSetForeground (int red, int green, int blue);
+  native void gtkWidgetSetSensitive (boolean sensitive);
+  native void gtkWidgetSetParent (ComponentPeer parent);
+  native void gtkWidgetRequestFocus ();
+  native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
+                                         int keyCode, int keyLocation);
+  native void gtkSetFont (String name, int style, int size);
+  native void gtkWidgetQueueDrawArea(int x, int y, int width, int height);
+  native void addExposeFilter();
+  native void removeExposeFilter();
 
   void create ()
   {
@@ -105,29 +116,59 @@
     this.awtComponent = awtComponent;
     insets = new Insets (0, 0, 0, 0);
 
-    /* temporary try/catch block until all peers use this creation method */
-    try {
-      create ();
-      
-      GtkArgList args = new GtkArgList ();
-      getArgs (awtComponent, args);
-      args.setArgs (this);
-
-      connectJObject ();
-      connectSignals ();
-
-      if (awtComponent.getForeground () != null)
-	setForeground (awtComponent.getForeground ());
-      if (awtComponent.getBackground () != null)
-	setBackground (awtComponent.getBackground ());
-      if (awtComponent.getFont() != null)
-	setFont(awtComponent.getFont());
-
-      setCursor (awtComponent.getCursor ());
-      Rectangle bounds = awtComponent.getBounds ();
-      setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+    create ();
+
+    setParent ();
+
+    connectJObject ();
+    connectSignals ();
+
+    if (awtComponent.getForeground () != null)
+      setForeground (awtComponent.getForeground ());
+    if (awtComponent.getBackground () != null)
+      setBackground (awtComponent.getBackground ());
+    if (awtComponent.getFont() != null)
+      setFont(awtComponent.getFont());
+
+    setCursor (awtComponent.getCursor ());
+
+    setComponentBounds ();
+
+    Rectangle bounds = awtComponent.getBounds ();
+    setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+    setVisibleAndEnabled ();
+  }
+
+  void setParent ()
+  {
+    ComponentPeer p;
+    Component component = awtComponent;
+    do
+      {
+        component = component.getParent ();
+        p = component.getPeer ();
+      }
+    while (p instanceof java.awt.peer.LightweightPeer);
+
+    if (p != null)
+      gtkWidgetSetParent (p);
+  }
+
+  /*
+   * Set the bounds of this peer's AWT Component based on dimensions
+   * returned by the native windowing system.  Most Components impose
+   * their dimensions on the peers so the default implementation does
+   * nothing.  However some peers, like GtkFileDialogPeer, need to
+   * pass their size back to the AWT Component.
+   */
+  void setComponentBounds ()
+  {
+  }
 
-    } catch (RuntimeException ex) { ; }
+  void setVisibleAndEnabled ()
+  {
+    setVisible (awtComponent.isVisible ());
+    setEnabled (awtComponent.isEnabled ());
   }
 
   public int checkImage (Image image, int width, int height, 
@@ -179,7 +220,10 @@
 
   public Graphics getGraphics ()
   {
-    return null;
+    if (GtkToolkit.useGraphics2D ())
+        return new GdkGraphics2D (this);
+    else
+        return new GdkGraphics (this);
   }
 
   public Point getLocationOnScreen () 
@@ -206,6 +250,48 @@
   
   public void handleEvent (AWTEvent event)
   {
+    int id = event.getID();
+    KeyEvent ke = null;
+
+    switch (id)
+      {
+      case PaintEvent.PAINT:
+      case PaintEvent.UPDATE:
+        {
+          try 
+            {
+              Graphics g = getGraphics ();
+          
+              // Some peers like GtkFileDialogPeer are repainted by Gtk itself
+              if (g == null)
+                break;
+		
+              g.setClip (((PaintEvent)event).getUpdateRect());
+
+              if (id == PaintEvent.PAINT)
+                awtComponent.paint (g);
+              else
+                awtComponent.update (g);
+
+              g.dispose ();
+            }
+          catch (InternalError e)
+            {
+              System.err.println (e);
+            }
+        }
+        break;
+      case KeyEvent.KEY_PRESSED:
+        ke = (KeyEvent) event;
+        gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
+                                   ke.getKeyCode (), ke.getKeyLocation ());
+        break;
+      case KeyEvent.KEY_RELEASED:
+        ke = (KeyEvent) event;
+        gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
+                                   ke.getKeyCode (), ke.getKeyLocation ());
+        break;
+      }
   }
   
   public boolean isFocusTraversable () 
@@ -224,7 +310,21 @@
 
   public void paint (Graphics g)
   {
-    awtComponent.paint (g);
+    Component parent = awtComponent.getParent();
+    GtkComponentPeer parentPeer = null;
+    if ((parent instanceof Container) && !parent.isLightweight())
+      parentPeer = (GtkComponentPeer) parent.getPeer();
+
+    addExposeFilter();
+    if (parentPeer != null)
+      parentPeer.addExposeFilter();
+
+    Rectangle clip = g.getClipBounds();
+    gtkWidgetQueueDrawArea(clip.x, clip.y, clip.width, clip.height);
+
+    removeExposeFilter();
+    if (parentPeer != null)
+      parentPeer.removeExposeFilter();
   }
 
   public Dimension preferredSize ()
@@ -275,7 +375,11 @@
 				 new Rectangle (x, y, width, height)));
   }
 
-  native public void requestFocus ();
+  public void requestFocus ()
+  {
+    gtkWidgetRequestFocus();
+    postFocusEvent(FocusEvent.FOCUS_GAINED, false);
+  }
 
   public void reshape (int x, int y, int width, int height) 
   {
@@ -292,8 +396,34 @@
   public void setBounds (int x, int y, int width, int height)
   {
     Component parent = awtComponent.getParent ();
-    
-    if (parent instanceof Window)
+
+    // Heavyweight components that are children of one or more
+    // lightweight containers have to be handled specially.  Because
+    // calls to GLightweightPeer.setBounds do nothing, GTK has no
+    // knowledge of the lightweight containers' positions.  So we have
+    // to add the offsets manually when placing a heavyweight
+    // component within a lightweight container.  The lightweight
+    // container may itself be in a lightweight container and so on,
+    // so we need to continue adding offsets until we reach a
+    // container whose position GTK knows -- that is, the first
+    // non-lightweight.
+    boolean lightweightChild = false;
+    Insets i;
+    while (parent.isLightweight ())
+      {
+	lightweightChild = true;
+
+	i = ((Container) parent).getInsets ();
+
+	x += parent.getX () + i.left;
+	y += parent.getY () + i.top;
+
+	parent = parent.getParent ();
+      }
+
+    // We only need to convert from Java to GTK coordinates if we're
+    // placing a heavyweight component in a Window.
+    if (parent instanceof Window && !lightweightChild)
       {
 	Insets insets = ((Window) parent).getInsets ();
 	// Convert from Java coordinates to GTK coordinates.
@@ -310,7 +440,7 @@
 
   public void setEnabled (boolean b)
   {
-    set ("sensitive", b);
+    gtkWidgetSetSensitive (b);
   }
 
   public void setFont (Font f)
@@ -318,6 +448,7 @@
     // FIXME: This should really affect the widget tree below me.
     // Currently this is only handled if the call is made directly on
     // a text widget, which implements setFont() itself.
+    gtkSetFont(f.getName(), f.getStyle(), f.getSize());
   }
 
   public void setForeground (Color c) 
@@ -339,18 +470,14 @@
 
   public void setVisible (boolean b)
   {
-    set ("visible", b);
-  }
-  
-  public void hide () 
-  {
-    setVisible (false);
+    if (b)
+      show ();
+    else
+      hide ();
   }
 
-  public void show () 
-  {
-    setVisible (true);
-  }
+  public native void hide ();
+  public native void show ();
 
   protected void postMouseEvent(int id, long when, int mods, int x, int y, 
 				int clickCount, boolean popupTrigger) 
@@ -366,10 +493,28 @@
   }
 
   protected void postKeyEvent (int id, long when, int mods,
-			       int keyCode, char keyChar, int keyLocation)
+                               int keyCode, char keyChar, int keyLocation)
   {
-    q.postEvent (new KeyEvent (awtComponent, id, when, mods,
-			       keyCode, keyChar, keyLocation));
+    KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods,
+                                      keyCode, keyChar, keyLocation);
+
+    // Also post a KEY_TYPED event if keyEvent is a key press that
+    // doesn't represent an action or modifier key.
+    if (keyEvent.getID () == KeyEvent.KEY_PRESSED
+        && (!keyEvent.isActionKey ()
+            && keyCode != KeyEvent.VK_SHIFT
+            && keyCode != KeyEvent.VK_CONTROL
+            && keyCode != KeyEvent.VK_ALT))
+      {
+        synchronized (q)
+          {
+            q.postEvent (keyEvent);
+            q.postEvent (new KeyEvent (awtComponent, KeyEvent.KEY_TYPED, when, mods,
+                                        KeyEvent.VK_UNDEFINED, keyChar, keyLocation));
+          }
+      }
+    else
+      q.postEvent (keyEvent);
   }
 
   protected void postFocusEvent (int id, boolean temporary)
@@ -384,46 +529,6 @@
 				item, stateChange));
   }
 
-  public void getArgs (Component component, GtkArgList args)
-  {
-    args.add ("visible", component.isVisible ());
-    args.add ("sensitive", component.isEnabled ());
-
-    ComponentPeer p;
-
-    do
-      {
-	component = component.getParent ();
-	p = component.getPeer ();
-      } while (p instanceof java.awt.peer.LightweightPeer);
-    
-    if (p != null)
-      args.add ("parent", p);
-  }
-
-  native void set (String name, String value);
-  native void set (String name, boolean value);
-  native void set (String name, int value);
-  native void set (String name, float value);
-  native void set (String name, Object value);
-
-  void set (GtkArg arg)
-  {
-    String name = arg.getName ();
-    Object value = arg.getValue ();
-
-    if (value instanceof Boolean)
-      set (name, ((Boolean)value).booleanValue ());
-    else if (value instanceof Integer)
-      set (name, ((Integer)value).intValue ());
-    else if (value instanceof Float)
-      set (name, ((Float)value).floatValue ());
-    else if (value instanceof String)
-      set (name, ((String) value));
-    else
-      set (name, value);
-  }
-
   public GraphicsConfiguration getGraphicsConfiguration ()
   {
     // FIXME: just a stub for now.
Index: gnu/java/awt/peer/gtk/GtkContainerPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java,v
retrieving revision 1.7
diff -u -r1.7 GtkContainerPeer.java
--- gnu/java/awt/peer/gtk/GtkContainerPeer.java	13 Jan 2004 17:55:20 -0000	1.7
+++ gnu/java/awt/peer/gtk/GtkContainerPeer.java	6 Sep 2004 16:35:39 -0000
@@ -42,6 +42,7 @@
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
+import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Insets;
 import java.awt.event.PaintEvent;
@@ -89,50 +90,23 @@
   public void setBounds (int x, int y, int width, int height)
   {
     super.setBounds (x, y, width, height);
-    awtComponent.validate ();
   }
 
-  public Graphics getGraphics ()
+  public void setFont(Font f)
   {
-    if (GtkToolkit.useGraphics2D ())
-        return new GdkGraphics2D (this);
-    else
-    return new GdkGraphics (this);
+    super.setFont(f);
+    Component[] components = ((Container) awtComponent).getComponents();
+    for (int i = 0; i < components.length; i++)
+      {
+        GtkComponentPeer peer = (GtkComponentPeer) components[i].getPeer();
+        if (peer != null && ! peer.awtComponent.isFontSet())
+          peer.setFont(f);
+      }
   }
 
-  public void handleEvent (AWTEvent event)
+  public Graphics getGraphics ()
   {
-    int id = event.getID();
-      
-    switch (id)
-      {
-      case PaintEvent.PAINT:
-      case PaintEvent.UPDATE:
-	{
-	  try 
-	    {
-	      Graphics g = getGraphics ();
-
-	      // Some peers like GtkFileDialogPeer are repainted by Gtk itself
-	      if (g == null)
-	        break;
-
-	      g.setClip (((PaintEvent)event).getUpdateRect());
-
-	      if (id == PaintEvent.PAINT)
-		awtComponent.paint (g);
-	      else
-		awtComponent.update (g);
-	      
-	      g.dispose ();
-	    } 
-	  catch (InternalError e)
-	    { 
-	      System.err.println (e);
-	    }
-	}
-	break;
-      }
+    return super.getGraphics();
   }
 
   public void beginLayout () { }
Index: gnu/java/awt/peer/gtk/GtkDialogPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java,v
retrieving revision 1.9
diff -u -r1.9 GtkDialogPeer.java
--- gnu/java/awt/peer/gtk/GtkDialogPeer.java	13 Jan 2004 20:54:46 -0000	1.9
+++ gnu/java/awt/peer/gtk/GtkDialogPeer.java	6 Sep 2004 16:35:39 -0000
@@ -41,7 +41,10 @@
 import java.awt.AWTEvent;
 import java.awt.Component;
 import java.awt.Dialog;
+import java.awt.Graphics;
 import java.awt.peer.DialogPeer;
+import java.awt.Rectangle;
+import java.awt.event.PaintEvent;
 
 public class GtkDialogPeer extends GtkWindowPeer
   implements DialogPeer
@@ -50,22 +53,43 @@
   {
     super (dialog);
   }
+  
+  public Graphics getGraphics ()
+  {
+    Graphics g;
+    if (GtkToolkit.useGraphics2D ())
+      g = new GdkGraphics2D (this);
+    else
+      g = new GdkGraphics (this);
+    g.translate (-insets.left, -insets.top);
+    return g;
+  }  
+  
+  protected void postMouseEvent(int id, long when, int mods, int x, int y, 
+				int clickCount, boolean popupTrigger)
+  {
+    super.postMouseEvent (id, when, mods, 
+			  x + insets.left, y + insets.top, 
+			  clickCount, popupTrigger);
+  }
+
+  protected void postExposeEvent (int x, int y, int width, int height)
+  {
+    q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
+				 new Rectangle (x + insets.left, 
+						y + insets.top, 
+						width, height)));
+  }  
 
   void create ()
   {
     // Create a decorated dialog window.
     create (GDK_WINDOW_TYPE_HINT_DIALOG, true);
-  }
-
-  public void getArgs (Component component, GtkArgList args)
-  {
-    super.getArgs (component, args);
 
-    Dialog dialog = (Dialog) component;
+    Dialog dialog = (Dialog) awtComponent;
 
-    args.add ("title", dialog.getTitle ());
-    args.add ("modal", dialog.isModal ());
-    args.add ("allow_shrink", dialog.isResizable ());
-    args.add ("allow_grow", dialog.isResizable ());
+    gtkWindowSetModal (dialog.isModal ());
+    setTitle (dialog.getTitle ());
+    setResizable (dialog.isResizable ());
   }
 }
Index: gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java,v
retrieving revision 1.4
diff -u -r1.4 GtkFileDialogPeer.java
--- gnu/java/awt/peer/gtk/GtkFileDialogPeer.java	8 Jan 2004 21:12:25 -0000	1.4
+++ gnu/java/awt/peer/gtk/GtkFileDialogPeer.java	6 Sep 2004 16:35:39 -0000
@@ -1,5 +1,5 @@
 /* GtkFileDialogPeer.java -- Implements FileDialogPeer with GTK
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,9 +42,11 @@
 import java.awt.Dialog;
 import java.awt.FileDialog;
 import java.awt.Graphics;
+import java.awt.Window;
 import java.awt.event.WindowEvent;
 import java.awt.peer.FileDialogPeer;
 import java.io.FilenameFilter;
+import java.io.File;
 
 public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer
 {
@@ -52,17 +54,47 @@
   
   private String currentFile = null;
   private String currentDirectory = null;
+  private FilenameFilter filter;
 
-  native void create ();
+  native void create (GtkContainerPeer parent);
+  native void connectJObject ();
+  native void connectSignals ();
+  native void nativeSetFile (String file);
+  native public String nativeGetDirectory();
+  native public void nativeSetDirectory(String directory);
+  native void nativeSetFilenameFilter (FilenameFilter filter);
+
+  public void create() {
+    create((GtkContainerPeer) awtComponent.getParent().getPeer());
+
+    FileDialog fd = (FileDialog) awtComponent;
+
+    setDirectory(fd.getDirectory());
+    setFile(fd.getFile());
+
+    FilenameFilter filter = fd.getFilenameFilter();
+    if (filter != null)
+      setFilenameFilter(filter);
+  }
 
   public GtkFileDialogPeer (FileDialog fd)
   {
     super (fd);
   }
 
-  native void connectJObject ();
-  native void connectSignals ();
-  native void nativeSetFile (String file);
+  void setComponentBounds ()
+  {
+    if (awtComponent.getHeight () == 0
+        && awtComponent.getWidth () == 0)
+      {
+        int[] dims = new int[2];
+        gtkWidgetGetPreferredDimensions (dims);
+        ((GtkFileDialogPeer) this).setBoundsCallback ((Window) awtComponent,
+                                                      awtComponent.getX (),
+                                                      awtComponent.getY (),
+                                                      dims[0], dims[1]);
+      }
+  }
 
   public void setFile (String fileName)
   {
@@ -80,26 +112,16 @@
         return;
       }
 
-    // Remove any directory path from the filename
-    int sepIndex = fileName.lastIndexOf (FS);
-    if (sepIndex < 0)
-      {
+    // GtkFileChooser requires absolute filenames. If the given filename
+    // is not absolute, let's construct it based on current directory.
         currentFile = fileName;
+    if (fileName.indexOf(FS) == 0)
+      {
         nativeSetFile (fileName);
       }
     else
       {
-        if (fileName.length() > (sepIndex + 1))
-	  {
-	    String fn = fileName.substring (sepIndex + 1);
-            currentFile = fn;
-            nativeSetFile (fn);
-	  }
-	else
-	  {
-            currentFile = "";
-            nativeSetFile ("");
-	  }
+        nativeSetFile (nativeGetDirectory() + FS + fileName);
       }
   }
 
@@ -120,20 +142,25 @@
       }
       
     currentDirectory = directory;
-
-    // Gtk expects the directory to end with a file separator
-    if (directory.substring (directory.length () - 1).equals (FS))
-      nativeSetFile (directory);
-    else
-      nativeSetFile (directory + FS);
+    nativeSetDirectory (directory);
   }
 
   public void setFilenameFilter (FilenameFilter filter)
   {
-    /* GTK has no filter callbacks yet.  It works by setting a pattern
-     * (see gtk_file_selection_complete), which we can't convert
-     * to the callback paradigm. With GTK-2.4 there will be a
-     * gtk_file_filter_add_custom function that we can use. */
+    this.filter = filter;
+    nativeSetFilenameFilter(filter);
+  }
+
+  /* This method interacts with the native callback function of the
+     same name.  The native function will extract the filename from the
+     GtkFileFilterInfo object and send it to this method, which will
+     in turn call the filter's accept() method and give back the return
+     value. */
+  boolean filenameFilterCallback (String fullname) {
+    String filename = fullname.substring(fullname.lastIndexOf(FS) + 1);
+    String dirname = fullname.substring(0, fullname.lastIndexOf(FS));
+    File dir = new File(dirname);
+    return filter.accept(dir, filename);
   }
 
   public Graphics getGraphics ()
Index: gnu/java/awt/peer/gtk/GtkFontPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkFontPeer.java
--- gnu/java/awt/peer/gtk/GtkFontPeer.java	31 Dec 2003 08:58:30 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkFontPeer.java	6 Sep 2004 16:35:39 -0000
@@ -43,6 +43,7 @@
 import java.awt.font.*;
 import java.util.Locale;
 import java.util.ResourceBundle;
+import java.util.MissingResourceException;
 import java.text.*;
 import gnu.java.awt.peer.ClasspathFontPeer;
 
@@ -62,15 +63,32 @@
       }
   }
 
-  final private String Xname; // uses %d for font size.
+  final private String Xname;
 
   public GtkFontPeer (String name, int style)
   {
-    super(name, style, 12 /* kludge */);
+    // All fonts get a default size of 12 if size is not specified.
+    this(name, style, 12);
+  }
+
+  public GtkFontPeer (String name, int style, int size)
+  {
+    super(name, style, size);
 
+    String Xname = null;
     if (bundle != null)
-      Xname = bundle.getString (name.toLowerCase () + "." + style);
-    else
+      {
+	try
+	  {
+	    Xname = bundle.getString (name.toLowerCase () + "." + style);
+	  }
+	catch (MissingResourceException mre)
+	  {
+	    // ignored
+	  }
+      }
+
+    if (Xname == null)
       {
 	String weight;
 	String slant;
@@ -90,8 +108,10 @@
 	else
 	  spacing = "c";
 
-        Xname = "-*-*-" + weight + "-" + slant + "-normal-*-%d-*-*-*-" + spacing + "-*-*-*";
+        Xname = "-*-*-" + weight + "-" + slant + "-normal-*-*-" + size + "-*-*-" + spacing + "-*-*-*";
       }
+
+    this.Xname = Xname;
   }
 
   public String getXLFD ()
Index: gnu/java/awt/peer/gtk/GtkFramePeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java,v
retrieving revision 1.8
diff -u -r1.8 GtkFramePeer.java
--- gnu/java/awt/peer/gtk/GtkFramePeer.java	13 Jan 2004 20:54:46 -0000	1.8
+++ gnu/java/awt/peer/gtk/GtkFramePeer.java	6 Sep 2004 16:35:39 -0000
@@ -1,5 +1,5 @@
 /* GtkFramePeer.java -- Implements FramePeer with GTK
-   Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -45,24 +45,87 @@
 import java.awt.Image;
 import java.awt.MenuBar;
 import java.awt.Rectangle;
+import java.awt.Window;
 import java.awt.event.PaintEvent;
+import java.awt.image.ColorModel;
 import java.awt.peer.FramePeer;
 import java.awt.peer.MenuBarPeer;
 
 public class GtkFramePeer extends GtkWindowPeer
     implements FramePeer
 {
-  int menuBarHeight = 0;
-  native int getMenuBarHeight ();
-
-  native public void setMenuBarPeer (MenuBarPeer bar);
+  private int menuBarHeight;
+  private MenuBarPeer menuBar;
+  native int getMenuBarHeight (MenuBarPeer bar);
+
+  native void setMenuBarPeer (MenuBarPeer bar);
+  native void removeMenuBarPeer ();
+  native void moveLayout (int offset);
+  native void gtkLayoutSetVisible (boolean vis);
 
   public void setMenuBar (MenuBar bar)
   {
     if (bar == null)
-      setMenuBarPeer (null);
+    {    
+      if (menuBar != null)
+      {
+        gtkLayoutSetVisible(false);
+        removeMenuBarPeer(); 
+        menuBar = null;
+        moveLayout(menuBarHeight);
+        insets.top -= menuBarHeight;
+        menuBarHeight = 0;      
+        awtComponent.doLayout();
+        gtkLayoutSetVisible(true);
+      }
+    }
     else
-      setMenuBarPeer ((MenuBarPeer) bar.getPeer ());
+    {
+      gtkLayoutSetVisible(false);
+      int oldHeight = 0;
+      if (menuBar != null)
+      {
+        removeMenuBarPeer();
+        oldHeight = menuBarHeight;
+        insets.top -= menuBarHeight;
+      }
+      menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer();
+      setMenuBarPeer(menuBar);
+      menuBarHeight = getMenuBarHeight (menuBar);
+      if (oldHeight != menuBarHeight)
+        moveLayout(oldHeight - menuBarHeight);
+      insets.top += menuBarHeight;
+      awtComponent.doLayout();
+      gtkLayoutSetVisible(true);
+    }
+  }
+
+  public void setBounds (int x, int y, int width, int height)
+  {
+    nativeSetBounds (x, y,
+		     width - insets.left - insets.right,
+		     height - insets.top - insets.bottom
+		     + menuBarHeight);
+  }  
+  
+  public void setResizable (boolean resizable)
+  {
+    // Call setSize; otherwise when resizable is changed from true to
+    // false the frame will shrink to the dimensions it had before it
+    // was resizable.
+    setSize (awtComponent.getWidth() - insets.left - insets.right,
+             awtComponent.getHeight() - insets.top - insets.bottom
+             + menuBarHeight);
+    gtkWindowSetResizable (resizable);
+  }
+
+  protected void postInsetsChangedEvent (int top, int left,
+					 int bottom, int right)
+  {
+    insets.top = top + menuBarHeight;
+    insets.left = left;
+    insets.bottom = bottom;
+    insets.right = right;
   }
 
   public GtkFramePeer (Frame frame)
@@ -74,22 +137,46 @@
   {
     // Create a normal decorated window.
     create (GDK_WINDOW_TYPE_HINT_NORMAL, true);
-  }
 
-  public void getArgs (Component component, GtkArgList args)
-  {
-    super.getArgs (component, args);
+    Frame frame = (Frame) awtComponent;
 
-    Frame frame = (Frame) component;
+    setMenuBar (frame.getMenuBar ());
 
-    args.add ("title", frame.getTitle ());
-    args.add ("allow_shrink", frame.isResizable ());
-    args.add ("allow_grow", frame.isResizable ());
+    setTitle (frame.getTitle ());
+    setResizable (frame.isResizable ());
+    setIconImage(frame.getIconImage());
   }
 
+  native void nativeSetIconImageFromDecoder (GdkPixbufDecoder decoder);
+  native void nativeSetIconImageFromData (int[] pixels, int width, int height);
   public void setIconImage (Image image) 
   {
-      /* TODO: Waiting on Toolkit Image routines */
+      if (image != null)
+        {
+          GtkImage img = (GtkImage) image;
+          // FIXME: Image should be loaded, but if not, do image loading here.
+          if (img.isLoaded())
+            {
+              if (img.getSource() instanceof GdkPixbufDecoder)
+                {
+                  nativeSetIconImageFromDecoder((GdkPixbufDecoder) img.getSource());
+                }
+              else
+                {
+                  int[] pixels = img.getPixelCache();
+                  ColorModel model = img.getColorModel();
+                  int[] data = new int[pixels.length * 4];
+                  for (int i = 0; i < pixels.length; i++)
+                    {
+                      data[i * 4] = model.getRed(pixels[i]);
+                      data[i * 4 + 1] = model.getGreen(pixels[i]);
+                      data[i * 4 + 2] = model.getBlue(pixels[i]);
+                      data[i * 4 + 3] = model.getAlpha(pixels[i]);
+                    }
+                  nativeSetIconImageFromData(data, img.getWidth(null), img.getHeight(null));
+                }
+            }
+        }
   }
 
   public Graphics getGraphics ()
@@ -102,10 +189,32 @@
     g.translate (-insets.left, -insets.top);
     return g;
   }
-
-  // FIXME: When MenuBars work, override postConfigureEvent and
-  // setBounds to account for MenuBar dimensions.
-
+  
+  protected void postConfigureEvent (int x, int y, int width, int height)
+  {
+    int frame_x = x - insets.left;
+    // Since insets.top includes the MenuBar height, we need to add back
+    // the MenuBar height to the frame's y position.
+    // If no MenuBar exists in this frame, the MenuBar height will be 0.
+    int frame_y = y - insets.top + menuBarHeight;
+    int frame_width = width + insets.left + insets.right;
+    // Ditto as above. Since insets.top already includes the MenuBar's height,
+    // we need to subtract the MenuBar's height from the top inset.
+    int frame_height = height + insets.top + insets.bottom - menuBarHeight;
+    if (frame_x != awtComponent.getX()
+        || frame_y != awtComponent.getY()
+        || frame_width != awtComponent.getWidth()
+        || frame_height != awtComponent.getHeight())
+      {
+        setBoundsCallback ((Window) awtComponent,
+                           frame_x,
+                           frame_y,
+                           frame_width,
+                           frame_height);
+      }
+    awtComponent.validate();
+  }
+  
   protected void postMouseEvent(int id, long when, int mods, int x, int y, 
 				int clickCount, boolean popupTrigger)
   {
Index: gnu/java/awt/peer/gtk/GtkImage.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkImage.java,v
retrieving revision 1.4
diff -u -r1.4 GtkImage.java
--- gnu/java/awt/peer/gtk/GtkImage.java	1 Dec 2003 15:28:22 -0000	1.4
+++ gnu/java/awt/peer/gtk/GtkImage.java	6 Sep 2004 16:35:39 -0000
@@ -89,6 +89,18 @@
     this.observer = observer;
   }
 
+  public synchronized int[]
+  getPixelCache ()
+  {
+    return pixelCache;
+  }
+
+  public synchronized ColorModel
+  getColorModel ()
+  {
+    return model;
+  }
+
   public synchronized int 
   getWidth (ImageObserver observer)
   {
@@ -202,7 +214,7 @@
   public synchronized void 
   setColorModel (ColorModel model)
   {
-    if (this.model == null || this.model == model)
+    if (this.model == null || this.model.equals(model))
       this.model = model;
     else
       isCacheable = false;
@@ -235,13 +247,13 @@
     if (!isCacheable)
       return;
 
-    if (cm != model || pixelCache == null)
+    if (!cm.equals(model) || pixelCache == null)
       {
 	isCacheable = false;
 	return;
       }
 
-    if (scansize == width)
+    if (scansize == width && height == 1)
       {
 	System.arraycopy (pixels, offset, 
 			  pixelCache, y * this.width + x,
Index: gnu/java/awt/peer/gtk/GtkImagePainter.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkImagePainter.java,v
retrieving revision 1.2
diff -u -r1.2 GtkImagePainter.java
--- gnu/java/awt/peer/gtk/GtkImagePainter.java	13 Jul 2003 15:09:20 -0000	1.2
+++ gnu/java/awt/peer/gtk/GtkImagePainter.java	6 Sep 2004 16:35:39 -0000
@@ -104,7 +104,7 @@
     s_width = Math.abs (sx2 - sx1);
     s_height = Math.abs (sy2 - sy1);
     clip = new Rectangle (sx1, sy1, s_width, s_height);
-    
+
     new Thread (this).start ();
   }
 
@@ -119,6 +119,11 @@
   static int[] 
   convertPixels (int[] pixels, ColorModel model)
   {
+    if (pixels == null || model == null)
+    {
+      return null;
+    }
+
     if (model.equals (ColorModel.getRGBdefault ()))
       return pixels;
     
@@ -133,6 +138,11 @@
   static int[]
   convertPixels (byte[] pixels, ColorModel model)
   {
+    if (pixels == null || model == null)
+    {
+      return null;
+    }
+
     int ret[] = new int[pixels.length];
 
     for (int i = 0; i < pixels.length; i++)
@@ -160,8 +170,6 @@
 
 	offset += r.y * scansize + r.x;
 
-	r.translate (-Math.abs (clip.x - startX), -Math.abs (clip.y - startY));
-
 	width = r.width;
 	height = r.height;
 	x = r.x;
@@ -178,8 +186,8 @@
   setPixels (int x, int y, int width, int height, ColorModel model, 
 	     byte[] pixels, int offset, int scansize)
   {
-    setPixels (x, y, width, height, model, convertPixels (pixels, model),
-	       offset, scansize);
+    setPixels (x, y, width, height, ColorModel.getRGBdefault(),
+	       convertPixels (pixels, model), offset, scansize);
   }
 
   public void 
@@ -238,5 +246,6 @@
   public void 
   imageComplete (int status)
   {
+    image.imageComplete(status);
   }
 }
Index: gnu/java/awt/peer/gtk/GtkLabelPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkLabelPeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkLabelPeer.java
--- gnu/java/awt/peer/gtk/GtkLabelPeer.java	11 Nov 2003 17:04:46 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkLabelPeer.java	6 Sep 2004 16:35:39 -0000
@@ -39,28 +39,30 @@
 package gnu.java.awt.peer.gtk;
 
 import java.awt.Component;
+import java.awt.Font;
 import java.awt.Label;
 import java.awt.peer.LabelPeer;
 
 public class GtkLabelPeer extends GtkComponentPeer
     implements LabelPeer
 {
+  native void create (String text, float alignment);
+  native void gtkSetFont (String name, int style, int size);
+  native void nativeSetAlignment (float alignment);
+
+  native public void setText (String text);
+
   void create ()
   {
     Label label = (Label) awtComponent;
     create (label.getText (), getGtkAlignment (label.getAlignment ()));
   }
 
-  native void create (String text, float alignment);
-
   public GtkLabelPeer (Label l)
   {
     super (l);
   }
 
-  native public void setText (String text);
-
-  native void nativeSetAlignment (float alignment);
   public void setAlignment (int alignment)
   {
     nativeSetAlignment (getGtkAlignment (alignment));
Index: gnu/java/awt/peer/gtk/GtkListPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkListPeer.java,v
retrieving revision 1.6
diff -u -r1.6 GtkListPeer.java
--- gnu/java/awt/peer/gtk/GtkListPeer.java	17 Dec 2003 18:02:56 -0000	1.6
+++ gnu/java/awt/peer/gtk/GtkListPeer.java	6 Sep 2004 16:35:39 -0000
@@ -48,13 +48,22 @@
 public class GtkListPeer extends GtkComponentPeer
   implements ListPeer
 {
-//    native void create (ComponentPeer parent, String [] items, boolean mode);
+  void create ()
+  {
+    List list = (List) awtComponent;
+
+    create (list.getRows ());
 
-  native void create ();
+    setMultipleMode (list.isMultipleMode ());
+  }
+
+  native void create (int rows);
   native void connectJObject ();
   native void connectSignals ();
+  native void gtkSetFont (String name, int style, int size);
+  native void gtkWidgetRequestFocus ();
 
-  native void getSize (int rows, int dims[]);
+  native void getSize (int rows, int visibleRows, int dims[]);
 
   public GtkListPeer (List list)
   {
@@ -85,18 +94,12 @@
   
   public Dimension getMinimumSize (int rows)
   {
-    int dims[] = new int[2];
-
-    getSize (rows, dims);
-    return (new Dimension (dims[0], dims[1]));
+    return minimumSize (rows);
   }
 
   public Dimension getPreferredSize (int rows)
   {
-    int dims[] = new int[2];
-
-    getSize (rows, dims);
-    return (new Dimension (dims[0], dims[1]));
+    return preferredSize (rows);
   }
   
   public native int[] getSelectedIndexes ();
@@ -104,12 +107,20 @@
 
   public Dimension minimumSize (int rows)
   {
-    return (getMinimumSize (rows));
+    int dims[] = new int[2];
+
+    int visibleRows = ((List) awtComponent).getRows();
+    getSize (rows, visibleRows, dims);
+    return new Dimension (dims[0], dims[1]);
   }
 
   public Dimension preferredSize (int rows)
   {
-    return (getPreferredSize (rows));
+    int dims[] = new int[2];
+
+    int visibleRows = ((List) awtComponent).getRows();
+    getSize (rows, visibleRows, dims);
+    return new Dimension (dims[0], dims[1]);
   }
 
   public void removeAll ()
@@ -129,20 +140,20 @@
   {
     if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ())
       {
-        /* Only generate the ActionEvent on the second click of
-	   a multiple click */
+        // Only generate the ActionEvent on the second click of a
+        // multiple click.
 	MouseEvent me = (MouseEvent) e;
 	if (!me.isConsumed ()
-	    && (me.getModifiers () & MouseEvent.BUTTON1_MASK) != 0
+	    && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
 	    && me.getClickCount() == 2)
 	  {
-            String selectedItem = ((List)awtComponent).getSelectedItem ();
+            String selectedItem = ((List) awtComponent).getSelectedItem ();
 
-            /* Double-click only generates an Action event
-	       if something is selected */
+            // Double-click only generates an Action event if
+            // something is selected.
             if (selectedItem != null)
-	      postActionEvent (((List)awtComponent).getSelectedItem (), 
-			       me.getModifiers ());
+	      postActionEvent (((List) awtComponent).getSelectedItem (), 
+			       me.getModifiersEx ());
 	  }
       }
 
@@ -151,11 +162,12 @@
 	KeyEvent ke = (KeyEvent) e;
 	if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_ENTER)
 	  {
-            String selectedItem = ((List)awtComponent).getSelectedItem ();
+            String selectedItem = ((List) awtComponent).getSelectedItem ();
 
-            /* Enter only generates an Action event if something is selected */
+            // Enter only generates an Action event if something is
+            // selected.
             if (selectedItem != null)
-	      postActionEvent (selectedItem, ke.getModifiers ());
+	      postActionEvent (selectedItem, ke.getModifiersEx ());
 	  }
       }
 
Index: gnu/java/awt/peer/gtk/GtkMainThread.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java,v
retrieving revision 1.1
diff -u -r1.1 GtkMainThread.java
--- gnu/java/awt/peer/gtk/GtkMainThread.java	31 Jan 2003 17:54:13 -0000	1.1
+++ gnu/java/awt/peer/gtk/GtkMainThread.java	6 Sep 2004 16:35:39 -0000
@@ -43,7 +43,18 @@
   private static Thread mainThread = null;
   private static Object mainThreadLock = new Object();
 
-  static native void gtkInit();
+  // Whether the gtk+ subsystem has been initialized.
+  private boolean gtkInitCalled = false;
+
+  /**
+   * Call gtk_init.  It is very important that this happen before any other
+   * gtk calls.
+   *
+   * @param portableNativeSync 1 if the Java property
+   * gnu.classpath.awt.gtk.portable.native.sync is set to "true".  0 if it is
+   * set to "false".  -1 if unset.
+   */
+  static native void gtkInit(int portableNativeSync);
   native void gtkMain();
   
   public GtkMainThread() 
@@ -59,18 +70,38 @@
     synchronized (this) 
       {
 	mainThread.start();
-	try {
-	  wait();
-	} catch (InterruptedException e) { }
+	
+	while (!gtkInitCalled)
+	  {
+	    try
+	      {
+		wait();
+	      }
+	    catch (InterruptedException e) { }
+	  }
       }
   }
   
   public void run() 
   {
+    /* Pass the value of the gnu.classpath.awt.gtk.portable.native.sync system
+     * property to C. */ 
+    int portableNativeSync;     
+    String portNatSyncProp = 
+      System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
+
+    if (portNatSyncProp == null)
+      portableNativeSync = -1;  // unset
+    else if (Boolean.valueOf(portNatSyncProp).booleanValue())
+      portableNativeSync = 1;   // true
+    else
+      portableNativeSync = 0;   // false
+    
     synchronized (this) 
       {
-	gtkInit();
-	notify();
+	gtkInit(portableNativeSync);
+	gtkInitCalled = true;
+	notifyAll();
       }
     gtkMain();
   }
Index: gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java,v
retrieving revision 1.2
diff -u -r1.2 GtkMenuBarPeer.java
--- gnu/java/awt/peer/gtk/GtkMenuBarPeer.java	13 Jul 2003 15:09:20 -0000	1.2
+++ gnu/java/awt/peer/gtk/GtkMenuBarPeer.java	6 Sep 2004 16:35:39 -0000
@@ -56,15 +56,12 @@
     create ();
   }
 
+  native void nativeSetHelpMenu(MenuPeer menuPeer);
+
   /* In Gnome, help menus are no longer right flushed. */
   public void addHelpMenu (Menu menu)
   {
-    addMenu (menu);
-  }
-
-  public void addMenu (Menu menu)
-  {
-    addMenu ((MenuPeer) menu.getPeer ());
+    nativeSetHelpMenu((MenuPeer) menu.getPeer());
   }
 
   native public void delMenu (int index);
Index: gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java,v
retrieving revision 1.2
diff -u -r1.2 GtkMenuComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java	13 Jul 2003 15:09:20 -0000	1.2
+++ gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java	6 Sep 2004 16:35:39 -0000
@@ -47,8 +47,6 @@
   {
     super (awtWidget);
   }
-
-  public void dispose ()
-  {
-  }
+  
+  public native void dispose();
 }
Index: gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkMenuItemPeer.java
--- gnu/java/awt/peer/gtk/GtkMenuItemPeer.java	8 Oct 2003 15:49:31 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkMenuItemPeer.java	6 Sep 2004 16:35:39 -0000
@@ -50,6 +50,7 @@
   implements MenuItemPeer
 {
   native void create (String label);
+  public native void connectSignals ();
 
   public GtkMenuItemPeer (MenuItem item)
   {
@@ -57,6 +58,9 @@
     create (item.getLabel ());
     setEnabled (item.isEnabled ());
     setParent (item);
+
+    if (item.getParent() instanceof Menu && ! (item instanceof Menu))
+      connectSignals();
   }
 
   void setParent (MenuItem item)
@@ -85,10 +89,8 @@
     setEnabled (true);
   }
 
-  public void setEnabled (boolean b)
-  {
-    // do nothing, for now.
-  }
+  native public void setEnabled (boolean b);
+
   native public void setLabel (String label);
 
   protected void postMenuActionEvent ()
Index: gnu/java/awt/peer/gtk/GtkMenuPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java,v
retrieving revision 1.2
diff -u -r1.2 GtkMenuPeer.java
--- gnu/java/awt/peer/gtk/GtkMenuPeer.java	13 Jul 2003 15:09:20 -0000	1.2
+++ gnu/java/awt/peer/gtk/GtkMenuPeer.java	6 Sep 2004 16:35:39 -0000
@@ -52,11 +52,15 @@
   native void create (String label);
   native void addItem (MenuItemPeer item, int key, boolean shiftModifier);
   native void setupAccelGroup (GtkGenericPeer container);
+  native void addTearOff ();
 
   public GtkMenuPeer (Menu menu)
   {
     super (menu);
     
+    if (menu.isTearOff())
+      addTearOff();
+
     MenuContainer parent = menu.getParent ();
     if (parent instanceof Menu)
       setupAccelGroup ((GtkGenericPeer)((Menu)parent).getPeer ());
@@ -95,10 +99,5 @@
     addItem (item, key, shiftModifier);
   }
 
-  public void addSeparator ()
-  {
-    addItem (new MenuItem ("-"));
-  }
-
   native public void delItem (int index);
 }
Index: gnu/java/awt/peer/gtk/GtkOffScreenImage.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkOffScreenImage.java,v
retrieving revision 1.2
diff -u -r1.2 GtkOffScreenImage.java
--- gnu/java/awt/peer/gtk/GtkOffScreenImage.java	13 Jul 2003 15:09:20 -0000	1.2
+++ gnu/java/awt/peer/gtk/GtkOffScreenImage.java	6 Sep 2004 16:35:39 -0000
@@ -76,7 +76,10 @@
 
   public Graphics getGraphics ()
   {
-    return g;
+    if (g instanceof GdkGraphics2D)
+      return new GdkGraphics2D ((GdkGraphics2D) this.g);
+    else
+      return new GdkGraphics ((GdkGraphics) this.g);
   }
 
   public Object getProperty (String name, ImageObserver observer)
Index: gnu/java/awt/peer/gtk/GtkPanelPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkPanelPeer.java
--- gnu/java/awt/peer/gtk/GtkPanelPeer.java	11 Dec 2003 13:50:50 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkPanelPeer.java	6 Sep 2004 16:35:39 -0000
@@ -38,7 +38,9 @@
 
 package gnu.java.awt.peer.gtk;
 
+import java.awt.AWTEvent;
 import java.awt.Panel;
+import java.awt.event.MouseEvent;
 import java.awt.peer.PanelPeer;
 
 public class GtkPanelPeer extends GtkContainerPeer
@@ -46,10 +48,22 @@
 {
   native void create ();
   native void connectJObject ();
-  native void connectSignals ();
 
   public GtkPanelPeer (Panel p)
   {
     super (p);
   }
+
+  public void handleEvent (AWTEvent event)
+  {
+    int id = event.getID();
+
+    switch (id)
+      {
+      case MouseEvent.MOUSE_PRESSED:
+        awtComponent.requestFocusInWindow ();
+        break;
+      }
+    super.handleEvent (event);
+  }
 }
Index: gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java,v
retrieving revision 1.3
diff -u -r1.3 GtkScrollPanePeer.java
--- gnu/java/awt/peer/gtk/GtkScrollPanePeer.java	5 Jan 2004 21:35:32 -0000	1.3
+++ gnu/java/awt/peer/gtk/GtkScrollPanePeer.java	6 Sep 2004 16:35:39 -0000
@@ -39,6 +39,7 @@
 package gnu.java.awt.peer.gtk;
 
 import java.awt.Adjustable;
+import java.awt.Dimension;
 import java.awt.ScrollPane;
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.ScrollPanePeer;
@@ -87,10 +88,10 @@
   native public int getVScrollbarWidth ();
   native public void setScrollPosition (int x, int y);
 
-//    public Dimension getPreferredSize ()
-//    {
-//      return new Dimension (60, 60);
-//    }
+  public Dimension getPreferredSize ()
+  {
+    return awtComponent.getSize();
+  }
 
   public void setUnitIncrement (Adjustable adj, int u)
   {
Index: gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java,v
retrieving revision 1.7
diff -u -r1.7 GtkTextAreaPeer.java
--- gnu/java/awt/peer/gtk/GtkTextAreaPeer.java	13 Jan 2004 20:58:33 -0000	1.7
+++ gnu/java/awt/peer/gtk/GtkTextAreaPeer.java	6 Sep 2004 16:35:39 -0000
@@ -47,9 +47,13 @@
 public class GtkTextAreaPeer extends GtkTextComponentPeer
   implements TextAreaPeer
 {
+  private static transient int DEFAULT_ROWS = 10;
+  private static transient int DEFAULT_COLS = 80;
+
   native void create (int width, int height, int scrollbarVisibility);
 
   native void gtkSetFont (String name, int style, int size);
+  native void gtkWidgetRequestFocus ();
 
   void create ()
   {
@@ -60,7 +64,7 @@
     // GtkComponent.create.
     if (f == null)
       {
-	f = new Font ("Fixed", Font.PLAIN, 12);
+	f = new Font ("Dialog", Font.PLAIN, 12);
 	awtComponent.setFont (f);
       }
 
@@ -71,13 +75,17 @@
       fm = new GdkFontMetrics (f);
 
     TextArea ta = ((TextArea) awtComponent);
-    int rows = ta.getRows ();
-    int cols = ta.getColumns ();
+    int sizeRows = ta.getRows ();
+    int sizeCols = ta.getColumns ();
+
+    sizeRows = sizeRows == 0 ? DEFAULT_ROWS : sizeRows;
+    sizeCols = sizeCols == 0 ? DEFAULT_COLS : sizeCols;
 
-    int width = cols * fm.getMaxAdvance ();
-    int height = rows * (fm.getMaxDescent () + fm.getMaxAscent ());
+    int width = sizeCols * fm.getMaxAdvance ();
+    int height = sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
 
     create (width, height, ta.getScrollbarVisibility ());
+    setEditable (ta.isEditable ());
   }
 
   public GtkTextAreaPeer (TextArea ta)
@@ -90,12 +98,14 @@
 
   public Dimension getMinimumSize (int rows, int cols)
   {
-    return minimumSize (rows, cols);
+    return minimumSize (rows == 0 ? DEFAULT_ROWS : rows,
+                        cols == 0 ? DEFAULT_COLS : cols);
   }
 
   public Dimension getPreferredSize (int rows, int cols)
   {
-    return preferredSize (rows, cols);
+    return preferredSize (rows == 0 ? DEFAULT_ROWS : rows,
+                          cols == 0 ? DEFAULT_COLS : cols);
   }
 
   native int getHScrollbarHeight ();
@@ -105,8 +115,6 @@
   public Dimension minimumSize (int rows, int cols)
   {
     TextArea ta = ((TextArea) awtComponent);
-    int hScrollbarHeight = 0;
-    int vScrollbarWidth = 0;
     int height = 0;
     int width = 0;
 
@@ -128,8 +136,11 @@
     else
       fm = new GdkFontMetrics (f);
 
-    width += cols * fm.getMaxAdvance ();
-    height += rows * (fm.getMaxDescent () + fm.getMaxAscent ());
+    int sizeRows = rows == 0 ? DEFAULT_ROWS : rows;
+    int sizeCols = cols == 0 ? DEFAULT_COLS : cols;
+
+    width += sizeCols * fm.getMaxAdvance ();
+    height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
 
     return new Dimension (width, height);
   }
@@ -137,8 +148,6 @@
   public Dimension preferredSize (int rows, int cols)
   {
     TextArea ta = ((TextArea) awtComponent);
-    int hScrollbarHeight = 0;
-    int vScrollbarWidth = 0;
     int height = 0;
     int width = 0;
 
@@ -160,8 +169,11 @@
     else
       fm = new GdkFontMetrics (f);
 
-    width += cols * fm.getMaxAdvance ();
-    height += rows * (fm.getMaxDescent () + fm.getMaxAscent ());
+    int sizeRows = rows == 0 ? DEFAULT_ROWS : rows;
+    int sizeCols = cols == 0 ? DEFAULT_COLS : cols;
+
+    width += sizeCols * fm.getMaxAdvance ();
+    height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
 
     return new Dimension (width, height);
   }
@@ -175,9 +187,4 @@
   {
     insert (str, pos);
   }
-
-  public void setFont (Font f)
-  {
-    gtkSetFont (f.getName (), f.getStyle (), f.getSize ());
-  }
 }
Index: gnu/java/awt/peer/gtk/GtkTextComponentPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkTextComponentPeer.java,v
retrieving revision 1.7
diff -u -r1.7 GtkTextComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkTextComponentPeer.java	11 Dec 2003 13:50:50 -0000	1.7
+++ gnu/java/awt/peer/gtk/GtkTextComponentPeer.java	6 Sep 2004 16:35:39 -0000
@@ -54,6 +54,7 @@
     super (tc);
 
     setText (tc.getText ());
+    setCaretPosition(0);
   }
 
   public native void connectSignals ();
Index: gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java,v
retrieving revision 1.8
diff -u -r1.8 GtkTextFieldPeer.java
--- gnu/java/awt/peer/gtk/GtkTextFieldPeer.java	8 Oct 2003 23:38:44 -0000	1.8
+++ gnu/java/awt/peer/gtk/GtkTextFieldPeer.java	6 Sep 2004 16:35:39 -0000
@@ -41,6 +41,7 @@
 import java.awt.AWTEvent;
 import java.awt.Dimension;
 import java.awt.Font;
+import java.awt.FontMetrics;
 import java.awt.TextField;
 import java.awt.event.KeyEvent;
 import java.awt.peer.TextFieldPeer;
@@ -48,14 +49,42 @@
 public class GtkTextFieldPeer extends GtkTextComponentPeer
   implements TextFieldPeer
 {
+  native void create (int width);
+  native void gtkWidgetSetBackground (int red, int green, int blue);
+  native void gtkWidgetSetForeground (int red, int green, int blue);
+
+  void create ()
+  {
+    Font f = awtComponent.getFont ();
+
+    // By default, Sun sets a TextField's font when its peer is
+    // created.  If f != null then the peer's font is set by
+    // GtkComponent.create.
+    if (f == null)
+      {
+	f = new Font ("Dialog", Font.PLAIN, 12);
+	awtComponent.setFont (f);
+      }
 
-//    native void create (ComponentPeer parent, String text);
+    FontMetrics fm;
+    if (GtkToolkit.useGraphics2D ())
+      fm = new GdkClasspathFontPeerMetrics (f);
+    else
+      fm = new GdkFontMetrics (f);
 
-  native void create ();
+    TextField tf = ((TextField) awtComponent);
+    int cols = tf.getColumns ();
 
-  native void gtkEntryGetSize (int dims[]);
+    int text_width = cols * fm.getMaxAdvance ();
 
-  native void gtkSetFont(String name, int style, int size);
+    create (text_width);
+
+    setEditable (tf.isEditable ());
+  }
+
+  native int gtkEntryGetBorderWidth ();
+
+  native void gtkSetFont (String name, int style, int size);
 
   public GtkTextFieldPeer (TextField tf)
   {
@@ -67,34 +96,61 @@
 
   public Dimension getMinimumSize (int cols)
   {
-    int dims[] = new int[2];
-
-    gtkEntryGetSize (dims);
-
-    return (new Dimension (dims[0], dims[1]));
+    return minimumSize (cols);
   }
 
   public Dimension getPreferredSize (int cols)
   {
-    int dims[] = new int[2];
-
-    gtkEntryGetSize (dims);
-
-    return (new Dimension (dims[0], dims[1]));
+    return preferredSize (cols);
   }
-  
-  public native void setEchoChar (char c);
 
-  /* Deprecated */
+  public native void setEchoChar (char c);
 
+  // Deprecated
   public Dimension minimumSize (int cols)
   {
-    return getMinimumSize (cols);
+    int dim[] = new int[2];
+
+    gtkWidgetGetPreferredDimensions (dim);
+
+    Font f = awtComponent.getFont ();
+    if (f == null)
+      return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+    FontMetrics fm;
+    if (GtkToolkit.useGraphics2D ())
+      fm = new GdkClasspathFontPeerMetrics (f);
+    else
+      fm = new GdkFontMetrics (f);
+
+    int text_width = cols * fm.getMaxAdvance ();
+
+    int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+    return new Dimension (width, dim[1]);
   }
 
   public Dimension preferredSize (int cols)
   {
-    return getPreferredSize (cols);
+    int dim[] = new int[2];
+
+    gtkWidgetGetPreferredDimensions (dim);
+
+    Font f = awtComponent.getFont ();
+    if (f == null)
+      return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+    FontMetrics fm;
+    if (GtkToolkit.useGraphics2D ())
+      fm = new GdkClasspathFontPeerMetrics (f);
+    else
+      fm = new GdkFontMetrics (f);
+
+    int text_width = cols * fm.getMaxAdvance ();
+
+    int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+    return new Dimension (width, dim[1]);
   }
 
   public void setEchoCharacter (char c)
@@ -102,20 +158,15 @@
     setEchoChar (c);
   }
 
-  public void setFont (Font f)
-  {
-    gtkSetFont(f.getName(), f.getStyle(), f.getSize());
-  }
-
   public void handleEvent (AWTEvent e)
   {
     if (e.getID () == KeyEvent.KEY_PRESSED)
       {
-        KeyEvent ke = (KeyEvent)e;
+        KeyEvent ke = (KeyEvent) e;
 
-        if (!ke.isConsumed()
-            && ke.getKeyCode() == KeyEvent.VK_ENTER)
-          postActionEvent (getText(), ke.getModifiers ());
+        if (!ke.isConsumed ()
+            && ke.getKeyCode () == KeyEvent.VK_ENTER)
+          postActionEvent (getText (), ke.getModifiersEx ());
       }
 
     super.handleEvent (e);
Index: gnu/java/awt/peer/gtk/GtkToolkit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java,v
retrieving revision 1.7
diff -u -r1.7 GtkToolkit.java
--- gnu/java/awt/peer/gtk/GtkToolkit.java	10 Jan 2004 21:32:23 -0000	1.7
+++ gnu/java/awt/peer/gtk/GtkToolkit.java	6 Sep 2004 16:35:40 -0000
@@ -44,12 +44,17 @@
 import java.awt.dnd.peer.DragSourceContextPeer;
 import java.awt.font.TextAttribute;
 import java.awt.im.InputMethodHighlight;
+import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
 import java.awt.image.ImageObserver;
+import java.awt.image.ImageConsumer;
 import java.awt.image.ImageProducer;
+import java.awt.GraphicsEnvironment;
 import java.awt.peer.*;
 import java.net.URL;
+import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.Properties;
@@ -115,31 +120,174 @@
   public int checkImage (Image image, int width, int height, 
 			 ImageObserver observer) 
   {
-    return ((GtkImage) image).checkImage ();
+    int status = ((GtkImage) image).checkImage ();
+
+    if (observer != null)
+      observer.imageUpdate (image, status,
+                            -1, -1,
+                            image.getWidth (observer),
+                            image.getHeight (observer));
+
+    return status;
+  }
+
+  /** 
+   * A helper class to return to clients in cases where a BufferedImage is
+   * desired but its construction fails.
+   */
+  private class GtkErrorImage extends Image
+  {
+    public GtkErrorImage()
+    {
+    }
+
+    public int getWidth(ImageObserver observer)
+    {
+      return -1;
+    }
+
+    public int getHeight(ImageObserver observer)
+    {
+      return -1;
+    }
+
+    public ImageProducer getSource()
+    {
+
+      return new ImageProducer() 
+        {          
+          HashSet consumers = new HashSet();          
+          public void addConsumer(ImageConsumer ic)
+          {
+            consumers.add(ic);
+          }
+
+          public boolean isConsumer(ImageConsumer ic)
+          {
+            return consumers.contains(ic);
+          }
+
+          public void removeConsumer(ImageConsumer ic)
+          {
+            consumers.remove(ic);
+          }
+
+          public void startProduction(ImageConsumer ic)
+          {
+            consumers.add(ic);
+            Iterator i = consumers.iterator();
+            while(i.hasNext())
+              {
+                ImageConsumer c = (ImageConsumer) i.next();
+                c.imageComplete(ImageConsumer.IMAGEERROR);
+              }
+          }
+          public void requestTopDownLeftRightResend(ImageConsumer ic)
+          {
+            startProduction(ic);
+          }        
+        };
+    }
+
+    public Graphics getGraphics() 
+    { 
+      return null; 
+    }
+
+    public Object getProperty(String name, ImageObserver observer)
+    {
+      return null;
+    }
+    public Image getScaledInstance(int width, int height, int flags)
+    {
+      return new GtkErrorImage();
+    }
+
+    public void flush() 
+    {
+    }
   }
 
+
+  /** 
+   * Helper to return either a BufferedImage -- the argument -- or a
+   * GtkErrorImage if the argument is null.
+   */
+
+  private Image bufferedImageOrError(BufferedImage b)
+  {
+    if (b == null) 
+      return new GtkErrorImage();
+    else
+      return b;
+  }
+
+
   public Image createImage (String filename)
   {
-    return new GtkImage (new GdkPixbufDecoder (filename), null);
+    if (useGraphics2D())
+      return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (filename));
+    else
+      {
+        GdkPixbufDecoder d = new GdkPixbufDecoder (filename);
+        GtkImage image = new GtkImage (d, null);
+        d.startProduction (image);
+        return image;        
+      }
   }
 
   public Image createImage (URL url)
   {
-    return new GtkImage (new GdkPixbufDecoder (url), null);
+    if (useGraphics2D())
+      return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (url));
+    else
+      {
+        GdkPixbufDecoder d = new GdkPixbufDecoder (url);
+        GtkImage image = new GtkImage (d, null);
+        d.startProduction (image);
+        return image;        
+      }
   }
 
   public Image createImage (ImageProducer producer) 
   {
-    return new GtkImage (producer, null);
+    if (useGraphics2D())
+      return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (producer));
+    else
+      {
+        GtkImage image = new GtkImage (producer, null);
+        producer.startProduction (image);
+        return image;        
+      }
   }
 
   public Image createImage (byte[] imagedata, int imageoffset,
 			    int imagelength)
   {
-    return new GtkImage (new GdkPixbufDecoder (imagedata,
-					       imageoffset,
-					       imagelength),
-			 null);
+    if (useGraphics2D())
+      return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (imagedata,
+                                                   imageoffset, 
+                                                                        imagelength));
+    else
+      {
+        GdkPixbufDecoder d = new GdkPixbufDecoder (imagedata,
+                                                   imageoffset, 
+                                                   imagelength);
+        GtkImage image = new GtkImage (d, null);
+        d.startProduction (image);
+        return image;        
+      }
+  }
+  
+  /**
+   * Creates an ImageProducer from the specified URL. The image is assumed
+   * to be in a recognised format. 
+   *
+   * @param url URL to read image data from.
+   */  
+  public ImageProducer createImageProducer(URL url)
+  {
+    return new GdkPixbufDecoder(url);  
   }
 
   public ColorModel getColorModel () 
@@ -166,12 +314,12 @@
 
   public Image getImage (String filename) 
   {
-    return new GtkImage (new GdkPixbufDecoder (filename), null);
+    return createImage (filename);
   }
 
   public Image getImage (URL url) 
   {
-    return new GtkImage (new GdkPixbufDecoder (url), null);
+    return createImage (url);
   }
 
   public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) 
@@ -352,14 +500,18 @@
    * @deprecated part of the older "logical font" system in earlier AWT
    * implementations. Our newer Font class uses getClasspathFontPeer.
    */
-  protected FontPeer getFontPeer (String name, int style) 
+  protected FontPeer getFontPeer (String name, int style) {
+    // All fonts get a default size of 12 if size is not specified.
+    return getFontPeer(name, style, 12);
+  }
+
+  /**
+   * Private method that allows size to be set at initialization time.
+   */
+  private FontPeer getFontPeer (String name, int style, int size) 
   {
-    try {
-      GtkFontPeer fp = new GtkFontPeer (name, style);
-      return fp;
-    } catch (MissingResourceException ex) {
-      return null;
-    }
+    GtkFontPeer fp = new GtkFontPeer (name, style, size);
+    return fp;
   }
 
   /**
@@ -374,7 +526,11 @@
       return new GdkClasspathFontPeer (name, attrs);
     else
       {
+        // Default values
+        int size = 12;
         int style = Font.PLAIN;
+        if (name == null)
+          name = "Default";
 
         if (attrs.containsKey (TextAttribute.WEIGHT))
           {
@@ -390,7 +546,13 @@
               style += Font.ITALIC;
           }
         
-        return (ClasspathFontPeer) this.getFontPeer (name, style);
+        if (attrs.containsKey (TextAttribute.SIZE))
+          {
+            Float fsize = (Float) attrs.get (TextAttribute.SIZE);
+            size = fsize.intValue();
+          }
+ 
+        return (ClasspathFontPeer) this.getFontPeer (name, style, size);
       }
   }
 
@@ -399,9 +561,7 @@
     return q;
   }
 
-  protected void loadSystemColors (int[] systemColors) 
-  {
-  }
+  protected native void loadSystemColors (int[] systemColors);
 
   public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
   {
@@ -417,7 +577,9 @@
 
   public GraphicsEnvironment getLocalGraphicsEnvironment()
   {
-    throw new java.lang.UnsupportedOperationException ();
+    GraphicsEnvironment ge;
+    ge = new GdkGraphicsEnvironment ();  
+    return ge;
   }
 
   public Font createFont(int format, java.io.InputStream stream)
Index: gnu/java/awt/peer/gtk/GtkWindowPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java,v
retrieving revision 1.10
diff -u -r1.10 GtkWindowPeer.java
--- gnu/java/awt/peer/gtk/GtkWindowPeer.java	13 Jan 2004 20:54:46 -0000	1.10
+++ gnu/java/awt/peer/gtk/GtkWindowPeer.java	6 Sep 2004 16:35:40 -0000
@@ -60,6 +60,10 @@
   private boolean hasBeenShown = false;
   private int oldState = Frame.NORMAL;
 
+  native void gtkWindowSetTitle (String title);
+  native void gtkWindowSetResizable (boolean resizable);
+  native void gtkWindowSetModal (boolean modal);
+
   native void create (int type, boolean decorated,
 		      int width, int height,
 		      GtkWindowPeer parent,
@@ -92,6 +96,16 @@
     create (GDK_WINDOW_TYPE_HINT_NORMAL, false);
   }
 
+  void setParent ()
+  {
+    setVisible (awtComponent.isVisible ());
+    setEnabled (awtComponent.isEnabled ());
+  }
+
+  void setVisibleAndEnabled ()
+  {
+  }
+
   native void connectJObject ();
   native void connectSignals ();
 
@@ -100,12 +114,6 @@
     super (window);
   }
 
-  public void getArgs (Component component, GtkArgList args)
-  {
-    args.add ("visible", component.isVisible ());
-    args.add ("sensitive", component.isEnabled ());
-  }
-
   native public void toBack ();
   native public void toFront ();
 
@@ -120,7 +128,7 @@
 
   public void setTitle (String title)
   {
-    set ("title", title);
+    gtkWindowSetTitle (title);
   }
 
   native void setSize (int width, int height);
@@ -132,8 +140,7 @@
     // was resizable.
     setSize (awtComponent.getWidth() - insets.left - insets.right,
 	     awtComponent.getHeight() - insets.top - insets.bottom);
-    set ("allow_shrink", resizable);
-    set ("allow_grow", resizable);
+    gtkWindowSetResizable (resizable);
   }
 
   native void setBoundsCallback (Window window,
Index: gnu/java/awt/peer/gtk/TestAWT.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/TestAWT.java,v
retrieving revision 1.3
diff -u -r1.3 TestAWT.java
--- gnu/java/awt/peer/gtk/TestAWT.java	13 Jan 2004 20:00:00 -0000	1.3
+++ gnu/java/awt/peer/gtk/TestAWT.java	6 Sep 2004 16:35:40 -0000
@@ -272,6 +272,7 @@
         public void windowClosing (WindowEvent e)
         {
           System.out.println ("Window Closing");
+	  text.setVisible (false);
           hide ();
         }
       });
@@ -305,7 +306,8 @@
     cb.addActionListener(new ActionListener () {
       public void actionPerformed (ActionEvent e) 
 	{
-	  dispose();
+	  text.setVisible (false);
+	  hide();
 	}
     });
     
Index: gnu/java/security/action/GetPropertyAction.java
===================================================================
RCS file: gnu/java/security/action/GetPropertyAction.java
diff -N gnu/java/security/action/GetPropertyAction.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/security/action/GetPropertyAction.java	6 Sep 2004 16:35:40 -0000
@@ -0,0 +1,89 @@
+/* GetPropertyAction.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.security.action;
+
+import java.security.PrivilegedAction;
+
+/**
+ * PrivilegedAction implementation that calls System.getProperty() with
+ * the property name passed to its constructor.
+ *
+ * Example of use:
+ * <code>
+ * GetPropertyAction action = new GetPropertyAction("http.proxyPort");
+ * String port = AccessController.doPrivileged(action);
+ * </code>
+ */
+public class GetPropertyAction implements PrivilegedAction
+{
+  String name;
+  String value = null;
+
+  public GetPropertyAction()
+  {
+  }
+  
+  public GetPropertyAction(String propName)
+  {
+    setParameters(propName);
+  }
+
+  public GetPropertyAction(String propName, String defaultValue)
+  {
+    setParameters(propName, defaultValue);
+  }
+  
+  public Object run()
+  {
+    return System.getProperty(name, value);
+  }
+  
+  public GetPropertyAction setParameters(String propName)
+  {
+    this.name = propName;
+    this.value = null;
+    return this;
+  }
+
+  public GetPropertyAction setParameters(String propName, String defaultValue)
+  {
+    this.name = propName;
+    this.value = defaultValue;
+    return this;
+  }
+}
Index: gnu/java/security/action/SetAccessibleAction.java
===================================================================
RCS file: gnu/java/security/action/SetAccessibleAction.java
diff -N gnu/java/security/action/SetAccessibleAction.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/security/action/SetAccessibleAction.java	6 Sep 2004 16:35:40 -0000
@@ -0,0 +1,77 @@
+/* SetAccessibleAction.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.security.action;
+
+import java.lang.reflect.AccessibleObject;
+import java.security.PrivilegedAction;
+
+/**
+ * PrivilegedAction implementation that calls setAccessible(true) on the 
+ * AccessibleObject passed to its constructor.
+ *
+ * Example of use:
+ * <code>
+ * Field dataField = cl.getDeclaredField("data");
+ * AccessController.doPrivileged(new SetAccessibleAction(dataField));
+ * </code>
+ */
+public class SetAccessibleAction implements PrivilegedAction
+{
+  AccessibleObject member;
+  
+  public SetAccessibleAction()
+  {
+  }
+  
+  public SetAccessibleAction(AccessibleObject member)
+  {
+    this.member = member;
+  }
+  
+  public Object run()
+  {
+    member.setAccessible(true);
+    return null;
+  }
+  
+  public SetAccessibleAction setMember(AccessibleObject member)
+  {
+    this.member = member;
+    return this;
+  }
+}
Index: java/awt/AWTEvent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/AWTEvent.java,v
retrieving revision 1.9
diff -u -r1.9 AWTEvent.java
--- java/awt/AWTEvent.java	9 Aug 2002 04:26:13 -0000	1.9
+++ java/awt/AWTEvent.java	6 Sep 2004 16:35:41 -0000
@@ -231,15 +231,23 @@
   }
 
   /**
-   * Returns a string representation of this event. This is in the format
-   * <code>getClass().getName() + '[' + paramString() + "] on "
-   * + source</code>.
+   * Create a string that represents this event in the format
+   * <code>classname[eventstring] on sourcecomponentname</code>.
    *
-   * @return a string representation of this event
+   * @return a string representing this event
    */
-  public String toString()
+  public String toString ()
   {
-    return getClass().getName() + "[" + paramString() + "] on " + source;
+    String string = null;
+
+    if (source instanceof Component)
+      string = getClass ().getName () + "[" + paramString () + "] on "
+        + ((Component) source).getName ();
+    else if (source instanceof MenuComponent)
+      string = getClass ().getName () + "[" + paramString () + "] on "
+        + ((MenuComponent) source).getName ();
+
+    return string;
   }
 
   /**
Index: java/awt/AWTKeyStroke.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/AWTKeyStroke.java,v
retrieving revision 1.1
diff -u -r1.1 AWTKeyStroke.java
--- java/awt/AWTKeyStroke.java	9 Aug 2002 04:26:13 -0000	1.1
+++ java/awt/AWTKeyStroke.java	6 Sep 2004 16:35:41 -0000
@@ -409,13 +409,13 @@
       {
         token = t.nextToken();
         if ("shift".equals(token))
-          modifiers |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK;
+          modifiers |= KeyEvent.SHIFT_DOWN_MASK;
         else if ("ctrl".equals(token) || "control".equals(token))
-          modifiers |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK;
+          modifiers |= KeyEvent.CTRL_DOWN_MASK;
         else if ("meta".equals(token))
-          modifiers |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK;
+          modifiers |= KeyEvent.META_DOWN_MASK;
         else if ("alt".equals(token))
-          modifiers |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK;
+          modifiers |= KeyEvent.ALT_DOWN_MASK;
         else if ("button1".equals(token))
           modifiers |= KeyEvent.BUTTON1_DOWN_MASK;
         else if ("button2".equals(token))
Index: java/awt/AWTPermission.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/AWTPermission.java,v
retrieving revision 1.4
diff -u -r1.4 AWTPermission.java
--- java/awt/AWTPermission.java	9 Aug 2002 04:26:13 -0000	1.4
+++ java/awt/AWTPermission.java	6 Sep 2004 16:35:41 -0000
@@ -79,7 +79,7 @@
  * <tr>
  *   <td><code>fullScreenExclusive</code></td>
  *   <td>enter full-screen exclusive mode</td>
- *   <td>malicious code could masquerade as a trusted program</td><tr>
+ *   <td>malicious code could masquerade as a trusted program</td></tr>
  * </table>
  *
  * @author Tom Tromey <tromey@redhat.com>
Index: java/awt/BorderLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/BorderLayout.java,v
retrieving revision 1.10
diff -u -r1.10 BorderLayout.java
--- java/awt/BorderLayout.java	10 Nov 2002 23:11:21 -0000	1.10
+++ java/awt/BorderLayout.java	6 Sep 2004 16:35:41 -0000
@@ -349,7 +349,28 @@
   if (constraints != null && ! (constraints instanceof String))
     throw new IllegalArgumentException("Constraint must be a string");
 
-  String str = (String)constraints;
+  addLayoutComponent((String) constraints, component);
+}
+
+/*************************************************************************/
+
+/**
+  * Adds a component to the layout in the specified constraint position, 
+  * which must be one of the string constants defined in this class.
+  *
+  * @param constraints The constraint string.
+  * @param component The component to add.
+  *
+  * @exception IllegalArgumentException If the constraint object is not
+  * one of the specified constants in this class.
+  *
+  * @deprecated This method is deprecated in favor of
+  * <code>addLayoutComponent(Component, Object)</code>.
+  */
+public void
+addLayoutComponent(String constraints, Component component)
+{
+  String str = constraints;
 
   if (str == null || str.equals(CENTER))
     center = component;
@@ -376,27 +397,6 @@
 /*************************************************************************/
 
 /**
-  * Adds a component to the layout in the specified constraint position, 
-  * which must be one of the string constants defined in this class.
-  *
-  * @param constraints The constraint string.
-  * @param component The component to add.
-  *
-  * @exception IllegalArgumentException If the constraint object is not
-  * one of the specified constants in this class.
-  *
-  * @deprecated This method is deprecated in favor of
-  * <code>addLayoutComponent(Component, Object)</code>.
-  */
-public void
-addLayoutComponent(String constraints, Component component)
-{
-  addLayoutComponent(component, constraints);
-}
-
-/*************************************************************************/
-
-/**
   * Removes the specified component from the layout.
   *
   * @param component The component to remove from the layout.
@@ -592,12 +592,21 @@
 
       int x1 = i.left;
       int x2 = x1 + w.width + hgap;
-      int x3 = t.width - i.right - e.width;
+      int x3;
+      if (t.width <= i.right + e.width)
+        x3 = x2 + w.width + hgap;
+      else
+        x3 = t.width - i.right - e.width;
       int ww = t.width - i.right - i.left;
 
       int y1 = i.top;
       int y2 = y1 + n.height + vgap;
-      int y3 = t.height - i.bottom - s.height;
+      int midh = Math.max(e.height, Math.max(w.height, c.height));
+      int y3;
+      if (t.height <= i.bottom + s.height)
+        y3 = y2 + midh + vgap;
+      else
+        y3 = t.height - i.bottom - s.height;
       int hh = y3-y2-vgap;
 
       setBounds(center, x2, y2, x3-x2-hgap, hh);
@@ -637,7 +646,7 @@
 private Dimension
 calcCompSize(Component comp, int what)
 {
-  if (comp == null)
+  if (comp == null || !comp.isVisible())
     return new Dimension(0, 0);
   if (what == MIN)
     return comp.getMinimumSize();
Index: java/awt/Button.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Button.java,v
retrieving revision 1.11
diff -u -r1.11 Button.java
--- java/awt/Button.java	5 Jun 2003 19:58:39 -0000	1.11
+++ java/awt/Button.java	6 Sep 2004 16:35:41 -0000
@@ -81,6 +81,11 @@
 // List of ActionListeners for this class.
 private transient ActionListener action_listeners;
 
+  /*
+   * The number used to generate the name returned by getName.
+   */
+  private static transient long next_button_number = 0;
+
 /*************************************************************************/
 
 /*
@@ -96,7 +101,7 @@
 public
 Button()
 {
-  this(null);
+  this("");
 }
 
 /*************************************************************************/
@@ -148,6 +153,7 @@
 setLabel(String label)
 {
   this.label = label;
+  actionCommand = label;
   if (peer != null)
     {
       ButtonPeer bp = (ButtonPeer) peer;
@@ -304,9 +310,24 @@
 protected String
 paramString()
 {
-  return ("label=" + getLabel() + ",actionCommand=" + getActionCommand()
-	  + "," + super.paramString());
+  return getName () + "," + getX () + "," + getY () + ","
+    + getWidth () + "x" + getHeight () + ",label=" + getLabel ();
 }
 
+  /**
+   * Generate a unique name for this button.
+   *
+   * @return A unique name for this button.
+   */
+  String generateName ()
+  {
+    return "button" + getUniqueLong ();
+  }
+
+  private static synchronized long getUniqueLong ()
+  {
+    return next_button_number++;
+  }
+
 } // class Button 
 
Index: java/awt/CardLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/CardLayout.java,v
retrieving revision 1.8
diff -u -r1.8 CardLayout.java
--- java/awt/CardLayout.java	15 Jan 2003 22:47:04 -0000	1.8
+++ java/awt/CardLayout.java	6 Sep 2004 16:35:41 -0000
@@ -90,7 +90,7 @@
     if (! (constraints instanceof String))
       throw new IllegalArgumentException ("Object " + constraints
 					  + " is not a string");
-    tab.put (constraints, comp);
+    addLayoutComponent ((String) constraints, comp);
   }
 
   /** Add a new component to the layout.  The name can be used later
@@ -102,7 +102,12 @@
    */
   public void addLayoutComponent (String name, Component comp)
   {
-    addLayoutComponent (comp, name);
+    tab.put (name, comp);
+    // First component added is the default component.
+    if (tab.size() == 1)
+      comp.setVisible(true);
+    else
+      comp.setVisible(false);
   }
 
   /** Cause the first component in the container to be displayed.
@@ -243,6 +248,8 @@
 	if (tab.get (key) == comp)
 	  {
 	    tab.remove (key);
+	    Container parent = comp.getParent();
+	    next(parent);
 	    break;
 	  }
       }
@@ -311,6 +318,13 @@
 	int num = parent.ncomponents;
 	// This is more efficient than calling getComponents().
 	Component[] comps = parent.component;
+
+	if (num == 1)
+	  {
+	    comps[0].setVisible(true);
+	    return;
+	  }
+
 	int choice = -1;
 
 	if (what == FIRST)
Index: java/awt/CheckboxGroup.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/CheckboxGroup.java,v
retrieving revision 1.4
diff -u -r1.4 CheckboxGroup.java
--- java/awt/CheckboxGroup.java	22 Jan 2002 22:40:04 -0000	1.4
+++ java/awt/CheckboxGroup.java	6 Sep 2004 16:35:41 -0000
@@ -95,8 +95,8 @@
 public Checkbox
 getSelectedCheckbox()
 {
-  return(selectedCheckbox);
-} 
+  return getCurrent ();
+}
 
 /*************************************************************************/
 
@@ -126,17 +126,7 @@
 public void
 setSelectedCheckbox(Checkbox selectedCheckbox)
 {
-  if (this.selectedCheckbox != null)
-    {
-      if (this.selectedCheckbox.getCheckboxGroup() != this)
-        return;
-
-      this.selectedCheckbox.setState(false);
-    }
-
-  this.selectedCheckbox = selectedCheckbox;
-  if (selectedCheckbox != null)
-    selectedCheckbox.setState(true);
+  setCurrent (selectedCheckbox);
 }
 
 /*************************************************************************/
@@ -153,7 +143,17 @@
 public void
 setCurrent(Checkbox selectedCheckbox)
 {
-  setSelectedCheckbox(selectedCheckbox);
+  if (this.selectedCheckbox != null)
+    {
+      if (this.selectedCheckbox.getCheckboxGroup() != this)
+        return;
+
+      this.selectedCheckbox.setState(false);
+    }
+
+  this.selectedCheckbox = selectedCheckbox;
+  if (selectedCheckbox != null)
+    selectedCheckbox.setState(true);
 }
 
 /*************************************************************************/
Index: java/awt/Choice.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Choice.java,v
retrieving revision 1.13
diff -u -r1.13 Choice.java
--- java/awt/Choice.java	5 Jan 2004 21:18:06 -0000	1.13
+++ java/awt/Choice.java	6 Sep 2004 16:35:41 -0000
@@ -111,7 +111,7 @@
 public int
 getItemCount()
 {
-  return(pItems.size());
+  return countItems ();
 }
 
 /*************************************************************************/
Index: java/awt/Color.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Color.java,v
retrieving revision 1.10
diff -u -r1.10 Color.java
--- java/awt/Color.java	13 Aug 2003 03:19:24 -0000	1.10
+++ java/awt/Color.java	6 Sep 2004 16:35:41 -0000
@@ -319,7 +319,12 @@
   {
     if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
         || (alpha & 255) != alpha)
-      throw new IllegalArgumentException("Bad RGB values");
+      throw new IllegalArgumentException("Bad RGB values"
+                                        +" red=0x"+Integer.toHexString(red)
+                                        +" green=0x"+Integer.toHexString(green)
+                                        +" blue=0x"+Integer.toHexString(blue)
+                                        +" alpha=0x"+Integer.toHexString(alpha)  );
+
     value = (alpha << 24) | (red << 16) | (green << 8) | blue;
     falpha = 1;
     cs = null;
@@ -501,7 +506,7 @@
 
   /**
    * Returns the RGB value for this color, in the sRGB color space. The blue
-   * value will be in bits 0-7, green in 8-15, red in 6-23, and alpha value in
+   * value will be in bits 0-7, green in 8-15, red in 16-23, and alpha value in
    * 24-31.
    *
    * @return the RGB value for this color
@@ -767,9 +772,9 @@
         if (red == max)
           array[0] = (green - blue) / delta;
         else if (green == max)
-          array[0] = 1 / 3 + (blue - red) / delta;
+          array[0] = 1f / 3 + (blue - red) / delta;
         else
-          array[0] = 2 / 3 + (red - green) / delta;
+          array[0] = 2f / 3 + (red - green) / delta;
         if (array[0] < 0)
           array[0]++;
       }
@@ -950,7 +955,7 @@
    * object, regardless of the parameters. Subclasses, however, may have a
    * mutable result.
    *
-   * @param cm the requested color model, ignored
+   * @param cm the requested color model
    * @param deviceBounds the bounding box in device coordinates, ignored
    * @param userBounds the bounding box in user coordinates, ignored
    * @param xform the bounds transformation, ignored
@@ -962,8 +967,8 @@
                                     AffineTransform xform,
                                     RenderingHints hints)
   {
-    if (context == null)
-      context = new ColorPaintContext(value);
+    if (context == null || !context.getColorModel().equals(cm))
+      context = new ColorPaintContext(cm,value);
     return context;
   }
 
Index: java/awt/ColorPaintContext.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/ColorPaintContext.java,v
retrieving revision 1.1
diff -u -r1.1 ColorPaintContext.java
--- java/awt/ColorPaintContext.java	9 Aug 2002 04:26:13 -0000	1.1
+++ java/awt/ColorPaintContext.java	6 Sep 2004 16:35:41 -0000
@@ -1,5 +1,5 @@
 /* ColorPaintContext.java -- context for painting solid colors
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -55,15 +55,31 @@
    * SystemColor.
    */
   final int color;
+  final ColorModel colorModel;
 
+  private ColorRaster cachedRaster;
+
+  
   /**
    * Create the context for a given color.
    *
-   * @param c the solid color to use
+   * @param c The solid color to use.
    */
-  ColorPaintContext(int c)
+  ColorPaintContext(int colorRGB)
   {
-    color = c;
+    this(ColorModel.getRGBdefault(), colorRGB);
+  }
+  
+  /**
+   * Create the context for a given color.
+   *
+   * @param cm The color model of this context. 
+   * @param c The solid color to use.
+   */
+  ColorPaintContext(ColorModel cm,int colorRGB)
+  {
+    color = colorRGB;
+    colorModel = cm;
   }
 
   /**
@@ -75,14 +91,13 @@
   }
 
   /**
-   * Return the color model of this context. This ignores the model passed
-   * in the request, since colors are always in sRGB.
+   * Return the color model of this context. 
    *
    * @return the context color model
    */
   public ColorModel getColorModel()
   {
-    return ColorModel.getRGBdefault();
+    return colorModel;
   }
 
   /**
@@ -94,10 +109,87 @@
    * @param h the height, in device space
    * @return a raster for the given area and color
    */
-  public Raster getRaster(int x, int y, int w, int h)
+  public Raster getRaster(int x, int y, int width, int height)
+  {
+   if(  cachedRaster == null 
+       || cachedRaster.getWidth() < width
+       || cachedRaster.getHeight() < height)
+   {
+     cachedRaster = new ColorRaster(colorModel, 0, 0, width, height, color);
+   }
+   return cachedRaster.createChild(0 ,0 ,width ,height ,x ,y , null);
+  }
+  
+  /**
+   * A ColorRaster is a raster that is completely filled with one color. The 
+   * data layout is taken from the color model given to the constructor.
+   */
+  private class ColorRaster extends Raster
   {
-    // XXX Implement. Sun uses undocumented implementation class
-    // sun.awt.image.IntegerInterleavedRaster.
-    throw new Error("not implemented");
+    
+    /**
+     * Create a raster that is compaltible with the given color model and 
+     * filled with the given color.
+     * @param cm The color model for this raster.
+     * @param x The smallest horizontal corrdinate in the raster.
+     * @param y The smallest vertical coordinate in the raster.
+     * @param width The width of the raster.
+     * @param height The height of the raster.
+     * @param rgbPixel The RGB value of the color for this raster.
+     */
+    ColorRaster(ColorModel cm,int x, int y, int width, int height, int rgbPixel)
+    {         
+      super(cm.createCompatibleSampleModel(width,height),new Point(x,y));
+      Object pixel = cm.getDataElements(rgbPixel,null);
+      getSampleModel().setDataElements(0, 0,
+                                       width, height,
+                                       multiplyData(pixel,null,width*height),
+                                       dataBuffer);
+    }
+    
+    
+    
+    private Object multiplyData(Object src, Object dest, int factor)
+    {
+      Object from;
+      int srcLength = 0;
+      if (src instanceof byte[])
+      {
+        srcLength = ((byte[])src).length;
+        
+        if (dest == null) dest = new byte[factor * srcLength];
+      }
+      else if (src instanceof short[])
+      {
+        srcLength = ((short[])src).length;
+        if (dest == null) dest = new short[factor * srcLength];
+      }
+      else if (src instanceof int[])
+      {
+        srcLength = ((int[]) src).length;
+        if (dest == null) dest = new int[factor * srcLength];
+      }
+      else
+      {
+        throw new ClassCastException("Unknown data buffer type");
+      }
+      
+      System.arraycopy(src,0,dest,0,srcLength);
+      
+      int count = 1;
+      while(count*2 < factor)
+      {
+        System.arraycopy(dest, 0, dest, count * srcLength, count*srcLength);
+        count *= 2; 
+      }
+      
+      if(factor > count)
+        System.arraycopy(dest,0, dest, count * srcLength, 
+                         (factor - count) * srcLength );
+      
+      return dest;
+    }
+    
   }
+  
 } // class ColorPaintContext
Index: java/awt/Component.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Component.java,v
retrieving revision 1.31
diff -u -r1.31 Component.java
--- java/awt/Component.java	12 Nov 2003 22:03:49 -0000	1.31
+++ java/awt/Component.java	6 Sep 2004 16:35:43 -0000
@@ -39,6 +39,7 @@
 package java.awt;
 
 import java.awt.dnd.DropTarget;
+import java.awt.event.ActionEvent;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
 import java.awt.event.FocusEvent;
@@ -48,6 +49,7 @@
 import java.awt.event.HierarchyListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
+import java.awt.event.InputEvent;
 import java.awt.event.InputMethodEvent;
 import java.awt.event.InputMethodListener;
 import java.awt.event.MouseEvent;
@@ -56,6 +58,7 @@
 import java.awt.event.MouseWheelListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
 import java.awt.im.InputContext;
 import java.awt.im.InputMethodRequests;
 import java.awt.image.BufferStrategy;
@@ -105,7 +108,7 @@
  * in inner classes, rather than using this object itself as the listener, if
  * external objects do not need to save the state of this object.
  *
- * <p><pre>
+ * <pre>
  * import java.awt.*;
  * import java.awt.event.*;
  * import java.io.Serializable;
@@ -127,6 +130,7 @@
  *     aButton.addActionListener(new MyActionListener());
  *   }
  * }
+ * </pre>
  *
  * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
  * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
@@ -382,18 +386,18 @@
   boolean focusable = true;
 
   /**
-   * Tracks whether this component uses default focus traversal, or has a
-   * different policy.
+   * Tracks whether this component's {@link #isFocusTraversable}
+   * method has been overridden.
    *
-   * @see #isFocusTraversableOverridden()
    * @since 1.4
    */
   int isFocusTraversableOverridden;
 
   /**
-   * The focus traversal keys, if not inherited from the parent or default
-   * keyboard manager. These sets will contain only AWTKeyStrokes that
-   * represent press and release events to use as focus control.
+   * The focus traversal keys, if not inherited from the parent or
+   * default keyboard focus manager. These sets will contain only
+   * AWTKeyStrokes that represent press and release events to use as
+   * focus control.
    *
    * @see #getFocusTraversalKeys(int)
    * @see #setFocusTraversalKeys(int, Set)
@@ -556,6 +560,12 @@
   transient BufferStrategy bufferStrategy;
 
   /**
+   * true if requestFocus was called on this component when its
+   * top-level ancestor was not focusable.
+   */
+  private transient FocusEvent pendingFocusRequest = null;
+
+  /**
    * The system properties that affect image updating.
    */
   private static transient boolean incrementalDraw;
@@ -565,6 +575,8 @@
   {
     incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
     redrawRate = Long.getLong ("awt.image.redrawrate");
+    // Set the default KeyboardFocusManager.
+    KeyboardFocusManager.setCurrentKeyboardFocusManager (null);
   }
 
   // Public and protected API.
@@ -779,9 +791,7 @@
    */
   public void setEnabled(boolean b)
   {
-    this.enabled = b;
-    if (peer != null)
-      peer.setEnabled(b);
+    enable (b);
   }
 
   /**
@@ -791,7 +801,9 @@
    */
   public void enable()
   {
-    setEnabled(true);
+    this.enabled = true;
+    if (peer != null)
+      peer.setEnabled (true);
   }
 
   /**
@@ -802,7 +814,10 @@
    */
   public void enable(boolean b)
   {
-    setEnabled(b);
+    if (b)
+      enable ();
+    else
+      disable ();
   }
 
   /**
@@ -812,7 +827,9 @@
    */
   public void disable()
   {
-    setEnabled(false);
+    this.enabled = false;
+    if (peer != null)
+      peer.setEnabled (false);
   }
 
   /**
@@ -856,10 +873,7 @@
     // Inspection by subclassing shows that Sun's implementation calls
     // show(boolean) which then calls show() or hide(). It is the show()
     // method that is overriden in subclasses like Window.
-    if (b)
-      show();
-    else
-      hide();
+    show (b);
   }
 
   /**
@@ -869,9 +883,21 @@
    */
   public void show()
   {
-    if (peer != null)
-      peer.setVisible(true);
-    this.visible = true;
+    // We must set visible before showing the peer.  Otherwise the
+    // peer could post paint events before visible is true, in which
+    // case lightweight components are not initially painted --
+    // Container.paint first calls isShowing () before painting itself
+    // and its children.
+    if(!isVisible())
+      {
+        this.visible = true;
+        if (peer != null)
+          peer.setVisible(true);
+        invalidate();
+        ComponentEvent ce =
+          new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
   }
 
   /**
@@ -882,7 +908,10 @@
    */
   public void show(boolean b)
   {
-    setVisible(b);
+    if (b)
+      show ();
+    else
+      hide ();
   }
 
   /**
@@ -892,9 +921,16 @@
    */
   public void hide()
   {
-    if (peer != null)
-      peer.setVisible(false);
-    this.visible = false;
+    if (isVisible())
+      {
+        if (peer != null)
+          peer.setVisible(false);
+        this.visible = false;
+        invalidate();
+        ComponentEvent ce =
+          new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
   }
 
   /**
@@ -908,7 +944,7 @@
   {
     if (foreground != null)
       return foreground;
-    return parent == null ? null : parent.getForeground();
+    return parent == null ? SystemColor.windowText : parent.getForeground();
   }
 
   /**
@@ -949,7 +985,7 @@
   {
     if (background != null)
       return background;
-    return parent == null ? null : parent.getBackground();
+    return parent == null ? SystemColor.window : parent.getBackground();
   }
 
   /**
@@ -962,8 +998,11 @@
    */
   public void setBackground(Color c)
   {
+    // If c is null, inherit from closest ancestor whose bg is set.
+    if (c == null && parent != null)
+      c = parent.getBackground();
     firePropertyChange("background", background, c);
-    if (peer != null)
+    if (peer != null && c != null)
       peer.setBackground(c);
     background = c;
   }
@@ -991,7 +1030,11 @@
   {
     if (font != null)
       return font;
-    return parent == null ? null : parent.getFont();
+
+    if (parent != null)
+      return parent.getFont ();
+    else
+      return new Font ("Dialog", Font.PLAIN, 12);
   }
 
   /**
@@ -1006,6 +1049,7 @@
     firePropertyChange("font", font, f);
     if (peer != null)
       peer.setFont(f);
+    invalidate();
     font = f;
   }
 
@@ -1078,7 +1122,7 @@
    */
   public Point getLocation()
   {
-    return new Point(x, y);
+    return location ();
   }
 
   /**
@@ -1105,7 +1149,7 @@
    */
   public Point location()
   {
-    return getLocation();
+    return new Point (x, y);
   }
 
   /**
@@ -1120,13 +1164,7 @@
    */
   public void setLocation(int x, int y)
   {
-    if (this.x == x && this.y == y)
-      return;
-    invalidate();
-    this.x = x;
-    this.y = y;
-    if (peer != null)
-      peer.setBounds(x, y, width, height);
+    move (x, y);
   }
 
   /**
@@ -1140,7 +1178,7 @@
    */
   public void move(int x, int y)
   {
-    setLocation(x, y);
+    setBounds(x, y, this.width, this.height);
   }
 
   /**
@@ -1168,7 +1206,7 @@
    */
   public Dimension getSize()
   {
-    return new Dimension(width, height);
+    return size ();
   }
 
   /**
@@ -1179,7 +1217,7 @@
    */
   public Dimension size()
   {
-    return getSize();
+    return new Dimension (width, height);
   }
 
   /**
@@ -1192,13 +1230,7 @@
    */
   public void setSize(int width, int height)
   {
-    if (this.width == width && this.height == height)
-      return;
-    invalidate();
-    this.width = width;
-    this.height = height;
-    if (peer != null)
-      peer.setBounds(x, y, width, height);
+    resize (width, height);
   }
 
   /**
@@ -1210,7 +1242,7 @@
    */
   public void resize(int width, int height)
   {
-    setSize(width, height);
+    setBounds(this.x, this.y, width, height);
   }
 
   /**
@@ -1224,7 +1256,7 @@
    */
   public void setSize(Dimension d)
   {
-    setSize(d.width, d.height);
+    resize (d);
   }
 
   /**
@@ -1236,7 +1268,7 @@
    */
   public void resize(Dimension d)
   {
-    setSize(d.width, d.height);
+    resize (d.width, d.height);
   }
 
   /**
@@ -1251,7 +1283,7 @@
    */
   public Rectangle getBounds()
   {
-    return new Rectangle(x, y, width, height);
+    return bounds ();
   }
 
   /**
@@ -1264,7 +1296,7 @@
    */
   public Rectangle bounds()
   {
-    return getBounds();
+    return new Rectangle (x, y, width, height);
   }
 
   /**
@@ -1284,15 +1316,7 @@
    */
   public void setBounds(int x, int y, int w, int h)
   {
-    if (this.x == x && this.y == y && width == w && height == h)
-      return;
-    invalidate();
-    this.x = x;
-    this.y = y;
-    width = w;
-    height = h;
-    if (peer != null)
-      peer.setBounds(x, y, w, h);
+    reshape (x, y, w, h);
   }
 
   /**
@@ -1301,13 +1325,65 @@
    *
    * @param x the X coordinate of the upper left corner of the rectangle
    * @param y the Y coordinate of the upper left corner of the rectangle
-   * @param w the width of the rectangle
-   * @param h the height of the rectangle
+   * @param width the width of the rectangle
+   * @param height the height of the rectangle
    * @deprecated use {@link #setBounds(int, int, int, int)} instead
    */
   public void reshape(int x, int y, int width, int height)
   {
-    setBounds(x, y, width, height);
+    int oldx = this.x;
+    int oldy = this.y;
+    int oldwidth = this.width;
+    int oldheight = this.height;
+
+    if (this.x == x && this.y == y
+        && this.width == width && this.height == height)
+      return;
+    invalidate ();
+    this.x = x;
+    this.y = y;
+    this.width = width;
+    this.height = height;
+    if (peer != null)
+      peer.setBounds (x, y, width, height);
+
+    // Erase old bounds and repaint new bounds for lightweights.
+    if (isLightweight())
+      {
+        boolean shouldRepaintParent = false;
+        boolean shouldRepaintSelf = false;
+
+        if (parent != null)
+          {
+            Rectangle parentBounds = parent.getBounds();
+            Rectangle oldBounds = new Rectangle(parent.getX() + oldx,
+                                                parent.getY() + oldy,
+                                                oldwidth, oldheight);
+            Rectangle newBounds = new Rectangle(parent.getX() + x,
+                                                parent.getY() + y,
+                                                width, height);
+            shouldRepaintParent = parentBounds.intersects(oldBounds);
+            shouldRepaintSelf = parentBounds.intersects(newBounds);
+          }
+
+        if (shouldRepaintParent)
+          parent.repaint(oldx, oldy, oldwidth, oldheight);
+        if (shouldRepaintSelf)
+          repaint();
+      }
+
+    if (oldx != x || oldy != y)
+      {
+        ComponentEvent ce = new ComponentEvent(this,
+                                               ComponentEvent.COMPONENT_MOVED);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
+    if (oldwidth != width || oldheight != height)
+      {
+        ComponentEvent ce = new ComponentEvent(this,
+                                               ComponentEvent.COMPONENT_RESIZED);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
   }
 
   /**
@@ -1324,7 +1400,7 @@
    */
   public void setBounds(Rectangle r)
   {
-    setBounds(r.x, r.y, r.width, r.height);
+    setBounds (r.x, r.y, r.width, r.height);
   }
 
   /**
@@ -1555,7 +1631,7 @@
    */
   public void doLayout()
   {
-    // nothing to do unless we're a container
+    layout ();
   }
 
   /**
@@ -1566,7 +1642,7 @@
    */
   public void layout()
   {
-    doLayout();
+    // Nothing to do unless we're a container.
   }
 
   /**
@@ -1697,6 +1773,9 @@
    */
   public void paint(Graphics g)
   {
+    // Paint the heavyweight peer
+    if (!isLightweight() && peer != null)
+      peer.paint(g);
   }
 
   /**
@@ -1714,6 +1793,15 @@
    */
   public void update(Graphics g)
   {
+    if (!isLightweight())
+      {
+        Rectangle clip = g.getClipBounds();
+        if (clip == null)
+          g.clearRect(0, 0, width, height);
+        else
+          g.clearRect(clip.x, clip.y, clip.width, clip.height);
+      }
+
     paint(g);
   }
 
@@ -1727,8 +1815,6 @@
   {
     if (! visible)
       return;
-    if (peer != null)
-      peer.paint(g);
     paint(g);
   }
 
@@ -2061,7 +2147,7 @@
    */
   public boolean contains(int x, int y)
   {
-    return x >= 0 && y >= 0 && x < width && y < height;
+    return inside (x, y);
   }
 
   /**
@@ -2075,7 +2161,7 @@
    */
   public boolean inside(int x, int y)
   {
-    return contains(x, y);
+    return x >= 0 && y >= 0 && x < width && y < height;
   }
 
   /**
@@ -2090,7 +2176,7 @@
    */
   public boolean contains(Point p)
   {
-    return contains(p.x, p.y);
+    return contains (p.x, p.y);
   }
 
   /**
@@ -2105,7 +2191,7 @@
    */
   public Component getComponentAt(int x, int y)
   {
-    return contains(x, y) ? this : null;
+    return locate (x, y);
   }
 
   /**
@@ -2120,7 +2206,7 @@
    */
   public Component locate(int x, int y)
   {
-    return getComponentAt(x, y);
+    return contains (x, y) ? this : null;
   }
 
   /**
@@ -2136,18 +2222,21 @@
    */
   public Component getComponentAt(Point p)
   {
-    return getComponentAt(p.x, p.y);
+    return getComponentAt (p.x, p.y);
   }
 
   /**
-   * AWT 1.0 event dispatcher.
+   * AWT 1.0 event delivery.
    *
-   * @param e the event to dispatch
+   * Deliver an AWT 1.0 event to this Component.  This method simply
+   * calls {@link #postEvent}.
+   *
+   * @param e the event to deliver
    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
    */
   public void deliverEvent(Event e)
   {
-    // XXX Add backward compatibility handling.
+    postEvent (e);
   }
 
   /**
@@ -2169,16 +2258,24 @@
   }
 
   /**
-   * AWT 1.0 event dispatcher.
+   * AWT 1.0 event handler.
    *
-   * @param e the event to dispatch
-   * @return false: since the method was deprecated, the return has no meaning
+   * This method simply calls handleEvent and returns the result.
+   *
+   * @param e the event to handle
+   * @return true if the event was handled, false otherwise
    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
    */
   public boolean postEvent(Event e)
   {
-    // XXX Add backward compatibility handling.
-    return false;
+    boolean handled = handleEvent (e);
+
+    if (!handled)
+      // FIXME: need to translate event coordinates to parent's
+      // coordinate space.
+      handled = getParent ().postEvent (e);
+
+    return handled;
   }
 
   /**
@@ -2782,8 +2879,6 @@
 
     if (e instanceof FocusEvent)
       processFocusEvent((FocusEvent) e);
-    else if (e instanceof PaintEvent)
-      processPaintEvent((PaintEvent) e);
     else if (e instanceof MouseWheelEvent)
       processMouseWheelEvent((MouseWheelEvent) e);
     else if (e instanceof MouseEvent)
@@ -2858,6 +2953,7 @@
   {
     if (focusListener == null)
       return;
+
     switch (e.id)
       {
         case FocusEvent.FOCUS_GAINED:
@@ -2933,6 +3029,7 @@
           mouseListener.mouseReleased(e);
         break;
       }
+      e.consume();
   }
 
   /**
@@ -2960,6 +3057,7 @@
           mouseMotionListener.mouseMoved(e);
         break;
       }
+      e.consume();
   }
 
   /**
@@ -2978,7 +3076,10 @@
   {
     if (mouseWheelListener != null
         && e.id == MouseEvent.MOUSE_WHEEL)
+    {
       mouseWheelListener.mouseWheelMoved(e);
+      e.consume();
+    }	
   }
 
   /**
@@ -3056,148 +3157,199 @@
   }
 
   /**
-   * AWT 1.0 event processor.
+   * AWT 1.0 event handler.
+   *
+   * This method calls one of the event-specific handler methods.  For
+   * example for key events, either {@link #keyDown (Event evt, int
+   * key)} or {@link keyUp (Event evt, int key)} is called.  A derived
+   * component can override one of these event-specific methods if it
+   * only needs to handle certain event types.  Otherwise it can
+   * override handleEvent itself and handle any event.
    *
    * @param evt the event to handle
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return true if the event was handled, false otherwise
    * @deprecated use {@link #processEvent(AWTEvent)} instead
    */
   public boolean handleEvent(Event evt)
   {
-    // XXX Add backward compatibility handling.
+    switch (evt.id)
+      {
+	// Handle key events.
+      case Event.KEY_ACTION:
+      case Event.KEY_PRESS:
+	return keyDown (evt, evt.key);
+      case Event.KEY_ACTION_RELEASE:
+      case Event.KEY_RELEASE:
+	return keyUp (evt, evt.key);
+
+	// Handle mouse events.
+      case Event.MOUSE_DOWN:
+	return mouseDown (evt, evt.x, evt.y);
+      case Event.MOUSE_UP:
+	return mouseUp (evt, evt.x, evt.y);
+      case Event.MOUSE_MOVE:
+	return mouseMove (evt, evt.x, evt.y);
+      case Event.MOUSE_DRAG:
+	return mouseDrag (evt, evt.x, evt.y);
+      case Event.MOUSE_ENTER:
+	return mouseEnter (evt, evt.x, evt.y);
+      case Event.MOUSE_EXIT:
+	return mouseExit (evt, evt.x, evt.y);
+
+	// Handle focus events.
+      case Event.GOT_FOCUS:
+	return gotFocus (evt, evt.arg);
+      case Event.LOST_FOCUS:
+	return lostFocus (evt, evt.arg);
+
+	// Handle action event.
+      case Event.ACTION_EVENT:
+	return action (evt, evt.arg);
+      }
+    // Unknown event.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_DOWN event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_DOWN handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
    */
   public boolean mouseDown(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_DRAG event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_DRAG handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
    */
   public boolean mouseDrag(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_UP event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_UP handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
    */
   public boolean mouseUp(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_MOVE event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_MOVE handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
    */
   public boolean mouseMove(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_ENTER event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_ENTER handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
    */
   public boolean mouseEnter(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 mouse event.
+   * AWT 1.0 MOUSE_EXIT event handler.  This method is meant to be
+   * overridden by components providing their own MOUSE_EXIT handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param x the x coordinate, ignored
    * @param y the y coordinate, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
    */
   public boolean mouseExit(Event evt, int x, int y)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 key press event.
+   * AWT 1.0 KEY_PRESS and KEY_ACTION event handler.  This method is
+   * meant to be overridden by components providing their own key
+   * press handler.  The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param key the key pressed, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
    */
   public boolean keyDown(Event evt, int key)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 key press event.
+   * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler.  This
+   * method is meant to be overridden by components providing their
+   * own key release handler.  The default implementation simply
+   * returns false.
    *
    * @param evt the event to handle
    * @param key the key pressed, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
    */
   public boolean keyUp(Event evt, int key)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 action event processor.
+   * AWT 1.0 ACTION_EVENT event handler.  This method is meant to be
+   * overridden by components providing their own action event
+   * handler.  The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param what the object acted on, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated in classes which support actions, use
    *             <code>processActionEvent(ActionEvent)</code> instead
    */
   public boolean action(Event evt, Object what)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
@@ -3241,30 +3393,32 @@
   }
 
   /**
-   * AWT 1.0 focus event.
+   * AWT 1.0 GOT_FOCUS event handler.  This method is meant to be
+   * overridden by components providing their own GOT_FOCUS handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param what the Object focused, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
    */
   public boolean gotFocus(Event evt, Object what)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
   /**
-   * AWT 1.0 focus event.
+   * AWT 1.0 LOST_FOCUS event handler.  This method is meant to be
+   * overridden by components providing their own LOST_FOCUS handler.
+   * The default implementation simply returns false.
    *
    * @param evt the event to handle
    * @param what the Object focused, ignored
-   * @return false: since the method was deprecated, the return has no meaning
+   * @return false
    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
    */
   public boolean lostFocus(Event evt, Object what)
   {
-    // XXX Add backward compatibility handling.
     return false;
   }
 
@@ -3279,7 +3433,7 @@
    */
   public boolean isFocusTraversable()
   {
-    return enabled && visible && (peer == null || peer.isFocusTraversable());
+    return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
   }
 
   /**
@@ -3294,7 +3448,11 @@
   }
 
   /**
-   * Specify whether this component can receive focus.
+   * Specify whether this component can receive focus. This method also
+   * sets the {@link #isFocusTraversableOverridden} field to 1, which
+   * appears to be the undocumented way {@link
+   * DefaultFocusTraversalPolicy#accept()} determines whether to respect
+   * the {@link #isFocusable()} method of the component.
    *
    * @param focusable the new focusable status
    * @since 1.4
@@ -3303,16 +3461,22 @@
   {
     firePropertyChange("focusable", this.focusable, focusable);
     this.focusable = focusable;
+    this.isFocusTraversableOverridden = 1;
   }
 
   /**
-   * Sets the focus traversal keys for a given type of focus events. Normally,
-   * the default values should match the operating system's native choices. To
-   * disable a given traversal, use <code>Collections.EMPTY_SET</code>. The
-   * event dispatcher will consume PRESSED, RELEASED, and TYPED events for the
-   * specified key, although focus can only transfer on PRESSED or RELEASED.
+   * Sets the focus traversal keys for one of the three focus
+   * traversal directions supported by Components: {@link
+   * #KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS}, {@link
+   * #KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS}, or {@link
+   * #KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
+   * default values should match the operating system's native
+   * choices. To disable a given traversal, use
+   * <code>Collections.EMPTY_SET</code>. The event dispatcher will
+   * consume PRESSED, RELEASED, and TYPED events for the specified
+   * key, although focus can only transfer on PRESSED or RELEASED.
    *
-   * <p>The defauts are:
+   * <p>The defaults are:
    * <table>
    *   <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
    *   <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
@@ -3325,10 +3489,13 @@
    *     <td>Go up a traversal cycle</td><td>None</td></tr>
    * </table>
    *
-   * <p>Specifying null allows inheritance from the parent, or from the current
-   * KeyboardFocusManager default set. If not null, the set must contain only
-   * AWTKeyStrokes that are not already focus keys and are not KEY_TYPED
-   * events.
+   * If keystrokes is null, this component's focus traversal key set
+   * is inherited from one of its ancestors.  If none of its ancestors
+   * has its own set of focus traversal keys, the focus traversal keys
+   * are set to the defaults retrieved from the current
+   * KeyboardFocusManager.  If not null, the set must contain only
+   * AWTKeyStrokes that are not already focus keys and are not
+   * KEY_TYPED events.
    *
    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
    *        UP_CYCLE_TRAVERSAL_KEYS
@@ -3343,7 +3510,24 @@
   public void setFocusTraversalKeys(int id, Set keystrokes)
   {
     if (keystrokes == null)
-      throw new IllegalArgumentException();
+      {
+        Container parent = getParent ();
+
+        while (parent != null)
+          {
+            if (parent.areFocusTraversalKeysSet (id))
+              {
+                keystrokes = parent.getFocusTraversalKeys (id);
+                break;
+              }
+            parent = parent.getParent ();
+          }
+
+        if (keystrokes == null)
+          keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
+            getDefaultFocusTraversalKeys (id);
+      }
+
     Set sa;
     Set sb;
     String name;
@@ -3371,50 +3555,60 @@
         name = "upCycleFocusTraversalKeys";
         break;
       default:
-        throw new IllegalArgumentException();
+        throw new IllegalArgumentException ();
       }
-    int i = keystrokes.size();
-    Iterator iter = keystrokes.iterator();
+
+    int i = keystrokes.size ();
+    Iterator iter = keystrokes.iterator ();
+
     while (--i >= 0)
       {
-        Object o = iter.next();
-        if (! (o instanceof AWTKeyStroke)
-            || sa.contains(o) || sb.contains(o)
+        Object o = iter.next ();
+        if (!(o instanceof AWTKeyStroke)
+            || sa.contains (o) || sb.contains (o)
             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
-          throw new IllegalArgumentException();
+          throw new IllegalArgumentException ();
       }
+
     if (focusTraversalKeys == null)
       focusTraversalKeys = new Set[3];
-    keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes));
-    firePropertyChange(name, focusTraversalKeys[id], keystrokes);
+
+    keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+    firePropertyChange (name, focusTraversalKeys[id], keystrokes);
+
     focusTraversalKeys[id] = keystrokes;
   }
 
   /**
-   * Returns the set of keys for a given focus traversal action, as defined
-   * in <code>setFocusTraversalKeys</code>. If not set, this is inherited from
-   * the parent component, which may have gotten it from the
-   * KeyboardFocusManager.
+   * Returns the set of keys for a given focus traversal action, as
+   * defined in <code>setFocusTraversalKeys</code>.  If not set, this
+   * is inherited from the parent component, which may have gotten it
+   * from the KeyboardFocusManager.
    *
-   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
-   *        UP_CYCLE_TRAVERSAL_KEYS
+   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
+   * or UP_CYCLE_TRAVERSAL_KEYS
    * @throws IllegalArgumentException if id is invalid
-   * @see #setFocusTraversalKeys(int, Set)
+   * @see #setFocusTraversalKeys (int, Set)
    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
    * @since 1.4
    */
-  public Set getFocusTraversalKeys(int id)
+  public Set getFocusTraversalKeys (int id)
   {
-    if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
-        || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
+    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
       throw new IllegalArgumentException();
+
     Set s = null;
+
     if (focusTraversalKeys != null)
       s = focusTraversalKeys[id];
+
     if (s == null && parent != null)
-      s = parent.getFocusTraversalKeys(id);
+      s = parent.getFocusTraversalKeys (id);
+
     return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
                         .getDefaultFocusTraversalKeys(id)) : s;
   }
@@ -3423,269 +3617,460 @@
    * Tests whether the focus traversal keys for a given action are explicitly
    * set or inherited.
    *
-   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
-   *        UP_CYCLE_TRAVERSAL_KEYS
+   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
+   * or UP_CYCLE_TRAVERSAL_KEYS
    * @return true if that set is explicitly specified
    * @throws IllegalArgumentException if id is invalid
-   * @see #getFocusTraversalKeys(int)
+   * @see #getFocusTraversalKeys (int)
    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
    * @since 1.4
    */
-  public boolean areFocusTraversalKeysSet(int id)
+  public boolean areFocusTraversalKeysSet (int id)
   {
-    if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
-        || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
-      throw new IllegalArgumentException();
+    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
+      throw new IllegalArgumentException ();
+
     return focusTraversalKeys != null && focusTraversalKeys[id] != null;
   }
 
   /**
-   * Sets whether focus traversal keys are enabled, which consumes traversal
-   * keys and performs the focus event automatically.
+   * Enable or disable focus traversal keys on this Component.  If
+   * they are, then the keyboard focus manager consumes and acts on
+   * key press and release events that trigger focus traversal, and
+   * discards the corresponding key typed events.  If focus traversal
+   * keys are disabled, then all key events that would otherwise
+   * trigger focus traversal are sent to this Component.
    *
    * @param focusTraversalKeysEnabled the new value of the flag
-   * @see #getFocusTraversalKeysEnabled()
-   * @see #setFocusTraversalKeys(int, Set)
-   * @see #getFocusTraversalKeys(int)
+   * @see #getFocusTraversalKeysEnabled ()
+   * @see #setFocusTraversalKeys (int, Set)
+   * @see #getFocusTraversalKeys (int)
    * @since 1.4
    */
-  public void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)
+  public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
   {
-    firePropertyChange("focusTraversalKeysEnabled",
-                       this.focusTraversalKeysEnabled,
-                       focusTraversalKeysEnabled);
+    firePropertyChange ("focusTraversalKeysEnabled",
+			this.focusTraversalKeysEnabled,
+			focusTraversalKeysEnabled);
     this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
   }
 
   /**
-   * Tests whether focus traversal keys are enabled. If they are, then focus
-   * traversal keys are consumed and focus events performed automatically,
-   * without the component seeing the keystrokes.
-   *
-   * @return true if focus traversal is enabled
-   * @see #setFocusTraversalKeysEnabled(boolean)
-   * @see #setFocusTraversalKeys(int, Set)
-   * @see #getFocusTraversalKeys(int)
+   * Check whether or not focus traversal keys are enabled on this
+   * Component.  If they are, then the keyboard focus manager consumes
+   * and acts on key press and release events that trigger focus
+   * traversal, and discards the corresponding key typed events.  If
+   * focus traversal keys are disabled, then all key events that would
+   * otherwise trigger focus traversal are sent to this Component.
+   *
+   * @return true if focus traversal keys are enabled
+   * @see #setFocusTraversalKeysEnabled (boolean)
+   * @see #setFocusTraversalKeys (int, Set)
+   * @see #getFocusTraversalKeys (int)
    * @since 1.4
    */
-  public boolean getFocusTraversalKeysEnabled()
+  public boolean getFocusTraversalKeysEnabled ()
   {
     return focusTraversalKeysEnabled;
   }
 
   /**
-   * Requests that this component be given focus. A <code>FOCUS_GAINED</code>
-   * event will be fired if and only if this request is successful. To be
-   * successful, the component must be displayable, visible, and focusable,
-   * and the top-level Window must be able to receive focus. Thus, this
-   * request may fail, or be delayed until the window receives focus. It is
-   * recommended that <code>requestFocusInWindow</code> be used where
-   * possible to be more platform-independent.
+   * Request that this Component be given the keyboard input focus and
+   * that its top-level ancestor become the focused Window.
+   *
+   * For the request to be granted, the Component must be focusable,
+   * displayable and showing and the top-level Window to which it
+   * belongs must be focusable.  If the request is initially denied on
+   * the basis that the top-level Window is not focusable, the request
+   * will be remembered and granted when the Window does become
+   * focused.
+   *
+   * Never assume that this Component is the focus owner until it
+   * receives a FOCUS_GAINED event.
+   *
+   * The behaviour of this method is platform-dependent.
+   * {@link #requestFocusInWindow} should be used instead.
    *
-   * @see #requestFocusInWindow()
+   * @see #requestFocusInWindow ()
    * @see FocusEvent
-   * @see #addFocusListener(FocusListener)
-   * @see #isFocusable()
-   * @see #isDisplayable()
-   * @see KeyboardFocusManager#clearGlobalFocusOwner()
-   */
-  public void requestFocus()
-  {
-    // If there's no peer then this component can't get the focus. We
-    // treat it as a silent rejection of the request.
-    if (peer != null)
-      peer.requestFocus();
+   * @see #addFocusListener (FocusListener)
+   * @see #isFocusable ()
+   * @see #isDisplayable ()
+   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+   */
+  public void requestFocus ()
+  {
+    if (isDisplayable ()
+	&& isShowing ()
+	&& isFocusable ())
+      {
+        synchronized (getTreeLock ())
+          {
+            // Find this Component's top-level ancestor.
+            Container parent = getParent ();
+
+            while (parent != null
+                   && !(parent instanceof Window))
+              parent = parent.getParent ();
+
+            Window toplevel = (Window) parent;
+            if (toplevel.isFocusableWindow ())
+              {
+                if (peer != null && !isLightweight())
+                  // This call will cause a FOCUS_GAINED event to be
+                  // posted to the system event queue if the native
+                  // windowing system grants the focus request.
+                  peer.requestFocus ();
+                else
+                  {
+                    // Either our peer hasn't been created yet or we're a
+                    // lightweight component.  In either case we want to
+                    // post a FOCUS_GAINED event.
+                    EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+                    synchronized (eq)
+                      {
+                        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                        Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                        if (currentFocusOwner != null)
+                          {
+                            eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                                         false, this));
+                            eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
+                                                         currentFocusOwner));
+                          }
+                        else
+                          eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
+                      }
+                  }
+              }
+            else
+              pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
+          }
+      }
   }
 
   /**
-   * Requests that this component be given focus. A <code>FOCUS_GAINED</code>
-   * event will be fired if and only if this request is successful. To be
-   * successful, the component must be displayable, visible, and focusable,
-   * and the top-level Window must be able to receive focus. Thus, this
-   * request may fail, or be delayed until the window receives focus. It is
-   * recommended that <code>requestFocusInWindow</code> be used where
-   * possible to be more platform-independent.
-   *
-   * <p>If the return value is false, the request is guaranteed to fail. If
-   * it is true, it will likely succeed unless the action is vetoed or
-   * something in the native windowing system intervenes. The temporary flag,
-   * and thus this method in general, is not designed for public use; rather
-   * it is a hook for lightweight components to notify their container in
-   * an attempt to reduce the amount of repainting necessary.
+   * Request that this Component be given the keyboard input focus and
+   * that its top-level ancestor become the focused Window.
+   *
+   * For the request to be granted, the Component must be focusable,
+   * displayable and showing and the top-level Window to which it
+   * belongs must be focusable.  If the request is initially denied on
+   * the basis that the top-level Window is not focusable, the request
+   * will be remembered and granted when the Window does become
+   * focused.
+   *
+   * Never assume that this Component is the focus owner until it
+   * receives a FOCUS_GAINED event.
+   *
+   * The behaviour of this method is platform-dependent.
+   * {@link #requestFocusInWindow} should be used instead.
+   *
+   * If the return value is false, the request is guaranteed to fail.
+   * If the return value is true, the request will succeed unless it
+   * is vetoed or something in the native windowing system intervenes,
+   * preventing this Component's top-level ancestor from becoming
+   * focused.  This method is meant to be called by derived
+   * lightweight Components that want to avoid unnecessary repainting
+   * when they know a given focus transfer need only be temporary.
    *
    * @param temporary true if the focus request is temporary
    * @return true if the request has a chance of success
-   * @see #requestFocusInWindow()
+   * @see #requestFocusInWindow ()
    * @see FocusEvent
-   * @see #addFocusListener(FocusListener)
-   * @see #isFocusable()
-   * @see #isDisplayable()
-   * @see KeyboardFocusManager#clearGlobalFocusOwner()
+   * @see #addFocusListener (FocusListener)
+   * @see #isFocusable ()
+   * @see #isDisplayable ()
+   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
    * @since 1.4
    */
-  protected boolean requestFocus(boolean temporary)
+  protected boolean requestFocus (boolean temporary)
   {
-    // XXX Implement correctly.
-    requestFocus();
+    if (isDisplayable ()
+	&& isShowing ()
+	&& isFocusable ())
+      {
+        synchronized (getTreeLock ())
+          {
+            // Find this Component's top-level ancestor.
+            Container parent = getParent ();
+
+            while (parent != null
+                   && !(parent instanceof Window))
+              parent = parent.getParent ();
+
+            Window toplevel = (Window) parent;
+            if (toplevel.isFocusableWindow ())
+              {
+                if (peer != null && !isLightweight())
+                  // This call will cause a FOCUS_GAINED event to be
+                  // posted to the system event queue if the native
+                  // windowing system grants the focus request.
+                  peer.requestFocus ();
+                else
+                  {
+                    // Either our peer hasn't been created yet or we're a
+                    // lightweight component.  In either case we want to
+                    // post a FOCUS_GAINED event.
+                    EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+                    synchronized (eq)
+                      {
+                        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                        Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                        if (currentFocusOwner != null)
+                          {
+                            eq.postEvent (new FocusEvent(currentFocusOwner,
+                                                         FocusEvent.FOCUS_LOST,
+                                                         temporary, this));
+                            eq.postEvent (new FocusEvent(this,
+                                                         FocusEvent.FOCUS_GAINED,
+                                                         temporary,
+                                                         currentFocusOwner));
+                          }
+                        else
+                    eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+                  }
+              }
+              }
+            else
+              // FIXME: need to add a focus listener to our top-level
+              // ancestor, so that we can post this event when it becomes
+              // the focused window.
+              pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
+          }
+      }
+    // Always return true.
     return true;
   }
 
   /**
-   * Requests that this component be given focus, if it resides in the
-   * top-level window which already has focus. A <code>FOCUS_GAINED</code>
-   * event will be fired if and only if this request is successful. To be
-   * successful, the component must be displayable, visible, and focusable,
-   * and the top-level Window must be focused.
-   *
-   * <p>If the return value is false, the request is guaranteed to fail. If
-   * it is true, it will likely succeed unless the action is vetoed or
-   * something in the native windowing system intervenes. The temporary flag,
-   * and thus this method in general, is not designed for public use; rather
-   * it is a hook for lightweight components to notify their container in
-   * an attempt to reduce the amount of repainting necessary.
+   * Request that this component be given the keyboard input focus, if
+   * its top-level ancestor is the currently focused Window.  A
+   * <code>FOCUS_GAINED</code> event will be fired if and only if this
+   * request is successful. To be successful, the component must be
+   * displayable, showing, and focusable, and its ancestor top-level
+   * Window must be focused.
+   *
+   * If the return value is false, the request is guaranteed to fail.
+   * If the return value is true, the request will succeed unless it
+   * is vetoed or something in the native windowing system intervenes,
+   * preventing this Component's top-level ancestor from becoming
+   * focused.
    *
    * @return true if the request has a chance of success
-   * @see #requestFocus()
+   * @see #requestFocus ()
    * @see FocusEvent
-   * @see #addFocusListener(FocusListener)
-   * @see #isFocusable()
-   * @see #isDisplayable()
-   * @see KeyboardFocusManager#clearGlobalFocusOwner()
+   * @see #addFocusListener (FocusListener)
+   * @see #isFocusable ()
+   * @see #isDisplayable ()
+   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
    * @since 1.4
    */
-  public boolean requestFocusInWindow()
+  public boolean requestFocusInWindow ()
   {
-    // XXX Implement correctly.
-    requestFocus();
-    return true;
+    return requestFocusInWindow (false);
   }
 
   /**
-   * Requests that this component be given focus, if it resides in the
-   * top-level window which already has focus. A <code>FOCUS_GAINED</code>
-   * event will be fired if and only if this request is successful. To be
-   * successful, the component must be displayable, visible, and focusable,
-   * and the top-level Window must be focused.
-   *
-   * <p>If the return value is false, the request is guaranteed to fail. If
-   * it is true, it will likely succeed unless the action is vetoed or
-   * something in the native windowing system intervenes. The temporary flag,
-   * and thus this method in general, is not designed for public use; rather
-   * it is a hook for lightweight components to notify their container in
-   * an attempt to reduce the amount of repainting necessary.
+   * Request that this component be given the keyboard input focus, if
+   * its top-level ancestor is the currently focused Window.  A
+   * <code>FOCUS_GAINED</code> event will be fired if and only if this
+   * request is successful. To be successful, the component must be
+   * displayable, showing, and focusable, and its ancestor top-level
+   * Window must be focused.
+   *
+   * If the return value is false, the request is guaranteed to fail.
+   * If the return value is true, the request will succeed unless it
+   * is vetoed or something in the native windowing system intervenes,
+   * preventing this Component's top-level ancestor from becoming
+   * focused.  This method is meant to be called by derived
+   * lightweight Components that want to avoid unnecessary repainting
+   * when they know a given focus transfer need only be temporary.
    *
    * @param temporary true if the focus request is temporary
    * @return true if the request has a chance of success
-   * @see #requestFocus()
+   * @see #requestFocus ()
    * @see FocusEvent
-   * @see #addFocusListener(FocusListener)
-   * @see #isFocusable()
-   * @see #isDisplayable()
-   * @see KeyboardFocusManager#clearGlobalFocusOwner()
+   * @see #addFocusListener (FocusListener)
+   * @see #isFocusable ()
+   * @see #isDisplayable ()
+   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
    * @since 1.4
    */
-  protected boolean requestFocusInWindow(boolean temporary)
+  protected boolean requestFocusInWindow (boolean temporary)
   {
-    // XXX Implement correctly.
-    requestFocus();
-    return true;
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    Window focusedWindow = manager.getFocusedWindow ();
+
+    if (isDisplayable ()
+	&& isShowing ()
+	&& isFocusable ())
+      {
+        if (focusedWindow != null)
+          {
+            synchronized (getTreeLock ())
+              {
+                Container parent = getParent ();
+
+                while (parent != null
+                       && !(parent instanceof Window))
+                  parent = parent.getParent ();
+
+                Window toplevel = (Window) parent;
+
+                // Check if top-level ancestor is currently focused window.
+                if (focusedWindow == toplevel)
+                  {
+                    if (peer != null
+                        && !isLightweight()
+                        && !(this instanceof Window))
+                      // This call will cause a FOCUS_GAINED event to be
+                      // posted to the system event queue if the native
+                      // windowing system grants the focus request.
+                      peer.requestFocus ();
+                    else
+                      {
+                        // Either our peer hasn't been created yet or we're a
+                        // lightweight component.  In either case we want to
+                        // post a FOCUS_GAINED event.
+                        EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+                        synchronized (eq)
+                          {
+                            Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                            if (currentFocusOwner != null)
+                              {
+                                eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                                             temporary, this));
+                                eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
+                                                             currentFocusOwner));
+                              }
+                            else
+                        eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+                      }
+                  }
+                  }
+                else
+                  return false;
+              }
+          }
+
+        return true;
+      }
+    return false;
   }
 
   /**
-   * Transfers focus to the next component in the focus traversal order, as
-   * though this were the current focus owner.
+   * Transfers focus to the next component in the focus traversal
+   * order, as though this were the current focus owner.
    *
    * @see #requestFocus()
    * @since 1.1
    */
-  public void transferFocus()
+  public void transferFocus ()
   {
-    Component next;
-    if (parent == null)
-      next = findNextFocusComponent(null);
-    else
-      next = parent.findNextFocusComponent(this);
-    if (next != null && next != this)
-      next.requestFocus();
+    nextFocus ();
   }
 
   /**
-   * Returns the root container that owns the focus cycle where this component
-   * resides. A focus cycle root is in two cycles, one as the ancestor, and
-   * one as the focusable element; this call always returns the ancestor.
+   * Returns the root container that owns the focus cycle where this
+   * component resides. A focus cycle root is in two cycles, one as
+   * the ancestor, and one as the focusable element; this call always
+   * returns the ancestor.
    *
    * @return the ancestor container that owns the focus cycle
    * @since 1.4
    */
-  public Container getFocusCycleRootAncestor()
+  public Container getFocusCycleRootAncestor ()
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    if (this instanceof Window
+	&& ((Container) this).isFocusCycleRoot ())
+      return (Container) this;
+
+    Container parent = getParent ();
+
+    while (parent != null
+	   && !parent.isFocusCycleRoot ())
+      parent = parent.getParent ();
+
+    return parent;
   }
 
   /**
-   * Tests if the container is the ancestor of the focus cycle that this
-   * component belongs to.
+   * Tests if the container is the ancestor of the focus cycle that
+   * this component belongs to.
    *
    * @param c the container to test
    * @return true if c is the focus cycle root
    * @since 1.4
    */
-  public boolean isFocusCycleRoot(Container c)
+  public boolean isFocusCycleRoot (Container c)
   {
-    return c == getFocusCycleRootAncestor();
+    return c == getFocusCycleRootAncestor ();
   }
 
   /**
-   * AWT 1.0 focus event processor.
+   * AWT 1.0 focus event processor.  Transfers focus to the next
+   * component in the focus traversal order, as though this were the
+   * current focus owner.
    *
-   * @deprecated use {@link #transferFocus()} instead
+   * @deprecated use {@link #transferFocus ()} instead
    */
-  public void nextFocus()
+  public void nextFocus ()
   {
-    transferFocus();
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    manager.focusNextComponent (this);
   }
 
   /**
-   * Transfers focus to the previous component in the focus traversal order, as
-   * though this were the current focus owner.
+   * Transfers focus to the previous component in the focus traversal
+   * order, as though this were the current focus owner.
    *
-   * @see #requestFocus()
+   * @see #requestFocus ()
    * @since 1.4
    */
-  public void transferFocusBackward()
+  public void transferFocusBackward ()
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    manager.focusPreviousComponent (this);
   }
 
   /**
-   * Transfers focus to the focus cycle root of this component. However, if
-   * this is a Window, the default focus owner in the window in the current
-   * focus cycle is focused instead.
+   * Transfers focus to the focus cycle root of this component.
+   * However, if this is a Window, the default focus owner in the
+   * window in the current focus cycle is focused instead.
    *
-   * @see #requestFocus()
-   * @see #isFocusCycleRoot()
+   * @see #requestFocus ()
+   * @see #isFocusCycleRoot ()
    * @since 1.4
    */
-  public void transferFocusUpCycle()
+  public void transferFocusUpCycle ()
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    manager.upFocusCycle (this);
   }
 
   /**
-   * Tests if this component is the focus owner. Use {@link #isFocusOwner()}
-   * instead.
+   * Tests if this component is the focus owner. Use {@link
+   * #isFocusOwner ()} instead.
    *
    * @return true if this component owns focus
    * @since 1.2
    */
-  public boolean hasFocus()
+  public boolean hasFocus ()
   {
-    return isFocusOwner();
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    Component focusOwner = manager.getFocusOwner ();
+
+    return this == focusOwner;
   }
 
   /**
@@ -3696,8 +4081,7 @@
    */
   public boolean isFocusOwner()
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    return hasFocus ();
   }
 
   /**
@@ -3712,6 +4096,12 @@
     if (popups == null)
       popups = new Vector();
     popups.add(popup);
+
+    if (popup.parent != null)
+      popup.parent.remove(popup);
+    popup.parent = this;
+    if (peer != null)
+      popup.addNotify();
   }
 
   /**
@@ -3739,8 +4129,8 @@
     String name = getName();
     if (name != null)
       param.append(name).append(",");
-    param.append(width).append("x").append(height).append("+").append(x)
-      .append("+").append(y);
+    param.append(x).append(",").append(y).append(",").append(width)
+      .append("x").append(height);
     if (! isValid())
       param.append(",invalid");
     if (! isVisible())
@@ -4108,15 +4498,238 @@
   }
 
   /**
-   * Implementation of dispatchEvent. Allows trusted package classes to
-   * dispatch additional events first.
+   * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
+   * event ({@link Event}).
+   *
+   * @param e an AWT 1.1 event to translate
+   *
+   * @return an AWT 1.0 event representing e
+   */
+  private Event translateEvent (AWTEvent e)
+  {
+    Component target = (Component) e.getSource ();
+    Event translated = null;
+
+    if (e instanceof InputEvent)
+      {
+        InputEvent ie = (InputEvent) e;
+        long when = ie.getWhen ();
+
+        int oldID = 0;
+        int id = e.getID ();
+
+        int oldMods = 0;
+        int mods = ie.getModifiersEx ();
+
+        if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
+          oldMods |= Event.META_MASK;
+        else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
+          oldMods |= Event.ALT_MASK;
+
+        if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
+          oldMods |= Event.SHIFT_MASK;
+
+        if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
+          oldMods |= Event.CTRL_MASK;
+
+        if ((mods & InputEvent.META_DOWN_MASK) != 0)
+          oldMods |= Event.META_MASK;
+
+        if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
+          oldMods |= Event.ALT_MASK;
+
+        if (e instanceof MouseEvent)
+          {
+            if (id == MouseEvent.MOUSE_PRESSED)
+              oldID = Event.MOUSE_DOWN;
+            else if (id == MouseEvent.MOUSE_RELEASED)
+              oldID = Event.MOUSE_UP;
+            else if (id == MouseEvent.MOUSE_MOVED)
+              oldID = Event.MOUSE_MOVE;
+            else if (id == MouseEvent.MOUSE_DRAGGED)
+              oldID = Event.MOUSE_DRAG;
+            else if (id == MouseEvent.MOUSE_ENTERED)
+              oldID = Event.MOUSE_ENTER;
+            else if (id == MouseEvent.MOUSE_EXITED)
+              oldID = Event.MOUSE_EXIT;
+            else
+              // No analogous AWT 1.0 mouse event.
+              return null;
+
+            MouseEvent me = (MouseEvent) e;
+
+            translated = new Event (target, when, oldID,
+                                    me.getX (), me.getY (), 0, oldMods);
+          }
+        else if (e instanceof KeyEvent)
+          {
+            if (id == KeyEvent.KEY_PRESSED)
+              oldID = Event.KEY_PRESS;
+            else if (e.getID () == KeyEvent.KEY_RELEASED)
+              oldID = Event.KEY_RELEASE;
+            else
+              // No analogous AWT 1.0 key event.
+              return null;
+
+            int oldKey = 0;
+            int newKey = ((KeyEvent) e).getKeyCode ();
+            switch (newKey)
+              {
+              case KeyEvent.VK_BACK_SPACE:
+                oldKey = Event.BACK_SPACE;
+                break;
+              case KeyEvent.VK_CAPS_LOCK:
+                oldKey = Event.CAPS_LOCK;
+                break;
+              case KeyEvent.VK_DELETE:
+                oldKey = Event.DELETE;
+                break;
+              case KeyEvent.VK_DOWN:
+              case KeyEvent.VK_KP_DOWN:
+                oldKey = Event.DOWN;
+                break;
+              case KeyEvent.VK_END:
+                oldKey = Event.END;
+                break;
+              case KeyEvent.VK_ENTER:
+                oldKey = Event.ENTER;
+                break;
+              case KeyEvent.VK_ESCAPE:
+                oldKey = Event.ESCAPE;
+                break;
+              case KeyEvent.VK_F1:
+                oldKey = Event.F1;
+                break;
+              case KeyEvent.VK_F10:
+                oldKey = Event.F10;
+                break;
+              case KeyEvent.VK_F11:
+                oldKey = Event.F11;
+                break;
+              case KeyEvent.VK_F12:
+                oldKey = Event.F12;
+                break;
+              case KeyEvent.VK_F2:
+                oldKey = Event.F2;
+                break;
+              case KeyEvent.VK_F3:
+                oldKey = Event.F3;
+                break;
+              case KeyEvent.VK_F4:
+                oldKey = Event.F4;
+                break;
+              case KeyEvent.VK_F5:
+                oldKey = Event.F5;
+                break;
+              case KeyEvent.VK_F6:
+                oldKey = Event.F6;
+                break;
+              case KeyEvent.VK_F7:
+                oldKey = Event.F7;
+                break;
+              case KeyEvent.VK_F8:
+                oldKey = Event.F8;
+                break;
+              case KeyEvent.VK_F9:
+                oldKey = Event.F9;
+                break;
+              case KeyEvent.VK_HOME:
+                oldKey = Event.HOME;
+                break;
+              case KeyEvent.VK_INSERT:
+                oldKey = Event.INSERT;
+                break;
+              case KeyEvent.VK_LEFT:
+              case KeyEvent.VK_KP_LEFT:
+                oldKey = Event.LEFT;
+                break;
+              case KeyEvent.VK_NUM_LOCK:
+                oldKey = Event.NUM_LOCK;
+                break;
+              case KeyEvent.VK_PAUSE:
+                oldKey = Event.PAUSE;
+                break;
+              case KeyEvent.VK_PAGE_DOWN:
+                oldKey = Event.PGDN;
+                break;
+              case KeyEvent.VK_PAGE_UP:
+                oldKey = Event.PGUP;
+                break;
+              case KeyEvent.VK_PRINTSCREEN:
+                oldKey = Event.PRINT_SCREEN;
+                break;
+              case KeyEvent.VK_RIGHT:
+              case KeyEvent.VK_KP_RIGHT:
+                oldKey = Event.RIGHT;
+                break;
+              case KeyEvent.VK_SCROLL_LOCK:
+                oldKey = Event.SCROLL_LOCK;
+                break;
+              case KeyEvent.VK_TAB:
+                oldKey = Event.TAB;
+                break;
+              case KeyEvent.VK_UP:
+              case KeyEvent.VK_KP_UP:
+                oldKey = Event.UP;
+                break;
+              default:
+                oldKey = newKey;
+              }
+
+            translated = new Event (target, when, oldID,
+                                    0, 0, oldKey, oldMods);
+          }
+      }
+    else if (e instanceof ActionEvent)
+      translated = new Event (target, Event.ACTION_EVENT,
+                              ((ActionEvent) e).getActionCommand ());
+
+    return translated;
+  }
+
+  /**
+   * Implementation of dispatchEvent. Allows trusted package classes
+   * to dispatch additional events first.  This implementation first
+   * translates <code>e</code> to an AWT 1.0 event and sends the
+   * result to {@link #postEvent}.  If the AWT 1.0 event is not
+   * handled, and events of type <code>e</code> are enabled for this
+   * component, e is passed on to {@link #processEvent}.
    *
    * @param e the event to dispatch
    */
-  void dispatchEventImpl(AWTEvent e)
+
+  void dispatchEventImpl (AWTEvent e)
   {
+    Event oldEvent = translateEvent (e);
+
+    if (oldEvent != null)
+      postEvent (oldEvent);
+
     if (eventTypeEnabled (e.id))
-      processEvent(e);
+      {
+        // the trick we use to communicate between dispatch and redispatch
+        // is to have KeyboardFocusManager.redispatch synchronize on the
+        // object itself. we then do not redispatch to KeyboardFocusManager
+        // if we are already holding the lock.
+        if (! Thread.holdsLock(e))
+          {
+            switch (e.id)
+              {
+              case WindowEvent.WINDOW_GAINED_FOCUS:
+              case WindowEvent.WINDOW_LOST_FOCUS:
+              case KeyEvent.KEY_PRESSED:
+              case KeyEvent.KEY_RELEASED:
+              case KeyEvent.KEY_TYPED:
+              case FocusEvent.FOCUS_GAINED:
+              case FocusEvent.FOCUS_LOST:
+                if (KeyboardFocusManager
+                    .getCurrentKeyboardFocusManager()
+                    .dispatchEvent(e))
+                    return;
+              }
+          }
+        processEvent (e);
+      }
   }
 
   /**
@@ -4147,6 +4760,8 @@
       case MouseEvent.MOUSE_EXITED:
       case MouseEvent.MOUSE_PRESSED:
       case MouseEvent.MOUSE_RELEASED:
+      case MouseEvent.MOUSE_MOVED:
+      case MouseEvent.MOUSE_DRAGGED:
         return (mouseListener != null
                 || mouseMotionListener != null
                 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
@@ -4220,45 +4835,12 @@
   }
 
   /**
-   * Does the work for a paint event.
-   *
-   * @param event the event to process
-   */
-  private void processPaintEvent(PaintEvent event)
-  {
-    // Can't do graphics without peer
-    if (peer == null)
-      return;
-
-    Graphics gfx = getGraphics();
-    try
-      {
-	Shape clip = event.getUpdateRect();
-	gfx.setClip(clip);
-
-	switch (event.id)
-	  {
-	  case PaintEvent.PAINT:
-	    paint(gfx);
-	    break;
-	  case PaintEvent.UPDATE:
-	    update(gfx);
-	    break;
-	  default:
-	    throw new IllegalArgumentException("unknown paint event");
-	  }
-      }
-    finally
-      {
-	gfx.dispose();
-      }
-  }
-
-  /**
    * This method is used to implement transferFocus(). CHILD is the child
    * making the request. This is overridden by Container; when called for an
    * ordinary component there is no child and so we always return null.
    *
+   * FIXME: is this still needed, in light of focus traversal policies?
+   *
    * @param child the component making the request
    * @return the next component to focus on
    */
@@ -4819,23 +5401,23 @@
      * Tests whether this component can accept focus.
      *
      * @return true if this is focus traversable
-     * @see #getAccessibleStateSet()
+     * @see #getAccessibleStateSet ()
      * @see AccessibleState#FOCUSABLE
      * @see AccessibleState#FOCUSED
      */
-    public boolean isFocusTraversable()
+    public boolean isFocusTraversable ()
     {
-      return Component.this.isFocusTraversable();
+      return Component.this.isFocusTraversable ();
     }
 
     /**
      * Requests focus for this component.
      *
-     * @see #isFocusTraversable()
+     * @see #isFocusTraversable ()
      */
-    public void requestFocus()
+    public void requestFocus ()
     {
-      Component.this.requestFocus();
+      Component.this.requestFocus ();
     }
 
     /**
Index: java/awt/ComponentOrientation.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/ComponentOrientation.java,v
retrieving revision 1.6
diff -u -r1.6 ComponentOrientation.java
--- java/awt/ComponentOrientation.java	9 Aug 2002 04:26:13 -0000	1.6
+++ java/awt/ComponentOrientation.java	6 Sep 2004 16:35:43 -0000
@@ -171,13 +171,15 @@
   }
 
   /**
-   * Gets an orientation from a resource bundle. This tries the following:<ol>
+   * Gets an orientation from a resource bundle. This tries the following:
+   *
+   * <ul>
    * <li>Use the key "Orientation" to find an instance of ComponentOrientation
    * in the bundle.</li>
    * <li>Get the locale of the resource bundle, and get the orientation of
    * that locale.</li>
-   * <li>Give up and get the orientation of the default locale.<li>
-   * <ol>
+   * <li>Give up and get the orientation of the default locale.</li>
+   * </ul>
    *
    * @param bdl the bundle to use
    * @return the orientation
Index: java/awt/Container.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Container.java,v
retrieving revision 1.29
diff -u -r1.29 Container.java
--- java/awt/Container.java	8 Jan 2004 03:52:52 -0000	1.29
+++ java/awt/Container.java	6 Sep 2004 16:35:43 -0000
@@ -1,5 +1,5 @@
 /* Container.java -- parent container class in AWT
-   Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation
+   Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -46,12 +46,19 @@
 import java.awt.peer.LightweightPeer;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.EventListener;
+import java.util.Iterator;
+import java.util.HashSet;
 import java.util.Set;
 import javax.accessibility.Accessible;
+import javax.swing.SwingUtilities;
 
 /**
  * A generic window toolkit object that acts as a container for other objects.
@@ -92,6 +99,21 @@
   transient ContainerListener containerListener;
   transient PropertyChangeSupport changeSupport; 
 
+  /** The focus traversal policy that determines how focus is
+      transferred between this Container and its children. */
+  private FocusTraversalPolicy focusTraversalPolicy;
+
+  /**
+   * The focus traversal keys, if not inherited from the parent or default
+   * keyboard manager. These sets will contain only AWTKeyStrokes that
+   * represent press and release events to use as focus control.
+   *
+   * @see #getFocusTraversalKeys(int)
+   * @see #setFocusTraversalKeys(int, Set)
+   * @since 1.4
+   */
+  transient Set[] focusTraversalKeys;
+
   /**
    * Default constructor for subclasses.
    */
@@ -106,7 +128,7 @@
    */
   public int getComponentCount()
   {
-    return ncomponents;
+    return countComponents ();
   }
 
   /**
@@ -118,7 +140,7 @@
    */
   public int countComponents()
   {
-    return getComponentCount();
+    return ncomponents;
   }
 
   /**
@@ -186,10 +208,7 @@
    */
   public Insets getInsets()
   {
-    if (peer == null)
-      return new Insets(0, 0, 0, 0);
-    
-    return ((ContainerPeer) peer).getInsets();
+    return insets ();
   }
 
   /**
@@ -201,7 +220,10 @@
    */
   public Insets insets()
   {
-    return getInsets();
+    if (peer == null)
+      return new Insets (0, 0, 0, 0);
+
+    return ((ContainerPeer) peer).getInsets ();
   }
 
   /**
@@ -396,6 +418,8 @@
         if (layoutMgr != null)
           layoutMgr.removeLayoutComponent(r);
 
+        r.parent = null;
+
         // Post event to notify of adding the container.
         ContainerEvent ce = new ContainerEvent(this,
                                                ContainerEvent.COMPONENT_REMOVED,
@@ -463,8 +487,7 @@
    */
   public void doLayout()
   {
-    if (layoutMgr != null)
-      layoutMgr.layoutContainer(this);
+    layout ();
   }
 
   /**
@@ -474,7 +497,8 @@
    */
   public void layout()
   {
-    doLayout();
+    if (layoutMgr != null)
+      layoutMgr.layoutContainer (this);
   }
 
   /**
@@ -501,6 +525,20 @@
   }
 
   /**
+   * Recursively invalidates the container tree.
+   */
+  private void invalidateTree()
+  {
+    for (int i = 0; i < ncomponents; i++)
+      {
+        Component comp = component[i];
+        comp.invalidate();
+        if (comp instanceof Container)
+          ((Container) comp).invalidateTree();
+      }
+  }
+
+  /**
    * Recursively validates the container tree, recomputing any invalid
    * layouts.
    */
@@ -545,7 +583,10 @@
   public void setFont(Font f)
   {
     super.setFont(f);
-    // FIXME, should invalidate all children with font == null
+    // FIXME: Although it might make more sense to invalidate only
+    // those children whose font == null, Sun invalidates all children.
+    // So we'll do the same.
+    invalidateTree();
   }
 
   /**
@@ -555,7 +596,7 @@
    */
   public Dimension getPreferredSize()
   {
-      return preferredSize();
+    return preferredSize ();
   }
 
   /**
@@ -567,10 +608,10 @@
    */
   public Dimension preferredSize()
   {
-      if (layoutMgr != null)
-	  return layoutMgr.preferredLayoutSize(this);
-      else
-	  return super.preferredSize();
+    if (layoutMgr != null)
+      return layoutMgr.preferredLayoutSize (this);
+    else
+      return super.preferredSize ();
   }
 
   /**
@@ -580,7 +621,7 @@
    */
   public Dimension getMinimumSize()
   {
-      return minimumSize();
+    return minimumSize ();
   }
 
   /**
@@ -592,10 +633,10 @@
    */
   public Dimension minimumSize()
   {
-      if (layoutMgr != null)
-	  return layoutMgr.minimumLayoutSize(this);
-      else
-	  return super.minimumSize();
+    if (layoutMgr != null)
+      return layoutMgr.minimumLayoutSize (this);
+    else
+      return super.minimumSize ();
   }
 
   /**
@@ -663,8 +704,9 @@
   {
     if (!isShowing())
       return;
-    super.paint(g);
-    visitChildren(g, GfxPaintVisitor.INSTANCE, true);
+    // Visit heavyweights as well, in case they were
+    // erased when we cleared the background for this container.
+    visitChildren(g, GfxPaintVisitor.INSTANCE, false);
   }
 
   /**
@@ -678,11 +720,6 @@
    */
   public void update(Graphics g)
   {
-    Rectangle clip = g.getClipBounds();
-    if (clip == null)
-      g.clearRect(0, 0, width, height);
-    else
-      g.clearRect(clip.x, clip.y, clip.width, clip.height);
     super.update(g);
   }
 
@@ -819,6 +856,16 @@
    */
   public void deliverEvent(Event e)
   {
+    if (!handleEvent (e))
+      {
+        synchronized (getTreeLock ())
+          {
+            Component parent = getParent ();
+
+            if (parent != null)
+              parent.deliverEvent (e);
+          }
+      }
   }
 
   /**
@@ -837,23 +884,7 @@
    */
   public Component getComponentAt(int x, int y)
   {
-    synchronized (getTreeLock ())
-      {
-        if (! contains(x, y))
-          return null;
-        for (int i = 0; i < ncomponents; ++i)
-          {
-            // Ignore invisible children...
-            if (!component[i].isVisible())
-              continue;
-
-            int x2 = x - component[i].x;
-            int y2 = y - component[i].y;
-            if (component[i].contains(x2, y2))
-              return component[i];
-          }
-        return this;
-      }
+    return locate (x, y);
   }
 
   /**
@@ -873,7 +904,23 @@
    */
   public Component locate(int x, int y)
   {
-    return getComponentAt(x, y);
+    synchronized (getTreeLock ())
+      {
+        if (!contains (x, y))
+          return null;
+        for (int i = 0; i < ncomponents; ++i)
+          {
+            // Ignore invisible children...
+            if (!component[i].isVisible ())
+              continue;
+
+            int x2 = x - component[i].x;
+            int y2 = y - component[i].y;
+            if (component[i].contains (x2, y2))
+              return component[i];
+          }
+        return this;
+      }
   }
 
   /**
@@ -890,7 +937,7 @@
    */
   public Component getComponentAt(Point p)
   {
-    return getComponentAt(p.x, p.y);
+    return getComponentAt (p.x, p.y);
   }
 
   public Component findComponentAt(int x, int y)
@@ -990,7 +1037,7 @@
   {
     String param = super.paramString();
     if (layoutMgr != null)
-      param = param + "," + layoutMgr.getClass().getName();
+      param = param + ",layout=" + layoutMgr.getClass().getName();
 
     return param;
   }
@@ -1054,9 +1101,89 @@
       throw new IllegalArgumentException ();
 
     if (keystrokes == null)
-      throw new IllegalArgumentException ();
+      {
+        Container parent = getParent ();
+
+        while (parent != null)
+          {
+            if (parent.areFocusTraversalKeysSet (id))
+              {
+                keystrokes = parent.getFocusTraversalKeys (id);
+                break;
+              }
+            parent = parent.getParent ();
+          }
 
-    throw new Error ("not implemented");
+        if (keystrokes == null)
+          keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
+            getDefaultFocusTraversalKeys (id);
+      }
+
+    Set sa;
+    Set sb;
+    Set sc;
+    String name;
+    switch (id)
+      {
+      case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+        sa = getFocusTraversalKeys
+          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        sb = getFocusTraversalKeys
+          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+        sc = getFocusTraversalKeys
+          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+        name = "forwardFocusTraversalKeys";
+        break;
+      case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+        sa = getFocusTraversalKeys
+          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        sb = getFocusTraversalKeys
+          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+        sc = getFocusTraversalKeys
+          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+        name = "backwardFocusTraversalKeys";
+        break;
+      case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+        sa = getFocusTraversalKeys
+          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        sb = getFocusTraversalKeys
+          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        sc = getFocusTraversalKeys
+          (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+        name = "upCycleFocusTraversalKeys";
+        break;
+      case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+        sa = getFocusTraversalKeys
+          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        sb = getFocusTraversalKeys
+          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        sc = getFocusTraversalKeys
+          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+        name = "downCycleFocusTraversalKeys";
+        break;
+      default:
+        throw new IllegalArgumentException ();
+      }
+
+    int i = keystrokes.size ();
+    Iterator iter = keystrokes.iterator ();
+
+    while (--i >= 0)
+      {
+        Object o = iter.next ();
+        if (!(o instanceof AWTKeyStroke)
+            || sa.contains (o) || sb.contains (o) || sc.contains (o)
+            || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
+          throw new IllegalArgumentException ();
+      }
+
+    if (focusTraversalKeys == null)
+      focusTraversalKeys = new Set[3];
+
+    keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+    firePropertyChange (name, focusTraversalKeys[id], keystrokes);
+
+    focusTraversalKeys[id] = keystrokes;
   }
   
   /**
@@ -1071,7 +1198,7 @@
    *
    * @since 1.4
    */
-  public Set getFocusTraversalKeys(int id)
+  public Set getFocusTraversalKeys (int id)
   {
     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
@@ -1079,9 +1206,18 @@
         id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
       throw new IllegalArgumentException ();
 
-    return null;
+    Set s = null;
+
+    if (focusTraversalKeys != null)
+      s = focusTraversalKeys[id];
+
+    if (s == null && parent != null)
+      s = parent.getFocusTraversalKeys (id);
+
+    return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
+                        .getDefaultFocusTraversalKeys(id)) : s;
   }
-  
+
   /**
    * Returns whether the Set of focus traversal keys for the given focus
    * traversal operation has been explicitly defined for this Container.
@@ -1096,7 +1232,7 @@
    *
    * @since 1.4
    */
-  public boolean areFocusTraversalKeysSet(int id)
+  public boolean areFocusTraversalKeysSet (int id)
   {
     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
@@ -1104,43 +1240,148 @@
         id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
       throw new IllegalArgumentException ();
 
-    return false;
+    return focusTraversalKeys != null && focusTraversalKeys[id] != null;
   }
-  
-  public boolean isFocusCycleRoot(Container c)
+
+  /**
+   * Check whether the given Container is the focus cycle root of this
+   * Container's focus traversal cycle.  If this Container is a focus
+   * cycle root itself, then it will be in two different focus cycles
+   * -- it's own, and that of its ancestor focus cycle root's.  In
+   * that case, if <code>c</code> is either of those containers, this
+   * method will return true.
+   *
+   * @param c the candidate Container
+   *
+   * @return true if c is the focus cycle root of the focus traversal
+   * cycle to which this Container belongs, false otherwise
+   *
+   * @since 1.4
+   */
+  public boolean isFocusCycleRoot (Container c)
   {
+    if (this == c
+        && isFocusCycleRoot ())
+      return true;
+
+    Container ancestor = getFocusCycleRootAncestor ();
+
+    if (c == ancestor)
+      return true;
+
     return false;
   }
-  
-  public void transferFocusBackward()
-  {
-  }
-  
-  public void setFocusTraversalPolicy(FocusTraversalPolicy policy)
+
+  /**
+   * If this Container is a focus cycle root, set the focus traversal
+   * policy that determines the focus traversal order for its
+   * children.  If non-null, this policy will be inherited by all
+   * inferior focus cycle roots.  If <code>policy</code> is null, this
+   * Container will inherit its policy from the closest ancestor focus
+   * cycle root that's had its policy set.
+   *
+   * @param policy the new focus traversal policy for this Container or null
+   *
+   * @since 1.4
+   */
+  public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
   {
+    focusTraversalPolicy = policy;
   }
-  
-  public FocusTraversalPolicy getFocusTraversalPolicy()
+
+  /**
+   * Return the focus traversal policy that determines the focus
+   * traversal order for this Container's children.  This method
+   * returns null if this Container is not a focus cycle root.  If the
+   * focus traversal policy has not been set explicitly, then this
+   * method will return an ancestor focus cycle root's policy instead.
+   *
+   * @return this Container's focus traversal policy or null
+   *
+   * @since 1.4
+   */
+  public FocusTraversalPolicy getFocusTraversalPolicy ()
   {
-    return null;
+    if (!isFocusCycleRoot ())
+      return null;
+
+    if (focusTraversalPolicy == null)
+      {
+        Container ancestor = getFocusCycleRootAncestor ();
+
+	if (ancestor != this)
+	  return ancestor.getFocusTraversalPolicy ();
+	else
+	  {
+	    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+	    return manager.getDefaultFocusTraversalPolicy ();
+	  }
+      }
+    else
+      return focusTraversalPolicy;
   }
-  
-  public boolean isFocusTraversalPolicySet()
+
+  /**
+   * Check whether this Container's focus traversal policy has been
+   * explicitly set.  If it has not, then this Container will inherit
+   * its focus traversal policy from one of its ancestor focus cycle
+   * roots.
+   *
+   * @return true if focus traversal policy is set, false otherwise
+  */
+  public boolean isFocusTraversalPolicySet ()
   {
-    return false;
+    return focusTraversalPolicy == null;
   }
-  
-  public void setFocusCycleRoot(boolean focusCycleRoot)
+
+  /**
+   * Set whether or not this Container is the root of a focus
+   * traversal cycle.  This Container's focus traversal policy
+   * determines the order of focus traversal.  Some policies prevent
+   * the focus from being transferred between two traversal cycles
+   * until an up or down traversal operation is performed.  In that
+   * case, normal traversal (not up or down) is limited to this
+   * Container and all of this Container's descendents that are not
+   * descendents of inferior focus cycle roots.  In the default case
+   * however, ContainerOrderFocusTraversalPolicy is in effect, and it
+   * supports implicit down-cycle traversal operations.
+   *
+   * @return true if this is a focus cycle root, false otherwise
+   *
+   * @since 1.4
+   */
+  public void setFocusCycleRoot (boolean focusCycleRoot)
   {
+    this.focusCycleRoot = focusCycleRoot;
   }
-  
-  public boolean isFocusCycleRoot()
+
+  /**
+   * Check whether this Container is a focus cycle root.
+   *
+   * @return true if this is a focus cycle root, false otherwise
+   *
+   * @since 1.4
+   */
+  public boolean isFocusCycleRoot ()
   {
-    return false;
+    return focusCycleRoot;
   }
-  
-  public void transferFocusDownCycle()
+
+  /**
+   * Transfer focus down one focus traversal cycle.  If this Container
+   * is a focus cycle root, then its default component becomes the
+   * focus owner, and this Container becomes the current focus cycle
+   * root.  No traversal will occur if this Container is not a focus
+   * cycle root.
+   *
+   * @since 1.4
+   */
+  public void transferFocusDownCycle ()
   {
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    manager.downFocusCycle (this);
   }
 
   /**
@@ -1204,8 +1445,12 @@
         for (int i = ncomponents - 1; i >= 0; --i)
           {
             Component comp = component[i];
+            // If we're visiting heavyweights as well,
+            // don't recurse into Containers here. This avoids
+            // painting the same nested child multiple times.
             boolean applicable = comp.isVisible()
-              && (comp.isLightweight() || !lightweightOnly);
+              && (comp.isLightweight()
+                  || !lightweightOnly && ! (comp instanceof Container));
 
             if (applicable)
               visitChild(gfx, visitor, comp);
@@ -1233,6 +1478,7 @@
     Rectangle oldClip = gfx.getClipBounds();
     if (oldClip == null)
       oldClip = bounds;
+
     Rectangle clip = oldClip.intersection(bounds);
 
     if (clip.isEmpty()) return;
@@ -1259,10 +1505,11 @@
   void dispatchEventImpl(AWTEvent e)
   {
     // Give lightweight dispatcher a chance to handle it.
-    if (dispatcher != null 
+    if (eventTypeEnabled (e.id)
+        && dispatcher != null 
         && dispatcher.handleEvent (e))
       return;
-
+    
     if ((e.id <= ContainerEvent.CONTAINER_LAST
              && e.id >= ContainerEvent.CONTAINER_FIRST)
         && (containerListener != null
@@ -1336,11 +1583,10 @@
 
                 // If we're not lightweight, and we just got a lightweight
                 // child, we need a lightweight dispatcher to feed it events.
-                if (! this.isLightweight() 
-                    && dispatcher == null)
+                if (! this.isLightweight()) 
                   {
-                    dispatcher = new LightweightDispatcher (this);
-                    dispatcher.enableEvents (component[i].eventMask);
+                    if (dispatcher == null)
+                      dispatcher = new LightweightDispatcher (this);
                   }	
 	  
 
@@ -1352,6 +1598,61 @@
       }
   }
 
+  /**
+   * Deserialize this Container:
+   * <ol>
+   * <li>Read from the stream the default serializable fields.</li>
+   * <li>Read a list of serializable ContainerListeners as optional
+   * data.  If the list is null, no listeners will be registered.</li>
+   * <li>Read this Container's FocusTraversalPolicy as optional data.
+   * If this is null, then this Container will use a
+   * DefaultFocusTraversalPolicy.</li>
+   * </ol>
+   *
+   * @param s the stream to read from
+   * @throws ClassNotFoundException if deserialization fails
+   * @throws IOException if the stream fails
+   */
+  private void readObject (ObjectInputStream s)
+    throws ClassNotFoundException, IOException
+  {
+    s.defaultReadObject ();
+    String key = (String) s.readObject ();
+    while (key != null)
+      {
+        Object object = s.readObject ();
+        if ("containerL".equals (key))
+          addContainerListener((ContainerListener) object);
+        // FIXME: under what key is the focus traversal policy stored?
+        else if ("focusTraversalPolicy".equals (key))
+          setFocusTraversalPolicy ((FocusTraversalPolicy) object);
+
+        key = (String) s.readObject();
+      }
+  }
+
+  /**
+   * Serialize this Container:
+   * <ol>
+   * <li>Write to the stream the default serializable fields.</li>
+   * <li>Write the list of serializable ContainerListeners as optional
+   * data.</li>
+   * <li>Write this Container's FocusTraversalPolicy as optional data.</li>
+   * </ol>
+   *
+   * @param s the stream to write to
+   * @throws IOException if the stream fails
+   */
+  private void writeObject (ObjectOutputStream s) throws IOException
+  {
+    s.defaultWriteObject ();
+    AWTEventMulticaster.save (s, "containerL", containerListener);
+    if (focusTraversalPolicy instanceof Serializable)
+      s.writeObject (focusTraversalPolicy);
+    else
+      s.writeObject (null);
+  }
+
   // Nested classes.
 
   /* The following classes are used in concert with the
@@ -1516,7 +1817,7 @@
           (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null);
       }
     } // class AccessibleContainerHandler
-  } // class AccessibleAWTPanel
+  } // class AccessibleAWTContainer
 } // class Container
 
 /**
@@ -1530,122 +1831,156 @@
 {
   private static final long serialVersionUID = 5184291520170872969L;
   private Container nativeContainer;
-  private Component focus;
   private Cursor nativeCursor;
   private long eventMask;
   
   private transient Component mouseEventTarget;
+  private transient Component pressedComponent;
+  private transient Component lastComponentEntered;
+  private transient int pressCount;
   
   LightweightDispatcher(Container c)
   {
     nativeContainer = c;
   }
 
-  void dispose()
-  {
-  }
-
-  void enableEvents(long l)
-  {
-    eventMask |= l;
-  }
-
-  void mouseExit (MouseEvent me, int x, int y)
-  {
-  }
-
-  void acquireComponentForMouseEvent (MouseEvent me)
+  void acquireComponentForMouseEvent(MouseEvent me)
   {
     int x = me.getX ();
     int y = me.getY ();
 
-    Component candidate = mouseEventTarget;
-
-    boolean candidate_is_container_with_children = 
-	    ((candidate != null)
-	     && (candidate instanceof Container)
-	     && (((Container)candidate).getComponentCount () > 0));
-
-    boolean candidate_does_not_contain_point =
-	    ((candidate != null)
-	     && (! candidate.contains (x - candidate.getX (),
-                                 y - candidate.getY ())));
-
-    if (candidate == null
-        || candidate_is_container_with_children
-        || candidate_does_not_contain_point)
-  {
-        // Try to reacquire.
-        candidate = nativeContainer.findComponentAt (x, y);
-  }
-
-    if (mouseEventTarget != null
-        && mouseEventTarget != candidate)
-  {
-        int nx = x - mouseEventTarget.getX ();
-        int ny = y - mouseEventTarget.getY ();
-        MouseEvent exited = new MouseEvent (mouseEventTarget, 
-                                            MouseEvent.MOUSE_EXITED,
-                                            me.getWhen (), 
-                                            me.getModifiers (), 
-                                            nx, ny,
-                                            me.getClickCount (),
-                                            me.isPopupTrigger (),
-                                            me.getButton ());
-        mouseEventTarget.dispatchEvent (exited); 
-        mouseEventTarget = null;
-  }
+    // Find the candidate which should receive this event.
+    Component parent = nativeContainer;
+    Component candidate = null;
+    Point p = me.getPoint();
+    while (candidate == null && parent != null)
+      {
+        candidate =
+          SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
+        if (candidate == null || (candidate.eventMask & me.getID()) == 0)
+        {
+          candidate = null;
+          p = SwingUtilities.convertPoint(parent, p.x, p.y, parent.parent);
+          parent = parent.parent;
+        }
+      }
 
+    // If the only candidate we found was the native container itself,
+    // don't dispatch any event at all.  We only care about the lightweight
+    // children here.
+    if (candidate == nativeContainer)
+      candidate = null;
+
+    // If our candidate is new, inform the old target we're leaving.
+    if (lastComponentEntered != null
+        && lastComponentEntered.isShowing()
+        && lastComponentEntered != candidate)
+      {
+        // Old candidate could have been removed from 
+        // the nativeContainer so we check first.
+        if (SwingUtilities.isDescendingFrom(lastComponentEntered, nativeContainer))
+        {
+          Point tp = 
+            SwingUtilities.convertPoint(nativeContainer, 
+                                        x, y, lastComponentEntered);
+          MouseEvent exited = new MouseEvent (lastComponentEntered, 
+                                              MouseEvent.MOUSE_EXITED,
+                                              me.getWhen (), 
+                                              me.getModifiersEx (), 
+                                              tp.x, tp.y,
+                                              me.getClickCount (),
+                                              me.isPopupTrigger (),
+                                              me.getButton ());
+          lastComponentEntered.dispatchEvent (exited); 
+        }
+        lastComponentEntered = null;
+      }
+    // If we have a candidate, maybe enter it.
     if (candidate != null)
-	    {
-        // Possibly set new state.
+      {
+        mouseEventTarget = candidate;
         if (candidate.isLightweight() 
+            && candidate.isShowing()
             && candidate != nativeContainer
-            && candidate != mouseEventTarget)
-  {
-			
-            mouseEventTarget = candidate;
-			
-            int nx = x - mouseEventTarget.getX ();
-            int ny = y - mouseEventTarget.getY ();
-			
-            // If acquired, enter it.
-            MouseEvent entered = new MouseEvent (mouseEventTarget, 
+            && candidate != lastComponentEntered)
+	  {			
+            lastComponentEntered = mouseEventTarget;
+            Point cp = SwingUtilities.convertPoint(nativeContainer, 
+                                                   x, y, lastComponentEntered);
+            MouseEvent entered = new MouseEvent (lastComponentEntered, 
                                                  MouseEvent.MOUSE_ENTERED,
                                                  me.getWhen (), 
-                                                 me.getModifiers (), 
-                                                 nx, ny,
+                                                 me.getModifiersEx (), 
+                                                 cp.x, cp.y,
                                                  me.getClickCount (),
                                                  me.isPopupTrigger (),
                                                  me.getButton ());
-            mouseEventTarget.dispatchEvent (entered);
+            lastComponentEntered.dispatchEvent (entered);
           }
-	    }
+      }
+
+    if (me.getID() == MouseEvent.MOUSE_RELEASED
+        || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
+        || me.getID() == MouseEvent.MOUSE_DRAGGED)
+      // If any of the following events occur while a button is held down,
+      // they should be dispatched to the same component to which the
+      // original MOUSE_PRESSED event was dispatched:
+      //   - MOUSE_RELEASED
+      //   - MOUSE_PRESSED: another button pressed while the first is held down
+      //   - MOUSE_DRAGGED
+      if (SwingUtilities.isDescendingFrom(pressedComponent, nativeContainer))
+        mouseEventTarget = pressedComponent;
+    else if (me.getID() == MouseEvent.MOUSE_CLICKED)
+      {
+        // Don't dispatch CLICKED events whose target is not the same as the
+        // target for the original PRESSED event.
+        if (candidate != pressedComponent)
+          mouseEventTarget = null;
+        else if (pressCount == 0)
+          pressedComponent = null;
+      }
   }
 
-  boolean handleEvent (AWTEvent e)
+  boolean handleEvent(AWTEvent e)
   {
-    if ((eventMask & e.getID ()) == 0)
-	    return false;
-
     if (e instanceof MouseEvent)
-  {
+      {
         MouseEvent me = (MouseEvent) e;
-        acquireComponentForMouseEvent (me);
 
-        if (mouseEventTarget != null)
+        acquireComponentForMouseEvent(me);
+	
+        // Avoid dispatching ENTERED and EXITED events twice.
+        if (mouseEventTarget != null
+            && mouseEventTarget.isShowing()
+            && e.getID() != MouseEvent.MOUSE_ENTERED
+            && e.getID() != MouseEvent.MOUSE_EXITED)
           {
-            Component oldSource = (Component) me.getSource ();
-            me.setSource (mouseEventTarget);
-            mouseEventTarget.dispatchEvent (me);
-            me.setSource (oldSource);
+            MouseEvent newEvt = 
+              SwingUtilities.convertMouseEvent(nativeContainer, me, 
+                                               mouseEventTarget);
+            mouseEventTarget.dispatchEvent(newEvt);
+
+            switch (e.getID())
+              {
+                case MouseEvent.MOUSE_PRESSED:
+                  if (pressCount++ == 0)
+                    pressedComponent = mouseEventTarget;
+                  break;
+
+                case MouseEvent.MOUSE_RELEASED:
+                  // Clear our memory of the original PRESSED event, only if
+                  // we're not expecting a CLICKED event after this. If
+                  // there is a CLICKED event after this, it will do clean up.
+                  if (--pressCount == 0
+                      && mouseEventTarget != pressedComponent)
+                    pressedComponent = null;
+                  break;
+              }
+              if (newEvt.isConsumed())
+                e.consume();
           }
-	    }
-    else if (e instanceof KeyEvent && focus != null)
-  {
-        focus.processKeyEvent ((KeyEvent) e);
-	    }
-      
+      }
+    
     return e.isConsumed();
   }
 
Index: java/awt/ContainerOrderFocusTraversalPolicy.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/ContainerOrderFocusTraversalPolicy.java,v
retrieving revision 1.5
diff -u -r1.5 ContainerOrderFocusTraversalPolicy.java
--- java/awt/ContainerOrderFocusTraversalPolicy.java	24 Mar 2003 13:50:32 -0000	1.5
+++ java/awt/ContainerOrderFocusTraversalPolicy.java	6 Sep 2004 16:35:43 -0000
@@ -41,7 +41,23 @@
 import java.io.Serializable;
 
 /**
+ * ContainerOrderFocusTraversalPolicy defines a focus traversal order
+ * based on the order in which Components were packed in a Container.
+ * This policy performs a pre-order traversal of the Component
+ * hierarchy starting from a given focus cycle root.  Portions of the
+ * hierarchy that are not visible and displayable are skipped.
+ *
+ * By default, this policy transfers focus down-cycle implicitly.
+ * That is, if a forward traversal is requested on a focus cycle root
+ * and the focus cycle root has focusable children, the focus will
+ * automatically be transfered down to the lower focus cycle.
+ *
+ * The default implementation of accept accepts only Components that
+ * are visible, displayable, enabled and focusable.  Derived classes
+ * can override these acceptance criteria by overriding accept.
+ *
  * @author Michael Koch
+ * @author Thomas Fitzsimmons <fitzsim@redhat.com>
  * @since 1.4
  */
 public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
@@ -52,12 +68,15 @@
    */
   static final long serialVersionUID = 486933713763926351L;
 
+  /**
+   * True if implicit down cycling is enabled.
+   */
   private boolean implicitDownCycleTraversal = true;
 
   /**
    * Creates the <code>ContainerOrderFocusTraversalPolicy</code> object.
    */
-  public ContainerOrderFocusTraversalPolicy()
+  public ContainerOrderFocusTraversalPolicy ()
   {
     // Nothing to do here
   }
@@ -66,37 +85,196 @@
    * Returns the Component that should receive the focus after current.
    * root must be a focus cycle root of current.
    *
+   * @param root a focus cycle root of current
+   * @param current a (possibly indirect) child of root, or root itself
+   *
+   * @return the next Component in the focus traversal order for root,
+   * or null if no acceptable Component exists.
+   *
    * @exception IllegalArgumentException If root is not a focus cycle
    * root of current, or if either root or current is null.
    */
-  public Component getComponentAfter(Container root, Component current)
+  public Component getComponentAfter (Container root, Component current)
   {
-    if (root == null
-        || current == null)
-      throw new IllegalArgumentException ();
-    
-    return null;
+    if (root == null)
+      throw new IllegalArgumentException ("focus cycle root is null");
+    if (current == null)
+      throw new IllegalArgumentException ("current component is null");
+
+    if (!root.isFocusCycleRoot ())
+      throw new IllegalArgumentException ("root is not a focus cycle root");
+
+    Container ancestor = current.getFocusCycleRootAncestor ();
+    Container prevAncestor = ancestor;
+    while (ancestor != root)
+      {
+	ancestor = current.getFocusCycleRootAncestor ();
+	if (ancestor == prevAncestor)
+	  {
+	    // We've reached the top focus cycle root ancestor.  Check
+	    // if it is root.
+	    if (ancestor != root)
+	      throw new IllegalArgumentException ("the given container is not"
+						  + " a focus cycle root of the"
+						  + " current component");
+	    else
+	      break;
+	  }
+	prevAncestor = ancestor;
+      }
+
+    // FIXME: is this the right thing to do here? It moves the context
+    // for traversal up one focus traversal cycle.  We'll need a test
+    // for this.
+    if ((Component) root == current)
+      root = current.getFocusCycleRootAncestor ();
+
+    // Check if we've reached the top of the component hierarchy.  If
+    // so then we want to loop around to the first component in the
+    // focus traversal cycle.
+    if (current instanceof Window)
+      return getFirstComponent ((Container) current);
+
+    Container parent = current.getParent ();
+
+    synchronized (parent.getTreeLock ())
+      {
+        Component[] components = parent.getComponents ();
+        int componentIndex = 0;
+        int numComponents = parent.getComponentCount ();
+
+        // Find component's index.
+        for (int i = 0; i < numComponents; i++)
+          {
+            if (components[i] == current)
+              componentIndex = i;
+          }
+
+        // Search forward for the next acceptable component.
+        for (int i = componentIndex + 1; i < numComponents; i++)
+          {
+            if (accept (components[i]))
+              return components[i];
+
+            if (components[i] instanceof Container)
+              {
+                Component result = getFirstComponent ((Container) components[i]);
+
+                if (result != null
+                    && implicitDownCycleTraversal)
+                  return result;
+              }
+          }
+
+        // No focusable components after current in its Container.  So go
+        // to the next Component after current's Container (parent).
+        Component result = getComponentAfter (root, parent);
+
+        return result;
+      }
   }
 
   /**
-   * Returns the Component that should receive the focus before current.
-   * root must be a focus cycle root of current.
+   * Returns the Component that should receive the focus before
+   * <code>current</code>.  <code>root</code> must be a focus cycle
+   * root of current.
+   *
+   * @param root a focus cycle root of current
+   * @param current a (possibly indirect) child of root, or root itself
+   *
+   * @return the previous Component in the focus traversal order for
+   * root, or null if no acceptable Component exists.
    *
    * @exception IllegalArgumentException If root is not a focus cycle
    * root of current, or if either root or current is null.
    */
-  public Component getComponentBefore(Container root, Component current)
+  public Component getComponentBefore (Container root, Component current)
   {
-    if (root == null
-        || current == null)
-      throw new IllegalArgumentException ();
+    if (root == null)
+      throw new IllegalArgumentException ("focus cycle root is null");
+    if (current == null)
+      throw new IllegalArgumentException ("current component is null");
+
+    if (!root.isFocusCycleRoot ())
+      throw new IllegalArgumentException ("root is not a focus cycle root");
+
+    Container ancestor = current.getFocusCycleRootAncestor ();
+    Container prevAncestor = ancestor;
+    while (ancestor != root)
+      {
+	ancestor = current.getFocusCycleRootAncestor ();
+	if (ancestor == prevAncestor)
+	  {
+	    // We've reached the top focus cycle root ancestor.  Check
+	    // if it is root.
+	    if (ancestor != root)
+	      throw new IllegalArgumentException ("the given container is not"
+						  + " a focus cycle root of the"
+						  + " current component");
+	    else
+	      break;
+	  }
+	prevAncestor = ancestor;
+      }
 
-    return null;
+    // FIXME: is this the right thing to do here? It moves the context
+    // for traversal up one focus traversal cycle.  We'll need a test
+    // for this.
+    if ((Component) root == current)
+      root = current.getFocusCycleRootAncestor ();
+
+    // Check if we've reached the top of the component hierarchy.  If
+    // so then we want to loop around to the last component in the
+    // focus traversal cycle.
+    if (current instanceof Window)
+      return getLastComponent ((Container) current);
+
+    Container parent = current.getParent ();
+
+    synchronized (parent.getTreeLock ())
+      {
+        Component[] components = parent.getComponents ();
+        int componentIndex = 0;
+        int numComponents = parent.getComponentCount ();
+
+        // Find component's index.
+        for (int i = 0; i < numComponents; i++)
+          {
+            if (components[i] == current)
+              componentIndex = i;
+          }
+
+        // Search backward for the next acceptable component.
+        for (int i = componentIndex - 1; i >= 0; i--)
+          {
+            if (accept (components[i]))
+              return components[i];
+
+            if (components[i] instanceof Container)
+              {
+                Component result = getLastComponent ((Container) components[i]);
+
+                if (result != null)
+                  return result;
+              }
+          }
+
+        // No focusable components before current in its Container.  So go
+        // to the previous Component before current's Container (parent).
+        Component result = getComponentBefore (root, parent);
+
+        return result;
+      }
   }
 
   /**
    * Returns the first Component of root that should receive the focus.
    *
+   * @param root a focus cycle root
+   *
+   * @return the first Component in the focus traversal order for
+   * root, or null if no acceptable Component exists.
+   *
    * @exception IllegalArgumentException If root is null.
    */
   public Component getFirstComponent(Container root)
@@ -117,18 +295,16 @@
       {
         Component component = componentArray [i];
 	
+	if (accept (component))
+	  return component;
+
         if (component instanceof Container)
           {
-            Component result = getLastComponent ((Container) component);
+            Component result = getFirstComponent ((Container) component);
 
             if (result != null)
               return result;
           }
-        else
-          {
-            if (accept (component))
-              return component;
-          }
       }
 
     return null;
@@ -137,9 +313,14 @@
   /**
    * Returns the last Component of root that should receive the focus.
    *
+   * @param root a focus cycle root
+   *
+   * @return the last Component in the focus traversal order for
+   * root, or null if no acceptable Component exists.
+   *
    * @exception IllegalArgumentException If root is null.
    */
-  public Component getLastComponent(Container root)
+  public Component getLastComponent (Container root)
   {
     if (root == null)
       throw new IllegalArgumentException ();
@@ -153,10 +334,13 @@
 
     Component[] componentArray = root.getComponents ();
     
-    for (int i = componentArray.length - 1; i >= 0; i++)
+    for (int i = componentArray.length - 1; i >= 0; i--)
       {
         Component component = componentArray [i];
 	
+	if (accept (component))
+	  return component;
+
         if (component instanceof Container)
           {
             Component result = getLastComponent ((Container) component);
@@ -164,11 +348,6 @@
             if (result != null)
               return result;
           }
-        else
-          {
-            if (accept (component))
-              return component;
-          }
       }
 
     return null;
@@ -177,28 +356,58 @@
   /**
    * Returns the default Component of root that should receive the focus.
    *
+   * @param root a focus cycle root
+   *
+   * @return the default Component in the focus traversal order for
+   * root, or null if no acceptable Component exists.
+   *
    * @exception IllegalArgumentException If root is null.
    */
-  public Component getDefaultComponent(Container root)
+  public Component getDefaultComponent (Container root)
   {
     return getFirstComponent (root);
   }
 
-  public void setImplicitDownCycleTraversal(boolean value)
+  /**
+   * Set whether or not implicit down cycling is enabled.  If it is,
+   * then initiating a forward focus traversal operation onto a focus
+   * cycle root, the focus will be implicitly transferred into the
+   * root container's focus cycle.
+   *
+   * @param value the setting for implicit down cycling
+   */
+  public void setImplicitDownCycleTraversal (boolean value)
   {
     implicitDownCycleTraversal = value;
   }
 
-  public boolean getImplicitDownCycleTraversal()
+  /**
+   * Check whether or not implicit down cycling is enabled.  If it is,
+   * then initiating a forward focus traversal operation onto a focus
+   * cycle root, the focus will be implicitly transferred into the
+   * root container's focus cycle.
+   *
+   * @return true if the focus will be transferred down-cycle
+   * implicitly
+   */
+  public boolean getImplicitDownCycleTraversal ()
   {
     return implicitDownCycleTraversal;
   }
 
-  protected boolean accept(Component current)
+  /**
+   * Check whether the given Component is an acceptable target for the
+   * keyboard input focus.
+   *
+   * @param current the Component to check
+   *
+   * @return true if current is acceptable, false otherwise
+   */
+  protected boolean accept (Component current)
   {
     return (current.visible
-            && current.isDisplayable()
+            && current.isDisplayable ()
             && current.enabled
             && current.focusable);
   }
-} // class ContainerOrderFocusTraversalPolicy
+}
Index: java/awt/DefaultFocusTraversalPolicy.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/DefaultFocusTraversalPolicy.java,v
retrieving revision 1.1
diff -u -r1.1 DefaultFocusTraversalPolicy.java
--- java/awt/DefaultFocusTraversalPolicy.java	9 Aug 2002 04:26:14 -0000	1.1
+++ java/awt/DefaultFocusTraversalPolicy.java	6 Sep 2004 16:35:43 -0000
@@ -39,17 +39,71 @@
 package java.awt;
 
 /**
- * STUB CLASS ONLY
+ * DefaultFocusTraversalPolicy is the default focus traversal policy
+ * used by Containers.
+ *
+ * This policy sharpens ContainerOrderFocusTraversalPolicy's
+ * acceptance criteria, to reject those Components that have
+ * unfocusable peers.  Despite this extra strictness, this policy will
+ * always accept a Component that has explicitly been set focusable by
+ * any means.
+ *
+ * This AWT implementation assumes that the peers of the following
+ * Components are not focusable: Canvas, Panel, Label, ScrollPane,
+ * Scrollbar, Window, and any lightweight Component.
+ *
+ * A Component's focusability is independent of the focusability of
+ * its peer.
+ *
+ * @author Thomas Fitzsimmons <fitzsim@redhat.com>
+ * @since 1.4
  */
 public class DefaultFocusTraversalPolicy
   extends ContainerOrderFocusTraversalPolicy
 {
-  public DefaultFocusTraversalPolicy()
+  /**
+   * Construct a default focus traversal policy.
+   */
+  public DefaultFocusTraversalPolicy ()
   {
   }
 
-  protected boolean accept(Component comp)
+  /**
+   * Check whether a given Component would be acceptable as a focus
+   * owner.  The Component must be displayable, visible and enabled to
+   * be acceptable.  If the Component's focus traversability has been
+   * overridden, by overriding Component.isFocusTraversable or
+   * Component.isFocusable, or by calling Component.setFocusable, then
+   * the Component will be accepted if it is focusable.  If the
+   * Component uses the default focus traversable behaviour, then
+   * <code>comp</code> will always be rejected if it is a Canvas,
+   * Panel, Label, ScrollPane, Scrollbar, Window or lightweight
+   * Component.
+   *
+   * @param comp the Component to check
+   *
+   * @return true if the Component is an acceptable target for
+   * keyboard input focus, false otherwise
+   */
+  protected boolean accept (Component comp)
   {
-    throw new Error("not implemented");
+    if (comp.visible
+	&& comp.isDisplayable ()
+	&& comp.enabled)
+      {
+	if (comp.isFocusTraversableOverridden != 0
+	    && (comp.isFocusTraversable () || comp.isFocusable()))
+          return true;
+        
+	if (!(comp instanceof Canvas
+              || comp instanceof Panel
+              || comp instanceof Label
+              || comp instanceof ScrollPane
+              || comp instanceof Scrollbar
+              || comp instanceof Window
+              || comp.isLightweight ()))
+          return true;
+      }
+    return false;
   }
-} // class DefaultFocusTraversalPolicy
+}
Index: java/awt/DefaultKeyboardFocusManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/DefaultKeyboardFocusManager.java,v
retrieving revision 1.1
diff -u -r1.1 DefaultKeyboardFocusManager.java
--- java/awt/DefaultKeyboardFocusManager.java	9 Aug 2002 04:26:14 -0000	1.1
+++ java/awt/DefaultKeyboardFocusManager.java	6 Sep 2004 16:35:44 -0000
@@ -38,59 +38,459 @@
 
 package java.awt;
 
-import java.awt.event.KeyEvent;
+import java.util.*;
+import java.awt.event.*;
 
-/**
- * STUB CLASS ONLY
- */
+// FIXME: finish documentation
 public class DefaultKeyboardFocusManager extends KeyboardFocusManager
 {
-  public DefaultKeyboardFocusManager()
+  /**
+   * This class models a request to delay the dispatch of events that
+   * arrive after a certain time, until a certain component becomes
+   * the focus owner.
+   */
+  private class EventDelayRequest implements Comparable
+  {
+    /** A {@link java.util.List} of {@link java.awt.event.KeyEvent}s
+        that are being delayed, pending this request's {@link
+        Component} receiving the keyboard focus. */
+    private LinkedList enqueuedKeyEvents = new LinkedList ();
+
+    /** An event timestamp.  All events that arrive after this time
+        should be queued in the {@link #enqueuedKeyEvents} {@link
+        java.util.List}. */
+    public long timestamp;
+    /** When this {@link Component} becomes focused, all events
+        between this EventDelayRequest and the next one in will be
+        dispatched from {@link #enqueuedKeyEvents}. */
+    public Component focusedComp;
+
+    /**
+     * Construct a new EventDelayRequest.
+     *
+     * @param timestamp events that arrive after this time will be
+     * delayed
+     * @param focusedComp the Component that needs to receive focus
+     * before events are dispatched
+     */
+    public EventDelayRequest (long timestamp, Component focusedComp)
+    {
+      this.timestamp = timestamp;
+      this.focusedComp = focusedComp;
+    }
+
+    public int compareTo (Object o)
+    {
+      if (!(o instanceof EventDelayRequest))
+        throw new ClassCastException ();
+
+      EventDelayRequest request = (EventDelayRequest) o;
+
+      if (request.timestamp < timestamp)
+        return -1;
+      else if (request.timestamp == timestamp)
+        return 0;
+      else
+        return 1;
+    }
+
+    public boolean equals (Object o)
+    {
+      if (!(o instanceof EventDelayRequest) || o == null)
+        return false;
+
+      EventDelayRequest request = (EventDelayRequest) o;
+
+      return (request.timestamp == timestamp
+              && request.focusedComp == focusedComp);
+    }
+
+    public void enqueueEvent (KeyEvent e)
+    {
+      KeyEvent last = (KeyEvent) enqueuedKeyEvents.getLast ();
+      if (last != null && e.getWhen () < last.getWhen ())
+        throw new RuntimeException ("KeyEvents enqueued out-of-order");
+
+      if (e.getWhen () <= timestamp)
+        throw new RuntimeException ("KeyEvents enqueued before starting timestamp");
+
+      enqueuedKeyEvents.add (e);
+    }
+
+    public void dispatchEvents ()
+    {
+      int size = enqueuedKeyEvents.size ();
+      for (int i = 0; i < size; i++)
+        {
+          KeyEvent e = (KeyEvent) enqueuedKeyEvents.remove (0);
+          dispatchKeyEvent (e);
+        }
+    }
+
+    public void discardEvents ()
+    {
+      enqueuedKeyEvents.clear ();
+    }
+  }
+
+  /** The {@link java.util.SortedSet} of current {@link
+      #EventDelayRequest}s. */
+  private SortedSet delayRequests = new TreeSet ();
+
+  public DefaultKeyboardFocusManager ()
   {
   }
 
-  public boolean dispatchEvent(AWTEvent e)
+  public boolean dispatchEvent (AWTEvent e)
+  {
+    if (e instanceof WindowEvent)
+      {
+        Window target = (Window) e.getSource ();
+
+        if (e.id == WindowEvent.WINDOW_ACTIVATED)
+          setGlobalActiveWindow (target);
+        else if (e.id == WindowEvent.WINDOW_GAINED_FOCUS)
+          setGlobalFocusedWindow (target);
+        else if (e.id != WindowEvent.WINDOW_LOST_FOCUS
+                 && e.id != WindowEvent.WINDOW_DEACTIVATED)
+          return false;
+
+        redispatchEvent(target, e);
+        return true;
+      }
+    else if (e instanceof FocusEvent)
+      {
+        Component target = (Component) e.getSource ();
+
+        if (e.id == FocusEvent.FOCUS_GAINED)
+          {
+            if (((FocusEvent) e).isTemporary ())
+              setGlobalFocusOwner (target);
+            else
+              setGlobalPermanentFocusOwner (target);
+          }
+        else if (e.id == FocusEvent.FOCUS_LOST)
+          {
+            // We need to set the window's focus owner here; we can't
+            // set it when the window loses focus because by that time
+            // the previous focus owner has already lost focus
+            // (FOCUS_LOST events are delivered before
+            // WINDOW_LOST_FOCUS events).
+
+            // Find the target Component's top-level ancestor.
+            Container parent = target.getParent ();
+
+            while (parent != null
+                   && !(parent instanceof Window))
+              parent = parent.getParent ();
+
+            Window toplevel = parent == null ?
+              (Window) target : (Window) parent;
+
+            Component focusOwner = getFocusOwner ();
+            if (focusOwner != null)
+              toplevel.setFocusOwner (focusOwner);
+
+            if (((FocusEvent) e).isTemporary ())
+              setGlobalFocusOwner (null);
+            else
+              setGlobalPermanentFocusOwner (null);
+          }
+
+        redispatchEvent(target, e);
+
+        return true;
+      }
+    else if (e instanceof KeyEvent)
+      {
+        // Loop through all registered KeyEventDispatchers, giving
+        // each a chance to handle this event.
+        Iterator i = getKeyEventDispatchers().iterator();
+
+        while (i.hasNext ())
+          {
+            KeyEventDispatcher dispatcher = (KeyEventDispatcher) i.next ();
+            if (dispatcher.dispatchKeyEvent ((KeyEvent) e))
+              return true;
+          }
+
+        // processKeyEvent checks if this event represents a focus
+        // traversal key stroke.
+        Component focusOwner = getGlobalPermanentFocusOwner ();
+
+        if (focusOwner != null)
+        processKeyEvent (focusOwner, (KeyEvent) e);
+
+        if (e.isConsumed ())
+          return true;
+
+        if (enqueueKeyEvent ((KeyEvent) e))
+          // This event was enqueued for dispatch at a later time.
+          return true;
+        else
+          // This event wasn't handled by any of the registered
+          // KeyEventDispatchers, and wasn't enqueued for dispatch
+          // later, so send it to the default dispatcher.
+          return dispatchKeyEvent ((KeyEvent) e);
+      }
+
+    return false;
+  }
+
+  private boolean enqueueKeyEvent (KeyEvent e)
   {
-    throw new Error("not implemented");
+    Iterator i = delayRequests.iterator ();
+    boolean oneEnqueued = false;
+    while (i.hasNext ())
+      {
+        EventDelayRequest request = (EventDelayRequest) i.next ();
+        if (e.getWhen () > request.timestamp)
+          {
+            request.enqueueEvent (e);
+            oneEnqueued = true;
+          }
+      }
+    return oneEnqueued;
   }
-  public boolean dispatchKeyEvent(KeyEvent e)
+
+  public boolean dispatchKeyEvent (KeyEvent e)
   {
-    throw new Error("not implemented");
+    Component focusOwner = getGlobalPermanentFocusOwner ();
+
+    if (focusOwner != null)
+      redispatchEvent(focusOwner, e);
+
+    // Loop through all registered KeyEventPostProcessors, giving
+    // each a chance to process this event.
+    Iterator i = getKeyEventPostProcessors().iterator();
+
+    while (i.hasNext ())
+      {
+        KeyEventPostProcessor processor = (KeyEventPostProcessor) i.next ();
+        if (processor.postProcessKeyEvent ((KeyEvent) e))
+          return true;
+      }
+
+    // The event hasn't been consumed yet.  Check if it is an
+    // MenuShortcut.
+    if (postProcessKeyEvent (e))
+      return true;
+
+    // Always return true.
+    return true;
   }
-  public boolean postProcessKeyEvent(KeyEvent e)
+
+  public boolean postProcessKeyEvent (KeyEvent e)
   {
-    throw new Error("not implemented");
+    // Check if this event represents a menu shortcut.
+
+    // MenuShortcuts are activated by Ctrl- KeyEvents, only on KEY_PRESSED.
+    int modifiers = e.getModifiersEx ();
+    if (e.getID() == KeyEvent.KEY_PRESSED
+        && (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0)
+      {
+        Window focusedWindow = getGlobalFocusedWindow ();
+        if (focusedWindow instanceof Frame)
+          {
+            MenuBar menubar = ((Frame) focusedWindow).getMenuBar ();
+
+            if (menubar != null)
+              {
+                // If there's a menubar, loop through all menu items,
+                // checking whether each one has a shortcut, and if
+                // so, whether this key event should activate it.
+                int numMenus = menubar.getMenuCount ();
+
+                for (int i = 0; i < numMenus; i++)
+                  {
+                    Menu menu = menubar.getMenu (i);
+                    int numItems = menu.getItemCount ();
+
+                    for (int j = 0; j < numItems; j++)
+                      {
+                        MenuItem item = menu.getItem (j);
+                        MenuShortcut shortcut = item.getShortcut ();
+
+                        if (item.isEnabled() && shortcut != null)
+                          {
+                            // Dispatch a new ActionEvent if:
+                            //
+                            //     a) this is a Shift- KeyEvent, and the
+                            //        shortcut requires the Shift modifier
+                            //
+                            // or, b) this is not a Shift- KeyEvent, and the
+                            //        shortcut does not require the Shift
+                            //        modifier.
+                            if (shortcut.getKey () == e.getKeyCode ()
+                                && ((shortcut.usesShiftModifier ()
+                                     && (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0)
+                                    || (! shortcut.usesShiftModifier ()
+                                        && (modifiers & KeyEvent.SHIFT_DOWN_MASK) == 0)))
+                              {
+                                item.dispatchEvent (new ActionEvent (item,
+                                                                     ActionEvent.ACTION_PERFORMED,
+                                                                     item.getActionCommand (),
+                                                                     modifiers));
+                                // The event was dispatched.
+                                return true;
+                              }
+                          }
+                      }
+                  }
+              }
+          }
+      }
+    return false;
   }
-  public void processKeyEvent(Component comp, KeyEvent e)
+
+  public void processKeyEvent (Component comp, KeyEvent e)
   {
-    throw new Error("not implemented");
+    AWTKeyStroke eventKeystroke = AWTKeyStroke.getAWTKeyStrokeForEvent (e);
+    // For every focus traversal keystroke, we need to also consume
+    // the other two key event types for the same key (e.g. if
+    // KEY_PRESSED TAB is a focus traversal keystroke, we also need to
+    // consume KEY_RELEASED and KEY_TYPED TAB key events).
+    AWTKeyStroke oppositeKeystroke = AWTKeyStroke.getAWTKeyStroke (e.getKeyCode (),
+                                                                   e.getModifiersEx (),
+                                                                   !(e.id == KeyEvent.KEY_RELEASED));
+
+    Set forwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+    Set backwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+    Set upKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+    Set downKeystrokes = null;
+    if (comp instanceof Container)
+      downKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+
+    if (forwardKeystrokes.contains (eventKeystroke))
+      {
+        focusNextComponent (comp);
+        e.consume ();
+      }
+    else if (backwardKeystrokes.contains (eventKeystroke))
+      {
+        focusPreviousComponent (comp);
+        e.consume ();
+      }
+    else if (upKeystrokes.contains (eventKeystroke))
+      {
+        upFocusCycle (comp);
+        e.consume ();
+      }
+    else if (comp instanceof Container
+             && downKeystrokes.contains (eventKeystroke))
+      {
+        downFocusCycle ((Container) comp);
+        e.consume ();
+      }
+    else if (forwardKeystrokes.contains (oppositeKeystroke)
+             || backwardKeystrokes.contains (oppositeKeystroke)
+             || upKeystrokes.contains (oppositeKeystroke)
+             || (comp instanceof Container &&
+                 downKeystrokes.contains (oppositeKeystroke)))
+      e.consume ();
   }
-  protected void enqueueKeyEvents(long after, Component comp)
+
+  protected void enqueueKeyEvents (long after, Component untilFocused)
   {
-    throw new Error("not implemented");
+    delayRequests.add (new EventDelayRequest (after, untilFocused));
   }
-  protected void dequeueKeyEvents(long after, Component comp)
+
+  protected void dequeueKeyEvents (long after, Component untilFocused)
   {
-    throw new Error("not implemented");
+    // FIXME: need synchronization on delayRequests and enqueuedKeyEvents.
+
+    // Remove the KeyEvent with the oldest timestamp, which should be
+    // the first element in the SortedSet.
+    if (after < 0)
+      {
+        int size = delayRequests.size ();
+        if (size > 0)
+          delayRequests.remove (delayRequests.first ());
+      }
+    else
+      {
+        EventDelayRequest template = new EventDelayRequest (after, untilFocused);
+        if (delayRequests.contains (template))
+          {
+            EventDelayRequest actual = (EventDelayRequest) delayRequests.tailSet (template).first ();
+            delayRequests.remove (actual);
+            actual.dispatchEvents ();
+          }
+      }
   }
-  protected void discardKeyEvents(Component comp)
+
+  protected void discardKeyEvents (Component comp)
   {
-    throw new Error("not implemented");
+    // FIXME: need synchronization on delayRequests and enqueuedKeyEvents.
+
+    Iterator i = delayRequests.iterator ();
+
+    while (i.hasNext ())
+      {
+        EventDelayRequest request = (EventDelayRequest) i.next ();
+
+        if (request.focusedComp == comp
+            || (comp instanceof Container
+                && ((Container) comp).isAncestorOf (request.focusedComp)))
+          request.discardEvents ();
+      }
   }
-  public void focusPreviousComponent(Component comp)
+
+  public void focusPreviousComponent (Component comp)
   {
-    throw new Error("not implemented");
+    Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+    Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+    FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+
+    Component previous = policy.getComponentBefore (focusCycleRoot, focusComp);
+    if (previous != null)
+      previous.requestFocusInWindow ();
   }
-  public void focusNextComponent(Component comp)
+
+  public void focusNextComponent (Component comp)
   {
-    throw new Error("not implemented");
+    Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+    Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+    FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+
+    Component next = policy.getComponentAfter (focusCycleRoot, focusComp);
+    if (next != null)
+      next.requestFocusInWindow ();
   }
-  public void upFocusCycle(Component comp)
+
+  public void upFocusCycle (Component comp)
   {
-    throw new Error("not implemented");
+    Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
+    Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
+
+    if (focusCycleRoot instanceof Window)
+      {
+        FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
+        Component defaultComponent = policy.getDefaultComponent (focusCycleRoot);
+        if (defaultComponent != null)
+          defaultComponent.requestFocusInWindow ();
+      }
+    else
+      {
+        Container parentFocusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor ();
+
+        focusCycleRoot.requestFocusInWindow ();
+        setGlobalCurrentFocusCycleRoot (parentFocusCycleRoot);
+      }
   }
-  public void downFocusCycle(Container cont)
+
+  public void downFocusCycle (Container cont)
   {
-    throw new Error("not implemented");
+    if (cont == null)
+      return;
+
+    if (cont.isFocusCycleRoot (cont))
+      {
+        FocusTraversalPolicy policy = cont.getFocusTraversalPolicy ();
+        Component defaultComponent = policy.getDefaultComponent (cont);
+        if (defaultComponent != null)
+          defaultComponent.requestFocusInWindow ();        
+        setGlobalCurrentFocusCycleRoot (cont);
+      }
   }
 } // class DefaultKeyboardFocusManager
Index: java/awt/Dialog.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Dialog.java,v
retrieving revision 1.13
diff -u -r1.13 Dialog.java
--- java/awt/Dialog.java	13 Jan 2004 02:56:18 -0000	1.13
+++ java/awt/Dialog.java	6 Sep 2004 16:35:44 -0000
@@ -123,8 +123,8 @@
   * parent and modality, that is resizable and which has no title.
   *
   * @param parent The parent frame of this dialog box.
-  * @param modal <true> if this dialog box is modal, <code>false</code>
-  * otherwise.
+  * @param modal <code>true</code> if this dialog box is modal,
+  * <code>false</code> otherwise.
   *
   * @exception IllegalArgumentException If the owner's GraphicsConfiguration
   * is not from a screen device, or if owner is null. This exception is always
@@ -164,8 +164,8 @@
   *
   * @param parent The parent frame of this dialog box.
   * @param title The title string for this dialog box.
-  * @param modal <true> if this dialog box is modal, <code>false</code>
-  * otherwise.
+  * @param modal <code>true</code> if this dialog box is modal,
+  * <code>false</code> otherwise.
   *
   * @exception IllegalArgumentException If owner is null or
   * GraphicsEnvironment.isHeadless() returns true.
@@ -183,8 +183,8 @@
  *
  * @param parent The parent frame of this dialog box.
  * @param title The title string for this dialog box.
- * @param modal <true> if this dialog box is modal, <code>false</code>
- * otherwise.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
  * @param gc The <code>GraphicsConfiguration</code> object to use.
  *
  * @exception IllegalArgumentException If owner is null, the
Index: java/awt/Event.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Event.java,v
retrieving revision 1.9
diff -u -r1.9 Event.java
--- java/awt/Event.java	10 Nov 2002 00:16:42 -0000	1.9
+++ java/awt/Event.java	6 Sep 2004 16:35:44 -0000
@@ -163,7 +163,8 @@
 
   protected String paramString ()
   {
-    return "id=" + id + ",x=" + x + ",y=" + y + "target=" + target;
+    return "id=" + id + ",x=" + x + ",y=" + y
+      + ",target=" + target + ",arg=" + arg;
   }
 
   public boolean shiftDown() 
Index: java/awt/EventDispatchThread.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/EventDispatchThread.java,v
retrieving revision 1.5
diff -u -r1.5 EventDispatchThread.java
--- java/awt/EventDispatchThread.java	16 Jan 2004 16:15:49 -0000	1.5
+++ java/awt/EventDispatchThread.java	6 Sep 2004 16:35:44 -0000
@@ -67,7 +67,17 @@
 	      // We are interrupted when we should finish executing
 	      return;
 	    }
-	  queue.dispatchEvent(evt);
+
+          KeyboardFocusManager manager;
+          manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+          // Try to dispatch this event to the current keyboard focus
+          // manager.  It will dispatch all FocusEvents, all
+          // WindowEvents related to focus, and all KeyEvents,
+          // returning true.  Otherwise, it returns false and we
+          // dispatch the event normally.
+          if (!manager.dispatchEvent (evt))
+            queue.dispatchEvent(evt);
 	}
 	catch (InterruptedException ie)
 	{
Index: java/awt/EventQueue.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/EventQueue.java,v
retrieving revision 1.13
diff -u -r1.13 EventQueue.java
--- java/awt/EventQueue.java	16 Jan 2004 16:15:49 -0000	1.13
+++ java/awt/EventQueue.java	6 Sep 2004 16:35:44 -0000
@@ -161,6 +161,9 @@
    */
   public synchronized void postEvent(AWTEvent evt)
   {
+    if (evt == null)
+      throw new NullPointerException();
+
     if (next != null)
       {
         next.postEvent(evt);
@@ -231,10 +234,11 @@
   public static void invokeAndWait(Runnable runnable)
     throws InterruptedException, InvocationTargetException
   {
+    if (isDispatchThread ())
+      throw new Error("Can't call invokeAndWait from event dispatch thread");
+
     EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
     Thread current = Thread.currentThread();
-    if (current == eq.dispatchThread)
-      throw new Error("Can't call invokeAndWait from event dispatch thread");
 
     InvocationEvent ie = 
       new InvocationEvent(eq, runnable, current, true);
@@ -293,8 +297,18 @@
   public static AWTEvent getCurrentEvent()
   {
     EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
-    if (Thread.currentThread() != eq.dispatchThread)
-      return null;
+    Thread ct = Thread.currentThread();
+    
+    /* Find out if this thread is the dispatch thread for any of the
+       EventQueues in the chain */ 
+    while (ct != eq.dispatchThread)
+      {
+        // Try next EventQueue, if any
+        if (eq.next == null)
+           return null;  // Not an event dispatch thread
+        eq = eq.next;
+      }
+
     return eq.currentEvent;
   }
 
@@ -348,30 +362,34 @@
     if (prev == null)
       throw new EmptyStackException();
 
-    // Don't synchronize both this and prev at the same time, or deadlock could
-    // occur.
+    /* The order is important here, we must get the prev lock first,
+       or deadlock could occur as callers usually get here following
+       prev's next pointer, and thus obtain prev's lock before trying
+       to get this lock. */
     synchronized (prev)
       {
-        prev.next = null;
-      }
+        prev.next = next;
+        if (next != null)
+          next.prev = prev;
 
-    synchronized (this)
-      {
-        int i = next_out;
-        while (i != next_in)
+        synchronized (this)
           {
-            prev.postEvent(queue[i]);
-            next_out = i;
-            if (++i == queue.length)
-              i = 0;
+            int i = next_out;
+            while (i != next_in)
+              {
+                prev.postEvent(queue[i]);
+                next_out = i;
+                if (++i == queue.length)
+                  i = 0;
+              }
+	    // Empty the queue so it can be reused
+	    next_in = 0;
+	    next_out = 0;
+
+            // Tell our EventDispatchThread that it can end execution
+            dispatchThread.interrupt ();
+	    dispatchThread = null;
           }
-	// Empty the queue so it can be reused
-	next_in = 0;
-	next_out = 0;
-
-        // Tell our EventDispatchThread that it can end execution
-        dispatchThread.interrupt ();
-	dispatchThread = null;
       }
   }
 
Index: java/awt/FileDialog.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/FileDialog.java,v
retrieving revision 1.7
diff -u -r1.7 FileDialog.java
--- java/awt/FileDialog.java	5 Jan 2004 21:23:12 -0000	1.7
+++ java/awt/FileDialog.java	6 Sep 2004 16:35:44 -0000
@@ -41,6 +41,7 @@
 import java.awt.peer.FileDialogPeer;
 import java.awt.peer.DialogPeer;
 import java.io.FilenameFilter;
+import java.io.Serializable;
 
 /**
   * This class implements a file selection dialog box widget.
@@ -48,7 +49,7 @@
   * @author Aaron M. Renn (arenn@urbanophile.com)
   * @author Tom Tromey <tromey@redhat.com>
   */
-public class FileDialog extends Dialog implements java.io.Serializable
+public class FileDialog extends Dialog implements Serializable
 {
 
 /*
Index: java/awt/Font.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Font.java,v
retrieving revision 1.16
diff -u -r1.16 Font.java
--- java/awt/Font.java	31 Dec 2003 08:58:30 -0000	1.16
+++ java/awt/Font.java	6 Sep 2004 16:35:44 -0000
@@ -1,5 +1,5 @@
 /* Font.java -- Font object
-   Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -330,16 +330,20 @@
   }
 
   public Font (Map attrs)
-{
-    this.peer = getPeerFromToolkit (null, attrs);
-}
+  {
+    this(null, attrs);
+  }
 
   /* This extra constructor is here to permit ClasspathToolkit and to build
      a font with a "logical name" as well as attrs.  */
   public Font (String name, Map attrs)
-{
+  {
+    // If attrs is null, setting it to an empty HashMap will give this
+    // Font default attributes.
+    if (attrs == null)
+      attrs = new HashMap();
     this.peer = getPeerFromToolkit (name, attrs);
-}
+  }
 
 /*************************************************************************/
 
@@ -646,6 +650,22 @@
 
 /**
   * Produces a new {@link Font} based on the current font, adjusted to a
+  * new size and style.
+  *
+  * @param style The style of the newly created font.
+  * @param size The size of the newly created font.
+  *
+  * @return A clone of the current font, with the specified size and style.
+  *
+  * @since 1.2
+  */
+  public Font deriveFont (int style, float size)
+{
+    return peer.deriveFont (this, style, size);
+}
+
+/**
+  * Produces a new {@link Font} based on the current font, adjusted to a
   * new size.
   *
   * @param size The size of the newly created font.
@@ -698,6 +718,27 @@
 }
 
 /**
+  * Produces a new {@link Font} based on the current font, subjected
+  * to a new affine transformation.
+  *
+  * @param a The transformation to apply.
+  *
+  * @return A clone of the current font, with the specified transform.
+  *
+  * @throws IllegalArgumentException If transformation is
+  * <code>null</code>.
+  *
+  * @since 1.2
+  */
+  public Font deriveFont (AffineTransform a)
+{
+    if (a == null)
+      throw new IllegalArgumentException ("Affine transformation is null");
+
+    return peer.deriveFont (this, a);
+}
+
+/**
   * Produces a new {@link Font} based on the current font, adjusted to a
   * new set of attributes.
   *
@@ -1224,13 +1265,28 @@
 public String
 toString()
 {
-  return(getClass().getName() 
-         + "(logical=" + getName () 
-         + ",family=" + getFamily ()
-         + ",face=" + getFontName ()
-         + ",style=" + getStyle ()
-         + ",size=" + getSize ()
-         + ",transform=" + getTransform () + ")");
+  String styleString = "";
+
+  switch (getStyle ())
+    {
+    case 0:
+      styleString = "plain";
+      break;
+    case 1:
+      styleString = "bold";
+      break;
+    case 2:
+      styleString = "italic";
+      break;
+    default:
+      styleString = "unknown";
+    }
+
+  return getClass ().getName () 
+    + "[family=" + getFamily ()
+    + ",name=" + getFontName ()
+    + ",style=" + styleString
+    + ",size=" + getSize () + "]";
 }
 
 
Index: java/awt/FontMetrics.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/FontMetrics.java,v
retrieving revision 1.4
diff -u -r1.4 FontMetrics.java
--- java/awt/FontMetrics.java	22 Jan 2002 22:58:08 -0000	1.4
+++ java/awt/FontMetrics.java	6 Sep 2004 16:35:44 -0000
@@ -47,12 +47,12 @@
   * least the following methods:
   * <p>
   * <ul>
-  * <li>getAscent
-  * <li>getDescent
-  * <li>getLeading()
-  * <li>getMaxAdvance()
-  * <li>charWidth(char)
-  * <li>charsWidth(char[], int, int)
+  * <li>getAscent()</li>
+  * <li>getDescent()</li>
+  * <li>getLeading()</li>
+  * <li>getMaxAdvance()</li>
+  * <li>charWidth(char)</li>
+  * <li>charsWidth(char[], int, int)</li>
   * </ul>
   *
   * @author Aaron M. Renn (arenn@urbanophile.com)
@@ -195,7 +195,7 @@
 public int
 getMaxDescent()
 {
-  return(getDescent());
+  return getMaxDecent ();
 }
 
 /*************************************************************************/
@@ -212,7 +212,7 @@
 public int
 getMaxDecent()
 {
-  return(getMaxDescent());
+  return getDescent ();
 }
 
 /*************************************************************************/
@@ -292,8 +292,7 @@
 {
   int total_width = 0;
   for (int i = offset; i < len; i++)
-    total_width = charWidth(buf[i]);
-
+    total_width += charWidth(buf[i]);
   return(total_width);
 }
 
@@ -328,7 +327,12 @@
 public int[]
 getWidths()
 {
-  return(new int[256]);
+  int [] result = new int[256];
+  for(char i = 0; i < 256; i++)
+  {
+    result[i]= charWidth(i);
+  }
+  return(result);
 }
 
 /*************************************************************************/
@@ -347,3 +351,4 @@
 
 } // class FontMetrics 
 
+
Index: java/awt/Frame.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Frame.java,v
retrieving revision 1.18
diff -u -r1.18 Frame.java
--- java/awt/Frame.java	19 Sep 2003 19:27:58 -0000	1.18
+++ java/awt/Frame.java	6 Sep 2004 16:35:44 -0000
@@ -1,5 +1,5 @@
 /* Frame.java -- AWT toplevel window
-   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -50,11 +50,6 @@
   */
 public class Frame extends Window implements MenuContainer
 {
-
-/*
- * Static Variables
- */
-
 /**
   * Constant for the default cursor.
   * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead.
@@ -148,12 +143,6 @@
 // Serialization version constant
 private static final long serialVersionUID = 2673458971256075116L;
 
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
 /**
   * @serial The version of the class data being serialized
   * // FIXME: what is this value?
@@ -208,11 +197,10 @@
    */
   private boolean undecorated = false;
 
-/*************************************************************************/
-
 /*
- * Constructors
+   * The number used to generate the name returned by getName.
  */
+  private static transient long next_frame_number = 0;
 
 /**
   * Initializes a new instance of <code>Frame</code> that is not visible
@@ -224,8 +212,6 @@
   this("");
 }
 
-/*************************************************************************/
-
 /**
   * Initializes a new instance of <code>Frame</code> that is not visible
   * and has the specified title.
@@ -256,12 +242,6 @@
   visible = false;
 }
 
-/*************************************************************************/
-
-/*
- * Instance Methods
- */
-
 /**
   * Returns this frame's title string.
   *
@@ -273,8 +253,6 @@
   return(title);
 }
 
-/*************************************************************************/
-
 /*
  * Sets this frame's title to the specified value.
  *
@@ -288,8 +266,6 @@
     ((FramePeer) peer).setTitle(title);
 }
 
-/*************************************************************************/
-
 /**
   * Returns this frame's icon.
   *
@@ -302,8 +278,6 @@
   return(icon);
 }
 
-/*************************************************************************/
-
 /**
   * Sets this frame's icon to the specified value.
   *
@@ -317,8 +291,6 @@
     ((FramePeer) peer).setIconImage(icon);
 }
 
-/*************************************************************************/
-
 /**
   * Returns this frame's menu bar.
   *
@@ -331,8 +303,6 @@
   return(menuBar);
 }
 
-/*************************************************************************/
-
 /**
   * Sets this frame's menu bar.
   *
@@ -341,13 +311,17 @@
 public synchronized void
 setMenuBar(MenuBar menuBar)
 {
-  this.menuBar = menuBar;
   if (peer != null)
+  {
+    if (this.menuBar != null)
+      this.menuBar.removeNotify();  
+    if (menuBar != null)
+      menuBar.addNotify();
     ((FramePeer) peer).setMenuBar(menuBar);
+  }
+  this.menuBar = menuBar;
 }
 
-/*************************************************************************/
-
 /**
   * Tests whether or not this frame is resizable.  This will be 
   * <code>true</code> by default.
@@ -361,8 +335,6 @@
   return(resizable);
 }
 
-/*************************************************************************/
-
 /**
   * Sets the resizability of this frame to the specified value.
   *
@@ -377,8 +349,6 @@
     ((FramePeer) peer).setResizable(resizable);
 }
 
-/*************************************************************************/
-
 /**
   * Returns the cursor type of the cursor for this window.  This will
   * be one of the constants in this class.
@@ -393,8 +363,6 @@
   return(getCursor().getType());
 }
 
-/*************************************************************************/
-
 /**
   * Sets the cursor for this window to the specified type.  The specified
   * type should be one of the constants in this class.
@@ -409,8 +377,6 @@
   setCursor(new Cursor(type));
 }
 
-/*************************************************************************/
-
 /**
   * Removes the specified component from this frame's menu.
   *
@@ -422,30 +388,60 @@
   menuBar.remove(menu);
 }
 
-/*************************************************************************/
-
 /**
   * Notifies this frame that it should create its native peer.
   */
 public void
 addNotify()
 {
+  if (menuBar != null)
+    menuBar.addNotify();
   if (peer == null)
     peer = getToolkit ().createFrame (this);
   super.addNotify();
 }
 
-/*************************************************************************/
+public void removeNotify()
+{
+  if (menuBar != null)
+    menuBar.removeNotify();
+  super.removeNotify();
+}
 
 /**
   * Returns a debugging string describing this window.
   *
   * @return A debugging string describing this window.
   */
-protected String
-paramString()
+  protected String paramString ()
 {
-  return(getClass().getName());
+    String title = getTitle ();
+
+    String resizable = "";
+    if (isResizable ())
+      resizable = ",resizable";
+
+    String state = "";
+    switch (getState ())
+      {
+      case NORMAL:
+        state = ",normal";
+        break;
+      case ICONIFIED:
+        state = ",iconified";
+        break;
+      case MAXIMIZED_BOTH:
+        state = ",maximized-both";
+        break;
+      case MAXIMIZED_HORIZ:
+        state = ",maximized-horiz";
+        break;
+      case MAXIMIZED_VERT:
+        state = ",maximized-vert";
+        break;
+      }
+
+    return super.paramString () + ",title=" + title + resizable + state;
 }
 
 public static Frame[]
@@ -538,5 +534,19 @@
 
     this.undecorated = undecorated;
   }
-} // class Frame 
 
+  /**
+   * Generate a unique name for this frame.
+   *
+   * @return A unique name for this frame.
+   */
+  String generateName ()
+  {
+    return "frame" + getUniqueLong ();
+  }
+
+  private static synchronized long getUniqueLong ()
+  {
+    return next_frame_number++;
+  }
+}
Index: java/awt/Graphics.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Graphics.java,v
retrieving revision 1.6
diff -u -r1.6 Graphics.java
--- java/awt/Graphics.java	11 Jun 2003 10:37:47 -0000	1.6
+++ java/awt/Graphics.java	6 Sep 2004 16:35:45 -0000
@@ -1,5 +1,5 @@
 /* Graphics.java -- Abstract Java drawing class
-   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -417,7 +417,7 @@
   drawLine(x1, y2, x1, y1);
   setColor(br);
   drawLine(x2, y1, x2, y2);
-  drawLine(x2, y1, x1, y2);
+  drawLine(x2, y2, x1, y2);
   setColor(color);
 }
 
@@ -732,14 +732,14 @@
 /*************************************************************************/
 
 /**
-  * Returns a string representation of this object.
-  *
-  * @param A string representation of this object. 
-  */
+ * Returns a string representation of this object.
+ *
+ * @param A string representation of this object. 
+ */
 public String
 toString()
 {
-  return(super.toString());
+  return getClass ().getName () + "[font=" + getFont () + ",color=" + getColor () + "]";
 }
 
 public boolean
Index: java/awt/GraphicsEnvironment.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/GraphicsEnvironment.java,v
retrieving revision 1.1
diff -u -r1.1 GraphicsEnvironment.java
--- java/awt/GraphicsEnvironment.java	9 Aug 2002 04:26:14 -0000	1.1
+++ java/awt/GraphicsEnvironment.java	6 Sep 2004 16:35:45 -0000
@@ -40,6 +40,7 @@
 
 import java.awt.image.BufferedImage;
 import java.util.Locale;
+import gnu.java.awt.ClasspathToolkit;
 
 /**
  * This descibes the collection of GraphicsDevice and Font objects available
@@ -70,7 +71,9 @@
    */
   public static GraphicsEnvironment getLocalGraphicsEnvironment()
   {
-    throw new Error("not implemented");
+    ClasspathToolkit tk;
+    tk = ((ClasspathToolkit) Toolkit.getDefaultToolkit ());
+    return tk.getLocalGraphicsEnvironment ();
   }
 
   /**
Index: java/awt/GridBagLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/GridBagLayout.java,v
retrieving revision 1.6
diff -u -r1.6 GridBagLayout.java
--- java/awt/GridBagLayout.java	14 Nov 2003 22:44:29 -0000	1.6
+++ java/awt/GridBagLayout.java	6 Sep 2004 16:35:45 -0000
@@ -39,7 +39,9 @@
 package java.awt;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.HashMap;
 
 /**
  * @author Michael Koch <konqueror@gmx.de>
@@ -54,7 +56,14 @@
     protected static final int PREFERREDSIZE = 2;
     protected static final int MAXGRIDSIZE = 512;
 
+    // comptable remembers the original contraints given to us.
+    // internalcomptable is used to keep track of modified constraint values
+    // that we calculate, particularly when we are given RELATIVE and
+    // REMAINDER constraints.
+    // Constraints kept in comptable are never modified, and constraints
+    // kept in internalcomptable can be modified internally only.
     protected Hashtable comptable;
+    private Hashtable internalcomptable;
     protected GridBagLayoutInfo layoutInfo;
     protected GridBagConstraints defaultConstraints;
 
@@ -66,6 +75,7 @@
     public GridBagLayout ()
     {
 	this.comptable = new Hashtable();
+	this.internalcomptable = new Hashtable();
 	this.defaultConstraints= new GridBagConstraints();
     }
 
@@ -149,7 +159,7 @@
 
     public void layoutContainer (Container parent)
     {
-	arrangeGrid (parent);
+      arrangeGrid (parent);
     }
 
     public float getLayoutAlignmentX (Container target)
@@ -213,6 +223,20 @@
 	return result;
     }
 
+    private GridBagConstraints lookupInternalConstraints (Component component)
+    {
+	GridBagConstraints result =
+            (GridBagConstraints) internalcomptable.get (component);
+
+	if (result == null)
+	{
+	    result = (GridBagConstraints) lookupConstraints(component).clone();
+	    internalcomptable.put (component, result);
+	}
+    
+	return result;
+    }
+
     /**
      * @since 1.1
      */
@@ -302,7 +326,8 @@
      */
     protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
     {
-	adjustForGravity (gbc, rect);
+      // FIXME
+      throw new Error ("Not implemented");
     }
 
     /**
@@ -310,7 +335,116 @@
      */
     protected void ArrangeGrid (Container parent)
     {
-	arrangeGrid (parent);
+      Component[] components = parent.getComponents();
+
+      if (components.length == 0)
+        return;
+
+      GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE);
+      if (info.cols == 0 && info.rows == 0)
+        return;
+      layoutInfo = info;
+
+      // DEBUG
+      //dumpLayoutInfo (layoutInfo);
+    
+      for(int i = 0; i < components.length; i++)
+	{
+          Component component = components [i];
+		
+          // If component is not visible we dont have to care about it.
+          if (!component.isVisible())
+            continue;
+		
+          GridBagConstraints constraints =
+              lookupInternalConstraints(component);
+
+          int cellx = sumIntArray(layoutInfo.colWidths, constraints.gridx);
+          int celly = sumIntArray(layoutInfo.rowHeights, constraints.gridy);
+          int cellw = sumIntArray(layoutInfo.colWidths,
+                                  constraints.gridx + constraints.gridwidth) - cellx;
+          int cellh = sumIntArray(layoutInfo.rowHeights,
+                                  constraints.gridy + constraints.gridheight) - celly;
+
+          Insets insets = constraints.insets;
+          if (insets != null)
+	    {
+              cellx += insets.left;
+              celly += insets.top;
+              cellw -= insets.left + insets.right;
+              cellh -= insets.top + insets.bottom;
+	    }
+
+          Dimension dim = component.getPreferredSize();
+
+          // Note: Documentation says that padding is added on both sides, but
+          // visual inspection shows that the Sun implementation only adds it
+          // once, so we do the same.
+          dim.width += constraints.ipadx;
+          dim.height += constraints.ipady;
+
+          switch(constraints.fill)
+	    {
+            case GridBagConstraints.HORIZONTAL:
+              dim.width = cellw;
+              break;
+            case GridBagConstraints.VERTICAL:
+              dim.height = cellh;
+              break;
+            case GridBagConstraints.BOTH:
+              dim.width = cellw;
+              dim.height = cellh;
+              break;
+	    }
+
+          int x;
+          int y;
+
+          switch(constraints.anchor)
+	    {
+            case GridBagConstraints.NORTH:
+              x = cellx + (cellw - dim.width) / 2;
+              y = celly;
+              break;
+            case GridBagConstraints.SOUTH:
+              x = cellx + (cellw - dim.width) / 2;
+              y = celly + cellh - dim.height;
+              break;
+            case GridBagConstraints.WEST:
+              x = cellx;
+              y = celly + (cellh - dim.height) / 2;
+              break;
+            case GridBagConstraints.EAST:
+              x = cellx + cellw - dim.width;
+              y = celly + (cellh - dim.height) / 2;
+              break;
+            case GridBagConstraints.NORTHEAST:
+              x = cellx + cellw - dim.width;
+              y = celly;
+              break;
+            case GridBagConstraints.NORTHWEST:
+              x = cellx;
+              y = celly;
+              break;
+            case GridBagConstraints.SOUTHEAST:
+              x = cellx + cellw - dim.width;
+              y = celly + cellh - dim.height;
+              break;
+            case GridBagConstraints.SOUTHWEST:
+              x = cellx;
+              y = celly + cellh - dim.height;
+              break;
+            default:
+              x = cellx + (cellw - dim.width) / 2;
+              y = celly + (cellh - dim.height) / 2;
+              break;
+	    }
+
+          component.setBounds(layoutInfo.pos_x + x, layoutInfo.pos_y + y, dim.width, dim.height);
+	}
+
+      // DEBUG
+      //dumpLayoutInfo (layoutInfo);
     }
 
     /**
@@ -318,7 +452,369 @@
      */
     protected GridBagLayoutInfo GetLayoutInfo (Container parent, int sizeflag)
     {
-	return getLayoutInfo (parent, sizeflag);
+      if (sizeflag != MINSIZE && sizeflag != PREFERREDSIZE)
+        throw new IllegalArgumentException();
+
+      Dimension parentDim = parent.getSize ();
+      Insets parentInsets = parent.getInsets ();
+      parentDim.width -= parentInsets.left + parentInsets.right;
+      parentDim.height -= parentInsets.top + parentInsets.bottom;
+   
+      int current_y = 0;
+      int max_x = 0;
+      int max_y = 0;
+
+      // Guaranteed to contain the last component added to the given row
+      // or column, whose gridwidth/height is not REMAINDER.
+      HashMap lastInRow = new HashMap();
+      HashMap lastInCol = new HashMap();
+
+      Component[] components = parent.getComponents();
+
+      // Components sorted by gridwidths/heights,
+      // smallest to largest, with REMAINDER and RELATIVE at the end.
+      // These are useful when determining sizes and weights.
+      ArrayList sortedByWidth = new ArrayList(components.length);
+      ArrayList sortedByHeight = new ArrayList(components.length);
+
+      // STEP 1: first we figure out how many rows/columns
+      for (int i = 0; i < components.length; i++)
+	{
+          Component component = components [i];
+		
+          // If component is not visible we dont have to care about it.
+          if (!component.isVisible())
+            continue;
+		
+          // When looking up the constraint for the first time, check the
+          // original unmodified constraint.  After the first time, always
+          // refer to the internal modified constraint.
+          GridBagConstraints originalConstraints = lookupConstraints (component);
+          GridBagConstraints constraints = (GridBagConstraints) originalConstraints.clone();
+          internalcomptable.put(component, constraints);
+
+          // Cases:
+          //
+          // 1. gridy == RELATIVE, gridx == RELATIVE
+          //
+          //       use y as the row number; check for the next
+          //       available slot at row y
+          //
+          // 2. only gridx == RELATIVE
+          //
+          //       check for the next available slot at row gridy
+          //
+          // 3. only gridy == RELATIVE
+          //
+          //       check for the next available slot at column gridx
+          //
+          // 4. neither gridx or gridy == RELATIVE
+          //
+          //       nothing to check; just add it
+
+
+          // cases 1 and 2
+          if(constraints.gridx == GridBagConstraints.RELATIVE)
+            {
+              if (constraints.gridy == GridBagConstraints.RELATIVE)
+              constraints.gridy = current_y;
+
+              int x;
+
+              // Check the component that occupies the right-most spot in this
+              // row. We want to add this component after it.
+              // If this row is empty, add to the 0 position.
+              if (!lastInRow.containsKey(new Integer(constraints.gridy))) 
+                x = 0;
+              else
+                {
+                  Component lastComponent = (Component) lastInRow.get(new Integer(constraints.gridy));
+                  GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                  x = lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth);
+                }
+
+              // Determine if this component will fit in the slot vertically.
+              // If not, bump it over to where it does fit.
+              for (int y = constraints.gridy + 1; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+                {
+                  if (lastInRow.containsKey(new Integer(y)))
+                    {
+                      Component lastComponent = (Component) lastInRow.get(new Integer(y));
+                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                      x = Math.max (x,
+                                    lastConstraints.gridx + Math.max(1, lastConstraints.gridwidth));
+                    }
+                }
+
+              constraints.gridx = x;
+            }
+          // case 3
+          else if(constraints.gridy == GridBagConstraints.RELATIVE)
+            {
+              int y;
+              // Check the component that occupies the bottom-most spot in
+              // this column. We want to add this component below it.
+              // If this column is empty, add to the 0 position.
+              if (!lastInCol.containsKey(new Integer(constraints.gridx))) 
+                y = 0;
+              else
+                {
+                  Component lastComponent = (Component)lastInCol.get(new Integer(constraints.gridx));
+                  GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                  y = lastConstraints.gridy + Math.max(1, lastConstraints.gridheight);
+                }
+
+              // Determine if this component will fit in the slot horizontally.
+              // If not, bump it down to where it does fit.
+              for (int x = constraints.gridx + 1; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+                {
+                  if (lastInCol.containsKey(new Integer(x)))
+                    {
+                      Component lastComponent = (Component) lastInCol.get(new Integer(x));
+                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                      y = Math.max (y,
+                                    lastConstraints.gridy + Math.max(1, lastConstraints.gridheight));
+                    }
+                }
+
+              constraints.gridy = y;
+            }
+          // case 4: do nothing
+
+          max_x = Math.max(max_x, 
+                           constraints.gridx + Math.max(1, constraints.gridwidth));
+          max_y = Math.max(max_y,
+                           constraints.gridy + Math.max(1, constraints.gridheight));
+
+          sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
+          sortBySpan(component, constraints.gridheight, sortedByHeight, false);
+
+          // Update our reference points for RELATIVE gridx and gridy.
+          if(constraints.gridwidth == GridBagConstraints.REMAINDER)
+	    {
+              current_y = constraints.gridy + Math.max(1, constraints.gridheight);
+	    }
+          else if (constraints.gridwidth != GridBagConstraints.REMAINDER)
+	    {
+              for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+                {
+                  if(lastInRow.containsKey(new Integer(y)))
+                    {
+                      Component lastComponent = (Component) lastInRow.get(new Integer(y));
+                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                      if (constraints.gridx > lastConstraints.gridx)
+                        {
+                          lastInRow.put(new Integer(y), component);
+                        }
+                    }
+                  else
+                    {
+                      lastInRow.put(new Integer(y), component);
+                    }
+                }
+
+              for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+                {
+                  if(lastInCol.containsKey(new Integer(x)))
+                    {
+                      Component lastComponent = (Component) lastInCol.get(new Integer(x));
+                      GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+                      if (constraints.gridy > lastConstraints.gridy)
+                        {
+                          lastInCol.put(new Integer(x), component);
+                        }
+                    }
+                  else
+                    {
+                      lastInCol.put(new Integer(x), component);
+                    }
+                }
+	    }
+	} // end of STEP 1
+	
+      GridBagLayoutInfo info = new GridBagLayoutInfo(max_x, max_y);
+
+      // Check if column widths and row heights are overridden.
+
+      for (int x = 0; x < max_x; x++)
+        {
+          if(columnWidths != null && columnWidths.length > x)
+            info.colWidths[x] = columnWidths[x];
+          if(columnWeights != null && columnWeights.length > x)
+            info.colWeights[x] = columnWeights[x];
+        }
+
+      for (int y = 0; y < max_y; y++)
+        {
+          if(rowHeights != null && rowHeights.length > y)
+            info.rowHeights[y] = rowHeights[y];
+          if(rowWeights != null && rowWeights.length > y)
+            info.rowWeights[y] = rowWeights[y];
+        }
+
+      // STEP 2: Fix up any cells with width/height as REMAINDER/RELATIVE.
+      for (int i = 0; i < components.length; i++)
+        {
+          Component component = components [i];
+			
+          // If component is not visible we dont have to care about it.
+          if (!component.isVisible())
+            continue;
+			
+          GridBagConstraints constraints = lookupInternalConstraints (component);
+
+          if(constraints.gridwidth == GridBagConstraints.REMAINDER || constraints.gridwidth == GridBagConstraints.RELATIVE)
+            {
+              if(constraints.gridwidth == GridBagConstraints.REMAINDER)
+                {
+                  for (int y = constraints.gridy; y < constraints.gridy + Math.max(1, constraints.gridheight); y++)
+                    {
+                      if (lastInRow.containsKey(new Integer(y)))
+                        {
+                          Component lastComponent = (Component) lastInRow.get(new Integer(y));
+                          GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+
+                          if (lastConstraints.gridwidth == GridBagConstraints.RELATIVE)
+                            {
+                              constraints.gridx = max_x - 1;
+                              break;
+                            }
+                          else
+                            {
+                              constraints.gridx = Math.max (constraints.gridx,
+                                                            lastConstraints.gridx + Math.max (1, lastConstraints.gridwidth));
+                            }
+                        }
+                    }
+                  constraints.gridwidth = max_x - constraints.gridx;
+                }
+              else if (constraints.gridwidth == GridBagConstraints.RELATIVE)
+                {
+                  constraints.gridwidth = max_x - constraints.gridx - 1;
+                }
+
+              // Re-sort
+              sortedByWidth.remove(sortedByWidth.indexOf(component));
+              sortBySpan(component, constraints.gridwidth, sortedByWidth, true);
+            }
+
+          if(constraints.gridheight == GridBagConstraints.REMAINDER || constraints.gridheight == GridBagConstraints.RELATIVE)
+            {
+              if(constraints.gridheight == GridBagConstraints.REMAINDER)
+                {
+                  for (int x = constraints.gridx; x < constraints.gridx + Math.max(1, constraints.gridwidth); x++)
+                    {
+                      if (lastInCol.containsKey(new Integer(x)))
+                        {
+                          Component lastComponent = (Component) lastInRow.get(new Integer(x));
+                          GridBagConstraints lastConstraints = lookupInternalConstraints(lastComponent);
+
+                          if (lastConstraints.gridheight == GridBagConstraints.RELATIVE)
+                            {
+                              constraints.gridy = max_y - 1;
+                              break;
+                            }
+                          else
+                            {
+                              constraints.gridy = Math.max (constraints.gridy,
+                                                            lastConstraints.gridy + Math.max (1, lastConstraints.gridheight));
+                            }
+                        }
+                    }
+                  constraints.gridheight = max_y - constraints.gridy;
+                }
+              else if (constraints.gridheight == GridBagConstraints.RELATIVE)
+                {
+                  constraints.gridheight = max_y - constraints.gridy - 1;
+                }
+
+              // Re-sort
+              sortedByHeight.remove(sortedByHeight.indexOf(component));
+              sortBySpan(component, constraints.gridheight, sortedByHeight, false);
+            }
+        } // end of STEP 2
+
+      // STEP 3: Determine sizes and weights for columns.
+      for (int i = 0; i < sortedByWidth.size(); i++)
+        {
+          Component component = (Component) sortedByWidth.get(i);
+			
+          // If component is not visible we dont have to care about it.
+          if (!component.isVisible())
+            continue;
+
+          GridBagConstraints constraints = lookupInternalConstraints (component);
+
+          int width = (sizeflag == PREFERREDSIZE) ?
+                      component.getPreferredSize().width :
+                      component.getMinimumSize().width;
+
+          if(constraints.insets != null)
+            width += constraints.insets.left + constraints.insets.right;
+
+          width += constraints.ipadx;
+
+          distributeSizeAndWeight(width,
+                                  constraints.weightx, 
+                                  constraints.gridx,
+                                  constraints.gridwidth,
+                                  info.colWidths,
+                                  info.colWeights);
+        } // end of STEP 3
+
+      // STEP 4: Determine sizes and weights for rows.
+      for (int i = 0; i < sortedByHeight.size(); i++)
+        {
+          Component component = (Component) sortedByHeight.get(i);
+			
+          // If component is not visible we dont have to care about it.
+          if (!component.isVisible())
+            continue;
+
+          GridBagConstraints constraints = lookupInternalConstraints (component);
+
+          int height = (sizeflag == PREFERREDSIZE) ?
+                       component.getPreferredSize().height :
+                       component.getMinimumSize().height;
+
+          if(constraints.insets != null)
+            height += constraints.insets.top + constraints.insets.bottom;
+
+          height += constraints.ipady;
+
+          distributeSizeAndWeight(height,
+                                  constraints.weighty, 
+                                  constraints.gridy,
+                                  constraints.gridheight,
+                                  info.rowHeights,
+                                  info.rowWeights);
+        } // end of STEP 4
+
+      // Adjust cell sizes iff parent size not zero.
+      if (parentDim.width > 0 && parentDim.height > 0)
+        {
+          calcCellSizes (info.colWidths, info.colWeights, parentDim.width);
+          calcCellSizes (info.rowHeights, info.rowWeights, parentDim.height);
+        }
+
+      int totalWidth = sumIntArray(info.colWidths);
+      int totalHeight = sumIntArray(info.rowHeights);
+
+      // Make sure pos_x and pos_y are never negative.
+      if (totalWidth >= parentDim.width)
+        info.pos_x = parentInsets.left;
+      else
+        info.pos_x = parentInsets.left + (parentDim.width - totalWidth) / 2;
+
+      if (totalHeight >= parentDim.height)
+        info.pos_y = parentInsets.top;
+      else
+        info.pos_y = parentInsets.top + (parentDim.height - totalHeight) / 2;
+
+      // DEBUG
+      //dumpLayoutInfo (info);
+
+      return info;
     }
 
     /**
@@ -326,7 +822,13 @@
      */
     protected Dimension GetMinSize (Container parent, GridBagLayoutInfo info)
     {
-	return getMinSize (parent, info);
+      if (parent == null || info == null)
+        return new Dimension (0, 0);
+
+      Insets insets = parent.getInsets();
+      int width = sumIntArray (info.colWidths) + insets.left + insets.right;
+      int height = sumIntArray (info.rowHeights) + insets.top + insets.bottom;
+      return new Dimension (width, height);
     }
 
     /**
@@ -334,31 +836,171 @@
      */
     protected Dimension getMinSize (Container parent, GridBagLayoutInfo info)
     {
-	if (parent == null || info == null)
-	    return new Dimension (0, 0);
+      return GetMinSize (parent, info);
+    }
+
+    /**
+     * Helper method used by GetLayoutInfo to keep components sorted, either
+     * by gridwidth or gridheight.
+     *
+     * @param component   Component to add to the sorted list.
+     * @param span        Either the component's gridwidth or gridheight.
+     * @param list        <code>ArrayList</code> of components, sorted by
+     *                    their span.
+     * @param sortByWidth Flag indicating sorting index. If true, sort by
+     *                    width. Otherwise, sort by height.
+     * FIXME: Use a better sorting algorithm.
+     */
+    private void sortBySpan (Component component, int span, ArrayList list, boolean sortByWidth)
+    {
+      if (span == GridBagConstraints.REMAINDER
+          || span == GridBagConstraints.RELATIVE)
+        {
+          // Put all RELATIVE and REMAINDER components at the end.
+          list.add(component);
+        }
+      else
+        {
+          int i = 0;
+          if (list.size() > 0)
+            {
+              GridBagConstraints gbc = lookupInternalConstraints((Component) list.get(i));
+              int otherspan = sortByWidth ?
+                              gbc.gridwidth :
+                              gbc.gridheight;
+              while (otherspan != GridBagConstraints.REMAINDER
+                     && otherspan != GridBagConstraints.RELATIVE
+                     && span >= otherspan)
+                {
+                  i++;
+                  if (i < list.size())
+                    {
+                      gbc = lookupInternalConstraints((Component) list.get(i));
+                      otherspan = sortByWidth ?
+                                  gbc.gridwidth :
+                                  gbc.gridheight;
+                    }
+                  else
+                    break;
+                }
+            }
+          list.add(i, component);
+        }
+    }
+
+    /**
+     * Helper method used by GetLayoutInfo to distribute a component's size
+     * and weight.
+     *
+     * @param size    Preferred size of component, with inset and padding
+     *                already added.
+     * @param weight  Weight of component.
+     * @param start   Starting position of component. Either
+     *                constraints.gridx or gridy.
+     * @param span    Span of component. either contraints.gridwidth or
+     *                gridheight.
+     * @param sizes   Sizes of rows or columns.
+     * @param weights Weights of rows or columns.
+     */
+    private void distributeSizeAndWeight (int size, double weight,
+                                          int start, int span,
+                                          int[] sizes, double[] weights)
+    {
+      if (span == 1)
+        {
+          sizes[start] = Math.max(sizes[start], size);
+          weights[start] = Math.max(weights[start], weight);
+        }
+      else
+        {
+          int numOccupied = span;
+          int lastOccupied = -1;
+
+          for(int i = start; i < start + span; i++)
+            {
+              if (sizes[i] == 0.0)
+                numOccupied--;
+              else
+                {
+                  size -= sizes[i];
+                  lastOccupied = i;
+                }
+            }
+
+          // A component needs to occupy at least one row.
+          if(numOccupied == 0)
+            sizes[start + span - 1] = size;
+          else if (size > 0)
+            sizes[lastOccupied] += size;
 
-	Insets insets = parent.getInsets();
-	int width = sumIntArray (info.colWidths) + insets.left + insets.right;
-	int height = sumIntArray (info.rowHeights) + insets.top + insets.bottom;
-	return new Dimension (width, height);
+          calcCellWeights(weight, weights, start, span);
+        }
     }
 
+    /**
+     * Helper method used by GetLayoutInfo to calculate weight distribution.
+     * @param weight  Weight of component.
+     * @param weights Weights of rows/columns.
+     * @param start   Starting position of component in grid (gridx/gridy).
+     * @param span    Span of component (gridwidth/gridheight).
+     */
+    private void calcCellWeights (double weight, double[] weights, int start, int span)
+    {
+      double totalWeight = 0.0;
+      for(int k = start; k < start + span; k++)
+        totalWeight += weights[k];
+
+      if(weight > totalWeight)
+        {
+          if (totalWeight == 0.0)
+            {
+              weights[start + span - 1] += weight;
+            }
+          else
+            {
+              double diff = weight - totalWeight ;
+              double remaining = diff;
+
+              for(int k = start; k < start + span; k++)
+                {
+                  double extraWeight = diff * weights[k] / totalWeight;
+                  weights[k] += extraWeight;
+                  remaining -= extraWeight;
+                } 
+
+              if (remaining > 0.0 && weights[start + span - 1] != 0.0)
+                {
+                  weights[start + span - 1] += remaining;
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper method used by GetLayoutInfo to distribute extra space
+     * based on weight distribution.
+     *
+     * @param sizes   Sizes of rows/columns.
+     * @param weights Weights of rows/columns.
+     * @param range   Dimension of container.
+     */
     private void calcCellSizes (int[] sizes, double[] weights, int range)
     {
-	int diff = range - sumIntArray (sizes);
+      int totalSize = sumIntArray (sizes);
+      double totalWeight = sumDoubleArray (weights);
 
-	if (diff == 0)
-	    return;
-    
-	double weight = sumDoubleArray (weights);
+      int diff = range - totalSize;
 
-	for (int i = 0; i < sizes.length; i++)
-	{
-	    sizes [i] += (int) (((double) diff) * weights [i] / weight );
+      if (diff == 0)
+        return;
 
-	    if (sizes [i] < 0)
-		sizes [i] = 0;
-	}
+      for (int i = 0; i < sizes.length; i++)
+        {
+          int newsize = (int) (sizes[i] + (((double) diff) * weights [i] / totalWeight ));
+
+          if (newsize > 0)
+            sizes[i] = newsize;
+        }
     }
 
     private void dumpLayoutInfo (GridBagLayoutInfo info)
@@ -404,116 +1046,7 @@
      */
     protected void arrangeGrid (Container parent)
     {
-	Component[] components = parent.getComponents();
-
-	if (components.length == 0)
-	    return;
-
-	GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE);
-	if (info.cols == 0 && info.rows == 0)
-	    return;
-	layoutInfo = info;
-
-	// DEBUG
-	//dumpLayoutInfo (layoutInfo);
-    
-	for(int i = 0; i < components.length; i++)
-	{
-	    Component component = components [i];
-		
-	    // If component is not visible we dont have to care about it.
-	    if (!component.isVisible())
-		continue;
-		
-	    GridBagConstraints constraints = lookupConstraints (component);
-
-	    int cellx = sumIntArray(layoutInfo.colWidths, constraints.gridx);
-	    int celly = sumIntArray(layoutInfo.rowHeights, constraints.gridy);
-	    int cellw = sumIntArray(layoutInfo.colWidths,
-		constraints.gridx + constraints.gridwidth) - cellx;
-	    int cellh = sumIntArray(layoutInfo.rowHeights,
-		constraints.gridy + constraints.gridheight) - celly;
-
-	    Insets insets = constraints.insets;
-	    if (insets != null)
-	    {
-		cellx += insets.left;
-		celly += insets.top;
-		cellw -= insets.left + insets.right;
-		cellh -= insets.top + insets.bottom;
-	    }
-
-	    Dimension dim = component.preferredSize();
-
-	    // Note: Documentation says that padding is added on both sides, but
-	    // visual inspection shows that the Sun implementation only adds it
-	    // once, so we do the same.
-	    dim.width += constraints.ipadx;
-	    dim.height += constraints.ipady;
-
-	    switch(constraints.fill)
-	    {
-		case GridBagConstraints.HORIZONTAL:
-		    dim.width = cellw;
-		    break;
-		case GridBagConstraints.VERTICAL:
-		    dim.height = cellh;
-		    break;
-		case GridBagConstraints.BOTH:
-		    dim.width = cellw;
-		    dim.height = cellh;
-		    break;
-	    }
-
-	    int x;
-	    int y;
-
-	    switch(constraints.anchor)
-	    {
-		case GridBagConstraints.NORTH:
-		    x = cellx + (cellw - dim.width) / 2;
-		    y = celly;
-		    break;
-		case GridBagConstraints.SOUTH:
-		    x = cellx + (cellw - dim.width) / 2;
-		    y = celly + cellh - dim.height;
-		    break;
-		case GridBagConstraints.WEST:
-		    x = cellx;
-		    y = celly + (cellh - dim.height) / 2;
-		    break;
-		case GridBagConstraints.EAST:
-		    x = cellx + cellw - dim.width;
-		    y = celly + (cellh - dim.height) / 2;
-		    break;
-		case GridBagConstraints.NORTHEAST:
-		    x = cellx + cellw - dim.width;
-		    y = celly;
-		    break;
-		case GridBagConstraints.NORTHWEST:
-		    x = cellx;
-		    y = celly;
-		    break;
-		case GridBagConstraints.SOUTHEAST:
-		    x = cellx + cellw - dim.width;
-		    y = celly + cellh - dim.height;
-		    break;
-		case GridBagConstraints.SOUTHWEST:
-		    x = cellx;
-		    y = celly + cellh - dim.height;
-		    break;
-		default:
-		    x = cellx + (cellw - dim.width) / 2;
-		    y = celly + (cellh - dim.height) / 2;
-		    break;
-	    }
-
-	    component.setBounds(layoutInfo.pos_x + x, layoutInfo.pos_y + y, dim.width, dim.height);
-	}
-    
-	// DEBUG
-	//dumpLayoutInfo (layoutInfo);
-
+      ArrangeGrid (parent);
     }
 
     /**
@@ -521,160 +1054,7 @@
      */
     protected GridBagLayoutInfo getLayoutInfo (Container parent, int sizeflag)
     {
-	if (sizeflag != MINSIZE && sizeflag != PREFERREDSIZE)
-	    throw new IllegalArgumentException();
-
-	Dimension parentDim = parent.size();
-	Insets parentInsets = parent.insets();
-	parentDim.width -= parentInsets.left + parentInsets.right;
-	parentDim.height -= parentInsets.top + parentInsets.bottom;
-   
-	int x = 0;
-	int y = 0;
-	int max_x = 0;
-	int max_y = 0;
-
-	// first we figure out how many rows/columns
-	Component[] components = parent.getComponents();
-	for (int i = 0; i < components.length; i++)
-	{
-	    Component component = components [i];
-		
-	    // If component is not visible we dont have to care about it.
-	    if (!component.isVisible())
-		continue;
-		
-	    GridBagConstraints constraints = lookupConstraints (component);
-		
-	    if(constraints.gridx == GridBagConstraints.RELATIVE)
-		constraints.gridx = x;
-
-	    if(constraints.gridy == GridBagConstraints.RELATIVE)
-		constraints.gridy = y;
-		
-	    max_x = Math.max(max_x, 
-		constraints.gridx + Math.max(1, constraints.gridwidth));
-	    max_y = Math.max(max_y,
-		constraints.gridy + Math.max(1, constraints.gridheight));
-
-	    if(constraints.gridwidth == GridBagConstraints.REMAINDER)
-	    {
-		x = 0;
-		y++;
-	    }
-	    else
-	    {
-		x = constraints.gridx + Math.max(1, constraints.gridwidth);
-		y = constraints.gridy;
-	    }
-	}
-	
-	GridBagLayoutInfo info = new GridBagLayoutInfo(max_x, max_y);
-
-	for (x = 0; x <= max_x; x++)
-	{
-	    if(columnWidths != null && columnWidths.length > x)
-	    {
-		info.colWidths[x] = columnWidths[x];
-	    }
-	    if(columnWeights != null && columnWeights.length > x)
-	    {
-		info.colWeights[x] = columnWeights[x];
-	    }
-	    for (int i = 0; i < components.length; i++)
-	    {
-		Component component = components [i];
-			
-		// If component is not visible we dont have to care about it.
-		if (!component.isVisible())
-		    continue;
-			
-		GridBagConstraints constraints = lookupConstraints (component);
-
-		// first we fix up any REMAINDER cells
-		if(constraints.gridwidth == GridBagConstraints.REMAINDER)
-		{
-		    constraints.gridwidth = max_x - constraints.gridx;
-		}
-		if(constraints.gridheight == GridBagConstraints.REMAINDER)
-		{
-		    constraints.gridheight = max_y - constraints.gridy;
-		}
-
-		if(constraints.gridx + constraints.gridwidth - 1 == x)
-		{
-		    int width = (sizeflag == PREFERREDSIZE) ?
-			component.preferredSize().width :
-			component.minimumSize().width;
-		    if(constraints.insets != null)
-		    {
-			width += constraints.insets.left + constraints.insets.right;
-		    }
-		    width += constraints.ipadx;
-		    for(int w = 1; w < constraints.gridwidth; w++)
-		    {
-			width -= info.colWidths[x - w];
-		    }
-		    info.colWidths[x] = Math.max(info.colWidths[x], width);
-		    info.colWeights[x] =
-			Math.max(info.colWeights[x], constraints.weightx);
-		}
-	    }
-	}
-
-	for (y = 0; y <= max_y; y++)
-	{
-	    if(rowHeights != null && rowHeights.length > y)
-	    {
-		info.rowHeights[y] = rowHeights[y];
-	    }
-	    if(rowWeights != null && rowWeights.length > y)
-	    {
-		info.rowWeights[y] = rowWeights[y];
-	    }
-	    for (int i = 0; i < components.length; i++)
-	    {
-		Component component = components [i];
-			
-		// If component is not visible we dont have to care about it.
-		if (!component.isVisible())
-		    continue;
-			
-		GridBagConstraints constraints = lookupConstraints (component);
-
-		if(constraints.gridy + constraints.gridheight - 1 == y)
-		{
-		    int height = (sizeflag == PREFERREDSIZE) ?
-			component.preferredSize().height :
-			component.minimumSize().height;
-		    if(constraints.insets != null)
-		    {
-			height += constraints.insets.top + constraints.insets.bottom;
-		    } 
-		    height += constraints.ipady;
-		    for(int h = 1; h < constraints.gridheight; h++)
-		    {
-			height -= info.rowHeights[y - h];
-		    }
-		    info.rowHeights[y] = Math.max(info.rowHeights[y], height);
-		    info.rowWeights[y] =
-			Math.max(info.rowWeights[y], constraints.weighty);
-		}
-	    }
-	}
-
-	calcCellSizes (info.colWidths, info.colWeights, parentDim.width);
-	calcCellSizes (info.rowHeights, info.rowWeights, parentDim.height);
-
-	int totalWidth = sumIntArray(info.colWidths);
-	int totalHeight = sumIntArray(info.rowHeights);
-	info.pos_x = parentInsets.left + (parentDim.width - totalWidth) / 2;
-	info.pos_y = parentInsets.top + (parentDim.height - totalHeight) / 2;
-
-	// DEBUG
-	//dumpLayoutInfo (info);
-
-	return info;
+      return GetLayoutInfo (parent, sizeflag);
     }
 
     /**
@@ -682,7 +1062,6 @@
      */
     protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
     {
-	// FIXME
-	throw new Error ("Not implemented");
+      AdjustForGravity (gbc, rect);
     }
 }
Index: java/awt/Image.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Image.java,v
retrieving revision 1.6
diff -u -r1.6 Image.java
--- java/awt/Image.java	9 Aug 2002 04:26:14 -0000	1.6
+++ java/awt/Image.java	6 Sep 2004 16:35:45 -0000
@@ -39,6 +39,7 @@
 package java.awt;
 
 import java.awt.image.AreaAveragingScaleFilter;
+import java.awt.image.FilteredImageSource;
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
 import java.awt.image.ReplicateScaleFilter;
@@ -179,7 +180,20 @@
    */
   public Image getScaledInstance(int width, int height, int flags)
   {
-    throw new Error("not implemented");
+    switch (flags)
+    {
+      case SCALE_DEFAULT:
+      case SCALE_FAST:
+      case SCALE_REPLICATE:
+        ImageProducer producer =
+          new FilteredImageSource(this.getSource(),
+                                  new ReplicateScaleFilter(width, height));
+        return Toolkit.getDefaultToolkit().createImage(producer);
+      case SCALE_SMOOTH:
+      case SCALE_AREA_AVERAGING:
+      default:
+        throw new Error("not implemented");
+    }
   }
 
   /**
Index: java/awt/KeyboardFocusManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/KeyboardFocusManager.java,v
retrieving revision 1.2
diff -u -r1.2 KeyboardFocusManager.java
--- java/awt/KeyboardFocusManager.java	13 Feb 2003 07:02:12 -0000	1.2
+++ java/awt/KeyboardFocusManager.java	6 Sep 2004 16:35:45 -0000
@@ -39,34 +39,66 @@
 package java.awt;
 
 import java.awt.event.KeyEvent;
+import java.awt.event.FocusEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.beans.PropertyVetoException;
 import java.beans.VetoableChangeListener;
 import java.beans.VetoableChangeSupport;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+// FIXME: finish documentation
+
 /**
  *
+ * FIXME: discuss applet contexts and thread groups and codebases
+ * being insulated.
+ *
+ * FIXME: discuss where default focus traversal key sets apply
+ * (inherited by child Components etc.)
+ *
  * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Thomas Fitzsimmons <fitzsim@redhat.com>
  * @since 1.4
  * @status partially updated to 1.4, needs documentation.
  */
 public abstract class KeyboardFocusManager
   implements KeyEventDispatcher, KeyEventPostProcessor
 {
+  /** Identifies {@link AWTKeyStroke}s that move the focus forward in
+      the focus cycle. */
   public static final int FORWARD_TRAVERSAL_KEYS = 0;
+
+  /** Identifies {@link AWTKeyStroke}s that move the focus backward in
+      the focus cycle. */
   public static final int BACKWARD_TRAVERSAL_KEYS = 1;
+
+  /** Identifies {@link AWTKeyStroke}s that move the focus up to the
+      parent focus cycle root. */
   public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
+
+  /** Identifies {@link AWTKeyStroke}s that move the focus down to the
+      child focus cycle root. */
   public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
 
+  /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
+      the next focusable Component in the focus cycle. */
   private static final Set DEFAULT_FORWARD_KEYS;
+
+  /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
+      the previous focusable Component in the focus cycle. */
   private static final Set DEFAULT_BACKWARD_KEYS;
+
+  /** Populate the DEFAULT_FORWARD_KEYS and DEFAULT_BACKWARD_KEYS
+      {@link java.util.Set}s. */
   static
   {
     Set s = new HashSet();
@@ -83,232 +115,405 @@
     DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s);
   }
 
-  private static KeyboardFocusManager current
-    = new DefaultKeyboardFocusManager();
-
-  // XXX Not implemented correctly. I think a good implementation here may
-  // be to have permanentFocusOwner be null, and fall back to focusOwner,
-  // unless a temporary focus change is in effect.
-  private static Component focusOwner;
-  private static Component permanentFocusOwner;
-
-  private static Window focusedWindow;
-  private static Window activeWindow;
-  private static Container focusCycleRoot;
+  /** The global object {@link java.util.Map}s. */
 
+  /** For security reasons, {@link java.applet.Applet}s in different
+      codebases must be insulated from one another.  Since {@link
+      KeyboardFocusManager}s have the ability to return {@link
+      Component}s from a given {@link java.applet.Applet}, each
+      codebase must have an independent {@link KeyboardFocusManager}.
+      Since each codebase has its own {@link ThreadGroup} in which its
+      {@link Applet}s run, it makes sense to partition {@link
+      KeyboardFocusManager}s according to {@link
+      java.lang.ThreadGroup}.  Thus, currentKeyboardFocusManagers is a
+      {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}. */
+  private static Map currentKeyboardFocusManagers = new HashMap ();
+
+  /** {@link java.applet.Applet}s in one codebase must not be allowed
+      to access {@link Component}s in {@link java.applet.Applet}s in
+      other codebases.  To enforce this restriction, we key the
+      following {@link java.util.Map}s on {@link java.lang.ThreadGroup}s (which
+      are per-codebase).  For example, if {@link
+      java.lang.ThreadGroup} A calls {@link #setGlobalFocusOwner},
+      passing {@link Component} C, currentFocusOwners[A] is assigned
+      C, and all other currentFocusOwners values are nullified.  Then
+      if {@link java.lang.ThreadGroup} A subsequently calls {@link
+      #getGlobalFocusOwner}, it will return currentFocusOwners[A],
+      that is, {@link Component} C.  If another {@link
+      java.lang.ThreadGroup} K calls {@link #getGlobalFocusOwner}, it
+      will return currentFocusOwners[K], that is, null.
+
+      Since this is a static field, we ensure that there is only one
+      focused {@link Component} per class loader. */
+  private static Map currentFocusOwners = new HashMap ();
+
+  /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+      that stores the {@link Component} that owns the permanent
+      keyboard focus. @see currentFocusOwners */
+  private static Map currentPermanentFocusOwners = new HashMap ();
+
+  /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+      that stores the focused {@link Window}. @see
+      currentFocusOwners */
+  private static Map currentFocusedWindows = new HashMap ();
+
+  /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+      that stores the active {@link Window}. @see
+      currentFocusOwners */
+  private static Map currentActiveWindows = new HashMap ();
+
+  /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
+      that stores the focus cycle root {@link Container}. @see
+      currentFocusOwners */
+  private static Map currentFocusCycleRoots = new HashMap ();
+
+  /** The default {@link FocusTraveralPolicy} that focus-managing
+      {@link Container}s will use to define their initial focus
+      traversal policy. */
   private FocusTraversalPolicy defaultPolicy;
-  private Set[] defaultFocusKeys = new Set[] {
+
+  /** An array that stores the {@link #FORWARD_TRAVERSAL_KEYS}, {@link
+      #BACKWARD_TRAVERSAL_KEYS}, {@link #UP_CYCLE_TRAVERSAL_KEYS} and
+      {@link #DOWN_CYCLE_TRAVERSAL_KEYS} {@link AWTKeyStroke}s {@link
+      java.util.Set}s. */
+  private Set[] defaultFocusKeys = new Set[]
+  {
     DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS,
     Collections.EMPTY_SET, Collections.EMPTY_SET
   };
 
-  private final PropertyChangeSupport propertyChangeSupport
-    = new PropertyChangeSupport(this);
-  private final VetoableChangeSupport vetoableChangeSupport
-    = new VetoableChangeSupport(this);
+  private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this);
+  private final VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport (this);
+
+  /** A list of {@link KeyEventDispatcher}s that process {@link
+      KeyEvent}s before they are processed the default keyboard focus
+      manager. */
   private final ArrayList keyEventDispatchers = new ArrayList();
-  private final ArrayList keyEventPostProcessors = new ArrayList();
 
-
-  public KeyboardFocusManager()
-  {
-  }
+  /** A list of {@link KeyEventPostProcessor}s that process unconsumed
+      {@link KeyEvent}s. */
+  private final ArrayList keyEventPostProcessors = new ArrayList();
 
-  public static KeyboardFocusManager getCurrentKeyboardFocusManager()
+  /**
+   * Construct a KeyboardFocusManager.
+   */
+  public KeyboardFocusManager ()
   {
-    // XXX Need a way to divide this into contexts.
-    return current;
   }
 
-  public static void setCurrentKeyboardFocusManager(KeyboardFocusManager m)
+  /**
+   * Retrieve the keyboard focus manager associated with the {@link
+   * java.lang.ThreadGroup} to which the calling thread belongs.
+   *
+   * @return the keyboard focus manager associated with the current
+   * thread group
+   */
+  public static KeyboardFocusManager getCurrentKeyboardFocusManager ()
+  {
+    ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+    return (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
+  }
+
+  /**
+   * Set the keyboard focus manager associated with the {@link
+   * java.lang.ThreadGroup} to which the calling thread belongs.
+   *
+   * @param m the keyboard focus manager for the current thread group
+   */
+  public static void setCurrentKeyboardFocusManager (KeyboardFocusManager m)
   {
-    SecurityManager sm = System.getSecurityManager();
+    SecurityManager sm = System.getSecurityManager ();
     if (sm != null)
-      sm.checkPermission(new AWTPermission("replaceKeyboardFocusManager"));
-    // XXX Need a way to divide this into contexts.
-    current = m == null ? new DefaultKeyboardFocusManager() : m;
-  }
+      sm.checkPermission (new AWTPermission ("replaceKeyboardFocusManager"));
 
-  public Component getFocusOwner()
-  {
-    // XXX Need an easy way to test if this thread is in the context of the
-    // global focus owner, to avoid creating the exception in the first place.
-    try
-      {
-        return getGlobalFocusOwner();
-      }
-    catch (SecurityException e)
-      {
-        return null;
-      }
-  }
-
-  protected Component getGlobalFocusOwner()
-  {
-    // XXX Need a way to test if this thread is in the context of the focus
-    // owner, and throw a SecurityException if that is the case.
-    // XXX Implement.
-    return focusOwner;
-  }
+    ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+    KeyboardFocusManager manager;
 
-  protected void setGlobalFocusOwner(Component owner)
+    if (m == null)
+      manager = new DefaultKeyboardFocusManager ();
+    else
+      manager = m;
+
+    currentKeyboardFocusManagers.put (currentGroup, manager);
+  }
+
+  /**
+   * Retrieve the {@link Component} that has the keyboard focus, or
+   * null if the focus owner was not set by a thread in the current
+   * {@link java.lang.ThreadGroup}.
+   *
+   * @return the keyboard focus owner or null
+   */
+  public Component getFocusOwner ()
+  {
+    Component owner = (Component) getObject (currentFocusOwners);
+    if (owner == null)
+      owner = (Component) getObject (currentPermanentFocusOwners);
+    return owner;
+  }
+
+  /**
+   * Retrieve the {@link Component} that has the keyboard focus,
+   * regardless of whether or not it was set by a thread in the
+   * current {@link java.lang.ThreadGroup}.  If there is no temporary
+   * focus owner in effect then this method will return the same value
+   * as {@link #getGlobalPermanentFocusOwner}.
+   *
+   * @return the keyboard focus owner
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   */
+  protected Component getGlobalFocusOwner ()
+  {
+    // Check if there is a temporary focus owner.
+    Component focusOwner = (Component) getGlobalObject (currentFocusOwners);
+
+    return (focusOwner == null) ? getGlobalPermanentFocusOwner () : focusOwner;
+  }
+
+  /**
+   * Set the {@link Component} that will be returned by {@link
+   * #getFocusOwner} (when it is called from the current {@link
+   * java.lang.ThreadGroup}) and {@link #getGlobalFocusOwner}.  This
+   * method does not actually transfer the keyboard focus.
+   *
+   * @param owner the Component to return from getFocusOwner and
+   * getGlobalFocusOwner
+   *
+   * @see Component.requestFocus ()
+   * @see Component.requestFocusInWindow ()
+   */
+  protected void setGlobalFocusOwner (Component owner)
   {
-    // XXX Should this send focus events to the components involved?
     if (owner == null || owner.focusable)
-      {
-        firePropertyChange("focusOwner", focusOwner, owner);
-        try
-          {
-            fireVetoableChange("focusOwner", focusOwner, owner);
-            focusOwner = owner;
-          }
-        catch (PropertyVetoException e)
-          {
-          }
-      }
+      setGlobalObject (currentFocusOwners, owner, "focusOwner");
   }
 
-  public void clearGlobalFocusOwner()
+  /**
+   * Clear the global focus owner and deliver a FOCUS_LOST event to
+   * the previously-focused {@link Component}.  Until another {@link
+   * Component} becomes the keyboard focus owner, key events will be
+   * discarded by top-level windows.
+   */
+  public void clearGlobalFocusOwner ()
   {
-    // XXX Is this enough?
-    setGlobalFocusOwner(null);
-  }
-
-  public Component getPermanentFocusOwner()
-  {
-    // XXX Need an easy way to test if this thread is in the context of the
-    // global focus owner, to avoid creating the exception in the first place.
-    try
+    synchronized (currentFocusOwners)
       {
-        return getGlobalPermanentFocusOwner();
-      }
-    catch (SecurityException e)
-      {
-        return null;
-      }
-  }
+        Component focusOwner = getGlobalFocusOwner ();
+        Component permanentFocusOwner = getGlobalPermanentFocusOwner ();
 
-  protected Component getGlobalPermanentFocusOwner()
-  {
-    // XXX Need a way to test if this thread is in the context of the focus
-    // owner, and throw a SecurityException if that is the case.
-    // XXX Implement.
-    return permanentFocusOwner == null ? focusOwner : permanentFocusOwner;
-  }
+        setGlobalFocusOwner (null);
+        setGlobalPermanentFocusOwner (null);
 
-  protected void setGlobalPermanentFocusOwner(Component focusOwner)
-  {
-    // XXX Should this send focus events to the components involved?
-    if (focusOwner == null || focusOwner.focusable)
-      {
-        firePropertyChange("permanentFocusOwner", permanentFocusOwner,
-                           focusOwner);
-        try
+        // Inform the old focus owner that it has lost permanent
+        // focus.
+        if (focusOwner != null)
           {
-            fireVetoableChange("permanentFocusOwner", permanentFocusOwner,
-                               focusOwner);
-            permanentFocusOwner = focusOwner;
+            // We can't cache the event queue, because of
+            // bootstrapping issues.  We need to set the default
+            // KeyboardFocusManager in EventQueue before the event
+            // queue is started.
+            EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+            if (focusOwner != permanentFocusOwner)
+              q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, true));
+            else
+              q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, false));
           }
-        catch (PropertyVetoException e)
+
+        if (focusOwner != permanentFocusOwner)
           {
+            EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+            q.postEvent (new FocusEvent (permanentFocusOwner, FocusEvent.FOCUS_LOST, false));
           }
       }
   }
 
-  public Window getFocusedWindow()
+  /**
+   * Retrieve the {@link Component} that has the permanent keyboard
+   * focus, or null if the focus owner was not set by a thread in the
+   * current {@link java.lang.ThreadGroup}.
+   *
+   * @return the keyboard focus owner or null
+   */
+  public Component getPermanentFocusOwner ()
+  {
+    return (Component) getObject (currentPermanentFocusOwners);
+  }
+
+  /**
+   * Retrieve the {@link Component} that has the permanent keyboard
+   * focus, regardless of whether or not it was set by a thread in the
+   * current {@link java.lang.ThreadGroup}.
+   *
+   * @return the keyboard focus owner
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   */
+  protected Component getGlobalPermanentFocusOwner ()
+  {
+    return (Component) getGlobalObject (currentPermanentFocusOwners);
+  }
+
+  /**
+   * Set the {@link Component} that will be returned by {@link
+   * #getPermanentFocusOwner} (when it is called from the current
+   * {@link java.lang.ThreadGroup}) and {@link
+   * #getGlobalPermanentFocusOwner}.  This method does not actually
+   * transfer the keyboard focus.
+   *
+   * @param focusOwner the Component to return from
+   * getPermanentFocusOwner and getGlobalPermanentFocusOwner
+   *
+   * @see Component.requestFocus ()
+   * @see Component.requestFocusInWindow ()
+   */
+  protected void setGlobalPermanentFocusOwner (Component focusOwner)
   {
-    // XXX Need an easy way to test if this thread is in the context of the
-    // global focus owner, to avoid creating the exception in the first place.
-    try
-      {
-        return getGlobalFocusedWindow();
-      }
-    catch (SecurityException e)
-      {
-        return null;
-      }
-  }
-
-  protected Window getGlobalFocusedWindow()
-  {
-    // XXX Need a way to test if this thread is in the context of the focus
-    // owner, and throw a SecurityException if that is the case.
-    // XXX Implement.
-    return focusedWindow;
+    if (focusOwner == null || focusOwner.focusable)
+      setGlobalObject (currentPermanentFocusOwners, focusOwner,
+		       "permanentFocusOwner");
   }
 
-  protected void setGlobalFocusedWindow(Window window)
+  /**
+   * Retrieve the {@link Window} that is or contains the keyboard
+   * focus owner, or null if the focused window was not set by a
+   * thread in the current {@link java.lang.ThreadGroup}.
+   *
+   * @return the focused window or null
+   */
+  public Window getFocusedWindow ()
+  {
+    return (Window) getObject (currentFocusedWindows);
+  }
+
+  /**
+   * Retrieve the {@link Window} that is or contains the focus owner,
+   * regardless of whether or not the {@link Window} was set focused
+   * by a thread in the current {@link java.lang.ThreadGroup}.
+   *
+   * @return the focused window
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   */
+  protected Window getGlobalFocusedWindow ()
+  {
+    return (Window) getGlobalObject (currentFocusedWindows);
+  }
+
+  /**
+   * Set the {@link Window} that will be returned by {@link
+   * #getFocusedWindow} (when it is called from the current {@link
+   * java.lang.ThreadGroup}) and {@link #getGlobalFocusedWindow}.
+   * This method does not actually cause <code>window</code> to become
+   * the focused {@link Window}.
+   *
+   * @param window the Window to return from getFocusedWindow and
+   * getGlobalFocusedWindow
+   */
+  protected void setGlobalFocusedWindow (Window window)
   {
-    // XXX Should this send focus events to the windows involved?
     if (window == null || window.focusable)
-      {
-        firePropertyChange("focusedWindow", focusedWindow, window);
-        try
-          {
-            fireVetoableChange("focusedWindow", focusedWindow, window);
-            focusedWindow = window;
-          }
-        catch (PropertyVetoException e)
-          {
-          }
-      }
+      setGlobalObject (currentFocusedWindows, window, "focusedWindow");
   }
 
+  /**
+   * Retrieve the active {@link Window}, or null if the active window
+   * was not set by a thread in the current {@link
+   * java.lang.ThreadGroup}.
+   *
+   * @return the active window or null
+   */
   public Window getActiveWindow()
   {
-    // XXX Need an easy way to test if this thread is in the context of the
-    // global focus owner, to avoid creating the exception in the first place.
-    try
-      {
-        return getGlobalActiveWindow();
-      }
-    catch (SecurityException e)
-      {
-        return null;
-      }
+    return (Window) getObject (currentActiveWindows);
   }
 
+  /**
+   * Retrieve the active {@link Window}, regardless of whether or not
+   * the {@link Window} was made active by a thread in the current
+   * {@link java.lang.ThreadGroup}.
+   *
+   * @return the active window
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   */
   protected Window getGlobalActiveWindow()
   {
-    // XXX Need a way to test if this thread is in the context of the focus
-    // owner, and throw a SecurityException if that is the case.
-    // XXX Implement.
-    return activeWindow;
+    return (Window) getGlobalObject (currentActiveWindows);
   }
 
+  /**
+   * Set the {@link Window} that will be returned by {@link
+   * #getActiveWindow} (when it is called from the current {@link
+   * java.lang.ThreadGroup}) and {@link #getGlobalActiveWindow}.  This
+   * method does not actually cause <code>window</code> to be made
+   * active.
+   *
+   * @param window the Window to return from getActiveWindow and
+   * getGlobalActiveWindow
+   */
   protected void setGlobalActiveWindow(Window window)
   {
-    // XXX Should this send focus events to the windows involved?
-    firePropertyChange("activeWindow", activeWindow, window);
-    try
-      {
-        fireVetoableChange("activeWindow", activeWindow, window);
-        activeWindow = window;
-      }
-    catch (PropertyVetoException e)
-      {
-      }
+    setGlobalObject (currentActiveWindows, window, "activeWindow");
   }
 
-  public FocusTraversalPolicy getDefaultFocusTraversalPolicy()
+  /**
+   * Retrieve the default {@link FocusTraversalPolicy}.
+   * Focus-managing {@link Container}s use the returned object to
+   * define their initial focus traversal policy.
+   *
+   * @return a non-null default FocusTraversalPolicy object
+   */
+  public FocusTraversalPolicy getDefaultFocusTraversalPolicy ()
   {
     if (defaultPolicy == null)
-      defaultPolicy = new DefaultFocusTraversalPolicy();
+      defaultPolicy = new DefaultFocusTraversalPolicy ();
     return defaultPolicy;
   }
 
-  public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy policy)
+  /**
+   * Set the {@link FocusTraversalPolicy} returned by {@link
+   * #getDefaultFocusTraversalPolicy}.  Focus-managing {@link
+   * Container}s created after this call will use policy as their
+   * initial focus traversal policy.  Existing {@link Container}s'
+   * focus traversal policies will not be affected by calls to this
+   * method.
+   *
+   * @param policy the FocusTraversalPolicy that will be returned by
+   * subsequent calls to getDefaultFocusTraversalPolicy
+   * @throws IllegalArgumentException if policy is null
+   */
+  public void setDefaultFocusTraversalPolicy (FocusTraversalPolicy policy)
   {
     if (policy == null)
-      throw new IllegalArgumentException();
-    firePropertyChange("defaultFocusTraversalPolicy", defaultPolicy, policy);
+      throw new IllegalArgumentException ();
+    firePropertyChange ("defaultFocusTraversalPolicy", defaultPolicy, policy);
     defaultPolicy = policy;
   }
 
-  public void setDefaultFocusTraversalKeys(int id, Set keystrokes)
-  {
+  /**
+   * Set the default {@link java.util.Set} of focus traversal keys for
+   * one of the focus traversal directions.
+   *
+   * @param id focus traversal direction identifier
+   * @param keystrokes set of AWTKeyStrokes
+   *
+   * @see #FORWARD_TRAVERSAL_KEYS
+   * @see #BACKWARD_TRAVERSAL_KEYS
+   * @see #UP_CYCLE_TRAVERSAL_KEYS
+   * @see #DOWN_CYCLE_TRAVERSAL_KEYS
+   */
+  public void setDefaultFocusTraversalKeys (int id, Set keystrokes)
+  {
+    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+        id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+      throw new IllegalArgumentException ();
+
     if (keystrokes == null)
-      throw new IllegalArgumentException();
+      throw new IllegalArgumentException ();
+
     Set sa;
     Set sb;
     Set sc;
@@ -340,56 +545,82 @@
         type = "downCycleDefaultFocusTraversalKeys";
         break;
       default:
-        throw new IllegalArgumentException();
+        throw new IllegalArgumentException ();
       }
-    int i = keystrokes.size();
-    Iterator iter = keystrokes.iterator();
+    int i = keystrokes.size ();
+    Iterator iter = keystrokes.iterator ();
     while (--i >= 0)
       {
-        Object o = iter.next();
-        if (! (o instanceof AWTKeyStroke)
-            || sa.contains(o) || sb.contains(o) || sc.contains(o)
+        Object o = iter.next ();
+        if (!(o instanceof AWTKeyStroke)
+            || sa.contains (o) || sb.contains (o) || sc.contains (o)
             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
-          throw new IllegalArgumentException();
+          throw new IllegalArgumentException ();
       }
-    keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes));
-    firePropertyChange(type, defaultFocusKeys[id], keystrokes);
+    keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+    firePropertyChange (type, defaultFocusKeys[id], keystrokes);
     defaultFocusKeys[id] = keystrokes;
   }
 
-  public Set getDefaultFocusTraversalKeys(int id)
+  /**
+   * Retrieve the default {@link java.util.Set} of focus traversal
+   * keys for one of the focus traversal directions.
+   *
+   * @param id focus traversal direction identifier
+   *
+   * @return the default set of AWTKeyStrokes
+   *
+   * @see #FORWARD_TRAVERSAL_KEYS
+   * @see #BACKWARD_TRAVERSAL_KEYS
+   * @see #UP_CYCLE_TRAVERSAL_KEYS
+   * @see #DOWN_CYCLE_TRAVERSAL_KEYS
+   */
+  public Set getDefaultFocusTraversalKeys (int id)
   {
     if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS)
-      throw new IllegalArgumentException();
+      throw new IllegalArgumentException ();
     return defaultFocusKeys[id];
   }
 
-  public Container getCurrentFocusCycleRoot()
+  /**
+   * Retrieve the current focus cycle root, or null if the focus owner
+   * was not set by a thread in the current {@link
+   * java.lang.ThreadGroup}.
+   *
+   * @return the current focus cycle root or null
+   */
+  public Container getCurrentFocusCycleRoot ()
+  {
+    return (Container) getObject (currentFocusCycleRoots);
+  }
+
+  /**
+   * Retrieve the current focus cycle root, regardless of whether or
+   * not it was made set by a thread in the current {@link
+   * java.lang.ThreadGroup}.
+   *
+   * @return the current focus cycle root
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   */
+  protected Container getGlobalCurrentFocusCycleRoot ()
+  {
+    return (Container) getGlobalObject (currentFocusCycleRoots);
+  }
+
+  /**
+   * Set the {@link Container} that will be returned by {@link
+   * #getCurrentFocusCycleRoot} (when it is called from the current
+   * {@link java.lang.ThreadGroup}) and {@link
+   * #getGlobalCurrentFocusCycleRoot}.  This method does not actually
+   * make <code>cycleRoot</code> the current focus cycle root.
+   * 
+   * @param cycleRoot the focus cycle root to return from
+   * getCurrentFocusCycleRoot and getGlobalCurrentFocusCycleRoot
+   */
+  public void setGlobalCurrentFocusCycleRoot (Container cycleRoot)
   {
-    // XXX Need an easy way to test if this thread is in the context of the
-    // global focus owner, to avoid creating the exception in the first place.
-    try
-      {
-        return getGlobalCurrentFocusCycleRoot();
-      }
-    catch (SecurityException e)
-      {
-        return null;
-      }
-  }
-
-  protected Container getGlobalCurrentFocusCycleRoot()
-  {
-    // XXX Need a way to test if this thread is in the context of the focus
-    // owner, and throw a SecurityException if that is the case.
-    // XXX Implement.
-    return focusCycleRoot;
-  }
-
-  public void setGlobalCurrentFocusCycleRoot(Container cycleRoot)
-  {
-    firePropertyChange("currentFocusCycleRoot", focusCycleRoot, cycleRoot);
-    focusCycleRoot = cycleRoot;
+    setGlobalObject (currentFocusCycleRoots, cycleRoot, "currentFocusCycleRoot");
   }
 
   public void addPropertyChangeListener(PropertyChangeListener l)
@@ -484,73 +715,199 @@
     keyEventDispatchers.remove(dispatcher);
   }
 
-  protected List getKeyEventDispatchers()
+  protected List getKeyEventDispatchers ()
   {
-    return (List) keyEventDispatchers.clone();
+    return (List) keyEventDispatchers.clone ();
   }
 
-  public void addKeyEventPostProcessor(KeyEventPostProcessor postProcessor)
+  public void addKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
   {
     if (postProcessor != null)
-      keyEventPostProcessors.add(postProcessor);
+      keyEventPostProcessors.add (postProcessor);
   }
 
-  public void removeKeyEventPostProcessor(KeyEventPostProcessor postProcessor)
+  public void removeKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
   {
-    keyEventPostProcessors.remove(postProcessor);
+    keyEventPostProcessors.remove (postProcessor);
   }
 
-  protected List getKeyEventPostProcessors()
+  protected List getKeyEventPostProcessors ()
   {
-    return (List) keyEventPostProcessors.clone();
+    return (List) keyEventPostProcessors.clone ();
   }
 
-  public abstract boolean dispatchEvent(AWTEvent e);
+  public abstract boolean dispatchEvent (AWTEvent e);
 
-  public final void redispatchEvent(Component target, AWTEvent e)
+  public final void redispatchEvent (Component target, AWTEvent e)
   {
-    throw new Error("not implemented");
+    synchronized (e)
+      {
+        e.setSource (target);
+        target.dispatchEvent (e);
+      }
   }
 
-  public abstract boolean dispatchKeyEvent(KeyEvent e);
+  public abstract boolean dispatchKeyEvent (KeyEvent e);
 
-  public abstract boolean postProcessKeyEvent(KeyEvent e);
+  public abstract boolean postProcessKeyEvent (KeyEvent e);
 
-  public abstract void processKeyEvent(Component focused, KeyEvent e);
+  public abstract void processKeyEvent (Component focused, KeyEvent e);
 
-  protected abstract void enqueueKeyEvents(long after, Component untilFocused);
+  protected abstract void enqueueKeyEvents (long after, Component untilFocused);
 
-  protected abstract void dequeueKeyEvents(long after, Component untilFocused);
+  protected abstract void dequeueKeyEvents (long after, Component untilFocused);
 
-  protected abstract void discardKeyEvents(Component comp);
+  protected abstract void discardKeyEvents (Component comp);
 
-  public abstract void focusNextComponent(Component comp);
+  public abstract void focusNextComponent (Component comp);
 
-  public abstract void focusPreviousComponent(Component comp);
+  public abstract void focusPreviousComponent (Component comp);
 
-  public abstract void upFocusCycle(Component comp);
+  public abstract void upFocusCycle (Component comp);
 
-  public abstract void downFocusCycle(Container cont);
+  public abstract void downFocusCycle (Container cont);
 
-  public final void focusNextComponent()
+  public final void focusNextComponent ()
   {
-    focusNextComponent(focusOwner);
+    focusNextComponent (null);
   }
 
-  public final void focusPreviousComponent()
+  public final void focusPreviousComponent ()
   {
-    focusPreviousComponent(focusOwner);
+    focusPreviousComponent (null);
   }
 
-  public final void upFocusCycle()
+  public final void upFocusCycle ()
   {
-    upFocusCycle(focusOwner);
+    upFocusCycle (null);
   }
 
-  public final void downFocusCycle()
+  public final void downFocusCycle ()
   {
+    Component focusOwner = getGlobalFocusOwner ();
     if (focusOwner instanceof Container
-        && ((Container) focusOwner).isFocusCycleRoot())
-      downFocusCycle((Container) focusOwner);
+        && ((Container) focusOwner).isFocusCycleRoot ())
+      downFocusCycle ((Container) focusOwner);
+  }
+
+  /**
+   * Retrieve an object from one of the global object {@link
+   * java.util.Map}s, if the object was set by the a thread in the
+   * current {@link java.lang.ThreadGroup}.  Otherwise, return null.
+   *
+   * @param globalMap one of the global object Maps
+   *
+   * @return a global object set by the current ThreadGroup, or null
+   *
+   * @see getFocusOwner
+   * @see getPermanentFocusOwner
+   * @see getFocusedWindow
+   * @see getActiveWindow
+   * @see getCurrentFocusCycleRoot
+   */
+  private Object getObject (Map globalMap)
+  {
+    ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+    return globalMap.get (currentGroup);
+  }
+
+  /**
+   * Retrieve an object from one of the global object {@link
+   * java.util.Map}s, regardless of whether or not the object was set
+   * by a thread in the current {@link java.lang.ThreadGroup}.
+   *
+   * @param globalMap one of the global object Maps
+   *
+   * @return a global object set by the current ThreadGroup, or null
+   *
+   * @throws SecurityException if this is not the keyboard focus
+   * manager associated with the current {@link java.lang.ThreadGroup}
+   *
+   * @see getGlobalFocusOwner
+   * @see getGlobalPermanentFocusOwner
+   * @see getGlobalFocusedWindow
+   * @see getGlobalActiveWindow
+   * @see getGlobalCurrentFocusCycleRoot
+   */
+  private Object getGlobalObject (Map globalMap)
+  {
+    ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+    KeyboardFocusManager managerForCallingThread
+      = (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
+
+    if (this != managerForCallingThread)
+      throw new SecurityException ("Attempted to retrieve an object from a "
+                                   + "keyboard focus manager that isn't "
+                                   + "associated with the current thread group.");
+
+    synchronized (globalMap)
+      {
+        Collection globalObjects = globalMap.values ();
+        Iterator i = globalObjects.iterator ();
+        Component globalObject;
+
+        while (i.hasNext ())
+          {
+            globalObject = (Component) i.next ();
+            if (globalObject != null)
+              return globalObject;
+          }
+      }
+
+    // No Object was found.
+    return null;
+  }
+
+  /**
+   * Set an object in one of the global object {@link java.util.Map}s,
+   * that will be returned by subsequent calls to getGlobalObject on
+   * the same {@link java.util.Map}.
+   *
+   * @param globalMap one of the global object Maps
+   * @param newObject the object to set
+   * @param property the property that will change
+   *
+   * @see setGlobalFocusOwner
+   * @see setGlobalPermanentFocusOwner
+   * @see setGlobalFocusedWindow
+   * @see setGlobalActiveWindow
+   * @see setGlobalCurrentFocusCycleRoot
+   */
+  private void setGlobalObject (Map globalMap,
+                                Object newObject,
+                                String property)
+  {
+    synchronized (globalMap)
+      {
+        // Save old object.
+        Object oldObject = getGlobalObject (globalMap);
+
+        // Nullify old object.
+        Collection threadGroups = globalMap.keySet ();
+        Iterator i = threadGroups.iterator ();
+        while (i.hasNext ())
+          {
+            ThreadGroup oldThreadGroup = (ThreadGroup) i.next ();
+            if (globalMap.get (oldThreadGroup) != null)
+              {
+                globalMap.put (oldThreadGroup, null);
+                // There should only be one object set at a time, so
+                // we can short circuit.
+                break;
+              }
+          }
+
+        ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+        firePropertyChange (property, oldObject, newObject);
+        try
+          {
+            fireVetoableChange (property, oldObject, newObject);
+            // Set new object.
+            globalMap.put (currentGroup, newObject);
+          }
+        catch (PropertyVetoException e)
+          {
+          }
+      }
   }
-} // class KeyboardFocusManager
+}
Index: java/awt/LayoutManager2.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/LayoutManager2.java,v
retrieving revision 1.6
diff -u -r1.6 LayoutManager2.java
--- java/awt/LayoutManager2.java	9 Aug 2002 04:26:14 -0000	1.6
+++ java/awt/LayoutManager2.java	6 Sep 2004 16:35:45 -0000
@@ -52,12 +52,12 @@
 {
   /**
    * Adds the specified component to the layout, with the specified
-   * constraint object.
+   * constraints object.
    *
    * @param component the component to add
-   * @param constraint the constraint to satisfy
+   * @param constraints the constraints to satisfy
    */
-  void addLayoutComponent(Component component, Object contraint);
+  void addLayoutComponent(Component component, Object contraints);
 
   /**
    * Determines the maximum size of the specified target container.
Index: java/awt/List.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/List.java,v
retrieving revision 1.16
diff -u -r1.16 List.java
--- java/awt/List.java	19 Dec 2003 02:53:36 -0000	1.16
+++ java/awt/List.java	6 Sep 2004 16:35:45 -0000
@@ -175,7 +175,7 @@
 public int
 getItemCount()
 {
-  return(items.size());
+  return countItems ();
 }
 
 /*************************************************************************/
@@ -191,7 +191,7 @@
 public int
 countItems()
 {
-  return(getItemCount());
+  return items.size ();
 }
 
 /*************************************************************************/
@@ -249,7 +249,7 @@
 public boolean
 isMultipleMode()
 {
-  return(multipleMode);
+  return allowsMultipleSelections ();
 }
 
 /*************************************************************************/
@@ -266,7 +266,7 @@
 public boolean
 allowsMultipleSelections()
 {
-  return(multipleMode);
+  return multipleMode;
 }
 
 /*************************************************************************/
@@ -281,12 +281,7 @@
 public void
 setMultipleMode(boolean multipleMode)
 {
-  this.multipleMode = multipleMode;
-  if (peer != null)
-    {
-      ListPeer l = (ListPeer) peer;
-      l.setMultipleMode (multipleMode);
-    }
+  setMultipleSelections (multipleMode);
 }
 
 /*************************************************************************/
@@ -303,7 +298,11 @@
 public void
 setMultipleSelections(boolean multipleMode)
 {
-  setMultipleMode(multipleMode);
+  this.multipleMode = multipleMode;
+
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    peer.setMultipleMode (multipleMode);
 }
 
 /*************************************************************************/
@@ -316,7 +315,7 @@
 public Dimension
 getMinimumSize()
 {
-  return(getMinimumSize(rows));
+  return getMinimumSize (getRows ());
 }
 
 /*************************************************************************/
@@ -332,7 +331,7 @@
 public Dimension
 minimumSize()
 {
-  return(getMinimumSize(rows));
+  return minimumSize (getRows ());
 }
 
 /*************************************************************************/
@@ -348,11 +347,7 @@
 public Dimension
 getMinimumSize(int rows)
 {
-  ListPeer lp = (ListPeer)getPeer();
-  if (lp != null)
-    return(lp.minimumSize(rows));
-  else
-    return(new Dimension(0,0));
+  return minimumSize (rows);
 }
 
 /*************************************************************************/
@@ -371,7 +366,11 @@
 public Dimension
 minimumSize(int rows)
 {
-  return(getMinimumSize(rows));
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    return peer.minimumSize (rows);
+  else
+    return new Dimension (0, 0);
 }
 
 /*************************************************************************/
@@ -384,7 +383,7 @@
 public Dimension
 getPreferredSize()
 {
-  return(getPreferredSize(rows));
+  return getPreferredSize (getRows ());
 }
 
 /*************************************************************************/
@@ -400,7 +399,7 @@
 public Dimension
 preferredSize()
 {
-  return(getPreferredSize(rows));
+  return preferredSize (getRows ());
 }
 
 /*************************************************************************/
@@ -416,11 +415,7 @@
 public Dimension
 getPreferredSize(int rows)
 {
-  ListPeer lp = (ListPeer)getPeer();
-  if (lp != null)
-    return(lp.preferredSize(rows));
-  else
-    return(new Dimension(0,0));
+  return preferredSize (rows);
 }
 
 /*************************************************************************/
@@ -439,7 +434,11 @@
 public Dimension
 preferredSize(int rows)
 {
-  return(getPreferredSize(rows));
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    return peer.preferredSize (rows);
+  else
+    return new Dimension (0, 0);
 }
 
 /*************************************************************************/
@@ -452,7 +451,7 @@
 public void
 add(String item)
 {
-  add(item, -1);
+  add (item, -1);
 }
 
 /*************************************************************************/
@@ -467,7 +466,7 @@
 public void
 addItem(String item)
 {
-  addItem(item, -1);
+  addItem (item, -1);
 }
 
 /*************************************************************************/
@@ -484,16 +483,7 @@
 public void
 add(String item, int index)
 {
-  if ((index == -1) || (index >= items.size()))
-    items.addElement(item);
-  else
-    items.insertElementAt(item, index);
-
-  if (peer != null)
-    {
-      ListPeer l = (ListPeer) peer;
-      l.add (item, index);
-    }
+  addItem (item, index);
 }
 
 /*************************************************************************/
@@ -512,7 +502,14 @@
 public void
 addItem(String item, int index)
 {
-  add(item, index);
+  if ((index == -1) || (index >= items.size ()))
+    items.addElement (item);
+  else
+    items.insertElementAt (item, index);
+
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    peer.add (item, index);
 }
 
 /*************************************************************************/
@@ -529,7 +526,11 @@
 public void
 delItem(int index) throws IllegalArgumentException
 {
-  remove(index);
+  items.removeElementAt (index);
+
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    peer.delItems (index, index);
 }
 
 /*************************************************************************/
@@ -544,12 +545,7 @@
 public void
 remove(int index) throws IllegalArgumentException
 {
-  items.removeElementAt (index);
-  if (peer != null)
-    {
-      ListPeer l = (ListPeer) peer;
-      l.delItems (index, index);
-    }
+  delItem (index);
 }
 
 /*************************************************************************/
@@ -613,12 +609,7 @@
 public synchronized void
 removeAll()
 {
-  items.clear();
-  if (peer != null)
-    {
-      ListPeer l = (ListPeer) peer;
-      l.removeAll ();
-    }
+  clear ();
 }
 
 /*************************************************************************/
@@ -631,7 +622,11 @@
 public void
 clear()
 {
-  removeAll();
+  items.clear();
+
+  ListPeer peer = (ListPeer) getPeer ();
+  if (peer != null)
+    peer.removeAll ();
 }
 
 /*************************************************************************/
@@ -782,13 +777,7 @@
 public boolean
 isIndexSelected(int index)
 {
-  int[] indexes = getSelectedIndexes();
-
-  for (int i = 0; i < indexes.length; i++)
-    if (indexes[i] == index)
-      return(true);
-
-  return(false);
+  return isSelected (index);
 }
 
 /*************************************************************************/
@@ -807,7 +796,13 @@
 public boolean
 isSelected(int index)
 {
-  return(isIndexSelected(index));
+  int[] indexes = getSelectedIndexes ();
+
+  for (int i = 0; i < indexes.length; i++)
+    if (indexes[i] == index)
+      return true;
+
+  return false;
 }
 
 /*************************************************************************/
Index: java/awt/MediaTracker.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/MediaTracker.java,v
retrieving revision 1.5
diff -u -r1.5 MediaTracker.java
--- java/awt/MediaTracker.java	12 Nov 2003 00:37:34 -0000	1.5
+++ java/awt/MediaTracker.java	6 Sep 2004 16:35:45 -0000
@@ -81,12 +81,17 @@
         status = ERRORED | COMPLETE;
       else if ((flags & ALLBITS) != 0)
         status = COMPLETE;
-      else
+      else if ((flags & SOMEBITS) != 0)
         status = LOADING;
-      
-      synchronized (MediaTracker.this)
+      else
+        status = 0;
+
+      if ((status & COMPLETE) == COMPLETE)
       {
-	MediaTracker.this.notifyAll();
+        synchronized (MediaTracker.this)
+        {
+          MediaTracker.this.notifyAll();
+        }
       }
       // If status is not COMPLETE then we need more updates.
       return (status & COMPLETE) == 0;
@@ -106,7 +111,8 @@
     e.next = head;
     head = e;
     // Start tracking image status.
-    target.checkImage(image, e);
+    int flags = target.checkImage(image, e);
+    e.imageUpdate(image, flags, -1, -1, -1, -1);
   }
 
   public void addImage(Image image, int id, int width, int height)
@@ -119,7 +125,8 @@
     e.height = height;
     head = e;
     // Start tracking image status.
-    target.checkImage(image, width, height, e);
+    int flags = target.checkImage(image, width, height, e);
+    e.imageUpdate(image, flags, -1, -1, width, height);
   }
 
   public boolean checkAll()
Index: java/awt/Menu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Menu.java,v
retrieving revision 1.13
diff -u -r1.13 Menu.java
--- java/awt/Menu.java	11 Jun 2003 10:37:47 -0000	1.13
+++ java/awt/Menu.java	6 Sep 2004 16:35:45 -0000
@@ -1,5 +1,5 @@
 /* Menu.java -- A Java AWT Menu
-   Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -41,6 +41,7 @@
 import java.awt.peer.MenuPeer;
 import java.io.Serializable;
 import java.util.Vector;
+import java.util.Enumeration;
 
 /**
   * This class represents a pull down or tear off menu in Java's AWT.
@@ -81,7 +82,7 @@
 // From the serialization spec.  FIXME: what should it be?
 private int menuSerializedDataVersion;
 
-static final MenuItem separator = new MenuItem("-");
+static final String separatorLabel = "-";
 
 /*************************************************************************/
 
@@ -170,7 +171,7 @@
 public int
 getItemCount()
 {
-  return(items.size());
+  return countItems ();
 }
 
 /**
@@ -182,7 +183,7 @@
  */
 public int countItems ()
 {
-  return getItemCount ();
+  return items.size ();
 }
  
 /*************************************************************************/
@@ -294,7 +295,7 @@
 public void
 addSeparator()
 {
-  add(separator);
+  add(new MenuItem(separatorLabel));
 }
 
 /*************************************************************************/
@@ -312,7 +313,7 @@
 public void
 insertSeparator(int index)
 {
-  insert(separator, index);
+  insert(new MenuItem(separatorLabel), index);
 }
 
 /*************************************************************************/
@@ -376,8 +377,14 @@
 public void
 addNotify()
 {
-  if (peer != null)
+  if (peer == null)
     peer = getToolkit().createMenu(this);
+  Enumeration e = items.elements();
+  while (e.hasMoreElements())
+  {
+    MenuItem mi = (MenuItem)e.nextElement();
+    mi.addNotify();
+  }    
   super.addNotify ();
 }
 
@@ -389,6 +396,12 @@
 public void
 removeNotify()
 {
+  Enumeration e = items.elements();
+  while (e.hasMoreElements())
+  {
+    MenuItem mi = (MenuItem) e.nextElement();
+    mi.removeNotify();
+  }
   super.removeNotify();
 }
 
Index: java/awt/MenuBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/MenuBar.java,v
retrieving revision 1.10
diff -u -r1.10 MenuBar.java
--- java/awt/MenuBar.java	2 Jan 2003 00:14:22 -0000	1.10
+++ java/awt/MenuBar.java	6 Sep 2004 16:35:45 -0000
@@ -1,5 +1,5 @@
 /* MenuBar.java -- An AWT menu bar class
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -128,15 +128,15 @@
       helpMenu.removeNotify ();
       helpMenu.parent = null;
     }
+  helpMenu = menu;
 
   if (menu.parent != null)
     menu.parent.remove (menu);
-  if (menu.parent != null)
-    menu.parent.remove (menu);
   menu.parent = this;
 
   if (peer != null)
     {
+      menu.addNotify();
       MenuBarPeer mp = (MenuBarPeer) peer;
       mp.addHelpMenu (menu);
     }
@@ -163,8 +163,7 @@
 
   if (peer != null)
     {
-      MenuBarPeer mp = (MenuBarPeer) peer;
-      mp.addMenu (menu);
+      menu.addNotify();
     }
 
   return(menu);
@@ -219,8 +218,7 @@
 public int
 getMenuCount()
 {
-  // FIXME: How does the help menu fit in here?
-  return(menus.size());
+  return countMenus ();
 }
 
 /*************************************************************************/
@@ -235,7 +233,8 @@
 public int
 countMenus()
 {
-  return(getMenuCount());
+  // FIXME: How does the help menu fit in here?
+  return menus.size ();
 }
 
 /*************************************************************************/
@@ -263,6 +262,17 @@
 {
   if (getPeer() == null)
     setPeer((MenuComponentPeer)getToolkit().createMenuBar(this));
+  Enumeration e = menus.elements();
+  while (e.hasMoreElements())
+  {
+    Menu mi = (Menu)e.nextElement();
+    mi.addNotify();
+  }
+  if (helpMenu != null)
+  {
+    helpMenu.addNotify();
+    ((MenuBarPeer) peer).addHelpMenu(helpMenu);
+  }
 }
 
 /*************************************************************************/
@@ -273,6 +283,12 @@
 public void
 removeNotify()
 {
+  Enumeration e = menus.elements();
+  while (e.hasMoreElements())
+  {
+    Menu mi = (Menu) e.nextElement();
+    mi.removeNotify();
+  }
   super.removeNotify();
 }
 
Index: java/awt/MenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/MenuItem.java,v
retrieving revision 1.14
diff -u -r1.14 MenuItem.java
--- java/awt/MenuItem.java	4 Dec 2003 19:31:01 -0000	1.14
+++ java/awt/MenuItem.java	6 Sep 2004 16:35:46 -0000
@@ -1,5 +1,5 @@
 /* MenuItem.java -- An item in a menu
-   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -77,7 +77,7 @@
 /**
   * @serial Indicates whether or not this menu item is enabled.
   */
-private boolean enabled;
+private boolean enabled = true;
 
 /**
   * @serial The mask of events that are enabled for this menu item.
@@ -202,15 +202,7 @@
 public synchronized void
 setEnabled(boolean enabled)
 {
-  if (enabled == this.enabled)
-    return;
-
-  this.enabled = enabled;
-  if (peer != null)
-    {
-      MenuItemPeer mp = (MenuItemPeer) peer;
-      mp.setEnabled (enabled);
-    }
+  enable (enabled);
 }
 
 /*************************************************************************/
@@ -226,7 +218,10 @@
 public void
 enable(boolean enabled)
 {
-  setEnabled(enabled);
+  if (enabled)
+    enable ();
+  else
+    disable ();
 }
 
 /*************************************************************************/
@@ -239,7 +234,12 @@
 public void
 enable()
 {
-  setEnabled(true);
+  if (enabled)
+    return;
+
+  this.enabled = true;
+  if (peer != null)
+    ((MenuItemPeer) peer).setEnabled (true);
 }
 
 /*************************************************************************/
@@ -252,7 +252,12 @@
 public void
 disable()
 {
-  setEnabled(false);
+  if (!enabled)
+    return;
+
+  this.enabled = false;
+  if (peer != null)
+    ((MenuItemPeer) peer).setEnabled (false);
 }
 
 /*************************************************************************/
@@ -305,7 +310,10 @@
 public String
 getActionCommand()
 {
-  return(actionCommand);
+  if (actionCommand == null)
+    return label;
+  else
+    return actionCommand;
 }
 
 /*************************************************************************/
@@ -361,7 +369,7 @@
 public void
 addNotify()
 {
-  if (peer != null)
+  if (peer == null)
     peer = getToolkit ().createMenuItem (this);
 }
 
@@ -416,6 +424,11 @@
       && (action_listeners != null
 	  || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
     processEvent(e);
+
+  // Send the event to the parent menu if it has not yet been
+  // consumed.
+  if (!e.isConsumed ())
+    ((Menu) getParent ()).processEvent (e);
 }
 
 /**
Index: java/awt/Panel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Panel.java,v
retrieving revision 1.8
diff -u -r1.8 Panel.java
--- java/awt/Panel.java	5 Jun 2003 19:58:39 -0000	1.8
+++ java/awt/Panel.java	6 Sep 2004 16:35:46 -0000
@@ -38,6 +38,7 @@
 
 package java.awt;
 
+import java.awt.event.PaintEvent;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
@@ -62,6 +63,19 @@
   /** The cached accessible context. */
   private transient AccessibleContext context;
 
+  /** Flag set when the first system-requested paint event is
+      dispatched. */
+  private transient boolean initialSystemUpdateDone;
+
+  /** Flag set when the first application-requested paint event is
+      consumed. */
+  private transient boolean initialUpdateConsumed;
+
+  /*
+   * The number used to generate the name returned by getName.
+   */
+  private static transient long next_panel_number = 0;
+
   /**
    * Initializes a new instance of <code>Panel</code> that has a default
    * layout manager of <code>FlowLayout</code>.
@@ -84,6 +98,36 @@
   }
 
   /**
+   * Consume initial application-requested paint event if it has not
+   * already been consumed, and if the initial system-requested paint
+   * event has not already been handled.  Otherwise, call
+   * super.dispatchEventImpl.  These extra steps are required to
+   * prevent a Panel from being painted twice when it is initially
+   * shown.
+   *
+   * @param e the event to dispatch
+   */
+  void dispatchEventImpl (AWTEvent e)
+  {
+    if (e instanceof PaintEvent)
+      {
+        if (e.id == PaintEvent.UPDATE)
+          {
+            if (!initialUpdateConsumed
+                && !initialSystemUpdateDone)
+              {
+                e.consume ();
+                initialUpdateConsumed = true;
+              }
+          }
+        else if (e.id == PaintEvent.PAINT)
+          initialSystemUpdateDone = true;
+      }
+    else
+      super.dispatchEventImpl (e);
+  }
+
+  /**
    * Notifies this object to create its native peer.
    *
    * @see #isDisplayable()
@@ -141,5 +185,20 @@
     {
       return AccessibleRole.PANEL;
     }
-  } // class AccessibleAWTPanel
-} // class Panel 
+  }
+
+  /**
+   * Generate a unique name for this panel.
+   *
+   * @return A unique name for this panel.
+   */
+  String generateName ()
+  {
+    return "panel" + getUniqueLong ();
+  }
+
+  private static synchronized long getUniqueLong ()
+  {
+    return next_panel_number++;
+  }
+}
Index: java/awt/Polygon.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Polygon.java,v
retrieving revision 1.3
diff -u -r1.3 Polygon.java
--- java/awt/Polygon.java	8 Dec 2003 22:59:51 -0000	1.3
+++ java/awt/Polygon.java	6 Sep 2004 16:35:46 -0000
@@ -258,10 +258,24 @@
    */
   public Rectangle getBounds()
   {
+    return getBoundingBox ();
+  }
+
+  /**
+   * Returns the bounding box of this polygon. This is the smallest
+   * rectangle with sides parallel to the X axis that will contain this
+   * polygon.
+   *
+   * @return the bounding box for this polygon
+   * @see #getBounds2D()
+   * @deprecated use {@link #getBounds()} instead
+   */
+  public Rectangle getBoundingBox()
+  {
     if (bounds == null)
       {
         if (npoints == 0)
-          return bounds = new Rectangle();
+          return bounds = new Rectangle ();
         int i = npoints - 1;
         int minx = xpoints[i];
         int maxx = minx;
@@ -280,26 +294,12 @@
             else if (y > maxy)
               maxy = y;
           }
-        bounds = new Rectangle(minx, maxy, maxx - minx, maxy - miny);
+        bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny);
       }
     return bounds;
   }
 
   /**
-   * Returns the bounding box of this polygon. This is the smallest
-   * rectangle with sides parallel to the X axis that will contain this
-   * polygon.
-   *
-   * @return the bounding box for this polygon
-   * @see #getBounds2D()
-   * @deprecated use {@link #getBounds()} instead
-   */
-  public Rectangle getBoundingBox()
-  {
-    return getBounds();
-  }
-
-  /**
    * Tests whether or not the specified point is inside this polygon.
    *
    * @param p the point to test
Index: java/awt/PopupMenu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/PopupMenu.java,v
retrieving revision 1.7
diff -u -r1.7 PopupMenu.java
--- java/awt/PopupMenu.java	5 Jun 2003 19:58:39 -0000	1.7
+++ java/awt/PopupMenu.java	6 Sep 2004 16:35:46 -0000
@@ -105,7 +105,7 @@
 public void
 addNotify()
 {
-  if (peer != null)
+  if (peer == null)
     peer = getToolkit ().createPopupMenu (this);
   super.addNotify ();
 }
@@ -123,6 +123,8 @@
 public void
 show(Component component, int x, int y)
 {
+  if (getPeer() == null)
+    this.addNotify();
   PopupMenuPeer pmp = (PopupMenuPeer)getPeer();
   if (pmp != null)
     {
Index: java/awt/Rectangle.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Rectangle.java,v
retrieving revision 1.11
diff -u -r1.11 Rectangle.java
--- java/awt/Rectangle.java	5 Jun 2003 19:58:39 -0000	1.11
+++ java/awt/Rectangle.java	6 Sep 2004 16:35:46 -0000
@@ -281,10 +281,7 @@
    */
   public void setBounds(Rectangle r)
   {
-    x = r.x;
-    y = r.y;
-    width = r.width;
-    height = r.height;
+    setBounds (r.x, r.y, r.width, r.height);
   }
 
   /**
@@ -298,10 +295,7 @@
    */
   public void setBounds(int x, int y, int width, int height)
   {
-    this.x = x;
-    this.y = y;
-    this.width = width;
-    this.height = height;
+    reshape (x, y, width, height);
   }
 
   /**
@@ -333,7 +327,10 @@
    */
   public void reshape(int x, int y, int width, int height)
   {
-    setBounds(x, y, width, height);
+    this.x = x;
+    this.y = y;
+    this.width = width;
+    this.height = height;
   }
 
   /**
@@ -360,8 +357,7 @@
    */
   public void setLocation(Point p)
   {
-    this.x = p.x;
-    this.y = p.y;
+    setLocation (p.x, p.y);
   }
 
   /**
@@ -374,8 +370,7 @@
    */
   public void setLocation(int x, int y)
   {
-    this.x = x;
-    this.y = y;
+    move (x, y);
   }
 
   /**
@@ -388,7 +383,8 @@
    */
   public void move(int x, int y)
   {
-    setLocation(x, y);
+    this.x = x;
+    this.y = y;
   }
 
   /**
@@ -426,8 +422,7 @@
    */
   public void setSize(Dimension d)
   {
-    width = d.width;
-    height = d.height;
+    setSize (d.width, d.height);
   }
 
   /**
@@ -439,8 +434,7 @@
    */
   public void setSize(int width, int height)
   {
-    this.width = width;
-    this.height = height;
+    resize (width, height);
   }
 
   /**
@@ -452,7 +446,8 @@
    */
   public void resize(int width, int height)
   {
-    setSize(width, height);
+    this.width = width;
+    this.height = height;
   }
 
   /**
@@ -469,9 +464,7 @@
    */
   public boolean contains(Point p)
   {
-    return width > 0 && height > 0
-      && p.x >= x && p.x < x + width
-      && p.y >= y && p.y < y + height;
+    return contains (p.x, p.y);
   }
 
   /**
@@ -487,9 +480,7 @@
    */
   public boolean contains(int x, int y)
   {
-    return width > 0 && height > 0
-      && x >= this.x && x < this.x + width
-      && y >= this.y && y < this.y + height;
+    return inside (x, y);
   }
 
   /**
@@ -504,9 +495,7 @@
    */
   public boolean contains(Rectangle r)
   {
-    return width > 0 && height > 0 && r.width > 0 && r.height > 0
-      && r.x >= x && r.x + r.width <= x + width
-      && r.y >= y && r.y + r.height <= y + height;
+    return contains (r.x, r.y, r.width, r.height);
   }
 
   /**
@@ -537,7 +526,9 @@
    */
   public boolean inside(int x, int y)
   {
-    return contains(x, y);
+    return width > 0 && height > 0
+      && x >= this.x && x < this.x + width
+      && y >= this.y && y < this.y + height;
   }
 
   /**
@@ -551,7 +542,7 @@
    */
   public boolean intersects(Rectangle r)
   {
-    return width > 0 && height > 0 && r.width > 0 && r.height > 0
+    return r.width > 0 && r.height > 0 && width > 0 && height > 0
       && r.x < x + width && r.x + r.width > x
       && r.y < y + height && r.y + r.height > y;
   }
Index: java/awt/ScrollPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/ScrollPane.java,v
retrieving revision 1.14
diff -u -r1.14 ScrollPane.java
--- java/awt/ScrollPane.java	5 Jan 2004 21:35:32 -0000	1.14
+++ java/awt/ScrollPane.java	6 Sep 2004 16:35:46 -0000
@@ -157,6 +157,9 @@
     }
 
   wheelScrollingEnabled = true;
+
+  // Default size.
+  setSize(100,100);
 }
 
 /*************************************************************************/
@@ -400,6 +403,15 @@
 
   setPeer((ComponentPeer)getToolkit().createScrollPane(this));
   super.addNotify();
+
+  Component[] list = getComponents();
+  if (list != null && list.length > 0 && ! (list[0] instanceof Panel))
+  {
+    Panel panel = new Panel();
+    panel.setLayout(new BorderLayout());
+    panel.add(list[0], BorderLayout.CENTER);
+    add(panel);
+  }
 }
 
 /*************************************************************************/
@@ -446,10 +458,25 @@
 public void
 doLayout()
 {
-  Component[] list = getComponents();
+  layout ();
+}
+
+/*************************************************************************/
+
+/**
+  * Lays out this component.  This consists of resizing the sole child
+  * component to its perferred size.
+  *
+  * @deprecated This method is deprecated in favor of
+  * <code>doLayout()</code>.
+  */
+public void
+layout()
+{
+  Component[] list = getComponents ();
   if ((list != null) && (list.length > 0))
     {
-      Dimension dim = list[0].getPreferredSize();
+      Dimension dim = list[0].getPreferredSize ();
       Dimension vp = getViewportSize ();
 
       if (dim.width < vp.width)
@@ -462,36 +489,21 @@
       if (peer != null)
 	peer.childResized (dim.width, dim.height);
 
-      list[0].resize (dim);
+      list[0].setSize (dim);
 
-      Point p = getScrollPosition();
+      Point p = getScrollPosition ();
       if (p.x > dim.width)
         p.x = dim.width;
       if (p.y > dim.height)
         p.y = dim.height;
 
-      setScrollPosition(p);
+      setScrollPosition (p);
     }
 }
 
 /*************************************************************************/
 
 /**
-  * Lays out this component.  This consists of resizing the sole child
-  * component to its perferred size.
-  *
-  * @deprecated This method is deprecated in favor of
-  * <code>doLayout()</code>.
-  */
-public void
-layout()
-{
-  doLayout();
-}
-
-/*************************************************************************/
-
-/**
   * This method overrides its superclass method to ensure no layout
   * manager is set for this container.  <code>ScrollPane</code>'s do
   * not have layout managers.
@@ -527,7 +539,19 @@
 public String
 paramString()
 {
-  return(getClass().getName());
+  Insets insets = getInsets();
+  return getName() + ","
+         + getX() + ","
+         + getY() + ","
+         + getWidth() + "x" + getHeight() + ","
+         + "ScrollPosition=(" + scrollPosition.getX() + "," 
+                              + scrollPosition.getY() + "),"
+         + "Insets=(" + insets.top + ","
+                      + insets.left + ","
+                      + insets.bottom + ","
+                      + insets.right + "),"
+         + "ScrollbarDisplayPolicy=" + getScrollbarDisplayPolicy() + ","
+         + "wheelScrollingEnabled=" + isWheelScrollingEnabled();
 }
 
   /**
Index: java/awt/Scrollbar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Scrollbar.java,v
retrieving revision 1.15
diff -u -r1.15 Scrollbar.java
--- java/awt/Scrollbar.java	5 Jun 2003 19:58:39 -0000	1.15
+++ java/awt/Scrollbar.java	6 Sep 2004 16:35:46 -0000
@@ -120,6 +120,11 @@
 
 private transient boolean valueIsAdjusting = false;
 
+  /*
+   * The number used to generate the name returned by getName.
+   */
+  private static transient long next_scrollbar_number = 0;
+
 /*************************************************************************/
 
 /*
@@ -194,9 +199,8 @@
   // Default is 1 according to online docs.
   lineIncrement = 1;
 
-  pageIncrement = (maximum - minimum) / 5;
-  if (pageIncrement == 0)
-    pageIncrement = 1;
+  // Default is 10 according to javadocs.
+  pageIncrement = 10;
 }
 
 /*************************************************************************/
@@ -333,7 +337,7 @@
 public int
 getVisibleAmount()
 {
-  return(visibleAmount);
+  return getVisible ();
 }
 
 /*************************************************************************/
@@ -350,7 +354,7 @@
 public int
 getVisible()
 {
-  return(getVisibleAmount());
+  return visibleAmount;
 }
 
 /*************************************************************************/
@@ -394,15 +398,17 @@
   if (visibleAmount > maximum - minimum)
     visibleAmount = maximum - minimum;
 
+  ScrollbarPeer peer = (ScrollbarPeer) getPeer ();
+  if (peer != null
+      && (this.value != value || this.visibleAmount != visibleAmount
+          || this.minimum != minimum || this.maximum != maximum))
+    peer.setValues(value, visibleAmount, minimum, maximum);
+
   this.value = value;
   this.visibleAmount = visibleAmount;
   this.minimum = minimum;
   this.maximum = maximum;
 
-  ScrollbarPeer sp = (ScrollbarPeer)getPeer();
-  if (sp != null)
-    sp.setValues(value, visibleAmount, minimum, maximum);
-
   int range = maximum - minimum;
   if (lineIncrement > range)
     {
@@ -411,8 +417,8 @@
       else
         lineIncrement = range;
 
-      if (sp != null)
-        sp.setLineIncrement(lineIncrement);
+      if (peer != null)
+        peer.setLineIncrement(lineIncrement);
     }
 
   if (pageIncrement > range)
@@ -422,8 +428,8 @@
       else
         pageIncrement = range;
 
-      if (sp != null)
-        sp.setPageIncrement(pageIncrement);
+      if (peer != null)
+        peer.setPageIncrement(pageIncrement);
     }
 }
 
@@ -438,7 +444,7 @@
 public int
 getUnitIncrement()
 {
-  return(lineIncrement);
+  return getLineIncrement ();
 }
 
 /*************************************************************************/
@@ -455,7 +461,7 @@
 public int
 getLineIncrement()
 {
-  return(lineIncrement);
+  return lineIncrement;
 }
 
 /*************************************************************************/
@@ -469,26 +475,7 @@
 public synchronized void
 setUnitIncrement(int unitIncrement)
 {
-  if (unitIncrement < 0)
-    throw new IllegalArgumentException("Unit increment less than zero.");
-
-  int range = maximum - minimum;
-  if (unitIncrement > range)
-    {
-      if (range == 0)
-        unitIncrement = 1;
-      else
-        unitIncrement = range;
-    }
-
-  if (unitIncrement == lineIncrement)
-    return;
-
-  lineIncrement = unitIncrement;
-
-  ScrollbarPeer sp = (ScrollbarPeer)getPeer();
-  if (sp != null)
-    sp.setLineIncrement(lineIncrement);
+  setLineIncrement (unitIncrement);
 }
 
 /*************************************************************************/
@@ -505,7 +492,26 @@
 public void
 setLineIncrement(int lineIncrement)
 {
-  setUnitIncrement(lineIncrement);
+  if (lineIncrement < 0)
+    throw new IllegalArgumentException ("Unit increment less than zero.");
+
+  int range = maximum - minimum;
+  if (lineIncrement > range)
+    {
+      if (range == 0)
+        lineIncrement = 1;
+      else
+        lineIncrement = range;
+    }
+
+  if (lineIncrement == this.lineIncrement)
+    return;
+
+  this.lineIncrement = lineIncrement;
+
+  ScrollbarPeer peer = (ScrollbarPeer) getPeer ();
+  if (peer != null)
+    peer.setLineIncrement (this.lineIncrement);
 }
 
 /*************************************************************************/
@@ -519,7 +525,7 @@
 public int
 getBlockIncrement()
 {
-  return(pageIncrement);
+  return getPageIncrement ();
 }
 
 /*************************************************************************/
@@ -536,7 +542,7 @@
 public int
 getPageIncrement()
 {
-  return(pageIncrement);
+  return pageIncrement;
 }
 
 /*************************************************************************/
@@ -550,26 +556,7 @@
 public synchronized void
 setBlockIncrement(int blockIncrement)
 {
-  if (blockIncrement < 0)
-    throw new IllegalArgumentException("Block increment less than zero.");
-
-  int range = maximum - minimum;
-  if (blockIncrement > range)
-    {
-      if (range == 0)
-        blockIncrement = 1;
-      else
-        blockIncrement = range;
-    }
-
-  if (blockIncrement == pageIncrement)
-    return;
-
-  pageIncrement = blockIncrement;
-
-  ScrollbarPeer sp = (ScrollbarPeer)getPeer();
-  if (sp != null)
-    sp.setPageIncrement(pageIncrement);
+  setPageIncrement (blockIncrement);
 }
 
 /*************************************************************************/
@@ -586,7 +573,26 @@
 public void
 setPageIncrement(int pageIncrement)
 {
-  setBlockIncrement(pageIncrement);
+  if (pageIncrement < 0)
+    throw new IllegalArgumentException ("Block increment less than zero.");
+
+  int range = maximum - minimum;
+  if (pageIncrement > range)
+    {
+      if (range == 0)
+        pageIncrement = 1;
+      else
+        pageIncrement = range;
+    }
+
+  if (pageIncrement == this.pageIncrement)
+    return;
+
+  this.pageIncrement = pageIncrement;
+
+  ScrollbarPeer peer = (ScrollbarPeer) getPeer ();
+  if (peer != null)
+    peer.setPageIncrement (this.pageIncrement);
 }
 
 /*************************************************************************/
@@ -746,5 +752,20 @@
   {
     this.valueIsAdjusting = valueIsAdjusting;
   }
+
+  /**
+   * Generate a unique name for this scroll bar.
+   *
+   * @return A unique name for this scroll bar.
+   */
+  String generateName ()
+  {
+    return "scrollbar" + getUniqueLong ();
+  }
+
+  private static synchronized long getUniqueLong ()
+  {
+    return next_scrollbar_number++;
+  }
 } // class Scrollbar 
 
Index: java/awt/SystemColor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/SystemColor.java,v
retrieving revision 1.4
diff -u -r1.4 SystemColor.java
--- java/awt/SystemColor.java	9 Aug 2002 04:26:14 -0000	1.4
+++ java/awt/SystemColor.java	6 Sep 2004 16:35:47 -0000
@@ -427,7 +427,7 @@
    * as the system color is solid, the context does not need any of the
    * passed parameters to do its job.
    *
-   * @param cm the requested color model, ignored
+   * @param cm the requested color model
    * @param deviceBounds the bounding box in device coordinates, ignored
    * @param userBounds the bounding box in user coordinates, ignored
    * @param xform the bounds transformation, ignored
@@ -441,8 +441,8 @@
   {
     Toolkit.getDefaultToolkit().loadSystemColors(colors);
     int color = colors[value] | ALPHA_MASK;
-    if (context == null || color != context.color)
-      context = new ColorPaintContext(color);
+    if (context == null || color != context.color || !context.getColorModel().equals(cm))
+      context = new ColorPaintContext(cm,color);
     return context;
   }    
 
Index: java/awt/TextArea.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/TextArea.java,v
retrieving revision 1.8
diff -u -r1.8 TextArea.java
--- java/awt/TextArea.java	5 Jun 2003 19:58:39 -0000	1.8
+++ java/awt/TextArea.java	6 Sep 2004 16:35:47 -0000
@@ -1,565 +1,599 @@
-/* TextArea.java -- A multi-line text entry widget
-   Copyright (C) 1999 Free Software Foundation, Inc.
+/* TextArea.java -- A multi-line text entry component
+   Copyright (C) 1999, 2004 Free Software Foundation, Inc.
 
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
+   This file is part of GNU Classpath.
 
+   GNU Classpath is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GNU Classpath is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Classpath; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   Linking this library statically or dynamically with other modules is
+   making a combined work based on this library.  Thus, the terms and
+   conditions of the GNU General Public License cover the whole
+   combination.
+
+   As a special exception, the copyright holders of this library give you
+   permission to link this library with independent modules to produce an
+   executable, regardless of the license terms of these independent
+   modules, and to copy and distribute the resulting executable under
+   terms of your choice, provided that you also meet, for each linked
+   independent module, the terms and conditions of the license of that
+   module.  An independent module is a module which is not derived from
+   or based on this library.  If you modify this library, you may extend
+   this exception to your version of the library, but you are not
+   obligated to do so.  If you do not wish to do so, delete this
+   exception statement from your version. */
 
 package java.awt;
 
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.TextAreaPeer;
+import java.awt.event.KeyEvent;
+import java.util.HashSet;
+import java.util.Set;
 
-/**
-  * This implements a multi-line text entry widget.
-  *
-  * @author Aaron M. Renn (arenn@urbanophile.com)
-  */
-public class TextArea extends TextComponent implements java.io.Serializable
-{
-
-/*
- * Static Variables
- */
-
-/**
-  * Use both horiztonal and vertical scroll bars.
-  */
-public static final int SCROLLBARS_BOTH = 0;
-
-/**
-  * Use vertical scroll bars only.
-  */
-public static final int SCROLLBARS_VERTICAL_ONLY = 1;
-
-/**
-  * Use horizatonal scroll bars only.
-  */
-public static final int SCROLLBARS_HORIZONTAL_ONLY = 2;
-
-/**
-  * Use no scrollbars.
-  */
-public static final int SCROLLBARS_NONE = 3;
-
-// Serialization constant
-private static final long serialVersionUID = 3692302836626095722L;
-
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
-  * @serial The number of columns in this text area.
-  */
-private int columns;
-
-/**
-  * @serial The number of rows in this text area.
-  */
-private int rows;
 
 /**
-  * @serial The type of scrollbars to display, which will be one of
-  * the contstants from this class.
-  */
-private int scrollbarVisibility;
-
-/*************************************************************************/
-
-/*
- * Constructors
+ * A TextArea is a text component capable of displaying multiple lines
+ * of user-editable text.  A TextArea handles its own scrolling and
+ * can display vertical and horizontal scrollbars as navigation aids.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
  */
-
-/**
-  * Initialize a new instance of <code>TextArea</code> that is empty
-  * and is one row and one column.  Both horizontal and vertical
-  * scrollbars will be used.
-  *
-  * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
-  */
-public
-TextArea()
-{
-  this("", 1, 1, SCROLLBARS_BOTH);
-}
-
-/*************************************************************************/
-
-/**
-  * Initializes a new instance of <code>TextArea</code> that 
-  * contains the specified string.  Both horizontal and veritcal
-  * scrollbars will be used.
-  *
-  * @param text The text to display in this text area.
-  *
-  * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
-  */
-public
-TextArea(String text)
-{
-  this(text, 1, text.length(), SCROLLBARS_BOTH);
-}
-
-/*************************************************************************/
-
-/**
-  * Initializes a new instance of <code>TextArea</code> that is empty
-  * and has the specified number of rows and columns.  Both
-  * horizontal and vertical scrollbars will be used.
-  *
-  * @param rows The number of rows in this text area.
-  * @param columns The number of columns in this text area.
-  *
-  * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
-  */
-public
-TextArea(int rows, int columns)
-{
-  this("", rows, columns, SCROLLBARS_BOTH);
-}
-
-/*************************************************************************/
-
-/**
-  * Initializes a new instance of <code>TextArea</code> that is the
-  * specified size and has the specified text.
-  *
-  * @param text The text to display in this text area.
-  * @param rows The number of rows in this text area.
-  * @param columns The number of columns in this text area.
-  *
-  * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
-  */
-public
-TextArea(String text, int rows, int columns)
-{
-  this(text, rows, columns, SCROLLBARS_BOTH);
-}
-
-/*************************************************************************/
-
-/** 
-  * Initializes a new instance of <code>TextArea</code> with the
-  * specified values.  The scrollbar visibility value must be one
-  * of the constants in this class.
-  *
-  * @param text The text to display in this text area.
-  * @param rows The number of rows in this text area.
-  * @param columns The number of columns in this text area.
-  * @param scrollbarVisibility Which scrollbars to display.
-  *
-  * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
-  */
-public
-TextArea(String text, int rows, int columns, int scrollbarVisibility)
-{
-  super(text);
-
-  if (GraphicsEnvironment.isHeadless())
-    throw new HeadlessException ();
-
-  if ((rows < 1) || (columns < 0))
-    throw new IllegalArgumentException("Bad row or column value");
-
-  if ((scrollbarVisibility != SCROLLBARS_BOTH) &&
-      (scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY) &&
-      (scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY) &&
-      (scrollbarVisibility != SCROLLBARS_NONE))
-    throw new IllegalArgumentException("Bad scrollbar visibility value");
-
-  this.rows = rows;
-  this.columns = columns;
-  this.scrollbarVisibility = scrollbarVisibility;
-}
-
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
-  * Returns the number of columns in the field.
-  *
-  * @return The number of columns in the field.
-  */
-public int
-getColumns()
-{
-  return(columns);
-}
-
-/*************************************************************************/
-
-/**
-  * Sets the number of columns in this field to the specified value.
-  *
-  * @param columns The new number of columns in the field.
-  *
-  * @exception IllegalArgumentException If columns is less than zero.
-  */
-public synchronized void
-setColumns(int columns)
-{
-  if (columns < 0)
-    throw new IllegalArgumentException("Value is less than zero: " +
-                                       columns);
-
-  this.columns = columns;
-  // FIXME: How to we communicate this to our peer?
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the number of rows in the field.
-  *
-  * @return The number of rows in the field.
-  */
-public int
-getRows()
-{
-  return(rows);
-}
-
-/*************************************************************************/
-
-/**
-  * Sets the number of rows in this field to the specified value.
-  *
-  * @param rows The new number of rows in the field.
-  *
-  * @exception IllegalArgumentException If rows is less than zero.
-  */
-public synchronized void
-setRows(int rows)
-{
-  if (rows < 1)
-    throw new IllegalArgumentException("Value is less than one: " +
-                                       rows);
-
-  this.rows = rows;
-  // FIXME: How to we communicate this to our peer?
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the minimum size for this text field.
-  *
-  * @return The minimum size for this text field.
-  */
-public Dimension
-getMinimumSize()
-{
-  return(getMinimumSize(getRows(), getColumns()));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the minimum size of a text field with the specified number
-  * of rows and columns.
-  *
-  * @param rows The number of rows to get the minimum size for.
-  * @param columns The number of columns to get the minimum size for.
-  */
-public Dimension
-getMinimumSize(int rows, int columns)
-{
-  TextAreaPeer tap = (TextAreaPeer)getPeer();
-  if (tap == null)
-    return(null); // FIXME: What do we do if there is no peer?
-
-  return(tap.getMinimumSize(rows, columns));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the minimum size for this text field.
-  *
-  * @return The minimum size for this text field.
-  *
-  * @deprecated This method is depcreated in favor of
-  * <code>getMinimumSize()</code>.
-  */
-public Dimension
-minimumSize()
-{
-  return(getMinimumSize(getRows(), getColumns()));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the minimum size of a text field with the specified number
-  * of rows and columns.
-  *
-  * @param rows The number of rows to get the minimum size for.
-  * @param columns The number of columns to get the minimum size for.
-  *
-  * @deprecated This method is deprecated in favor of 
-  * <code>getMinimumSize(int)</code>.
-  */
-public Dimension
-minimumSize(int rows, int columns)
-{
-  return(getMinimumSize(rows, columns));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the preferred size for this text field.
-  *
-  * @return The preferred size for this text field.
-  */
-public Dimension
-getPreferredSize()
-{
-  return(getPreferredSize(getRows(), getColumns()));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the preferred size of a text field with the specified number
-  * of rows and columns.
-  *
-  * @param rows The number of rows to get the preferred size for.
-  * @param columns The number of columns to get the preferred size for.
-  */
-public Dimension
-getPreferredSize(int rows, int columns)
-{
-  TextAreaPeer tap = (TextAreaPeer)getPeer();
-  if (tap == null)
-    {
-      // Sun's JDK just seems to return Dimension(0,0) in this case.
-      // we do the same.
-      return new Dimension(0, 0);
-    }
-
-  return(tap.getPreferredSize(rows, columns));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the preferred size for this text field.
-  *
-  * @return The preferred size for this text field.
-  *
-  * @deprecated This method is deprecated in favor of 
-  * <code>getPreferredSize()</code>.
-  */
-public Dimension
-preferredSize()
-{
-  return(getPreferredSize(getRows(), getColumns()));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns the preferred size of a text field with the specified number
-  * of rows and columns.
-  *
-  * @param rows The number of rows to get the preferred size for.
-  * @param columns The number of columns to get the preferred size for.
-  *
-  * @deprecated This method is deprecated in favor of 
-  * <code>getPreferredSize(int)</code>.
-  */
-public Dimension
-preferredSize(int rows, int columns)
-{
-  return(getPreferredSize(rows, columns));
-}
-
-/*************************************************************************/
-
-/**
-  * Returns one of the constants from this class indicating which
-  * types of scrollbars this object uses, if any.
-  *
-  * @return The scrollbar type constant for this object.
-  */
-public int
-getScrollbarVisibility()
-{
-  return(scrollbarVisibility);
-}
-
-/*************************************************************************/
-
-/**
-  * Notify this object that it should create its native peer.
-  */
-public void
-addNotify()
-{
-  if (getPeer() != null)
-    return;
-
-  setPeer((ComponentPeer)getToolkit().createTextArea(this));
-}
-
-/*************************************************************************/
-
-/**
-  * Appends the specified text to the end of the current text.
-  *
-  * @param text The text to append.
-  */
-public void
-append(String str)
-{
-  TextAreaPeer tap = (TextAreaPeer)getPeer();
-  if (tap == null) 
-    return;
-
-  tap.insert(str, tap.getText().length());
-}
-
-/*************************************************************************/
-
-/**
-  * Appends the specified text to the end of the current text.
-  *
-  * @param text The text to append.
-  *
-  * @deprecated This method is deprecated in favor of 
-  * <code>append()</code>.
-  */
-public void
-appendText(String text)
-{
-  append(text);
-}
- 
-/*************************************************************************/
-
-/**
-  * Inserts the specified text at the specified location.
-  *
-  * @param text The text to insert.
-  * @param pos The insert position.
-  */
-public void
-insert(String text, int pos)
-{
-  TextAreaPeer tap = (TextAreaPeer)getPeer();
-  if (tap == null)
-    return;
-
-  tap.insert(text, pos);
-}
-
-/*************************************************************************/
-
-/**
-  * Inserts the specified text at the specified location.
-  *
-  * @param text The text to insert.
-  * @param pos The insert position.
-  *
-  * @deprecated This method is depcreated in favor of <code>insert()</code>.
-  */
-public void
-insertText(String text, int pos)
-{
-  insert(text, pos);
-}
-
-/*************************************************************************/
-
-/**
-  * Replaces the text bounded by the specified start and end positions
-  * with the specified text.
-  *
-  * @param text The new text for the range.
-  * @param start The start position of the replacement range.
-  * @param end The end position of the replacement range.
-  */
-public void
-replaceRange(String text, int start, int end)
-{
-  TextAreaPeer tap = (TextAreaPeer)getPeer();
-  if (tap == null)
-    return;
-
-  tap.replaceRange(text, start, end);
-}
-
-/*************************************************************************/
-
-/**
-  * Replaces the text bounded by the specified start and end positions
-  * with the specified text.
-  *
-  * @param text The new text for the range.
-  * @param start The start position of the replacement range.
-  * @param end The end position of the replacement range.
-  *
-  * @deprecated This method is deprecated in favor of
-  * <code>replaceRange()</code>.
-  */
-public void
-replaceText(String text, int start, int end)
-{
-  replaceRange(text, start, end);
-}
-
-/*************************************************************************/
-
-/**
-  * Returns a debugging string for this text area.
-  *
-  * @return A debugging string for this text area.
-  */
-protected String
-paramString()
+public class TextArea extends TextComponent implements java.io.Serializable
 {
-  return(getClass().getName() + "(rows=" + getRows() + ",columns=" +
-         getColumns() + ",scrollbars=" + getScrollbarVisibility() +
-         ")");
+  /**
+   * Display both horiztonal and vertical scroll bars.
+   */
+  public static final int SCROLLBARS_BOTH = 0;
+
+  /**
+   * Display vertical scroll bar only.
+   */
+  public static final int SCROLLBARS_VERTICAL_ONLY = 1;
+
+  /**
+   * Display horizatonal scroll bar only.
+   */
+  public static final int SCROLLBARS_HORIZONTAL_ONLY = 2;
+
+  /**
+   * Do not display scrollbars.
+   */
+  public static final int SCROLLBARS_NONE = 3;
+
+  /**
+   * Serialization constant.
+   */
+  private static final long serialVersionUID = 3692302836626095722L;
+
+  /**
+   * @serial The number of columns used in this text area's preferred
+   * and minimum size calculations.
+   */
+  private int columns;
+
+  /**
+   * @serial The number of rows used in this text area's preferred and
+   * minimum size calculations.
+   */
+  private int rows;
+
+  /**
+   * @serial The scrollbar display policy.  One of SCROLLBARS_BOTH,
+   * SCROLLBARS_VERTICAL_ONLY, SCROLLBARS_HORIZONTAL_ONLY,
+   * SCROLLBARS_NONE.
+   */
+  private int scrollbarVisibility;
+
+  /*
+   * The number used to generate the name returned by getName.
+   */
+  private static transient long next_text_number = 0;
+
+  /**
+   * Initialize a new instance of <code>TextArea</code> that is empty.
+   * Conceptually the <code>TextArea</code> has 0 rows and 0 columns
+   * but its initial bounds are defined by its peer or by the
+   * container in which it is packed.  Both horizontal and vertical
+   * scrollbars will be displayed.
+   *
+   * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+   */
+  public TextArea ()
+  {
+    this ("", 0, 0, SCROLLBARS_BOTH);
+  }
+
+  /**
+   * Initialize a new instance of <code>TextArea</code> that contains
+   * the specified text.  Conceptually the <code>TextArea</code> has 0
+   * rows and 0 columns but its initial bounds are defined by its peer
+   * or by the container in which it is packed.  Both horizontal and
+   * veritcal scrollbars will be displayed.
+   *
+   * @param text The text to display in this text area.
+   *
+   * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+   */
+  public TextArea (String text)
+  {
+    this (text, 0, 0, SCROLLBARS_BOTH);
+  }
+
+  /**
+   * Initialize a new instance of <code>TextArea</code> that is empty
+   * and can display the specified number of rows and columns of text,
+   * without the need to scroll.  Both horizontal and vertical
+   * scrollbars will be displayed.
+   *
+   * @param rows The number of rows in this text area.
+   * @param columns The number of columns in this text area.
+   *
+   * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+   */
+  public TextArea (int rows, int columns)
+  {
+    this ("", rows, columns, SCROLLBARS_BOTH);
+  }
+
+  /**
+   * Initialize a new instance of <code>TextArea</code> that can
+   * display the specified number of rows and columns of text, without
+   * the need to scroll.  The TextArea initially contains the
+   * specified text.
+   *
+   * @param text The text to display in this text area.
+   * @param rows The number of rows in this text area.
+   * @param columns The number of columns in this text area.
+   *
+   * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+   */
+  public TextArea (String text, int rows, int columns)
+  {
+    this (text, rows, columns, SCROLLBARS_BOTH);
+  }
+
+  /**
+   * Initialize a new instance of <code>TextArea</code> that initially
+   * contains the specified text.  The TextArea can display the
+   * specified number of rows and columns of text, without the need to
+   * scroll.  This constructor allows specification of the scroll bar
+   * display policy.
+   *
+   * @param text The text to display in this text area.
+   * @param rows The number of rows in this text area.
+   * @param columns The number of columns in this text area.
+   * @param scrollbarVisibility The scroll bar display policy. One of
+   * SCROLLBARS_BOTH, SCROLLBARS_VERTICAL_ONLY,
+   * SCROLLBARS_HORIZONTAL_ONLY, SCROLLBARS_NONE.
+   *
+   * @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
+   */
+  public TextArea (String text, int rows, int columns, int scrollbarVisibility)
+  {
+    super (text);
+
+    if (GraphicsEnvironment.isHeadless ())
+      throw new HeadlessException ();
+
+    if (rows < 0 || columns < 0)
+      throw new IllegalArgumentException ("Bad row or column value");
+
+    if (scrollbarVisibility != SCROLLBARS_BOTH
+        && scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY
+        && scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY
+        && scrollbarVisibility != SCROLLBARS_NONE)
+      throw new IllegalArgumentException ("Bad scrollbar visibility value");
+
+    this.rows = rows;
+    this.columns = columns;
+    this.scrollbarVisibility = scrollbarVisibility;
+
+    // TextAreas need to receive tab key events so we override the
+    // default forward and backward traversal key sets.
+    Set s = new HashSet ();
+    s.add (AWTKeyStroke.getAWTKeyStroke (KeyEvent.VK_TAB,
+                                         KeyEvent.CTRL_DOWN_MASK));
+    setFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, s);
+    s = new HashSet ();
+    s.add (AWTKeyStroke.getAWTKeyStroke (KeyEvent.VK_TAB,
+                                         KeyEvent.SHIFT_DOWN_MASK
+                                         | KeyEvent.CTRL_DOWN_MASK));
+    setFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, s);
+  }
+
+  /**
+   * Retrieve the number of columns that this text area would prefer
+   * to display.  This value may or may not correspond to the number
+   * of columns that are actually displayed.
+   *
+   * @return The preferred number of columns.
+   */
+  public int getColumns ()
+  {
+    return columns;
+  }
+
+  /**
+   * Set the preferred number of columns for this text area.  This
+   * method does not cause the number of columns displayed by the text
+   * area to be updated, if the text area is currently visible.
+   *
+   * @param columns The preferred number of columns.
+   *
+   * @exception IllegalArgumentException If columns is less than zero.
+   */
+  public synchronized void setColumns (int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException ("Value is less than zero: "
+                                          + columns);
+
+    this.columns = columns;
+  }
+
+  /**
+   * Retrieve the number of rows that this text area would prefer to
+   * display.  This value may or may not correspond to the number of
+   * rows that are actually displayed.
+   *
+   * @return The preferred number of rows.
+   */
+  public int getRows ()
+  {
+    return rows;
+  }
+
+  /**
+   * Set the preferred number of rows for this text area.  This method
+   * does not cause the number of columns displayed by the text area
+   * to be updated, if the text area is currently visible.
+   *
+   * @param rows The preferred number of rows.
+   *
+   * @exception IllegalArgumentException If rows is less than zero.
+   */
+  public synchronized void setRows (int rows)
+  {
+    if (rows < 1)
+      throw new IllegalArgumentException ("Value is less than one: " + rows);
+
+    this.rows = rows;
+  }
+
+  /**
+   * Retrieve the minimum size for this text area, considering the
+   * text area's current row and column values.  A text area's minimum
+   * size depends on the number of rows and columns of text it would
+   * prefer to display, and on the size of the font in which the text
+   * would be displayed.
+   *
+   * @return The minimum size for this text field.
+   */
+  public Dimension getMinimumSize ()
+  {
+    return getMinimumSize (getRows (), getColumns ());
+  }
+
+  /**
+   * Retrieve the minimum size that this text area would have if its
+   * row and column values were equal to those specified.  A text
+   * area's minimum size depends on the number of rows and columns of
+   * text it would prefer to display, and on the size of the font in
+   * which the text would be displayed.
+   *
+   * @param rows The number of rows to use in the minimum size
+   * calculation.
+   * @param columns The number of columns to use in the minimum size
+   * calculation.
+   *
+   * @return The minimum size for this text area.
+   */
+  public Dimension getMinimumSize (int rows, int columns)
+  {
+    return minimumSize (rows, columns);
+  }
+
+  /**
+   * Retrieve the minimum size for this text area, considering the
+   * text area's current row and column values.  A text area's minimum
+   * size depends on the number of rows and columns of text it would
+   * prefer to display, and on the size of the font in which the text
+   * would be displayed.
+   *
+   * @return The minimum size for this text area.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>getMinimumSize ()</code>.
+   */
+  public Dimension minimumSize ()
+  {
+    return minimumSize (getRows (), getColumns ());
+  }
+
+  /**
+   * Retrieve the minimum size that this text area would have if its
+   * row and column values were equal to those specified.  A text
+   * area's minimum size depends on the number of rows and columns of
+   * text it would prefer to display, and on the size of the font in
+   * which the text would be displayed.
+   *
+   * @param rows The number of rows to use in the minimum size
+   * calculation.
+   * @param columns The number of columns to use in the minimum size
+   * calculation.
+   *
+   * @return The minimum size for this text area.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>getMinimumSize (int, int)</code>.
+   */
+  public Dimension minimumSize (int rows, int columns)
+  {
+    TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+    // Sun returns Dimension (0,0) in this case.
+    if (peer == null)
+      return new Dimension (0, 0);
+
+    return peer.getMinimumSize (rows, columns);
+  }
+
+  /**
+   * Retrieve the preferred size for this text area, considering the
+   * text area's current row and column values.  A text area's preferred
+   * size depends on the number of rows and columns of text it would
+   * prefer to display, and on the size of the font in which the text
+   * would be displayed.
+   *
+   * @return The preferred size for this text field.
+   */
+  public Dimension getPreferredSize ()
+  {
+    return getPreferredSize (getRows (), getColumns ());
+  }
+
+  /**
+   * Retrieve the preferred size that this text area would have if its
+   * row and column values were equal to those specified.  A text
+   * area's preferred size depends on the number of rows and columns
+   * of text it would prefer to display, and on the size of the font
+   * in which the text would be displayed.
+   *
+   * @param rows The number of rows to use in the preferred size
+   * calculation.
+   * @param columns The number of columns to use in the preferred size
+   * calculation.
+   *
+   * @return The preferred size for this text area.
+   */
+  public Dimension getPreferredSize (int rows, int columns)
+  {
+    return preferredSize (rows, columns);
+  }
+
+  /**
+   * Retrieve the preferred size for this text area, considering the
+   * text area's current row and column values.  A text area's preferred
+   * size depends on the number of rows and columns of text it would
+   * prefer to display, and on the size of the font in which the text
+   * would be displayed.
+   *
+   * @return The preferred size for this text field.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>getPreferredSize ()</code>.
+   */
+  public Dimension preferredSize ()
+  {
+    return preferredSize (getRows (), getColumns ());
+  }
+
+  /**
+   * Retrieve the preferred size that this text area would have if its
+   * row and column values were equal to those specified.  A text
+   * area's preferred size depends on the number of rows and columns
+   * of text it would prefer to display, and on the size of the font
+   * in which the text would be displayed.
+   *
+   * @param rows The number of rows to use in the preferred size
+   * calculation.
+   * @param columns The number of columns to use in the preferred size
+   * calculation.
+   *
+   * @return The preferred size for this text area.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>getPreferredSize (int, int)</code>.
+   */
+  public Dimension preferredSize (int rows, int columns)
+  {
+    TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+    // Sun returns Dimension (0,0) in this case.
+    if (peer == null)
+      return new Dimension (0, 0);
+
+    return peer.getPreferredSize (rows, columns);
+  }
+
+  /**
+   * Retrieve the scroll bar display policy -- one of SCROLLBARS_BOTH,
+   * SCROLLBARS_VERTICAL_ONLY, SCROLLBARS_HORIZONTAL_ONLY,
+   * SCROLLBARS_NONE.
+   *
+   * @return The current scroll bar display policy.
+   */
+  public int getScrollbarVisibility ()
+  {
+    return scrollbarVisibility;
+  }
+
+  /**
+   * Notify this object that it should create its native peer.
+   */
+  public void addNotify ()
+  {
+    if (getPeer () == null)
+      setPeer ((ComponentPeer) getToolkit().createTextArea (this));
+  }
+
+  /**
+   * Append the specified text to the end of the current text.
+   *
+   * @param str The text to append.
+   */
+  public void append (String str)
+  {
+    appendText (str);
+  }
+
+  /**
+   * Append the specified text to the end of the current text.
+   *
+   * @param str The text to append.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>append ()</code>.
+   */
+  public void appendText (String str)
+  {
+    TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+    if (peer != null)
+      peer.insert (str, peer.getText().length ());
+  }
+
+  /**
+   * Insert the specified text at the specified position.  The first
+   * character in the text area is at position zero.
+   *
+   * @param str The text to insert.
+   * @param pos The position at which to insert text.
+   */
+  public void insert (String str, int pos)
+  {
+    insertText (str, pos);
+  }
+
+  /**
+   * Insert the specified text at the specified position.  The first
+   * character in the text area is at position zero.
+   *
+   * @param str The text to insert.
+   * @param pos The position at which to insert text.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>insert ()</code>.
+   */
+  public void insertText (String str, int pos)
+  {
+    TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+    if (peer != null)
+      peer.insert (str, pos);
+  }
+
+  /**
+   * Replace a range of characters with the specified text.  The
+   * character at the start position will be replaced, unless start ==
+   * end.  The character at the end posistion will not be replaced.
+   * The first character in the text area is at position zero.  The
+   * length of the replacement text may differ from the length of the
+   * text that is replaced.
+   *
+   * @param str The new text for the range.
+   * @param start The start position of the replacement range.
+   * @param end The end position of the replacement range.
+   */
+  public void replaceRange (String str, int start, int end)
+  {
+    replaceText (str, start, end);
+  }
+
+  /**
+   * Replace a range of characters with the specified text.  The
+   * character at the start position will be replaced, unless start ==
+   * end.  The character at the end posistion will not be replaced.
+   * The first character in the text area is at position zero.  The
+   * length of the replacement text may differ from the length of the
+   * text that is replaced.
+   *
+   * @param str The new text for the range.
+   * @param start The start position of the replacement range.
+   * @param end The end position of the replacement range.
+   *
+   * @deprecated This method is deprecated in favor of
+   * <code>replaceRange ()</code>.
+   */
+  public void replaceText (String str, int start, int end)
+  {
+    TextAreaPeer peer = (TextAreaPeer) getPeer ();
+
+    if (peer != null)
+      peer.replaceRange (str, start, end);
+  }
+
+  /**
+   * Retrieve a debugging string for this text area.
+   *
+   * @return A debugging string for this text area.
+   */
+  protected String paramString ()
+  {
+    String sbVisibility = "";
+
+    switch (scrollbarVisibility)
+      {
+      case SCROLLBARS_BOTH:
+	sbVisibility = "both";
+	break;
+      case SCROLLBARS_VERTICAL_ONLY:
+	sbVisibility = "vertical-only";
+	break;
+      case SCROLLBARS_HORIZONTAL_ONLY:
+	sbVisibility = "horizontal-only";
+	break;
+      case SCROLLBARS_NONE:
+	sbVisibility = "none";
+	break;
+      }
+
+    String editable = "";
+    if (isEditable ())
+      editable = "editable,";
+
+    return getName () + "," + getX () + "," + getY () + "," + getWidth ()
+           + "x" + getHeight () + "," + "text=" + getText () + "," + editable
+           + "selection=" + getSelectionStart () + "-" + getSelectionEnd ()
+           + ",rows=" + rows + ",columns=" + columns + ",scrollbarVisibility="
+           + sbVisibility;
+  }
+
+  /**
+   * Generate a unique name for this text area.
+   *
+   * @return A unique name for this text area.
+   */
+  String generateName ()
+  {
+    return "text" + getUniqueLong ();
+  }
+
+  private static synchronized long getUniqueLong ()
+  {
+    return next_text_number++;
+  }
 }
-
-} // class TextArea 
-
Index: java/awt/TextComponent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/TextComponent.java,v
retrieving revision 1.11
diff -u -r1.11 TextComponent.java
--- java/awt/TextComponent.java	4 Dec 2003 19:31:01 -0000	1.11
+++ java/awt/TextComponent.java	6 Sep 2004 16:35:47 -0000
@@ -41,7 +41,6 @@
 import java.awt.event.TextEvent;
 import java.awt.event.TextListener;
 import java.awt.peer.TextComponentPeer;
-import java.awt.peer.ComponentPeer;
 import java.io.Serializable;
 import java.util.EventListener;
 
@@ -142,6 +141,7 @@
   TextComponentPeer tcp = (TextComponentPeer)getPeer();
   if (tcp != null)
     tcp.setText(text);
+  setCaretPosition(0);
 }
 
 /*************************************************************************/
@@ -234,11 +234,11 @@
   * specified start and end positions.  Illegal values for these
   * positions are silently fixed.
   *
-  * @param startSelection The new start position for the selected text.
-  * @param endSelection The new end position for the selected text.
+  * @param selectionStart The new start position for the selected text.
+  * @param selectionEnd The new end position for the selected text.
   */
 public synchronized void
-select(int selectionStart, int endSelection)
+select(int selectionStart, int selectionEnd)
 {
   if (selectionStart < 0)
     selectionStart = 0;
Index: java/awt/TextField.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/TextField.java,v
retrieving revision 1.8
diff -u -r1.8 TextField.java
--- java/awt/TextField.java	5 Jun 2003 19:58:39 -0000	1.8
+++ java/awt/TextField.java	6 Sep 2004 16:35:47 -0000
@@ -212,11 +212,7 @@
 public void
 setEchoChar(char echoChar)
 {
-  this.echoChar = echoChar;
-
-  TextFieldPeer tfp = (TextFieldPeer)getPeer();
-  if (tfp != null)
-    tfp.setEchoChar(echoChar);
+  setEchoCharacter (echoChar);
 }
 
 /*************************************************************************/
@@ -233,7 +229,11 @@
 public void
 setEchoCharacter(char echoChar)
 {
-  setEchoChar(echoChar);
+  this.echoChar = echoChar;
+
+  TextFieldPeer peer = (TextFieldPeer) getPeer ();
+  if (peer != null)
+    peer.setEchoChar (echoChar);
 }
 
 /*************************************************************************/
@@ -264,7 +264,7 @@
 public Dimension
 getMinimumSize()
 {
-  return(getMinimumSize(getColumns()));
+  return getMinimumSize (getColumns ());
 }
 
 /*************************************************************************/
@@ -278,11 +278,7 @@
 public Dimension
 getMinimumSize(int columns)
 {
-  TextFieldPeer tfp = (TextFieldPeer)getPeer();
-  if (tfp == null)
-    return(null); // FIXME: What do we do if there is no peer?
-
-  return(tfp.getMinimumSize(columns));
+  return minimumSize (columns);
 }
 
 /*************************************************************************/
@@ -292,13 +288,13 @@
   *
   * @return The minimum size for this text field.
   *
-  * @deprecated This method is depcreated in favor of
+  * @deprecated This method is deprecated in favor of
   * <code>getMinimumSize()</code>.
   */
 public Dimension
 minimumSize()
 {
-  return(getMinimumSize(getColumns()));
+  return minimumSize (getColumns ());
 }
 
 /*************************************************************************/
@@ -315,7 +311,11 @@
 public Dimension
 minimumSize(int columns)
 {
-  return(getMinimumSize(columns));
+  TextFieldPeer peer = (TextFieldPeer) getPeer ();
+  if (peer == null)
+    return null; // FIXME: What do we do if there is no peer?
+
+  return peer.getMinimumSize (columns);
 }
 
 /*************************************************************************/
@@ -328,7 +328,7 @@
 public Dimension
 getPreferredSize()
 {
-  return(getPreferredSize(getColumns()));
+  return getPreferredSize (getColumns ());
 }
 
 /*************************************************************************/
@@ -342,12 +342,7 @@
 public Dimension
 getPreferredSize(int columns)
 {
-  TextFieldPeer tfp = (TextFieldPeer)getPeer();
-  if (tfp == null)
-    {
-      return new Dimension(0, 0);
-    }
-  return(tfp.getPreferredSize(columns));
+  return preferredSize (columns);
 }
 
 /*************************************************************************/
@@ -363,7 +358,7 @@
 public Dimension
 preferredSize()
 {
-  return(getPreferredSize(getColumns()));
+  return preferredSize (getColumns ());
 }
 
 /*************************************************************************/
@@ -380,7 +375,11 @@
 public Dimension
 preferredSize(int columns)
 {
-  return(getPreferredSize(columns));
+  TextFieldPeer peer = (TextFieldPeer) getPeer ();
+  if (peer == null)
+    return new Dimension (0, 0);
+
+  return peer.getPreferredSize (columns);
 }
 
 /*************************************************************************/
Index: java/awt/Toolkit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Toolkit.java,v
retrieving revision 1.25
diff -u -r1.25 Toolkit.java
--- java/awt/Toolkit.java	18 Sep 2003 22:37:48 -0000	1.25
+++ java/awt/Toolkit.java	6 Sep 2004 16:35:47 -0000
@@ -1,5 +1,6 @@
 /* Toolkit.java -- AWT Toolkit superclass
-   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -365,15 +366,46 @@
 
   /**
    * Copies the current system colors into the specified array.  This is
-   * the interface used by the <code>SystemColors</code> class.
+   * the interface used by the <code>SystemColor</code> class.  Although
+   * this method fills in the array with some default colors a real Toolkit
+   * should override this method and provide real system colors for the
+   * native GUI platform.
    *
    * @param colors The array to copy the system colors into.
+   *               It must be at least 26 elements.
    *
    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+   *
+   * @see java.awt.SystemColor
    */
   protected void loadSystemColors(int systemColors[])
   {
-    // XXX Implement.
+    systemColors[SystemColor.DESKTOP]                 = 0xFF005C5C;
+    systemColors[SystemColor.ACTIVE_CAPTION]          = 0xFF000080;
+    systemColors[SystemColor.ACTIVE_CAPTION_TEXT]     = 0xFFFFFFFF;
+    systemColors[SystemColor.ACTIVE_CAPTION_BORDER]   = 0xFFC0C0C0;
+    systemColors[SystemColor.INACTIVE_CAPTION]        = 0xFF808080;
+    systemColors[SystemColor.INACTIVE_CAPTION_TEXT]   = 0xFFC0C0C0;
+    systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = 0xFFC0C0C0;
+    systemColors[SystemColor.WINDOW]                  = 0xFFFFFFFF;
+    systemColors[SystemColor.WINDOW_BORDER]           = 0xFF000000;
+    systemColors[SystemColor.WINDOW_TEXT]             = 0xFF000000;
+    systemColors[SystemColor.MENU]                    = 0xFFC0C0C0;
+    systemColors[SystemColor.MENU_TEXT]               = 0xFF000000;
+    systemColors[SystemColor.TEXT]                    = 0xFFC0C0C0;
+    systemColors[SystemColor.TEXT_TEXT]               = 0xFF000000;
+    systemColors[SystemColor.TEXT_HIGHLIGHT]          = 0xFF000090;
+    systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT]     = 0xFFFFFFFF;
+    systemColors[SystemColor.TEXT_INACTIVE_TEXT]      = 0xFF808080;
+    systemColors[SystemColor.CONTROL]                 = 0xFFC0C0C0;
+    systemColors[SystemColor.CONTROL_TEXT]            = 0xFF000000;
+    systemColors[SystemColor.CONTROL_HIGHLIGHT]       = 0xFFFFFFFF;
+    systemColors[SystemColor.CONTROL_LT_HIGHLIGHT]    = 0xFFE0E0E0;
+    systemColors[SystemColor.CONTROL_SHADOW]          = 0xFF808080;
+    systemColors[SystemColor.CONTROL_DK_SHADOW]       = 0xFF000000;
+    systemColors[SystemColor.SCROLLBAR]               = 0xFFE0E0E0;
+    systemColors[SystemColor.INFO]                    = 0xFFE0E000;
+    systemColors[SystemColor.INFO_TEXT]               = 0xFF000000;
   }
 
   /**
Index: java/awt/Window.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Window.java,v
retrieving revision 1.32
diff -u -r1.32 Window.java
--- java/awt/Window.java	24 Oct 2003 19:40:29 -0000	1.32
+++ java/awt/Window.java	6 Sep 2004 16:35:47 -0000
@@ -38,6 +38,9 @@
 
 package java.awt;
 
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowFocusListener;
 import java.awt.event.WindowListener;
@@ -82,6 +85,10 @@
   private transient GraphicsConfiguration graphicsConfiguration;
   private transient AccessibleContext accessibleContext;
 
+  private transient boolean shown;
+
+  private transient Component windowFocusOwner;
+
   /** 
    * This (package access) constructor is used by subclasses that want
    * to build windows that do not have parents.  Eg. toplevel
@@ -91,7 +98,37 @@
   Window()
   {
     visible = false;
+    // Windows are the only Containers that default to being focus
+    // cycle roots.
+    focusCycleRoot = true;
     setLayout(new BorderLayout());
+
+    addWindowFocusListener (new WindowAdapter ()
+      {
+        public void windowGainedFocus (WindowEvent event)
+        {
+          if (windowFocusOwner != null)
+            {
+              // FIXME: move this section and the other similar
+              // sections in Component into a separate method.
+              EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+              synchronized (eq)
+                {
+                  KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                  Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                  if (currentFocusOwner != null)
+                    {
+                      eq.postEvent (new FocusEvent (currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                                    false, windowFocusOwner));
+                      eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED,
+                                                    false, currentFocusOwner));
+                    }
+                  else
+                    eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED, false));
+                }
+            }
+        }
+      });
   }
 
   Window(GraphicsConfiguration gc)
@@ -241,6 +278,23 @@
     validate();
     super.show();
     toFront();
+
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+    manager.setGlobalFocusedWindow (this);
+
+    if (!shown)
+      {
+        FocusTraversalPolicy policy = getFocusTraversalPolicy ();
+        Component initialFocusOwner = null;
+
+        if (policy != null)
+          initialFocusOwner = policy.getInitialComponent (this);
+
+        if (initialFocusOwner != null)
+          initialFocusOwner.requestFocusInWindow (false);
+
+        shown = true;
+      }
   }
 
   public void hide()
@@ -626,10 +680,31 @@
    * @return The component that has focus, or <code>null</code> if no
    * component has focus.
    */
-  public Component getFocusOwner()
+  public Component getFocusOwner ()
   {
-    // FIXME
-    return null;
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    Window activeWindow = manager.getActiveWindow ();
+
+    // The currently-focused Component belongs to the active Window.
+    if (activeWindow == this)
+      return manager.getFocusOwner ();
+    else
+      return windowFocusOwner;
+  }
+
+  /**
+   * Set the focus owner for this window.  This method is used to
+   * remember which component was focused when this window lost
+   * top-level focus, so that when it regains top-level focus the same
+   * child component can be refocused.
+   *
+   * @param windowFocusOwner the component in this window that owns
+   * the focus.
+   */
+  void setFocusOwner (Component windowFocusOwner)
+  {
+    this.windowFocusOwner = windowFocusOwner;
   }
 
   /**
@@ -641,8 +716,7 @@
    */
   public boolean postEvent(Event e)
   {
-    // FIXME
-    return false;
+    return handleEvent (e);
   }
 
   /**
@@ -673,7 +747,8 @@
    */
   public void applyResourceBundle(String rbName)
   {
-    ResourceBundle rb = ResourceBundle.getBundle(rbName);
+    ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(),
+      ClassLoader.getSystemClassLoader());
     if (rb != null)
       applyResourceBundle(rb);    
   }
@@ -784,9 +859,23 @@
     if (this.x == x && this.y == y && width == w && height == h)
       return;
     invalidate();
+    boolean resized = width != w || height != h;
+    boolean moved = this.x != x || this.y != y;
     this.x = x;
     this.y = y;
     width = w;
     height = h;
+    if (resized)
+      {
+        ComponentEvent ce =
+          new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
+    if (moved)
+      {
+        ComponentEvent ce =
+          new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED);
+        getToolkit().getSystemEventQueue().postEvent(ce);
+      }
   }
 }
Index: java/awt/datatransfer/DataFlavor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/datatransfer/DataFlavor.java,v
retrieving revision 1.12
diff -u -r1.12 DataFlavor.java
--- java/awt/datatransfer/DataFlavor.java	8 Dec 2003 23:37:58 -0000	1.12
+++ java/awt/datatransfer/DataFlavor.java	6 Sep 2004 16:35:47 -0000
@@ -1,5 +1,5 @@
 /* DataFlavor.java -- A type of data to transfer via the clipboard.
-   Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -60,11 +60,7 @@
 {
   static final long serialVersionUID = 8367026044764648243L;
 
-// FIXME: Serialization: Need to write methods for.
-
-/*
- * Static Variables
- */
+  // FIXME: Serialization: Need to write methods for.
 
 /**
  * This is the data flavor used for tranferring plain text.  The MIME
@@ -90,6 +86,10 @@
  */
 public static final DataFlavor javaFileListFlavor;
 
+/**
+ * This is an image flavor used for transferring images.  The
+ * representation type is a <code>java.awt.Image</code>.
+ */
 public static final DataFlavor imageFlavor;
 
 /**
@@ -105,7 +105,7 @@
  * being transferred.
  */
 public static final String javaJVMLocalObjectMimeType =
-  "application/x-java-jvm-local-object";
+  "application/x-java-jvm-local-objectref";
 
 /**
  * This is the MIME type used to transfer a link to a remote object.
@@ -270,7 +270,7 @@
 /**
  * Initializes a new instance of <code>DataFlavor</code> with the
  * specified MIME type and description.  If the MIME type has a
- * "class=<rep class>" parameter then the representation class will
+ * "class=&lt;rep class&gt;" parameter then the representation class will
  * be the class name specified. Otherwise the class defaults to
  * <code>java.io.InputStream</code>. If the human readable name
  * is not specified (<code>null</code>) then the human readable name
@@ -319,7 +319,7 @@
 /**
  * Initializes a new instance of <code>DataFlavor</code> with the
  * specified MIME type and description.  If the MIME type has a
- * "class=<rep class>" parameter then the representation class will
+ * "class=&lt;rep class&gt;" parameter then the representation class will
  * be the class name specified. Otherwise the class defaults to
  * <code>java.io.InputStream</code>. If the human readable name
  * is not specified (<code>null</code>) then the human readable name
@@ -709,10 +709,10 @@
  * are met:
  * <p>
  * <ul>
- * <li>The object is not <code>null</code>.
- * <li>The object is an instance of <code>DataFlavor</code>.
+ * <li>The object is not <code>null</code>.</li>
+ * <li>The object is an instance of <code>DataFlavor</code>.</li>
  * <li>The object's MIME type and representation class are equal to
- * this object's.
+ * this object's.</li>
  * </ul>
  *
  * @param obj The <code>Object</code> to test against.
Index: java/awt/event/InvocationEvent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/event/InvocationEvent.java,v
retrieving revision 1.4
diff -u -r1.4 InvocationEvent.java
--- java/awt/event/InvocationEvent.java	9 Aug 2002 04:26:15 -0000	1.4
+++ java/awt/event/InvocationEvent.java	6 Sep 2004 16:35:48 -0000
@@ -189,8 +189,13 @@
         }
     else
       runnable.run();
-    if (notifier != null)
-      notifier.notifyAll();
+
+    Object o = notifier;
+    if (o != null)
+      synchronized(o)
+	{
+	  o.notifyAll();
+	}
   }
 
   /**
Index: java/awt/event/MouseEvent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/event/MouseEvent.java,v
retrieving revision 1.5
diff -u -r1.5 MouseEvent.java
--- java/awt/event/MouseEvent.java	9 Aug 2002 04:26:15 -0000	1.5
+++ java/awt/event/MouseEvent.java	6 Sep 2004 16:35:48 -0000
@@ -220,11 +220,11 @@
     if ((modifiers & EventModifier.OLD_MASK) != 0)
       {
         if ((modifiers & BUTTON1_MASK) != 0)
-          button = BUTTON1;
+          this.button = BUTTON1;
         else if ((modifiers & BUTTON2_MASK) != 0)
-          button = BUTTON2;
+          this.button = BUTTON2;
         else if ((modifiers & BUTTON3_MASK) != 0)
-          button = BUTTON3;
+          this.button = BUTTON3;
       }
   }
 
Index: java/awt/geom/AffineTransform.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/AffineTransform.java,v
retrieving revision 1.7
diff -u -r1.7 AffineTransform.java
--- java/awt/geom/AffineTransform.java	17 Sep 2003 19:06:55 -0000	1.7
+++ java/awt/geom/AffineTransform.java	6 Sep 2004 16:35:48 -0000
@@ -226,7 +226,7 @@
   private double m00;
 
   /**
-   * The Y coordinate scaling element of the transform matrix.
+   * The Y coordinate shearing element of the transform matrix.
    *
    * @serial matrix[1,0]
    */
@@ -240,7 +240,7 @@
   private double m01;
 
   /**
-   * The Y coordinate shearing element of the transform matrix.
+   * The Y coordinate scaling element of the transform matrix.
    *
    * @serial matrix[1,1]
    */
@@ -738,10 +738,10 @@
    */
   public void shear(double shx, double shy)
   {
-    double n00 = m00 + shx * m01;
-    double n01 = shx * m00 + m01;
-    double n10 = m10 * shy + m11;
-    double n11 = shx * m10 + m11;
+    double n00 = m00 + (shy * m01);
+    double n01 = m01 + (shx * m00);
+    double n10 = m10 + (shy * m11);
+    double n11 = m11 + (shx * m10);
     m00 = n00;
     m01 = n01;
     m10 = n10;
@@ -996,6 +996,38 @@
    * map multiple points to the same line or point). A transform exists only
    * if getDeterminant() has a non-zero value.
    *
+   * The inverse is calculated as:
+   * 
+   * <pre>
+   *
+   * Let A be the matrix for which we want to find the inverse:
+   *
+   * A = [ m00 m01 m02 ]
+   *     [ m10 m11 m12 ]
+   *     [ 0   0   1   ] 
+   *
+   *
+   *                 1    
+   * inverse (A) =  ---   x  adjoint(A) 
+   *                det 
+   *
+   *
+   *
+   *             =   1       [  m11  -m01   m01*m12-m02*m11  ]
+   *                ---   x  [ -m10   m00  -m00*m12+m10*m02  ]
+   *                det      [  0     0     m00*m11-m10*m01  ]
+   *
+   *
+   *
+   *             = [  m11/det  -m01/det   m01*m12-m02*m11/det ]
+   *               [ -m10/det   m00/det  -m00*m12+m10*m02/det ]
+   *               [   0           0          1               ]
+   *
+   *
+   * </pre>
+   *
+   *
+   *
    * @return a new inverse transform
    * @throws NoninvertibleTransformException if inversion is not possible
    * @see #getDeterminant()
@@ -1006,8 +1038,15 @@
     double det = getDeterminant();
     if (det == 0)
       throw new NoninvertibleTransformException("can't invert transform");
-    return new AffineTransform(m11 / det, -m10 / det, m01 / det, -m00 / det,
-                               -m02, -m12);
+    
+    double im00 = m11 / det;
+    double im10 = -m10 / det;
+    double im01 = -m01 / det;
+    double im11 = m00 / det;
+    double im02 = (m01 * m12 - m02 * m11) / det;
+    double im12 = (-m00 * m12 + m10 * m02) / det;
+    
+    return new AffineTransform (im00, im10, im01, im11, im02, im12);
   }
 
   /**
Index: java/awt/geom/Arc2D.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/Arc2D.java,v
retrieving revision 1.3
diff -u -r1.3 Arc2D.java
--- java/awt/geom/Arc2D.java	17 Sep 2003 19:06:55 -0000	1.3
+++ java/awt/geom/Arc2D.java	6 Sep 2004 16:35:49 -0000
@@ -50,7 +50,7 @@
  * and while the angle can be any value, the path iterator only traverses the
  * first 360 degrees. Storage is up to the subclasses.
  *
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
  * @since 1.2
  * @status updated to 1.4, but still missing functionality
  */
@@ -527,7 +527,7 @@
    * This class is used to iterate over an arc. Since ellipses are a subclass
    * of arcs, this is used by Ellipse2D as well.
    *
-   * @author Eric Blake <ebb9@email.byu.edu>
+   * @author Eric Blake (ebb9@email.byu.edu)
    */
   static final class ArcIterator implements PathIterator
   {
@@ -766,7 +766,7 @@
   /**
    * This class implements an arc in double precision.
    *
-   * @author Eric Blake <ebb9@email.byu.edu
+   * @author Eric Blake (ebb9@email.byu.edu)
    * @since 1.2
    */
   public static class Double extends Arc2D
@@ -985,7 +985,7 @@
   /**
    * This class implements an arc in float precision.
    *
-   * @author Eric Blake <ebb9@email.byu.edu
+   * @author Eric Blake (ebb9@email.byu.edu)
    * @since 1.2
    */
   public static class Float extends Arc2D
Index: java/awt/geom/CubicCurve2D.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/CubicCurve2D.java,v
retrieving revision 1.4
diff -u -r1.4 CubicCurve2D.java
--- java/awt/geom/CubicCurve2D.java	5 Jan 2004 19:19:29 -0000	1.4
+++ java/awt/geom/CubicCurve2D.java	6 Sep 2004 16:35:49 -0000
@@ -1,5 +1,5 @@
 /* CubicCurve2D.java -- represents a parameterized cubic curve in 2-D space
-   Copyright (C) 2002, 2003 Free Software Foundation
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package java.awt.geom;
 
 import java.awt.Rectangle;
@@ -53,12 +52,14 @@
  * @author Eric Blake (ebb9@email.byu.edu)
  * @author Graydon Hoare (graydon@redhat.com)
  * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
  *
  * @since 1.2
  */
-public abstract class CubicCurve2D
-  implements Shape, Cloneable
+public abstract class CubicCurve2D implements Shape, Cloneable
 {
+  private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+
   /**
    * Constructs a new CubicCurve2D. Typical users will want to
    * construct instances of a subclass, such as {@link
@@ -68,87 +69,74 @@
   {
   }
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s start
    * point.
    */
   public abstract double getX1();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s start
    * point.
    */
   public abstract double getY1();
 
-
   /**
    * Returns the curve&#x2019;s start point.
    */
   public abstract Point2D getP1();
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s first
    * control point.
    */
   public abstract double getCtrlX1();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s first
    * control point.
    */
   public abstract double getCtrlY1();
 
-
   /**
    * Returns the curve&#x2019;s first control point.
    */
   public abstract Point2D getCtrlP1();
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s second
    * control point.
    */
   public abstract double getCtrlX2();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s second
    * control point.
    */
   public abstract double getCtrlY2();
 
-
   /**
    * Returns the curve&#x2019;s second control point.
    */
   public abstract Point2D getCtrlP2();
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s end
    * point.
    */
   public abstract double getX2();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s end
    * point.
    */
   public abstract double getY2();
 
-
   /**
    * Returns the curve&#x2019;s end point.
    */
   public abstract Point2D getP2();
 
-
   /**
    * Changes the curve geometry, separately specifying each coordinate
    * value.
@@ -183,7 +171,6 @@
   public abstract void setCurve(double x1, double y1, double cx1, double cy1,
                                 double cx2, double cy2, double x2, double y2);
 
-
   /**
    * Changes the curve geometry, specifying coordinate values in an
    * array.
@@ -206,13 +193,11 @@
    */
   public void setCurve(double[] coords, int offset)
   {
-    setCurve(coords[offset++], coords[offset++],
-             coords[offset++], coords[offset++],
-             coords[offset++], coords[offset++],
+    setCurve(coords[offset++], coords[offset++], coords[offset++],
+             coords[offset++], coords[offset++], coords[offset++],
              coords[offset++], coords[offset++]);
   }
 
-
   /**
    * Changes the curve geometry, specifying coordinate values in
    * separate Point objects.
@@ -232,11 +217,10 @@
    */
   public void setCurve(Point2D p1, Point2D c1, Point2D c2, Point2D p2)
   {
-    setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(),
-             c2.getX(), c2.getY(), p2.getX(), p2.getY());
+    setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(), c2.getX(), c2.getY(),
+             p2.getX(), p2.getY());
   }
 
-
   /**
    * Changes the curve geometry, specifying coordinate values in an
    * array of Point objects.
@@ -258,12 +242,10 @@
    */
   public void setCurve(Point2D[] pts, int offset)
   {
-    setCurve(pts[offset].getX(), pts[offset++].getY(),
-             pts[offset].getX(), pts[offset++].getY(),
-             pts[offset].getX(), pts[offset++].getY(),
+    setCurve(pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(),
+             pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY(),
              pts[offset].getX(), pts[offset++].getY());
   }
-  
 
   /**
    * Changes the curve geometry to that of another curve.
@@ -276,7 +258,6 @@
              c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2());
   }
 
-
   /**
    * Calculates the squared flatness of a cubic curve, directly
    * specifying each coordinate value. The flatness is the maximal
@@ -309,7 +290,6 @@
                     Line2D.ptSegDistSq(x1, y1, x2, y2, cx2, cy2));
   }
 
-
   /**
    * Calculates the flatness of a cubic curve, directly specifying
    * each coordinate value. The flatness is the maximal distance of a
@@ -340,7 +320,6 @@
     return Math.sqrt(getFlatnessSq(x1, y1, cx1, cy1, cx2, cy2, x2, y2));
   }
 
-
   /**
    * Calculates the squared flatness of a cubic curve, specifying the
    * coordinate values in an array. The flatness is the maximal
@@ -374,13 +353,11 @@
    */
   public static double getFlatnessSq(double[] coords, int offset)
   {
-    return getFlatnessSq(coords[offset++], coords[offset++],
-                         coords[offset++], coords[offset++],
-                         coords[offset++], coords[offset++],
+    return getFlatnessSq(coords[offset++], coords[offset++], coords[offset++],
+                         coords[offset++], coords[offset++], coords[offset++],
                          coords[offset++], coords[offset++]);
   }
 
-
   /**
    * Calculates the flatness of a cubic curve, specifying the
    * coordinate values in an array. The flatness is the maximal
@@ -420,7 +397,6 @@
                                    coords[offset++], coords[offset++]));
   }
 
-
   /**
    * Calculates the squared flatness of this curve.  The flatness is
    * the maximal distance of a control point to the line between start
@@ -441,7 +417,6 @@
                          getCtrlX2(), getCtrlY2(), getX2(), getY2());
   }
 
-
   /**
    * Calculates the flatness of this curve.  The flatness is the
    * maximal distance of a control point to the line between start and
@@ -458,12 +433,10 @@
    */
   public double getFlatness()
   {
-    return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(),
-                                   getCtrlY1(), getCtrlX2(), getCtrlY2(),
-                                   getX2(), getY2()));
+    return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
+                                   getCtrlX2(), getCtrlY2(), getX2(), getY2()));
   }
 
-
   /**
    * Subdivides this curve into two halves.
    *
@@ -482,9 +455,11 @@
   public void subdivide(CubicCurve2D left, CubicCurve2D right)
   {
     // Use empty slots at end to share single array.
-    double[] d = new double[] { getX1(), getY1(), getCtrlX1(), getCtrlY1(),
-                                getCtrlX2(), getCtrlY2(), getX2(), getY2(),
-                                0, 0, 0, 0, 0, 0 };
+    double[] d = new double[]
+                 {
+                   getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(),
+                   getCtrlY2(), getX2(), getY2(), 0, 0, 0, 0, 0, 0
+                 };
     subdivide(d, 0, d, 0, d, 6);
     if (left != null)
       left.setCurve(d, 0);
@@ -492,7 +467,6 @@
       right.setCurve(d, 6);
   }
 
-
   /**
    * Subdivides a cubic curve into two halves.
    *
@@ -510,13 +484,12 @@
    * of <code>src</code>, or <code>null</code> if the caller is not
    * interested in the right half.
    */
-  public static void subdivide(CubicCurve2D src,
-                               CubicCurve2D left, CubicCurve2D right)
+  public static void subdivide(CubicCurve2D src, CubicCurve2D left,
+                               CubicCurve2D right)
   {
     src.subdivide(left, right);
   }
 
-
   /**
    * Subdivides a cubic curve into two halves, passing all coordinates
    * in an array.
@@ -563,18 +536,29 @@
    * index where the start point&#x2019;s <i>x</i> coordinate will be
    * stored.
    */
-  public static void subdivide(double[] src, int srcOff,
-                               double[] left, int leftOff,
-                               double[] right, int rightOff)
+  public static void subdivide(double[] src, int srcOff, double[] left,
+                               int leftOff, double[] right, int rightOff)
   {
     // To understand this code, please have a look at the image
     // "CubicCurve2D-3.png" in the sub-directory "doc-files".
-    double src_C1_x, src_C1_y, src_C2_x, src_C2_y;
-    double left_P1_x, left_P1_y;
-    double left_C1_x, left_C1_y, left_C2_x, left_C2_y;
-    double right_C1_x, right_C1_y, right_C2_x, right_C2_y;
-    double right_P2_x, right_P2_y;
-    double Mid_x, Mid_y; // Mid = left.P2 = right.P1
+    double src_C1_x;
+    double src_C1_y;
+    double src_C2_x;
+    double src_C2_y;
+    double left_P1_x;
+    double left_P1_y;
+    double left_C1_x;
+    double left_C1_y;
+    double left_C2_x;
+    double left_C2_y;
+    double right_C1_x;
+    double right_C1_y;
+    double right_C2_x;
+    double right_C2_y;
+    double right_P2_x;
+    double right_P2_y;
+    double Mid_x; // Mid = left.P2 = right.P1
+    double Mid_y; // Mid = left.P2 = right.P1
 
     left_P1_x = src[srcOff];
     left_P1_y = src[srcOff + 1];
@@ -599,31 +583,30 @@
     Mid_y = (left_C2_y + right_C1_y) / 2;
 
     if (left != null)
-    {
-      left[leftOff] = left_P1_x;
-      left[leftOff + 1] = left_P1_y;
-      left[leftOff + 2] = left_C1_x;
-      left[leftOff + 3] = left_C1_y;
-      left[leftOff + 4] = left_C2_x;
-      left[leftOff + 5] = left_C2_y;
-      left[leftOff + 6] = Mid_x;
-      left[leftOff + 7] = Mid_y;
-    }
+      {
+	left[leftOff] = left_P1_x;
+	left[leftOff + 1] = left_P1_y;
+	left[leftOff + 2] = left_C1_x;
+	left[leftOff + 3] = left_C1_y;
+	left[leftOff + 4] = left_C2_x;
+	left[leftOff + 5] = left_C2_y;
+	left[leftOff + 6] = Mid_x;
+	left[leftOff + 7] = Mid_y;
+      }
 
     if (right != null)
-    {
-      right[rightOff] = Mid_x;
-      right[rightOff + 1] = Mid_y;
-      right[rightOff + 2] = right_C1_x;
-      right[rightOff + 3] = right_C1_y;
-      right[rightOff + 4] = right_C2_x;
-      right[rightOff + 5] = right_C2_y;
-      right[rightOff + 6] = right_P2_x;
-      right[rightOff + 7] = right_P2_y;
-    }
+      {
+	right[rightOff] = Mid_x;
+	right[rightOff + 1] = Mid_y;
+	right[rightOff + 2] = right_C1_x;
+	right[rightOff + 3] = right_C1_y;
+	right[rightOff + 4] = right_C2_x;
+	right[rightOff + 5] = right_C2_y;
+	right[rightOff + 6] = right_P2_x;
+	right[rightOff + 7] = right_P2_y;
+      }
   }
 
-
   /**
    * Finds the non-complex roots of a cubic equation, placing the
    * results into the same array as the equation coefficients. The
@@ -670,7 +653,6 @@
     return solveCubic(eqn, eqn);
   }
 
-
   /**
    * Finds the non-complex roots of a cubic equation. The following
    * equation is being solved:
@@ -727,9 +709,19 @@
     // The Java implementation is very similar to the GSL code, but
     // not a strict one-to-one copy. For example, GSL would sort the
     // result.
-
-    double a, b, c, q, r, Q, R;
-    double c3, Q3, R2, CR2, CQ3;
+    
+    double a;
+    double b;
+    double c;
+    double q;
+    double r;
+    double Q;
+    double R;
+    double c3;
+    double Q3;
+    double R2;
+    double CR2;
+    double CQ3;
 
     // If the cubic coefficient is zero, we have a quadratic equation.
     c3 = eqn[3];
@@ -755,219 +747,267 @@
     CQ3 = 2916 * q * q * q;
 
     if (R == 0 && Q == 0)
-    {
-      // The GNU Scientific Library would return three identical
-      // solutions in this case.
-      res[0] = -a/3;
-      return 1;
-    }
-
-    if (CR2 == CQ3) 
-    {
-      /* this test is actually R2 == Q3, written in a form suitable
-         for exact computation with integers */
-
-      /* Due to finite precision some double roots may be missed, and
-         considered to be a pair of complex roots z = x +/- epsilon i
-         close to the real axis. */
-
-      double sqrtQ = Math.sqrt(Q);
-
-      if (R > 0)
       {
-        res[0] = -2 * sqrtQ - a/3;
-        res[1] = sqrtQ - a/3;
+	// The GNU Scientific Library would return three identical
+	// solutions in this case.
+	res[0] = -a / 3;
+	return 1;
       }
-      else
+
+    if (CR2 == CQ3)
       {
-        res[0] = -sqrtQ - a/3;
-        res[1] = 2 * sqrtQ - a/3;
+	/* this test is actually R2 == Q3, written in a form suitable
+	   for exact computation with integers */
+	/* Due to finite precision some double roots may be missed, and
+	   considered to be a pair of complex roots z = x +/- epsilon i
+	   close to the real axis. */
+	double sqrtQ = Math.sqrt(Q);
+
+	if (R > 0)
+	  {
+	    res[0] = -2 * sqrtQ - a / 3;
+	    res[1] = sqrtQ - a / 3;
+	  }
+	else
+	  {
+	    res[0] = -sqrtQ - a / 3;
+	    res[1] = 2 * sqrtQ - a / 3;
+	  }
+	return 2;
       }
-      return 2;
-    }
 
     if (CR2 < CQ3) /* equivalent to R2 < Q3 */
-    {
-      double sqrtQ = Math.sqrt(Q);
-      double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
-      double theta = Math.acos(R / sqrtQ3);
-      double norm = -2 * sqrtQ;
-      res[0] = norm * Math.cos(theta / 3) - a / 3;
-      res[1] = norm * Math.cos((theta + 2.0 * Math.PI) / 3) - a/3;
-      res[2] = norm * Math.cos((theta - 2.0 * Math.PI) / 3) - a/3;
+      {
+	double sqrtQ = Math.sqrt(Q);
+	double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
+	double theta = Math.acos(R / sqrtQ3);
+	double norm = -2 * sqrtQ;
+	res[0] = norm * Math.cos(theta / 3) - a / 3;
+	res[1] = norm * Math.cos((theta + 2.0 * Math.PI) / 3) - a / 3;
+	res[2] = norm * Math.cos((theta - 2.0 * Math.PI) / 3) - a / 3;
 
-      // The GNU Scientific Library sorts the results. We don't.
-      return 3;
-    }
+	// The GNU Scientific Library sorts the results. We don't.
+	return 3;
+      }
 
     double sgnR = (R >= 0 ? 1 : -1);
-    double A = -sgnR * Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0/3.0);
-    double B = Q / A ;
-    res[0] = A + B - a/3;
+    double A = -sgnR * Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
+    double B = Q / A;
+    res[0] = A + B - a / 3;
     return 1;
   }
 
-
   /**
-   * Determines whether a position lies inside the area that is bounded
+   * Determines whether a position lies inside the area bounded
    * by the curve and the straight line connecting its end points.
    *
    * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
    * alt="A drawing of the area spanned by the curve" />
    *
    * <p>The above drawing illustrates in which area points are
-   * considered &#x201c;contained&#x201d; in a CubicCurve2D.
+   * considered &#x201c;inside&#x201d; a CubicCurve2D.
    */
   public boolean contains(double x, double y)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().contains(x, y))
+      return false;
 
+    return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
+  }
 
   /**
-   * Determines whether a point lies inside the area that is bounded
+   * Determines whether a point lies inside the area bounded
    * by the curve and the straight line connecting its end points.
    *
    * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
    * alt="A drawing of the area spanned by the curve" />
    *
    * <p>The above drawing illustrates in which area points are
-   * considered &#x201c;contained&#x201d; in a CubicCurve2D.
+   * considered &#x201c;inside&#x201d; a CubicCurve2D.
    */
   public boolean contains(Point2D p)
   {
     return contains(p.getX(), p.getY());
   }
 
-
+  /**
+   * Determines whether any part of a rectangle is inside the area bounded
+   * by the curve and the straight line connecting its end points.
+   *
+   * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+   * alt="A drawing of the area spanned by the curve" />
+   *
+   * <p>The above drawing illustrates in which area points are
+   * considered &#x201c;inside&#x201d; in a CubicCurve2D.
+   * @see #contains(double, double)
+   */
   public boolean intersects(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().contains(x, y, w, h))
+      return false;
 
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, true, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+        || getAxisIntersections(x, y, false, h) != 0) /* left */
+      return true;
 
+    /* No intersections, is any point inside? */
+    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Determines whether any part of a Rectangle2D is inside the area bounded 
+   * by the curve and the straight line connecting its end points.
+   * @see #intersects(double, double, double, double)
+   */
   public boolean intersects(Rectangle2D r)
   {
     return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
-
+  /**
+   * Determine whether a rectangle is entirely inside the area that is bounded
+   * by the curve and the straight line connecting its end points.
+   *
+   * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+   * alt="A drawing of the area spanned by the curve" />
+   *
+   * <p>The above drawing illustrates in which area points are
+   * considered &#x201c;inside&#x201d; a CubicCurve2D.
+   * @see #contains(double, double)
+   */
   public boolean contains(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().intersects(x, y, w, h))
+      return false;
+
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, true, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+        || getAxisIntersections(x, y, false, h) != 0) /* left */
+      return false;
 
+    /* No intersections, is any point inside? */
+    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+      return true;
 
+    return false;
+  }
+
+  /**
+   * Determine whether a Rectangle2D is entirely inside the area that is 
+   * bounded by the curve and the straight line connecting its end points.
+   *
+   * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
+   * alt="A drawing of the area spanned by the curve" />
+   *
+   * <p>The above drawing illustrates in which area points are
+   * considered &#x201c;inside&#x201d; a CubicCurve2D.
+   * @see #contains(double, double)
+   */
   public boolean contains(Rectangle2D r)
   {
     return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
-
   /**
    * Determines the smallest rectangle that encloses the
-   * curve&#x2019;s start, end and control points. As the illustration
-   * below shows, the invisible control points may cause the bounds to
-   * be much larger than the area that is actually covered by the
-   * curve.
-   *
-   * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180"
-   * alt="An illustration of the bounds of a CubicCurve2D" />
+   * curve&#x2019;s start, end and control points.
    */
   public Rectangle getBounds()
   {
     return getBounds2D().getBounds();
   }
 
-
   public PathIterator getPathIterator(final AffineTransform at)
   {
     return new PathIterator()
-    {
-      /** Current coordinate. */
-      private int current = 0;
-
-      public int getWindingRule()
-      {
-        return WIND_NON_ZERO;
-      }
-
-      public boolean isDone()
       {
-        return current >= 2;
-      }
-
-      public void next()
-      {
-        current++;
-      }
+	/** Current coordinate. */
+	private int current = 0;
 
-      public int currentSegment(float[] coords)
-      {
-        int result;
-        switch (current)
-          {
-          case 0:
-            coords[0] = (float) getX1();
-            coords[1] = (float) getY1();
-            result = SEG_MOVETO;
-            break;            
-          case 1:
-            coords[0] = (float) getCtrlX1();
-            coords[1] = (float) getCtrlY1();
-            coords[2] = (float) getCtrlX2();
-            coords[3] = (float) getCtrlY2();
-            coords[4] = (float) getX2();
-            coords[5] = (float) getY2();
-            result = SEG_CUBICTO;
-            break;
-          default:
-            throw new NoSuchElementException("cubic iterator out of bounds");            
-          }
-        if (at != null)
-          at.transform(coords, 0, coords, 0, 3);
-        return result;
-      }
-
-      public int currentSegment(double[] coords)
-      {
-        int result;
-        switch (current)
-          {
-          case 0:
-            coords[0] = getX1();
-            coords[1] = getY1();
-            result = SEG_MOVETO;
-            break;
-          case 1:
-            coords[0] = getCtrlX1();
-            coords[1] = getCtrlY1();
-            coords[2] = getCtrlX2();
-            coords[3] = getCtrlY2();
-            coords[4] = getX2();
-            coords[5] = getY2();
-            result = SEG_CUBICTO;
-            break;
-          default:
-            throw new NoSuchElementException("cubic iterator out of bounds");
-          }        
-        if (at != null)
-          at.transform(coords, 0, coords, 0, 3);
-        return result;
-      }
-    };
+	public int getWindingRule()
+	{
+	  return WIND_NON_ZERO;
+	}
+
+	public boolean isDone()
+	{
+	  return current >= 2;
+	}
+
+	public void next()
+	{
+	  current++;
+	}
+
+	public int currentSegment(float[] coords)
+	{
+	  int result;
+	  switch (current)
+	    {
+	    case 0:
+	      coords[0] = (float) getX1();
+	      coords[1] = (float) getY1();
+	      result = SEG_MOVETO;
+	      break;
+	    case 1:
+	      coords[0] = (float) getCtrlX1();
+	      coords[1] = (float) getCtrlY1();
+	      coords[2] = (float) getCtrlX2();
+	      coords[3] = (float) getCtrlY2();
+	      coords[4] = (float) getX2();
+	      coords[5] = (float) getY2();
+	      result = SEG_CUBICTO;
+	      break;
+	    default:
+	      throw new NoSuchElementException("cubic iterator out of bounds");
+	    }
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 3);
+	  return result;
+	}
+
+	public int currentSegment(double[] coords)
+	{
+	  int result;
+	  switch (current)
+	    {
+	    case 0:
+	      coords[0] = getX1();
+	      coords[1] = getY1();
+	      result = SEG_MOVETO;
+	      break;
+	    case 1:
+	      coords[0] = getCtrlX1();
+	      coords[1] = getCtrlY1();
+	      coords[2] = getCtrlX2();
+	      coords[3] = getCtrlY2();
+	      coords[4] = getX2();
+	      coords[5] = getY2();
+	      result = SEG_CUBICTO;
+	      break;
+	    default:
+	      throw new NoSuchElementException("cubic iterator out of bounds");
+	    }
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 3);
+	  return result;
+	}
+      };
   }
 
-
   public PathIterator getPathIterator(AffineTransform at, double flatness)
   {
     return new FlatteningPathIterator(getPathIterator(at), flatness);
   }
 
-
   /**
    * Create a new curve with the same contents as this one.
    *
@@ -976,15 +1016,118 @@
   public Object clone()
   {
     try
-    {
-      return super.clone();
-    }
+      {
+	return super.clone();
+      }
     catch (CloneNotSupportedException e)
-    {
-      throw (Error) new InternalError().initCause(e); // Impossible
-    }
+      {
+	throw (Error) new InternalError().initCause(e); // Impossible
+      }
   }
 
+  /**
+   * Helper method used by contains() and intersects() methods, that
+   * returns the number of curve/line intersections on a given axis
+   * extending from a certain point.
+   *
+   * @param x x coordinate of the origin point
+   * @param y y coordinate of the origin point
+   * @param useYaxis axis used, if true the positive Y axis is used,
+   * false uses the positive X axis.
+   *
+   * This is an implementation of the line-crossings algorithm,
+   * Detailed in an article on Eric Haines' page:
+   * http://www.acm.org/tog/editors/erich/ptinpoly/
+   *
+   * A special-case not adressed in this code is self-intersections
+   * of the curve, e.g. if the axis intersects the self-itersection,
+   * the degenerate roots of the polynomial will erroneously count as 
+   * a single intersection of the curve, and not two.
+   */
+  private int getAxisIntersections(double x, double y, boolean useYaxis,
+                                   double distance)
+  {
+    int nCrossings = 0;
+    double a0;
+    double a1;
+    double a2;
+    double a3;
+    double b0;
+    double b1;
+    double b2;
+    double b3;
+    double[] r = new double[4];
+    int nRoots;
+
+    a0 = a3 = 0.0;
+
+    if (useYaxis)
+      {
+	a0 = getY1() - y;
+	a1 = getCtrlY1() - y;
+	a2 = getCtrlY2() - y;
+	a3 = getY2() - y;
+	b0 = getX1() - x;
+	b1 = getCtrlX1() - x;
+	b2 = getCtrlX2() - x;
+	b3 = getX2() - x;
+      }
+    else
+      {
+	a0 = getX1() - x;
+	a1 = getCtrlX1() - x;
+	a2 = getCtrlX2() - x;
+	a3 = getX2() - x;
+	b0 = getY1() - y;
+	b1 = getCtrlY1() - y;
+	b2 = getCtrlY2() - y;
+	b3 = getY2() - y;
+      }
+
+    /* If the axis intersects a start/endpoint, shift it up by some small 
+       amount to guarantee the line is 'inside'
+       If this is not done, bad behaviour may result for points on that axis.*/
+    if (a0 == 0.0 || a3 == 0.0)
+      {
+	double small = getFlatness() * (1E-10);
+	if (a0 == 0.0)
+	  a0 += small;
+	if (a3 == 0.0)
+	  a3 += small;
+      }
+
+    if (useYaxis)
+      {
+	if (Line2D.linesIntersect(b0, a0, b3, a3, 0.0, 0.0, distance, 0.0))
+	  nCrossings++;
+      }
+    else
+      {
+	if (Line2D.linesIntersect(a0, b0, a3, b3, 0.0, 0.0, 0.0, distance))
+	  nCrossings++;
+      }
+
+    r[0] = a0;
+    r[1] = 3 * (a1 - a0);
+    r[2] = 3 * (a2 + a0 - 2 * a1);
+    r[3] = a3 - 3 * a2 + 3 * a1 - a0;
+
+    if ((nRoots = solveCubic(r)) != 0)
+      for (int i = 0; i < nRoots; i++)
+        {
+	  double t = r[i];
+	  if (t >= 0.0 && t <= 1.0)
+	    {
+	      double crossing = -(t * t * t) * (b0 - 3 * b1 + 3 * b2 - b3)
+	                        + 3 * t * t * (b0 - 2 * b1 + b2)
+	                        + 3 * t * (b1 - b0) + b0;
+	      if (crossing > 0.0 && crossing <= distance)
+		nCrossings++;
+	    }
+        }
+
+    return (nCrossings);
+  }
 
   /**
    * A two-dimensional curve that is parameterized with a cubic
@@ -996,57 +1139,48 @@
    * @author Eric Blake (ebb9@email.byu.edu)
    * @author Sascha Brawer (brawer@dandelis.ch)
    */
-  public static class Double
-    extends CubicCurve2D
+  public static class Double extends CubicCurve2D
   {
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s start point.
      */
     public double x1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s start point.
      */
     public double y1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s first control point.
      */
     public double ctrlx1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s first control point.
      */
     public double ctrly1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s second control point.
      */
     public double ctrlx2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s second control point.
      */
     public double ctrly2;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s end point.
      */
     public double x2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s end point.
      */
     public double y2;
 
-
     /**
      * Constructs a new CubicCurve2D that stores its coordinate values
      * in double-precision floating-point format. All points are
@@ -1056,7 +1190,6 @@
     {
     }
 
-
     /**
      * Constructs a new CubicCurve2D that stores its coordinate values
      * in double-precision floating-point format, specifying the
@@ -1089,8 +1222,8 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
      */
-    public Double(double x1, double y1, double cx1, double cy1,
-                  double cx2, double cy2, double x2, double y2)
+    public Double(double x1, double y1, double cx1, double cy1, double cx2,
+                  double cy2, double x2, double y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -1102,7 +1235,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1112,7 +1244,6 @@
       return x1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1122,7 +1253,6 @@
       return y1;
     }
 
-
     /**
      * Returns the curve&#x2019;s start point.
      */
@@ -1131,7 +1261,6 @@
       return new Point2D.Double(x1, y1);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s first
      * control point.
@@ -1141,7 +1270,6 @@
       return ctrlx1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s first
      * control point.
@@ -1151,7 +1279,6 @@
       return ctrly1;
     }
 
-
     /**
      * Returns the curve&#x2019;s first control point.
      */
@@ -1160,7 +1287,6 @@
       return new Point2D.Double(ctrlx1, ctrly1);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s second
      * control point.
@@ -1170,7 +1296,6 @@
       return ctrlx2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s second
      * control point.
@@ -1180,7 +1305,6 @@
       return ctrly2;
     }
 
-
     /**
      * Returns the curve&#x2019;s second control point.
      */
@@ -1189,7 +1313,6 @@
       return new Point2D.Double(ctrlx2, ctrly2);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1199,7 +1322,6 @@
       return x2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1209,7 +1331,6 @@
       return y2;
     }
 
-
     /**
      * Returns the curve&#x2019;s end point.
      */
@@ -1218,7 +1339,6 @@
       return new Point2D.Double(x2, y2);
     }
 
-
     /**
      * Changes the curve geometry, separately specifying each coordinate
      * value.
@@ -1263,7 +1383,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Determines the smallest rectangle that encloses the
      * curve&#x2019;s start, end and control points. As the
@@ -1284,7 +1403,6 @@
     }
   }
 
-
   /**
    * A two-dimensional curve that is parameterized with a cubic
    * function and stores coordinate values in single-precision
@@ -1295,57 +1413,48 @@
    * @author Eric Blake (ebb9@email.byu.edu)
    * @author Sascha Brawer (brawer@dandelis.ch)
    */
-  public static class Float
-    extends CubicCurve2D
+  public static class Float extends CubicCurve2D
   {
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s start point.
      */
     public float x1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s start point.
      */
     public float y1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s first control point.
      */
     public float ctrlx1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s first control point.
      */
     public float ctrly1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s second control point.
      */
     public float ctrlx2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s second control point.
      */
     public float ctrly2;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s end point.
      */
     public float x2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s end point.
      */
     public float y2;
 
-
     /**
      * Constructs a new CubicCurve2D that stores its coordinate values
      * in single-precision floating-point format. All points are
@@ -1355,7 +1464,6 @@
     {
     }
 
-
     /**
      * Constructs a new CubicCurve2D that stores its coordinate values
      * in single-precision floating-point format, specifying the
@@ -1388,8 +1496,8 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
      */
-    public Float(float x1, float y1, float cx1, float cy1,
-                 float cx2, float cy2, float x2, float y2)
+    public Float(float x1, float y1, float cx1, float cy1, float cx2,
+                 float cy2, float x2, float y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -1401,7 +1509,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1411,7 +1518,6 @@
       return x1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1421,7 +1527,6 @@
       return y1;
     }
 
-
     /**
      * Returns the curve&#x2019;s start point.
      */
@@ -1430,7 +1535,6 @@
       return new Point2D.Float(x1, y1);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s first
      * control point.
@@ -1440,7 +1544,6 @@
       return ctrlx1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s first
      * control point.
@@ -1450,7 +1553,6 @@
       return ctrly1;
     }
 
-
     /**
      * Returns the curve&#x2019;s first control point.
      */
@@ -1459,7 +1561,6 @@
       return new Point2D.Float(ctrlx1, ctrly1);
     }
 
-
     /**
      * Returns the <i>s</i> coordinate of the curve&#x2019;s second
      * control point.
@@ -1469,7 +1570,6 @@
       return ctrlx2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s second
      * control point.
@@ -1479,7 +1579,6 @@
       return ctrly2;
     }
 
-
     /**
      * Returns the curve&#x2019;s second control point.
      */
@@ -1488,7 +1587,6 @@
       return new Point2D.Float(ctrlx2, ctrly2);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1498,7 +1596,6 @@
       return x2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1508,7 +1605,6 @@
       return y2;
     }
 
-
     /**
      * Returns the curve&#x2019;s end point.
      */
@@ -1517,7 +1613,6 @@
       return new Point2D.Float(x2, y2);
     }
 
-
     /**
      * Changes the curve geometry, separately specifying each coordinate
      * value as a double-precision floating-point number.
@@ -1562,7 +1657,6 @@
       this.y2 = (float) y2;
     }
 
-
     /**
      * Changes the curve geometry, separately specifying each coordinate
      * value as a single-precision floating-point number.
@@ -1594,8 +1688,8 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
      * point.
      */
-    public void setCurve(float x1, float y1, float cx1, float cy1,
-                         float cx2, float cy2, float x2, float y2)
+    public void setCurve(float x1, float y1, float cx1, float cy1, float cx2,
+                         float cy2, float x2, float y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -1607,7 +1701,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Determines the smallest rectangle that encloses the
      * curve&#x2019;s start, end and control points. As the
Index: java/awt/geom/GeneralPath.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/GeneralPath.java,v
retrieving revision 1.3
diff -u -r1.3 GeneralPath.java
--- java/awt/geom/GeneralPath.java	21 Oct 2003 13:18:22 -0000	1.3
+++ java/awt/geom/GeneralPath.java	6 Sep 2004 16:35:49 -0000
@@ -1,50 +1,80 @@
 /* GeneralPath.java -- represents a shape built from subpaths
-   Copyright (C) 2002, 2003 Free Software Foundation
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation
 
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
+   This file is part of GNU Classpath.
 
+   GNU Classpath is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GNU Classpath is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Classpath; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   Linking this library statically or dynamically with other modules is
+   making a combined work based on this library.  Thus, the terms and
+   conditions of the GNU General Public License cover the whole
+   combination.
+
+   As a special exception, the copyright holders of this library give you
+   permission to link this library with independent modules to produce an
+   executable, regardless of the license terms of these independent
+   modules, and to copy and distribute the resulting executable under
+   terms of your choice, provided that you also meet, for each linked
+   independent module, the terms and conditions of the license of that
+   module.  An independent module is a module which is not derived from
+   or based on this library.  If you modify this library, you may extend
+   this exception to your version of the library, but you are not
+   obligated to do so.  If you do not wish to do so, delete this
+   exception statement from your version. */
 
 package java.awt.geom;
 
 import java.awt.Rectangle;
 import java.awt.Shape;
 
+
 /**
- * STUBS ONLY
- * XXX Implement and document. Note that Sun's implementation only expects
- * float precision, not double.
+ * A general geometric path, consisting of any number of subpaths
+ * constructed out of straight lines and cubic or quadratic Bezier
+ * curves.
+ *
+ * <p>The inside of the curve is defined for drawing purposes by a winding
+ * rule. Either the WIND_EVEN_ODD or WIND_NON_ZERO winding rule can be chosen.
+ *
+ * <p><img src="doc-files/GeneralPath-1.png" width="300" height="210"
+ * alt="A drawing of a GeneralPath" />
+ * <p>The EVEN_ODD winding rule defines a point as inside a path if:
+ * A ray from the point towards infinity in an arbitrary direction
+ * intersects the path an odd number of times. Points <b>A</b> and
+ * <b>C</b> in the image are considered to be outside the path.
+ * (both intersect twice)
+ * Point <b>B</b> intersects once, and is inside.
+ *
+ * <p>The NON_ZERO winding rule defines a point as inside a path if:
+ * The path intersects the ray in an equal number of opposite directions.
+ * Point <b>A</b> in the image is outside (one intersection in the 
+ * &#x2019;up&#x2019;
+ * direction, one in the &#x2019;down&#x2019; direction) Point <b>B</b> in 
+ * the image is inside (one intersection &#x2019;down&#x2019;)
+ * Point <b>C</b> in the image is outside (two intersections 
+ * &#x2019;down&#x2019;)
+ *
+ * @see Line2D
+ * @see CubicCurve2D
+ * @see QuadCurve2D
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
  */
 public final class GeneralPath implements Shape, Cloneable
 {
@@ -52,35 +82,63 @@
   public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
 
   /** Initial size if not specified. */
-  private static final int INIT_SIZE = 20;
+  private static final int INIT_SIZE = 10;
+
+  /** A big number, but not so big it can't survive a few float operations */
+  private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
 
   /** The winding rule. */
   private int rule;
+
   /**
-   * The path type in points. Note that points[index] maps to
-   * types[index >> 1]; the control points of quad and cubic paths map as
+   * The path type in points. Note that xpoints[index] and ypoints[index] maps
+   * to types[index]; the control points of quad and cubic paths map as
    * well but are ignored.
    */
   private byte[] types;
+
   /**
    * The list of all points seen. Since you can only append floats, it makes
-   * sense for this to be a float[]. I have no idea why Sun didn't choose to
+   * sense for these to be float[]. I have no idea why Sun didn't choose to
    * allow a general path of double precision points.
+   * Note: Storing x and y coords seperately makes for a slower transforms,
+   * But it speeds up and simplifies box-intersection checking a lot.
    */
-  private float[] points;
+  private float[] xpoints;
+  private float[] ypoints;
+
   /** The index of the most recent moveto point, or null. */
   private int subpath = -1;
+
   /** The next available index into points. */
   private int index;
 
+  /**
+   * Constructs a GeneralPath with the default (NON_ZERO)
+   * winding rule and initial capacity (20).
+   */
   public GeneralPath()
   {
     this(WIND_NON_ZERO, INIT_SIZE);
   }
+
+  /**
+   * Constructs a GeneralPath with a specific winding rule
+   * and the default initial capacity (20).
+   * @param rule the winding rule (WIND_NON_ZERO or WIND_EVEN_ODD)
+   */
   public GeneralPath(int rule)
   {
     this(rule, INIT_SIZE);
   }
+
+  /**
+   * Constructs a GeneralPath with a specific winding rule
+   * and the initial capacity. The initial capacity should be
+   * the approximate number of path segments to be used.
+   * @param rule the winding rule (WIND_NON_ZERO or WIND_EVEN_ODD)
+   * @param capacity the inital capacity, in path segments
+   */
   public GeneralPath(int rule, int capacity)
   {
     if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
@@ -88,68 +146,112 @@
     this.rule = rule;
     if (capacity < INIT_SIZE)
       capacity = INIT_SIZE;
-    types = new byte[capacity >> 1];
-    points = new float[capacity];
+    types = new byte[capacity];
+    xpoints = new float[capacity];
+    ypoints = new float[capacity];
   }
+
+  /**
+   * Constructs a GeneralPath from an arbitrary shape object.
+   * The Shapes PathIterator path and winding rule will be used.
+   * @param s the shape
+   */
   public GeneralPath(Shape s)
   {
-    types = new byte[INIT_SIZE >> 1];
-    points = new float[INIT_SIZE];
+    types = new byte[INIT_SIZE];
+    xpoints = new float[INIT_SIZE];
+    ypoints = new float[INIT_SIZE];
     PathIterator pi = s.getPathIterator(null);
     setWindingRule(pi.getWindingRule());
     append(pi, false);
   }
 
+  /**
+   * Adds a new point to a path.
+   */
   public void moveTo(float x, float y)
   {
     subpath = index;
-    ensureSize(index + 2);
-    types[index >> 1] = PathIterator.SEG_MOVETO;
-    points[index++] = x;
-    points[index++] = y;
+    ensureSize(index + 1);
+    types[index] = PathIterator.SEG_MOVETO;
+    xpoints[index] = x;
+    ypoints[index++] = y;
   }
+
+  /**
+   * Appends a straight line to the current path.
+   * @param x x coordinate of the line endpoint.
+   * @param y y coordinate of the line endpoint.
+   */
   public void lineTo(float x, float y)
   {
-    ensureSize(index + 2);
-    types[index >> 1] = PathIterator.SEG_LINETO;
-    points[index++] = x;
-    points[index++] = y;
+    ensureSize(index + 1);
+    types[index] = PathIterator.SEG_LINETO;
+    xpoints[index] = x;
+    ypoints[index++] = y;
   }
+
+  /**
+   * Appends a quadratic Bezier curve to the current path.
+   * @param x1 x coordinate of the control point
+   * @param y1 y coordinate of the control point
+   * @param x2 x coordinate of the curve endpoint.
+   * @param y2 y coordinate of the curve endpoint.
+   */
   public void quadTo(float x1, float y1, float x2, float y2)
   {
-    ensureSize(index + 4);
-    types[index >> 1] = PathIterator.SEG_QUADTO;
-    points[index++] = x1;
-    points[index++] = y1;
-    points[index++] = x2;
-    points[index++] = y2;
-  }
-  public void curveTo(float x1, float y1, float x2, float y2,
-                      float x3, float y3)
-  {
-    ensureSize(index + 6);
-    types[index >> 1] = PathIterator.SEG_CUBICTO;
-    points[index++] = x1;
-    points[index++] = y1;
-    points[index++] = x2;
-    points[index++] = y2;
-    points[index++] = x3;
-    points[index++] = y3;
+    ensureSize(index + 2);
+    types[index] = PathIterator.SEG_QUADTO;
+    xpoints[index] = x1;
+    ypoints[index++] = y1;
+    xpoints[index] = x2;
+    ypoints[index++] = y2;
   }
+
+  /**
+   * Appends a cubic Bezier curve to the current path.
+   * @param x1 x coordinate of the first control point
+   * @param y1 y coordinate of the first control point
+   * @param x2 x coordinate of the second control point
+   * @param y2 y coordinate of the second control point
+   * @param x3 x coordinate of the curve endpoint.
+   * @param y3 y coordinate of the curve endpoint.
+   */
+  public void curveTo(float x1, float y1, float x2, float y2, float x3,
+                      float y3)
+  {
+    ensureSize(index + 3);
+    types[index] = PathIterator.SEG_CUBICTO;
+    xpoints[index] = x1;
+    ypoints[index++] = y1;
+    xpoints[index] = x2;
+    ypoints[index++] = y2;
+    xpoints[index] = x3;
+    ypoints[index++] = y3;
+  }
+
+  /**
+   * Closes the current subpath by drawing a line
+   * back to the point of the last moveTo.
+   */
   public void closePath()
   {
-    ensureSize(index + 2);
-    types[index >> 1] = PathIterator.SEG_CLOSE;
-    points[index++] = points[subpath];
-    points[index++] = points[subpath + 1];
+    ensureSize(index + 1);
+    types[index] = PathIterator.SEG_CLOSE;
+    xpoints[index] = xpoints[subpath];
+    ypoints[index++] = ypoints[subpath];
   }
 
+  /**
+   * Appends the segments of a Shape to the path. If <code>connect</code> is 
+   * true, the new path segments are connected to the existing one with a line.
+   * The winding rule of the Shape is ignored.
+   */
   public void append(Shape s, boolean connect)
   {
     append(s.getPathIterator(null), connect);
   }
 
-
   /**
    * Appends the segments of a PathIterator to this GeneralPath.
    * Optionally, the initial {@link PathIterator#SEG_MOVETO} segment
@@ -158,7 +260,7 @@
    *
    * @param iter the PathIterator specifying which segments shall be
    * appended.
-   * 
+   *
    * @param connect <code>true</code> for substituting the initial
    * {@link PathIterator#SEG_MOVETO} segment by a {@link
    * PathIterator#SEG_LINETO}, or <code>false</code> for not
@@ -171,50 +273,55 @@
   {
     // A bad implementation of this method had caused Classpath bug #6076.
     float[] f = new float[6];
-    while (!iter.isDone())
-    {
-      switch (iter.currentSegment(f))
+    while (! iter.isDone())
       {
-      case PathIterator.SEG_MOVETO:
-        if (!connect || (index == 0))
-        {
-          moveTo(f[0], f[1]);
-          break;
-        }
+	switch (iter.currentSegment(f))
+	  {
+	  case PathIterator.SEG_MOVETO:
+	    if (! connect || (index == 0))
+	      {
+		moveTo(f[0], f[1]);
+		break;
+	      }
+	    if ((index >= 1) && (types[index - 1] == PathIterator.SEG_CLOSE)
+	        && (f[0] == xpoints[index - 1])
+	        && (f[1] == ypoints[index - 1]))
+	      break;
+
+	  // Fall through.
+	  case PathIterator.SEG_LINETO:
+	    lineTo(f[0], f[1]);
+	    break;
+	  case PathIterator.SEG_QUADTO:
+	    quadTo(f[0], f[1], f[2], f[3]);
+	    break;
+	  case PathIterator.SEG_CUBICTO:
+	    curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
+	    break;
+	  case PathIterator.SEG_CLOSE:
+	    closePath();
+	    break;
+	  }
 
-        if ((index >= 2) && (types[(index - 2) >> 2] == PathIterator.SEG_CLOSE)
-            && (f[0] == points[index - 2]) && (f[1] == points[index - 1]))
-          break;
-        
-        // Fall through.
-
-      case PathIterator.SEG_LINETO:
-        lineTo(f[0], f[1]);
-        break;
-
-      case PathIterator.SEG_QUADTO:
-        quadTo(f[0], f[1], f[2], f[3]);
-        break;
-
-      case PathIterator.SEG_CUBICTO:
-        curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
-        break;
-
-      case PathIterator.SEG_CLOSE:
-        closePath();
-        break;
+	connect = false;
+	iter.next();
       }
-
-      connect = false;
-      iter.next();
-    }
   }
 
-
+  /**
+   * Returns the path&#x2019;s current winding rule.
+   */
   public int getWindingRule()
   {
     return rule;
   }
+
+  /**
+   * Sets the path&#x2019;s winding rule, which controls which areas are 
+   * considered &#x2019;inside&#x2019; or &#x2019;outside&#x2019; the path 
+   * on drawing. Valid rules are WIND_EVEN_ODD for an even-odd winding rule, 
+   * or WIND_NON_ZERO for a non-zero winding rule.
+   */
   public void setWindingRule(int rule)
   {
     if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
@@ -222,22 +329,48 @@
     this.rule = rule;
   }
 
+  /**
+   * Returns the current appending point of the path.
+   */
   public Point2D getCurrentPoint()
   {
     if (subpath < 0)
       return null;
-    return new Point2D.Float(points[index - 2], points[index - 1]);
+    return new Point2D.Float(xpoints[index - 1], ypoints[index - 1]);
   }
+
+  /**
+   * Resets the path. All points and segments are destroyed.
+   */
   public void reset()
   {
     subpath = -1;
     index = 0;
   }
 
+  /**
+   * Applies a transform to the path.
+   */
   public void transform(AffineTransform xform)
   {
-    xform.transform(points, 0, points, 0, index >> 1);
+    double nx;
+    double ny;
+    double[] m = new double[6];
+    xform.getMatrix(m);
+    for (int i = 0; i < index; i++)
+      {
+	nx = m[0] * xpoints[i] + m[2] * ypoints[i] + m[4];
+	ny = m[1] * xpoints[i] + m[3] * ypoints[i] + m[5];
+	xpoints[i] = (float) nx;
+	ypoints[i] = (float) ny;
+      }
   }
+
+  /**
+   * Creates a transformed version of the path.
+   * @param xform the transform to apply
+   * @return a new transformed GeneralPath
+   */
   public Shape createTransformedShape(AffineTransform xform)
   {
     GeneralPath p = new GeneralPath(this);
@@ -245,85 +378,174 @@
     return p;
   }
 
+  /**
+   * Returns the path&#x2019;s bounding box.
+   */
   public Rectangle getBounds()
   {
     return getBounds2D().getBounds();
   }
+
+  /**
+   * Returns the path&#x2019;s bounding box, in <code>float</code> precision
+   */
   public Rectangle2D getBounds2D()
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    float x1;
+    float y1;
+    float x2;
+    float y2;
+
+    if (index > 0)
+      {
+	x1 = x2 = xpoints[0];
+	y1 = y2 = ypoints[0];
+      }
+    else
+      x1 = x2 = y1 = y2 = 0.0f;
+
+    for (int i = 0; i < index; i++)
+      {
+	x1 = Math.min(xpoints[i], x1);
+	y1 = Math.min(ypoints[i], y1);
+	x2 = Math.max(xpoints[i], x2);
+	y2 = Math.max(ypoints[i], y2);
+      }
+    return (new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
   }
 
+  /**
+   * Evaluates if a point is within the GeneralPath,
+   * The NON_ZERO winding rule is used, regardless of the
+   * set winding rule.
+   * @param x x coordinate of the point to evaluate
+   * @param y y coordinate of the point to evaluate
+   * @return true if the point is within the path, false otherwise
+   */
   public boolean contains(double x, double y)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    return (getWindingNumber(x, y) != 0);
   }
+
+  /**
+   * Evaluates if a Point2D is within the GeneralPath,
+   * The NON_ZERO winding rule is used, regardless of the
+   * set winding rule.
+   * @param p The Point2D to evaluate
+   * @return true if the point is within the path, false otherwise
+   */
   public boolean contains(Point2D p)
   {
     return contains(p.getX(), p.getY());
   }
+
+  /**
+   * Evaluates if a rectangle is completely contained within the path.
+   * This method will return false in the cases when the box
+   * intersects an inner segment of the path.
+   * (i.e.: The method is accurate for the EVEN_ODD winding rule)
+   */
   public boolean contains(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    if (! getBounds2D().intersects(x, y, w, h))
+      return false;
+
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, false, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, true, h) != 0 /* right */
+        || getAxisIntersections(x, y, true, h) != 0) /* left */
+      return false;
+
+    /* No intersections, is any point inside? */
+    if (getWindingNumber(x, y) != 0)
+      return true;
+
+    return false;
   }
+
+  /**
+   * Evaluates if a rectangle is completely contained within the path.
+   * This method will return false in the cases when the box
+   * intersects an inner segment of the path.
+   * (i.e.: The method is accurate for the EVEN_ODD winding rule)
+   * @param r the rectangle
+   * @return <code>true</code> if the rectangle is completely contained
+   * within the path, <code>false</code> otherwise
+   */
   public boolean contains(Rectangle2D r)
   {
     return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
+  /**
+   * Evaluates if a rectangle intersects the path.
+   * @param x x coordinate of the rectangle
+   * @param y y coordinate of the rectangle
+   * @param w width of the rectangle
+   * @param h height of the rectangle
+   * @return <code>true</code> if the rectangle intersects the path,
+   * <code>false</code> otherwise
+   */
   public boolean intersects(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, false, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, true, h) != 0 /* right */
+        || getAxisIntersections(x, y, true, h) != 0) /* left */
+      return true;
+
+    /* No intersections, is any point inside? */
+    if (getWindingNumber(x, y) != 0)
+      return true;
+
+    return false;
   }
+
+  /**
+   * Evaluates if a Rectangle2D intersects the path.
+   * @param r The rectangle
+   * @return <code>true</code> if the rectangle intersects the path,
+   * <code>false</code> otherwise
+   */
   public boolean intersects(Rectangle2D r)
   {
     return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
-
   /**
    * A PathIterator that iterates over the segments of a GeneralPath.
    *
    * @author Sascha Brawer (brawer@dandelis.ch)
    */
-  private static class GeneralPathIterator
-    implements PathIterator
+  private static class GeneralPathIterator implements PathIterator
   {
     /**
      * The number of coordinate values for each segment type.
      */
-    private static final int[] NUM_COORDS =
-    {
-      /* 0: SEG_MOVETO */ 2,
-      /* 1: SEG_LINETO */ 2,
-      /* 2: SEG_QUADTO */ 4,
-      /* 3: SEG_CUBICTO */ 6,
-      /* 4: SEG_CLOSE */ 0
-    };
-
+    private static final int[] NUM_COORDS = { 
+                                            /* 0: SEG_MOVETO */ 1, 
+                                            /* 1: SEG_LINETO */ 1, 
+                                            /* 2: SEG_QUADTO */ 2, 
+                                            /* 3: SEG_CUBICTO */ 3, 
+                                            /* 4: SEG_CLOSE */ 0};
 
     /**
      * The GeneralPath whose segments are being iterated.
      */
     private final GeneralPath path;
 
-
     /**
      * The affine transformation used to transform coordinates.
      */
     private final AffineTransform transform;
 
-
     /**
      * The current position of the iterator.
      */
     private int pos;
 
-
     /**
      * Constructs a new iterator for enumerating the segments of a
      * GeneralPath.
@@ -338,7 +560,6 @@
       this.transform = transform;
     }
 
-
     /**
      * Returns the current winding rule of the GeneralPath.
      */
@@ -347,7 +568,6 @@
       return path.rule;
     }
 
-
     /**
      * Determines whether the iterator has reached the last segment in
      * the path.
@@ -357,7 +577,6 @@
       return pos >= path.index;
     }
 
-
     /**
      * Advances the iterator position by one segment.
      */
@@ -365,70 +584,72 @@
     {
       int seg;
 
-      /* Increment pos by the number of coordinate values. Note that
-       * we store two values even for a SEG_CLOSE segment, which is
-       * why we increment pos at least by 2. 
+      /*
+       * Increment pos by the number of coordinate pairs.
        */
-      seg = path.types[pos >> 1];
+      seg = path.types[pos];
       if (seg == SEG_CLOSE)
-        pos += 2;
+	pos++;
       else
-        pos += NUM_COORDS[seg];
+	pos += NUM_COORDS[seg];
     }
 
-
     /**
      * Returns the current segment in float coordinates.
      */
     public int currentSegment(float[] coords)
     {
-      int seg, numCoords;
+      int seg;
+      int numCoords;
 
-      seg = path.types[pos >> 1];
+      seg = path.types[pos];
       numCoords = NUM_COORDS[seg];
       if (numCoords > 0)
-      {
-        if (transform == null)
-          System.arraycopy(path.points, pos, coords, 0, numCoords);
-        else
-          transform.transform(/* src */ path.points, /* srcOffset */ pos,
-                              /* dest */ coords, /* destOffset */ 0,
-                              /* numPoints */ numCoords >> 1);
-      }
+        {
+	  for (int i = 0; i < numCoords; i++)
+	    {
+	      coords[i << 1] = path.xpoints[pos + i];
+	      coords[(i << 1) + 1] = path.ypoints[pos + i];
+	    }
+
+	  if (transform != null)
+	    transform.transform( /* src */
+	    coords, /* srcOffset */
+	    0, /* dest */ coords, /* destOffset */
+	    0, /* numPoints */ numCoords);
+        }
       return seg;
     }
 
-
     /**
      * Returns the current segment in double coordinates.
      */
     public int currentSegment(double[] coords)
     {
-      int seg, numCoords;
+      int seg;
+      int numCoords;
 
-      seg = path.types[pos >> 1];
+      seg = path.types[pos];
       numCoords = NUM_COORDS[seg];
       if (numCoords > 0)
-      {
-        if (transform == null)
         {
-          // System.arraycopy throws an exception if the source and destination
-          // array are not of the same primitive type.
-          for (int i = 0; i < numCoords; i++)
-            coords[i] = (double) path.points[pos + i];
+	  for (int i = 0; i < numCoords; i++)
+	    {
+	      coords[i << 1] = (double) path.xpoints[pos + i];
+	      coords[(i << 1) + 1] = (double) path.ypoints[pos + i];
+	    }
+	  if (transform != null)
+	    transform.transform( /* src */
+	    coords, /* srcOffset */
+	    pos, /* dest */ coords, /* destOffset */
+	    0, /* numPoints */ numCoords);
         }
-        else
-          transform.transform(/* src */ path.points, /* srcOffset */ pos,
-                              /* dest */ coords, /* destOffset */ 0,
-                              /* numPoints */ numCoords >> 1);
-      }
       return seg;
     }
   }
 
-
   /**
-   * Creates a PathIterator for iterating along the segments of this path.
+   * Creates a PathIterator for iterating along the segments of the path.
    *
    * @param at an affine transformation for projecting the returned
    * points, or <code>null</code> to let the created iterator return
@@ -439,15 +660,17 @@
     return new GeneralPathIterator(this, at);
   }
 
-
+  /**
+   * Creates a new FlatteningPathIterator for the path
+   */
   public PathIterator getPathIterator(AffineTransform at, double flatness)
   {
     return new FlatteningPathIterator(getPathIterator(at), flatness);
   }
 
   /**
-   * Create a new shape of the same run-time type with the same contents as
-   * this one.
+   * Creates a new shape of the same run-time type with the same contents 
+   * as this one.
    *
    * @return the clone
    *
@@ -461,17 +684,261 @@
     return new GeneralPath(this);
   }
 
+  /**
+   * Helper method - ensure the size of the data arrays,
+   * otherwise, reallocate new ones twice the size
+   */
   private void ensureSize(int size)
   {
     if (subpath < 0)
       throw new IllegalPathStateException("need initial moveto");
-    if (size <= points.length)
+    if (size <= xpoints.length)
       return;
-    byte[] b = new byte[points.length];
-    System.arraycopy(types, 0, b, 0, index >> 1);
+    byte[] b = new byte[types.length << 1];
+    System.arraycopy(types, 0, b, 0, index);
     types = b;
-    float[] f = new float[points.length << 1];
-    System.arraycopy(points, 0, f, 0, index);
-    points = f;
+    float[] f = new float[xpoints.length << 1];
+    System.arraycopy(xpoints, 0, f, 0, index);
+    xpoints = f;
+    f = new float[ypoints.length << 1];
+    System.arraycopy(ypoints, 0, f, 0, index);
+    ypoints = f;
+  }
+
+  /**
+   * Helper method - Get the total number of intersections from (x,y) along 
+   * a given axis, within a given distance.
+   */
+  private int getAxisIntersections(double x, double y, boolean useYaxis,
+                                   double distance)
+  {
+    return (evaluateCrossings(x, y, false, useYaxis, distance));
+  }
+
+  /**
+   * Helper method - returns the winding number of a point.
+   */
+  private int getWindingNumber(double x, double y)
+  {
+    /* Evaluate the crossings from x,y to infinity on the y axis (arbitrary 
+       choice). Note that we don't actually use Double.INFINITY, since that's 
+       slower, and may cause problems. */
+    return (evaluateCrossings(x, y, true, true, BIG_VALUE));
+  }
+
+  /**
+   * Helper method - evaluates the number of intersections on an axis from 
+   * the point (x,y) to the point (x,y+distance) or (x+distance,y).
+   * @param x x coordinate.
+   * @param y y coordinate.
+   * @param neg True if opposite-directed intersections should cancel, 
+   * false to sum all intersections.
+   * @param useYaxis Use the Y axis, false uses the X axis.
+   * @param distance Interval from (x,y) on the selected axis to find 
+   * intersections.
+   */
+  private int evaluateCrossings(double x, double y, boolean neg,
+                                boolean useYaxis, double distance)
+  {
+    float cx = 0.0f;
+    float cy = 0.0f;
+    float firstx = 0.0f;
+    float firsty = 0.0f;
+
+    int negative = (neg) ? -1 : 1;
+    double x0;
+    double x1;
+    double x2;
+    double x3;
+    double y0;
+    double y1;
+    double y2;
+    double y3;
+    double[] r = new double[4];
+    int nRoots;
+    double epsilon = 0.0;
+    int pos = 0;
+    int windingNumber = 0;
+    boolean pathStarted = false;
+
+    if (index == 0)
+      return (0);
+    if (useYaxis)
+      {
+	float[] swap1;
+	swap1 = ypoints;
+	ypoints = xpoints;
+	xpoints = swap1;
+	double swap2;
+	swap2 = y;
+	y = x;
+	x = swap2;
+      }
+
+    /* Get a value which is hopefully small but not insignificant relative
+     the path. */
+    epsilon = ypoints[0] * 1E-9;
+
+    pos = 0;
+    while (pos < index)
+      {
+	switch (types[pos])
+	  {
+	  case PathIterator.SEG_MOVETO:
+	    if (pathStarted) // close old path
+	      {
+		x0 = cx;
+		y0 = cy;
+		x1 = firstx;
+		y1 = firsty;
+
+		if (y0 == 0.0)
+		  y0 += epsilon;
+		if (y1 == 0.0)
+		  y1 += epsilon;
+		if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance,
+		                          0.0))
+		  windingNumber += (y1 < y0) ? 1 : negative;
+
+		cx = firstx;
+		cy = firsty;
+	      }
+	    cx = firstx = xpoints[pos] - (float) x;
+	    cy = firsty = ypoints[pos++] - (float) y;
+	    pathStarted = true;
+	    break;
+	  case PathIterator.SEG_CLOSE:
+	    x0 = cx;
+	    y0 = cy;
+	    x1 = firstx;
+	    y1 = firsty;
+
+	    if (y0 == 0.0)
+	      y0 += epsilon;
+	    if (y1 == 0.0)
+	      y1 += epsilon;
+	    if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance, 0.0))
+	      windingNumber += (y1 < y0) ? 1 : negative;
+
+	    cx = firstx;
+	    cy = firsty;
+	    pos++;
+	    pathStarted = false;
+	    break;
+	  case PathIterator.SEG_LINETO:
+	    x0 = cx;
+	    y0 = cy;
+	    x1 = xpoints[pos] - (float) x;
+	    y1 = ypoints[pos++] - (float) y;
+
+	    if (y0 == 0.0)
+	      y0 += epsilon;
+	    if (y1 == 0.0)
+	      y1 += epsilon;
+	    if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance, 0.0))
+	      windingNumber += (y1 < y0) ? 1 : negative;
+
+	    cx = xpoints[pos - 1] - (float) x;
+	    cy = ypoints[pos - 1] - (float) y;
+	    break;
+	  case PathIterator.SEG_QUADTO:
+	    x0 = cx;
+	    y0 = cy;
+	    x1 = xpoints[pos] - x;
+	    y1 = ypoints[pos++] - y;
+	    x2 = xpoints[pos] - x;
+	    y2 = ypoints[pos++] - y;
+
+	    /* check if curve may intersect X+ axis. */
+	    if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0)
+	        && (y0 * y1 <= 0 || y1 * y2 <= 0))
+	      {
+		if (y0 == 0.0)
+		  y0 += epsilon;
+		if (y2 == 0.0)
+		  y2 += epsilon;
+
+		r[0] = y0;
+		r[1] = 2 * (y1 - y0);
+		r[2] = (y2 - 2 * y1 + y0);
+
+		/* degenerate roots (=tangent points) do not
+		   contribute to the winding number. */
+		if ((nRoots = QuadCurve2D.solveQuadratic(r)) == 2)
+		  for (int i = 0; i < nRoots; i++)
+		    {
+		      float t = (float) r[i];
+		      if (t > 0.0f && t < 1.0f)
+		        {
+			  double crossing = t * t * (x2 - 2 * x1 + x0)
+			                    + 2 * t * (x1 - x0) + x0;
+			  if (crossing >= 0.0 && crossing <= distance)
+			    windingNumber += (2 * t * (y2 - 2 * y1 + y0)
+			                   + 2 * (y1 - y0) < 0) ? 1 : negative;
+		        }
+		    }
+	      }
+
+	    cx = xpoints[pos - 1] - (float) x;
+	    cy = ypoints[pos - 1] - (float) y;
+	    break;
+	  case PathIterator.SEG_CUBICTO:
+	    x0 = cx;
+	    y0 = cy;
+	    x1 = xpoints[pos] - x;
+	    y1 = ypoints[pos++] - y;
+	    x2 = xpoints[pos] - x;
+	    y2 = ypoints[pos++] - y;
+	    x3 = xpoints[pos] - x;
+	    y3 = ypoints[pos++] - y;
+
+	    /* check if curve may intersect X+ axis. */
+	    if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
+	        && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
+	      {
+		if (y0 == 0.0)
+		  y0 += epsilon;
+		if (y3 == 0.0)
+		  y3 += epsilon;
+
+		r[0] = y0;
+		r[1] = 3 * (y1 - y0);
+		r[2] = 3 * (y2 + y0 - 2 * y1);
+		r[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+		if ((nRoots = CubicCurve2D.solveCubic(r)) != 0)
+		  for (int i = 0; i < nRoots; i++)
+		    {
+		      float t = (float) r[i];
+		      if (t > 0.0 && t < 1.0)
+		        {
+			  double crossing = -(t * t * t) * (x0 - 3 * x1
+			                    + 3 * x2 - x3)
+			                    + 3 * t * t * (x0 - 2 * x1 + x2)
+			                    + 3 * t * (x1 - x0) + x0;
+			  if (crossing >= 0 && crossing <= distance)
+			    windingNumber += (3 * t * t * (y3 + 3 * y1
+			                     - 3 * y2 - y0)
+			                     + 6 * t * (y0 - 2 * y1 + y2)
+			                   + 3 * (y1 - y0) < 0) ? 1 : negative;
+		        }
+		    }
+	      }
+
+	    cx = xpoints[pos - 1] - (float) x;
+	    cy = ypoints[pos - 1] - (float) y;
+	    break;
+	  }
+      }
+
+    // swap coordinates back
+    if (useYaxis)
+      {
+	float[] swap;
+	swap = ypoints;
+	ypoints = xpoints;
+	xpoints = swap;
+      }
+    return (windingNumber);
   }
 } // class GeneralPath
Index: java/awt/geom/QuadCurve2D.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/QuadCurve2D.java,v
retrieving revision 1.6
diff -u -r1.6 QuadCurve2D.java
--- java/awt/geom/QuadCurve2D.java	5 Jan 2004 19:19:29 -0000	1.6
+++ java/awt/geom/QuadCurve2D.java	6 Sep 2004 16:35:49 -0000
@@ -1,5 +1,5 @@
 /* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space
-   Copyright (C) 2002, 2003 Free Software Foundation
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package java.awt.geom;
 
 import java.awt.Rectangle;
@@ -53,12 +52,14 @@
  * @author Eric Blake (ebb9@email.byu.edu)
  * @author Graydon Hoare (graydon@redhat.com)
  * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sven de Marothy (sven@physto.se)
  *
  * @since 1.2
  */
-public abstract class QuadCurve2D
-  implements Shape, Cloneable
+public abstract class QuadCurve2D implements Shape, Cloneable
 {
+  private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+
   /**
    * Constructs a new QuadCurve2D. Typical users will want to
    * construct instances of a subclass, such as {@link
@@ -68,67 +69,57 @@
   {
   }
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s start
    * point.
    */
   public abstract double getX1();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s start
    * point.
    */
   public abstract double getY1();
 
-
   /**
    * Returns the curve&#x2019;s start point.
    */
   public abstract Point2D getP1();
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s control
    * point.
    */
   public abstract double getCtrlX();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s control
    * point.
    */
   public abstract double getCtrlY();
 
-
   /**
    * Returns the curve&#x2019;s control point.
    */
   public abstract Point2D getCtrlPt();
 
-
   /**
    * Returns the <i>x</i> coordinate of the curve&#x2019;s end
    * point.
    */
   public abstract double getX2();
 
-
   /**
    * Returns the <i>y</i> coordinate of the curve&#x2019;s end
    * point.
    */
   public abstract double getY2();
 
-
   /**
    * Returns the curve&#x2019;s end point.
    */
   public abstract Point2D getP2();
 
-
   /**
    * Changes the curve geometry, separately specifying each coordinate
    * value.
@@ -154,7 +145,6 @@
   public abstract void setCurve(double x1, double y1, double cx, double cy,
                                 double x2, double y2);
 
-
   /**
    * Changes the curve geometry, passing coordinate values in an
    * array.
@@ -174,12 +164,10 @@
    */
   public void setCurve(double[] coords, int offset)
   {
-    setCurve(coords[offset++], coords[offset++],
-             coords[offset++], coords[offset++],
-             coords[offset++], coords[offset++]);
+    setCurve(coords[offset++], coords[offset++], coords[offset++],
+             coords[offset++], coords[offset++], coords[offset++]);
   }
 
-
   /**
    * Changes the curve geometry, specifying coordinate values in
    * separate Point objects.
@@ -198,11 +186,9 @@
    */
   public void setCurve(Point2D p1, Point2D c, Point2D p2)
   {
-    setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(),
-             p2.getX(), p2.getY());
+    setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY());
   }
 
-
   /**
    * Changes the curve geometry, specifying coordinate values in an
    * array of Point objects.
@@ -223,12 +209,11 @@
    */
   public void setCurve(Point2D[] pts, int offset)
   {
-    setCurve(pts[offset].getX(), pts[offset].getY(),
-             pts[offset + 1].getX(), pts[offset + 1].getY(),
-             pts[offset + 2].getX(), pts[offset + 2].getY());
+    setCurve(pts[offset].getX(), pts[offset].getY(), pts[offset + 1].getX(),
+             pts[offset + 1].getY(), pts[offset + 2].getX(),
+             pts[offset + 2].getY());
   }
 
-
   /**
    * Changes the geometry of the curve to that of another curve.
    *
@@ -236,11 +221,10 @@
    */
   public void setCurve(QuadCurve2D c)
   {
-    setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(),
-             c.getX2(), c.getY2());
+    setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(),
+             c.getY2());
   }
 
-
   /**
    * Calculates the squared flatness of a quadratic curve, directly
    * specifying each coordinate value. The flatness is the distance of
@@ -267,7 +251,6 @@
     return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);
   }
 
-
   /**
    * Calculates the flatness of a quadratic curve, directly specifying
    * each coordinate value. The flatness is the distance of the
@@ -294,7 +277,6 @@
     return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);
   }
 
-
   /**
    * Calculates the squared flatness of a quadratic curve, specifying
    * the coordinate values in an array. The flatness is the distance
@@ -328,7 +310,6 @@
                               coords[offset + 2], coords[offset + 3]);
   }
 
-
   /**
    * Calculates the flatness of a quadratic curve, specifying the
    * coordinate values in an array. The flatness is the distance of
@@ -362,7 +343,6 @@
                             coords[offset + 2], coords[offset + 3]);
   }
 
-
   /**
    * Calculates the squared flatness of this curve. The flatness is
    * the distance of the control point to the line between start and
@@ -378,12 +358,10 @@
    */
   public double getFlatnessSq()
   {
-    return Line2D.ptSegDistSq(getX1(), getY1(),
-                              getX2(), getY2(),
-                              getCtrlX(), getCtrlY());
+    return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
+                              getCtrlY());
   }
 
-
   /**
    * Calculates the flatness of this curve. The flatness is the
    * distance of the control point to the line between start and end
@@ -399,12 +377,10 @@
    */
   public double getFlatness()
   {
-    return Line2D.ptSegDist(getX1(), getY1(),
-                            getX2(), getY2(),
-                            getCtrlX(), getCtrlY());
+    return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
+                            getCtrlY());
   }
 
-
   /**
    * Subdivides this curve into two halves.
    *
@@ -423,8 +399,11 @@
   public void subdivide(QuadCurve2D left, QuadCurve2D right)
   {
     // Use empty slots at end to share single array.
-    double[] d = new double[] { getX1(), getY1(), getCtrlX(), getCtrlY(),
-                                getX2(), getY2(), 0, 0, 0, 0 };
+    double[] d = new double[]
+                 {
+                   getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(),
+                   0, 0, 0, 0
+                 };
     subdivide(d, 0, d, 0, d, 4);
     if (left != null)
       left.setCurve(d, 0);
@@ -432,7 +411,6 @@
       right.setCurve(d, 4);
   }
 
-
   /**
    * Subdivides a quadratic curve into two halves.
    *
@@ -456,7 +434,6 @@
     src.subdivide(left, right);
   }
 
-
   /**
    * Subdivides a quadratic curve into two halves, passing all
    * coordinates in an array.
@@ -500,11 +477,15 @@
    * index where the start point&#x2019;s <i>x</i> coordinate will be
    * stored.
    */
-  public static void subdivide(double[] src, int srcOff,
-                               double[] left, int leftOff,
-                               double[] right, int rightOff)
+  public static void subdivide(double[] src, int srcOff, double[] left,
+                               int leftOff, double[] right, int rightOff)
   {
-    double x1, y1, xc, yc, x2, y2;
+    double x1;
+    double y1;
+    double xc;
+    double yc;
+    double x2;
+    double y2;
 
     x1 = src[srcOff];
     y1 = src[srcOff + 1];
@@ -514,16 +495,16 @@
     y2 = src[srcOff + 5];
 
     if (left != null)
-    {
-      left[leftOff] = x1;
-      left[leftOff + 1] = y1;
-    }
+      {
+	left[leftOff] = x1;
+	left[leftOff + 1] = y1;
+      }
 
     if (right != null)
-    {
-      right[rightOff + 4] = x2;
-      right[rightOff + 5] = y2;
-    }
+      {
+	right[rightOff + 4] = x2;
+	right[rightOff + 5] = y2;
+      }
 
     x1 = (x1 + xc) / 2;
     x2 = (xc + x2) / 2;
@@ -533,23 +514,22 @@
     yc = (y1 + y2) / 2;
 
     if (left != null)
-    {
-      left[leftOff + 2] = x1;
-      left[leftOff + 3] = y1;
-      left[leftOff + 4] = xc;
-      left[leftOff + 5] = yc;
-    }
+      {
+	left[leftOff + 2] = x1;
+	left[leftOff + 3] = y1;
+	left[leftOff + 4] = xc;
+	left[leftOff + 5] = yc;
+      }
 
     if (right != null)
-    {
-      right[rightOff] = xc;
-      right[rightOff + 1] = yc;
-      right[rightOff + 2] = x2;
-      right[rightOff + 3] = y2;
-    }
+      {
+	right[rightOff] = xc;
+	right[rightOff + 1] = yc;
+	right[rightOff + 2] = x2;
+	right[rightOff + 3] = y2;
+      }
   }
 
-
   /**
    * Finds the non-complex roots of a quadratic equation, placing the
    * results into the same array as the equation coefficients. The
@@ -594,7 +574,6 @@
     return solveQuadratic(eqn, eqn);
   }
 
-
   /**
    * Finds the non-complex roots of a quadratic equation. The
    * following equation is being solved:
@@ -649,8 +628,10 @@
     // The Java implementation is very similar to the GSL code, but
     // not a strict one-to-one copy. For example, GSL would sort the
     // result.
-
-    double a, b, c, disc;
+    double a;
+    double b;
+    double c;
+    double disc;
 
     c = eqn[0];
     b = eqn[1];
@@ -661,13 +642,13 @@
     // wouldn't return -1 for constant functions, and 2 instead of 1
     // for linear functions.
     if (a == 0)
-    {
-      if (b == 0)
-        return -1;
-      
-      res[0] = -c / b;
-      return 1;
-    }
+      {
+	if (b == 0)
+	  return -1;
+
+	res[0] = -c / b;
+	return 1;
+      }
 
     disc = b * b - 4 * a * c;
 
@@ -675,96 +656,149 @@
       return 0;
 
     if (disc == 0)
-    {
-      // The GNU Scientific Library returns two identical results here.
-      // We just return one.
-      res[0] = -0.5 * b / a ;
-      return 1;
-    }
+      {
+	// The GNU Scientific Library returns two identical results here.
+	// We just return one.
+	res[0] = -0.5 * b / a;
+	return 1;
+      }
 
     // disc > 0
     if (b == 0)
-    {
-      double r;
+      {
+	double r;
 
-      r = Math.abs(0.5 * Math.sqrt(disc) / a);
-      res[0] = -r;
-      res[1] = r;
-    }
+	r = Math.abs(0.5 * Math.sqrt(disc) / a);
+	res[0] = -r;
+	res[1] = r;
+      }
     else
-    {
-      double sgnb, temp;
-      
-      sgnb = (b > 0 ? 1 : -1);
-      temp = -0.5 * (b + sgnb * Math.sqrt(disc));
-
-      // The GNU Scientific Library sorts the result here. We don't.
-      res[0] = temp / a;
-      res[1] = c / temp;
-    }
+      {
+	double sgnb;
+	double temp;
+
+	sgnb = (b > 0 ? 1 : -1);
+	temp = -0.5 * (b + sgnb * Math.sqrt(disc));
+
+	// The GNU Scientific Library sorts the result here. We don't.
+	res[0] = temp / a;
+	res[1] = c / temp;
+      }
     return 2;
   }
 
-
   /**
-   * Determines whether a point lies inside the area that is bounded
+   * Determines whether a point is inside the area bounded
    * by the curve and the straight line connecting its end points.
    *
    * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
    * alt="A drawing of the area spanned by the curve" />
    *
    * <p>The above drawing illustrates in which area points are
-   * considered &#x201c;contained&#x201d; in a QuadCurve2D.
+   * considered &#x201c;inside&#x201d; a QuadCurve2D.
    */
   public boolean contains(double x, double y)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().contains(x, y))
+      return false;
 
+    return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
+  }
 
   /**
-   * Determines whether a point lies inside the area that is bounded
+   * Determines whether a point is inside the area bounded
    * by the curve and the straight line connecting its end points.
    *
    * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
    * alt="A drawing of the area spanned by the curve" />
    *
    * <p>The above drawing illustrates in which area points are
-   * considered &#x201c;contained&#x201d; in a QuadCurve2D.
+   * considered &#x201c;inside&#x201d; a QuadCurve2D.
    */
   public boolean contains(Point2D p)
   {
     return contains(p.getX(), p.getY());
   }
 
-
+  /**
+   * Determines whether any part of a rectangle is inside the area bounded
+   * by the curve and the straight line connecting its end points.
+   *
+   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+   * alt="A drawing of the area spanned by the curve" />
+   *
+   * <p>The above drawing illustrates in which area points are
+   * considered &#x201c;inside&#x201d; in a CubicCurve2D.
+   */
   public boolean intersects(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().contains(x, y, w, h))
+      return false;
+
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, true, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+        || getAxisIntersections(x, y, false, h) != 0) /* left */
+      return true;
+
+    /* No intersections, is any point inside? */
+    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+      return true;
 
+    return false;
+  }
 
+  /**
+   * Determines whether any part of a Rectangle2D is inside the area bounded 
+   * by the curve and the straight line connecting its end points.
+   * @see #intersects(double, double, double, double)
+   */
   public boolean intersects(Rectangle2D r)
   {
     return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
-
+  /**
+   * Determines whether a rectangle is entirely inside the area bounded
+   * by the curve and the straight line connecting its end points.
+   *
+   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
+   * alt="A drawing of the area spanned by the curve" />
+   *
+   * <p>The above drawing illustrates in which area points are
+   * considered &#x201c;inside&#x201d; a QuadCurve2D.
+   * @see #contains(double, double)
+   */
   public boolean contains(double x, double y, double w, double h)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
-  }
+    if (! getBounds2D().intersects(x, y, w, h))
+      return false;
+
+    /* Does any edge intersect? */
+    if (getAxisIntersections(x, y, true, w) != 0 /* top */
+        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
+        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
+        || getAxisIntersections(x, y, false, h) != 0) /* left */
+      return false;
 
+    /* No intersections, is any point inside? */
+    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
+      return true;
+
+    return false;
+  }
 
+  /**
+   * Determines whether a Rectangle2D is entirely inside the area that is 
+   * bounded by the curve and the straight line connecting its end points.
+   * @see #contains(double, double, double, double)
+   */
   public boolean contains(Rectangle2D r)
   {
     return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
   }
 
-
   /**
    * Determines the smallest rectangle that encloses the
    * curve&#x2019;s start, end and control point. As the illustration
@@ -780,97 +814,85 @@
     return getBounds2D().getBounds();
   }
 
-
   public PathIterator getPathIterator(final AffineTransform at)
   {
     return new PathIterator()
-    {
-      /** Current coordinate. */
-      private int current = 0;
-
-
-      public int getWindingRule()
-      {
-        return WIND_NON_ZERO;
-      }
-
-
-      public boolean isDone()
-      {
-        return current >= 2;
-      }
-
-
-      public void next()
-      {
-        current++;
-      }
-
-
-      public int currentSegment(float[] coords)
       {
-        int result;
-        switch (current)
-        {
-        case 0:
-          coords[0] = (float) getX1();
-          coords[1] = (float) getY1();
-          result = SEG_MOVETO;
-          break;
-
-        case 1:
-          coords[0] = (float) getCtrlX();
-          coords[1] = (float) getCtrlY();
-          coords[2] = (float) getX2();
-          coords[3] = (float) getY2();
-          result = SEG_QUADTO;
-          break;
-
-        default:
-          throw new NoSuchElementException("quad iterator out of bounds");
-        }
-        if (at != null)
-          at.transform(coords, 0, coords, 0, 2);
-        return result;
-      }
-
+	/** Current coordinate. */
+	private int current = 0;
 
-      public int currentSegment(double[] coords)
-      {
-        int result;
-        switch (current)
-        {
-        case 0:
-          coords[0] = getX1();
-          coords[1] = getY1();
-          result = SEG_MOVETO;
-          break;
-
-        case 1:
-          coords[0] = getCtrlX();
-          coords[1] = getCtrlY();
-          coords[2] = getX2();
-          coords[3] = getY2();
-          result = SEG_QUADTO;
-          break;
-
-        default:
-          throw new NoSuchElementException("quad iterator out of bounds");
-        }
-        if (at != null)
-          at.transform(coords, 0, coords, 0, 2);
-        return result;
-      }
-    };
+	public int getWindingRule()
+	{
+	  return WIND_NON_ZERO;
+	}
+
+	public boolean isDone()
+	{
+	  return current >= 2;
+	}
+
+	public void next()
+	{
+	  current++;
+	}
+
+	public int currentSegment(float[] coords)
+	{
+	  int result;
+	  switch (current)
+	    {
+	    case 0:
+	      coords[0] = (float) getX1();
+	      coords[1] = (float) getY1();
+	      result = SEG_MOVETO;
+	      break;
+	    case 1:
+	      coords[0] = (float) getCtrlX();
+	      coords[1] = (float) getCtrlY();
+	      coords[2] = (float) getX2();
+	      coords[3] = (float) getY2();
+	      result = SEG_QUADTO;
+	      break;
+	    default:
+	      throw new NoSuchElementException("quad iterator out of bounds");
+	    }
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 2);
+	  return result;
+	}
+
+	public int currentSegment(double[] coords)
+	{
+	  int result;
+	  switch (current)
+	    {
+	    case 0:
+	      coords[0] = getX1();
+	      coords[1] = getY1();
+	      result = SEG_MOVETO;
+	      break;
+	    case 1:
+	      coords[0] = getCtrlX();
+	      coords[1] = getCtrlY();
+	      coords[2] = getX2();
+	      coords[3] = getY2();
+	      result = SEG_QUADTO;
+	      break;
+	    default:
+	      throw new NoSuchElementException("quad iterator out of bounds");
+	    }
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 2);
+	  return result;
+	}
+      };
   }
 
-
   public PathIterator getPathIterator(AffineTransform at, double flatness)
   {
     return new FlatteningPathIterator(getPathIterator(at), flatness);
   }
 
-
   /**
    * Creates a new curve with the same contents as this one.
    *
@@ -879,15 +901,106 @@
   public Object clone()
   {
     try
-    {
-      return super.clone();
-    }
+      {
+	return super.clone();
+      }
     catch (CloneNotSupportedException e)
-    {
-      throw (Error) new InternalError().initCause(e); // Impossible
-    }
+      {
+	throw (Error) new InternalError().initCause(e); // Impossible
+      }
   }
 
+  /**
+   * Helper method used by contains() and intersects() methods
+   * Return the number of curve/line intersections on a given axis
+   * extending from a certain point. useYaxis is true for using the Y axis,
+   * @param x x coordinate of the origin point
+   * @param y y coordinate of the origin point
+   * @param useYaxis axis to follow, if true the positive Y axis is used,
+   * false uses the positive X axis.
+   *
+   * This is an implementation of the line-crossings algorithm,
+   * Detailed in an article on Eric Haines' page:
+   * http://www.acm.org/tog/editors/erich/ptinpoly/
+   */
+  private int getAxisIntersections(double x, double y, boolean useYaxis,
+                                   double distance)
+  {
+    int nCrossings = 0;
+    double a0;
+    double a1;
+    double a2;
+    double b0;
+    double b1;
+    double b2;
+    double[] r = new double[3];
+    int nRoots;
+
+    a0 = a2 = 0.0;
+
+    if (useYaxis)
+      {
+	a0 = getY1() - y;
+	a1 = getCtrlY() - y;
+	a2 = getY2() - y;
+	b0 = getX1() - x;
+	b1 = getCtrlX() - x;
+	b2 = getX2() - x;
+      }
+    else
+      {
+	a0 = getX1() - x;
+	a1 = getCtrlX() - x;
+	a2 = getX2() - x;
+	b0 = getY1() - y;
+	b1 = getCtrlY() - y;
+	b2 = getY2() - y;
+      }
+
+    /* If the axis intersects a start/endpoint, shift it up by some small 
+       amount to guarantee the line is 'inside'
+       If this is not done,bad behaviour may result for points on that axis. */
+    if (a0 == 0.0 || a2 == 0.0)
+      {
+	double small = getFlatness() * (1E-10);
+	if (a0 == 0.0)
+	  a0 += small;
+
+	if (a2 == 0.0)
+	  a2 += small;
+      }
+
+    r[0] = a0;
+    r[1] = 2 * (a1 - a0);
+    r[2] = (a2 - 2 * a1 + a0);
+
+    nRoots = solveQuadratic(r);
+    for (int i = 0; i < nRoots; i++)
+      {
+	double t = r[i];
+	if (t >= 0.0 && t <= 1.0)
+	  {
+	    double crossing = t * t * (b2 - 2 * b1 + b0) + 2 * t * (b1 - b0)
+	                      + b0;
+	    /* single root is always doubly degenerate in quads */
+	    if (crossing > 0 && crossing < distance)
+	      nCrossings += (nRoots == 1) ? 2 : 1;
+	  }
+      }
+
+    if (useYaxis)
+      {
+	if (Line2D.linesIntersect(b0, a0, b2, a2, 0.0, 0.0, distance, 0.0))
+	  nCrossings++;
+      }
+    else
+      {
+	if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, 0.0, 0.0, distance))
+	  nCrossings++;
+      }
+
+    return (nCrossings);
+  }
 
   /**
    * A two-dimensional curve that is parameterized with a quadratic
@@ -899,45 +1012,38 @@
    * @author Eric Blake (ebb9@email.byu.edu)
    * @author Sascha Brawer (brawer@dandelis.ch)
    */
-  public static class Double
-    extends QuadCurve2D
+  public static class Double extends QuadCurve2D
   {
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s start point.
      */
     public double x1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s start point.
      */
     public double y1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s control point.
      */
     public double ctrlx;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s control point.
      */
     public double ctrly;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s end point.
      */
     public double x2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s end point.
      */
     public double y2;
 
-
     /**
      * Constructs a new QuadCurve2D that stores its coordinate values
      * in double-precision floating-point format. All points are
@@ -947,7 +1053,6 @@
     {
     }
 
-
     /**
      * Constructs a new QuadCurve2D that stores its coordinate values
      * in double-precision floating-point format, specifying the
@@ -971,8 +1076,8 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
      */
-    public Double(double x1, double y1, double cx, double cy,
-                  double x2, double y2)
+    public Double(double x1, double y1, double cx, double cy, double x2,
+                  double y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -982,7 +1087,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s start
      * point.
@@ -992,7 +1096,6 @@
       return x1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1002,7 +1105,6 @@
       return y1;
     }
 
-
     /**
      * Returns the curve&#x2019;s start point.
      */
@@ -1011,7 +1113,6 @@
       return new Point2D.Double(x1, y1);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s control
      * point.
@@ -1021,7 +1122,6 @@
       return ctrlx;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s control
      * point.
@@ -1031,7 +1131,6 @@
       return ctrly;
     }
 
-
     /**
      * Returns the curve&#x2019;s control point.
      */
@@ -1040,7 +1139,6 @@
       return new Point2D.Double(ctrlx, ctrly);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1050,7 +1148,6 @@
       return x2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1060,7 +1157,6 @@
       return y2;
     }
 
-
     /**
      * Returns the curve&#x2019;s end point.
      */
@@ -1069,7 +1165,6 @@
       return new Point2D.Double(x2, y2);
     }
 
-
     /**
      * Changes the geometry of the curve.
      *
@@ -1102,7 +1197,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Determines the smallest rectangle that encloses the
      * curve&#x2019;s start, end and control point. As the
@@ -1123,7 +1217,6 @@
     }
   }
 
-
   /**
    * A two-dimensional curve that is parameterized with a quadratic
    * function and stores coordinate values in single-precision
@@ -1134,45 +1227,38 @@
    * @author Eric Blake (ebb9@email.byu.edu)
    * @author Sascha Brawer (brawer@dandelis.ch)
    */
-  public static class Float
-    extends QuadCurve2D
+  public static class Float extends QuadCurve2D
   {
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s start point.
      */
     public float x1;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s start point.
      */
     public float y1;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s control point.
      */
     public float ctrlx;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s control point.
      */
     public float ctrly;
 
-
     /**
      * The <i>x</i> coordinate of the curve&#x2019;s end point.
      */
     public float x2;
 
-
     /**
      * The <i>y</i> coordinate of the curve&#x2019;s end point.
      */
     public float y2;
 
-
     /**
      * Constructs a new QuadCurve2D that stores its coordinate values
      * in single-precision floating-point format. All points are
@@ -1182,7 +1268,6 @@
     {
     }
 
-
     /**
      * Constructs a new QuadCurve2D that stores its coordinate values
      * in single-precision floating-point format, specifying the
@@ -1206,8 +1291,7 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
      */
-    public Float(float x1, float y1, float cx, float cy,
-                 float x2, float y2)
+    public Float(float x1, float y1, float cx, float cy, float x2, float y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -1217,7 +1301,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1227,7 +1310,6 @@
       return x1;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s start
      * point.
@@ -1237,7 +1319,6 @@
       return y1;
     }
 
-
     /**
      * Returns the curve&#x2019;s start point.
      */
@@ -1246,7 +1327,6 @@
       return new Point2D.Float(x1, y1);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s control
      * point.
@@ -1256,7 +1336,6 @@
       return ctrlx;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s control
      * point.
@@ -1266,7 +1345,6 @@
       return ctrly;
     }
 
-
     /**
      * Returns the curve&#x2019;s control point.
      */
@@ -1275,7 +1353,6 @@
       return new Point2D.Float(ctrlx, ctrly);
     }
 
-
     /**
      * Returns the <i>x</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1285,7 +1362,6 @@
       return x2;
     }
 
-
     /**
      * Returns the <i>y</i> coordinate of the curve&#x2019;s end
      * point.
@@ -1295,7 +1371,6 @@
       return y2;
     }
 
-
     /**
      * Returns the curve&#x2019;s end point.
      */
@@ -1304,7 +1379,6 @@
       return new Point2D.Float(x2, y2);
     }
 
-
     /**
      * Changes the geometry of the curve, specifying coordinate values
      * as double-precision floating-point numbers.
@@ -1338,7 +1412,6 @@
       this.y2 = (float) y2;
     }
 
-
     /**
      * Changes the geometry of the curve, specifying coordinate values
      * as single-precision floating-point numbers.
@@ -1361,8 +1434,8 @@
      * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
      * end point.
      */
-    public void setCurve(float x1, float y1, float cx, float cy,
-                         float x2, float y2)
+    public void setCurve(float x1, float y1, float cx, float cy, float x2,
+                         float y2)
     {
       this.x1 = x1;
       this.y1 = y1;
@@ -1372,7 +1445,6 @@
       this.y2 = y2;
     }
 
-
     /**
      * Determines the smallest rectangle that encloses the
      * curve&#x2019;s start, end and control point. As the
Index: java/awt/geom/RoundRectangle2D.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/geom/RoundRectangle2D.java,v
retrieving revision 1.5
diff -u -r1.5 RoundRectangle2D.java
--- java/awt/geom/RoundRectangle2D.java	26 Sep 2003 15:14:21 -0000	1.5
+++ java/awt/geom/RoundRectangle2D.java	6 Sep 2004 16:35:49 -0000
@@ -1,5 +1,5 @@
 /* RoundRectangle2D.java -- represents a rectangle with rounded corners
-   Copyright (C) 2000, 2002, 2003 Free Software Foundation
+   Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -39,6 +39,7 @@
 
 import java.util.NoSuchElementException;
 
+
 /** This class implements a rectangle with rounded corners.
  * @author Tom Tromey <tromey@cygnus.com>
  * @date December 3, 2000
@@ -60,12 +61,12 @@
    * @param arcHeight The arc height
    */
   public abstract void setRoundRect(double x, double y, double w, double h,
-                                     double arcWidth, double arcHeight);
+                                    double arcWidth, double arcHeight);
 
   /** Create a RoundRectangle2D.  This is protected because this class
    * is abstract and cannot be instantiated.
    */
-  protected  RoundRectangle2D()
+  protected RoundRectangle2D()
   {
   }
 
@@ -87,8 +88,11 @@
     // Now check to see if the point is in range of an arc.
     double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y));
     double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x));
-    double aw = getArcWidth();
-    double ah = getArcHeight();
+
+    // The arc dimensions are that of the corresponding ellipse
+    // thus a 90 degree segment is half of that.
+    double aw = getArcWidth() / 2.0;
+    double ah = getArcHeight() / 2.0;
     if (dx > aw || dy > ah)
       return true;
 
@@ -112,8 +116,8 @@
   {
     // We have to check all four points here (for ordinary rectangles
     // we can just check opposing corners).
-    return (contains(x, y) && contains(x + w, h)
-            && contains(x, y + h) && contains(x + w, y + h));
+    return (contains(x, y) && contains(x, y + h) && contains(x + w, y + h)
+           && contains(x + w, y));
   }
 
   /** Return a new path iterator which iterates over this rectangle.
@@ -128,154 +132,161 @@
     final double arcwidth = getArcWidth();
     final double archeight = getArcHeight();
     return new PathIterator()
-    {
-      /** We iterate clockwise around the rectangle, starting in the
-       * upper left.  This variable tracks our current point, which
-       * can be on either side of a given corner.  */
-      private int current = 0;
-
-      /** Child path iterator, used for corners.  */
-      private PathIterator corner;
-
-      /** This is used when rendering the corners.  We re-use the arc
-       * for each corner.  */
-      private Arc2D arc = new Arc2D.Double();
-
-      /** Temporary array used by getPoint.  */
-      private double[] temp = new double[2];
-
-      public int getWindingRule()
-      {
-	return WIND_NON_ZERO;
-      }
-
-      public boolean isDone()
-      {
-	return current > 9;
-      }
-
-      private void getPoint(int val)
-      {
-	switch (val)
-	  {
-	  case 0:
-	  case 8:
-	    temp[0] = minx;
-	    temp[1] = miny + archeight;
-	    break;
-	  case 1:
-	    temp[0] = minx + arcwidth;
-	    temp[1] = miny;
-	    break;
-	  case 2:
-	    temp[0] = maxx - arcwidth;
-	    temp[1] = maxy;
-	    break;
-	  case 3:
-	    temp[0] = maxx;
-	    temp[1] = miny + archeight;
-	    break;
-	  case 4:
-	    temp[0] = maxx;
-	    temp[1] = maxy - archeight;
-	    break;
-	  case 5:
-	    temp[0] = maxx - arcwidth;
-	    temp[1] = maxy;
-	    break;
-	  case 6:
-	    temp[0] = minx + arcwidth;
-	    temp[1] = maxy;
-	    break;
-	  case 7:
-	    temp[0] = minx;
-	    temp[1] = maxy - archeight;
-	    break;
-	  }
-      }
-
-      public void next()
-      {
-	if (current >= 8)
-	  ++current;
-	else if (corner != null)
-	  {
-	    // We're iterating through the corner.  Work on the child
-	    // iterator; if it finishes, reset and move to the next
-	    // point along the rectangle.
-	    corner.next();
-	    if (corner.isDone())
-	      {
-		corner = null;
-		++current;
-	      }
-	  }
-	else
-	  {
-	    // Make an arc between this point on the rectangle and
-	    // the next one, and then iterate over this arc.
-	    getPoint(current);
-	    double x1 = temp[0];
-	    double y1 = temp[1];
-	    getPoint(current + 1);
-	    arc.setFrameFromDiagonal(x1, y1, temp[0], temp[1]);
-	    arc.setAngles(x1, y1, temp[0], temp[1]);
-	    corner = arc.getPathIterator(at);
-	  }
-      }
-
-      public int currentSegment(float[] coords)
-      {
-	if (corner != null)
-	  {
-	    int r = corner.currentSegment(coords);
-	    if (r == SEG_MOVETO)
-	      r = SEG_LINETO;
-	    return r;
-	  }
-
-	if (current < 9)
-	  {
-	    getPoint(current);
-	    coords[0] = (float) temp[0];
-	    coords[1] = (float) temp[1];
-	  }
-	else if (current == 9)
-	  return SEG_CLOSE;
-	else
-	  throw new NoSuchElementException("rect iterator out of bounds");
-
-	if (at != null)
-	  at.transform(coords, 0, coords, 0, 1);
-	return current == 0 ? SEG_MOVETO : SEG_LINETO;
-      }
-
-      public int currentSegment(double[] coords)
       {
-	if (corner != null)
-	  {
-	    int r = corner.currentSegment(coords);
-	    if (r == SEG_MOVETO)
-	      r = SEG_LINETO;
-	    return r;
-	  }
-
-	if (current < 9)
-	  {
-	    getPoint(current);
-	    coords[0] = temp[0];
-	    coords[1] = temp[1];
-	  }
-	else if (current == 9)
-	  return SEG_CLOSE;
-	else
-	  throw new NoSuchElementException("rect iterator out of bounds");
-
-	if (at != null)
-	  at.transform(coords, 0, coords, 0, 1);
-	return current == 0 ? SEG_MOVETO : SEG_LINETO;
-      }
-    };
+	/** We iterate counterclockwise around the rectangle, starting in the
+	 * upper right.  This variable tracks our current point, which
+	 * can be on either side of a given corner.  */
+	private int current = 0;
+
+	/** Child path iterator, used for corners.  */
+	private PathIterator corner;
+
+	/** This is used when rendering the corners.  We re-use the arc
+	 * for each corner.  */
+	private Arc2D arc = new Arc2D.Double();
+
+	/** Temporary array used by getPoint.  */
+	private double[] temp = new double[2];
+
+	public int getWindingRule()
+	{
+	  return WIND_NON_ZERO;
+	}
+
+	public boolean isDone()
+	{
+	  return current > 9;
+	}
+
+	private void getPoint(int val)
+	{
+	  switch (val)
+	    {
+	    case 0:
+	    case 8:
+	      temp[0] = maxx;
+	      temp[1] = miny + archeight;
+	      break;
+	    case 7:
+	      temp[0] = maxx;
+	      temp[1] = maxy - archeight;
+	      break;
+	    case 6:
+	      temp[0] = maxx - arcwidth;
+	      temp[1] = maxy;
+	      break;
+	    case 5:
+	      temp[0] = minx + arcwidth;
+	      temp[1] = maxy;
+	      break;
+	    case 4:
+	      temp[0] = minx;
+	      temp[1] = maxy - archeight;
+	      break;
+	    case 3:
+	      temp[0] = minx;
+	      temp[1] = miny + archeight;
+	      break;
+	    case 2:
+	      temp[0] = minx + arcwidth;
+	      temp[1] = miny;
+	      break;
+	    case 1:
+	      temp[0] = maxx - arcwidth;
+	      temp[1] = miny;
+	      break;
+	    }
+	}
+
+	public void next()
+	{
+	  if (current >= 8)
+	    ++current;
+	  else if (corner != null)
+	    {
+	      // We're iterating through the corner.  Work on the child
+	      // iterator; if it finishes, reset and move to the next
+	      // point along the rectangle.
+	      corner.next();
+	      if (corner.isDone())
+	        {
+		  corner = null;
+		  ++current;
+	        }
+	    }
+	  else
+	    {
+	      // Make an arc between this point on the rectangle and
+	      // the next one, and then iterate over this arc.
+	      getPoint(current);
+	      double x1 = temp[0];
+	      double y1 = temp[1];
+	      getPoint(current + 1);
+	      Rectangle2D.Double r = new Rectangle2D.Double(Math.min(x1,
+	                                                             temp[0]),
+	                                                    Math.min(y1,
+	                                                             temp[1]),
+	                                                    Math.abs(x1
+	                                                             - temp[0]),
+	                                                    Math.abs(y1
+	                                                             - temp[1]));
+	      arc.setArc(r, (current >> 1) * 90.0, 90.0, Arc2D.OPEN);
+	      corner = arc.getPathIterator(at);
+	    }
+	}
+
+	public int currentSegment(float[] coords)
+	{
+	  if (corner != null)
+	    {
+	      int r = corner.currentSegment(coords);
+	      if (r == SEG_MOVETO)
+		r = SEG_LINETO;
+	      return r;
+	    }
+
+	  if (current < 9)
+	    {
+	      getPoint(current);
+	      coords[0] = (float) temp[0];
+	      coords[1] = (float) temp[1];
+	    }
+	  else if (current == 9)
+	    return SEG_CLOSE;
+	  else
+	    throw new NoSuchElementException("rect iterator out of bounds");
+
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 1);
+	  return current == 0 ? SEG_MOVETO : SEG_LINETO;
+	}
+
+	public int currentSegment(double[] coords)
+	{
+	  if (corner != null)
+	    {
+	      int r = corner.currentSegment(coords);
+	      if (r == SEG_MOVETO)
+		r = SEG_LINETO;
+	      return r;
+	    }
+
+	  if (current < 9)
+	    {
+	      getPoint(current);
+	      coords[0] = temp[0];
+	      coords[1] = temp[1];
+	    }
+	  else if (current == 9)
+	    return SEG_CLOSE;
+	  else
+	    throw new NoSuchElementException("rect iterator out of bounds");
+
+	  if (at != null)
+	    at.transform(coords, 0, coords, 0, 1);
+	  return current == 0 ? SEG_MOVETO : SEG_LINETO;
+	}
+      };
   }
 
   /** Return true if the given rectangle intersects this shape.
@@ -286,14 +297,9 @@
    */
   public boolean intersects(double x, double y, double w, double h)
   {
-    // Here we can use the same code we use for an ordinary rectangle.
-    double mx = getX();
-    double mw = getWidth();
-    if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw)
-      return false;
-    double my = getY();
-    double mh = getHeight();
-    return y >= my && y < my + mh && y + h >= my && y + h < my + mh;
+    // Check if any corner is within the rectangle
+    return (contains(x, y) || contains(x, y + h) || contains(x + w, y + h)
+           || contains(x + w, y));
   }
 
   /** Set the boundary of this round rectangle.
@@ -315,7 +321,7 @@
   public void setRoundRect(RoundRectangle2D rr)
   {
     setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(),
-                  rr.getArcWidth(), rr.getArcHeight());
+                 rr.getArcWidth(), rr.getArcHeight());
   }
 
   /** A subclass of RoundRectangle which keeps its parameters as
@@ -353,8 +359,8 @@
      * @param arcWidth The arc width
      * @param arcHeight The arc height
      */
-    public Double(double x, double y, double w, double h,
-                   double arcWidth, double arcHeight)
+    public Double(double x, double y, double w, double h, double arcWidth,
+                  double arcHeight)
     {
       this.x = x;
       this.y = y;
@@ -405,7 +411,7 @@
     }
 
     public void setRoundRect(double x, double y, double w, double h,
-                              double arcWidth, double arcHeight)
+                             double arcWidth, double arcHeight)
     {
       this.x = x;
       this.y = y;
@@ -451,8 +457,8 @@
      * @param arcWidth The arc width
      * @param arcHeight The arc height
      */
-    public Float(float x, float y, float w, float h,
-                  float arcWidth, float arcHeight)
+    public Float(float x, float y, float w, float h, float arcWidth,
+                 float arcHeight)
     {
       this.x = x;
       this.y = y;
@@ -503,7 +509,7 @@
     }
 
     public void setRoundRect(float x, float y, float w, float h,
-                              float arcWidth, float arcHeight)
+                             float arcWidth, float arcHeight)
     {
       this.x = x;
       this.y = y;
@@ -514,7 +520,7 @@
     }
 
     public void setRoundRect(double x, double y, double w, double h,
-                              double arcWidth, double arcHeight)
+                             double arcWidth, double arcHeight)
     {
       this.x = (float) x;
       this.y = (float) y;
Index: java/awt/im/InputContext.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/im/InputContext.java,v
retrieving revision 1.3
diff -u -r1.3 InputContext.java
--- java/awt/im/InputContext.java	11 Jul 2003 18:27:54 -0000	1.3
+++ java/awt/im/InputContext.java	6 Sep 2004 16:35:49 -0000
@@ -86,22 +86,22 @@
   private static final ArrayList descriptors = new ArrayList();
   static
   {
-    Enumeration enum;
+    Enumeration e;
     try
       {
-        enum = ClassLoader.getSystemResources
+        e = ClassLoader.getSystemResources
           ("META_INF/services/java.awt.im.spi.InputMethodDescriptor");
       }
     catch (IOException ex)
       {
         // XXX Should we do something else?
-        enum = EmptyEnumeration.getInstance();
+        e = EmptyEnumeration.getInstance();
       }
-    while (enum.hasMoreElements())
+    while (e.hasMoreElements())
       {
-        URL url = (URL) enum.nextElement();
-        BufferedReader in;
-        String line;
+        URL url = (URL) e.nextElement();
+        BufferedReader in = null;
+        String line = null;
         try
           {
             in = new BufferedReader
@@ -125,7 +125,7 @@
                   }
                 line = in.readLine().trim();
               }
-            catch (IOException e)
+            catch (IOException ex)
               {
                 continue outer;
               }
Index: java/awt/image/AffineTransformOp.java
===================================================================
RCS file: java/awt/image/AffineTransformOp.java
diff -N java/awt/image/AffineTransformOp.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/AffineTransformOp.java	6 Sep 2004 16:35:50 -0000
@@ -0,0 +1,264 @@
+/* AffineTransformOp.java --  This class performs affine 
+ * transformation between two images or rasters in 2 
+ * dimensions. Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.geom.*;
+
+
+/**
+ * This class performs affine transformation between two images or 
+ * rasters in 2 dimensions. 
+ *
+ * @author Olga Rodimina <rodimina@redhat.com> 
+ */
+ 
+public class AffineTransformOp implements BufferedImageOp, RasterOp
+{
+    public static final int TYPE_BILINEAR = 0;
+    public static final int TYPE_NEAREST_NEIGHBOR = 1;
+
+    private AffineTransform transform;
+    private RenderingHints hints;
+    
+    /**
+     * Construct AffineTransformOp with the given xform and interpolationType.
+     * Interpolation type can be either TYPE_BILINEAR or TYPE_NEAREST_NEIGHBOR.
+     *
+     * @param xform AffineTransform that will applied to the source image 
+     * @param interpolationType type of interpolation used
+     */
+    public AffineTransformOp (AffineTransform xform, int interpolationType)
+    {
+      this.transform = xform;
+
+      if (interpolationType == 0) 
+        hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION, 
+                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+				   
+      else
+        hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
+                                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+
+    }
+
+    /**
+     * Construct AffineTransformOp with the given xform and rendering hints.
+     * 
+     * @param xform AffineTransform that will applied to the source image
+     * @param hints rendering hints that will be used during transformation
+     */
+    public AffineTransformOp (AffineTransform xform, RenderingHints hints)
+    {
+      this.transform = xform;
+      this.hints = hints;
+    }
+
+    /**
+     * Creates empty BufferedImage with the size equal to that of the 
+     * transformed image and correct number of bands. The newly created 
+     * image is created with the specified ColorModel. 
+     * If the ColorModel is equal to null, then image is created 
+     * with the ColorModel of the source image.
+     *
+     * @param src source image
+     * @param destCM color model for the destination image
+     * @return new compatible destination image
+     */
+    public BufferedImage createCompatibleDestImage (BufferedImage src,
+                                                    ColorModel destCM)
+    {
+
+      // if destCm is not specified, use color model of the source image
+
+      if (destCM == null) 
+        destCM = src.getColorModel ();
+
+      return new BufferedImage (destCM, 
+                                createCompatibleDestRaster (src.getRaster ()),
+                                src.isAlphaPremultiplied (),
+                                null);		             
+
+    }
+
+    /**
+     * Creates empty WritableRaster with the size equal to the transformed 
+     * source raster and correct number of bands 
+     *
+     * @param src source raster
+     * @throws RasterFormatException if resulting width or height of raster is 0
+     * @return new compatible raster
+     */
+    public WritableRaster createCompatibleDestRaster (Raster src)
+    {
+      Rectangle rect = (Rectangle) getBounds2D (src);
+      
+      // throw RasterFormatException if resulting width or height of the
+      // transformed raster is 0
+
+      if (rect.getWidth () == 0 || rect.getHeight () == 0) 
+        throw new RasterFormatException("width or height is 0");
+
+      return src.createCompatibleWritableRaster ((int) rect.getWidth (), 
+                                                (int) rect.getHeight ());
+    }
+
+    /**
+     * Transforms source image using transform specified at the constructor.
+     * The resulting transformed image is stored in the destination image. 
+     *
+     * @param src source image
+     * @param dst destination image
+     * @return transformed source image
+     */
+    public BufferedImage filter (BufferedImage src, BufferedImage dst)
+    {
+
+      if (dst == src)
+        throw new IllegalArgumentException ("src image cannot be the same as the dst image");
+
+      // If the destination image is null, then BufferedImage is 
+      // created with ColorModel of the source image
+
+      if (dst == null)
+        dst = createCompatibleDestImage(src, src.getColorModel ());
+
+      // FIXME: Must check if color models of src and dst images are the same.
+      // If it is not, then source image should be converted to color model
+      // of the destination image
+
+      Graphics2D gr = (Graphics2D) dst.createGraphics ();
+      gr.setRenderingHints (hints);	
+      gr.drawImage (src, transform, null);
+      return dst;
+
+    }
+
+    /**
+     * Transforms source raster using transform specified at the constructor.
+     * The resulting raster is stored in the destination raster.
+     *
+     * @param src source raster
+     * @param dst destination raster
+     * @return transformed raster
+     */
+    public WritableRaster filter (Raster src, WritableRaster dst)
+    {
+      throw new UnsupportedOperationException ("not implemented yet");	
+    }
+
+    /**
+     * Transforms source image using transform specified at the constructor and 
+     * returns bounds of the transformed image.
+     *
+     * @param src image to be transformed
+     * @return bounds of the transformed image.
+     */
+    public Rectangle2D getBounds2D (BufferedImage src)
+    {
+      return getBounds2D (src.getRaster());
+    }
+   
+    /**
+     * Returns bounds of the transformed raster.
+     *
+     * @param src raster to be transformed
+     * @return bounds of the transformed raster.
+     */
+    public Rectangle2D getBounds2D (Raster src)
+    {
+      // determine new size for the transformed raster.
+      // Need to calculate transformed coordinates of the lower right
+      // corner of the raster. The upper left corner is always (0,0)
+              
+      double x2 = (double) src.getWidth () + src.getMinX ();
+      double y2 = (double) src.getHeight () + src.getMinY ();
+      Point2D p2 = getPoint2D (new Point2D.Double (x2,y2), null);
+
+      Rectangle2D rect = new Rectangle (0, 0, (int) p2.getX (), (int) p2.getY ());
+      return rect.getBounds ();
+    }
+
+    /**
+     * Returns interpolation type used during transformations
+     *
+     * @return interpolation type
+     */
+    public int getInterpolationType ()
+    {
+      if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+        return TYPE_BILINEAR;
+      else 
+        return TYPE_NEAREST_NEIGHBOR;
+    }
+
+    /** 
+     * Returns location of the transformed source point. The resulting point 
+     * is stored in the dstPt if one is specified.
+     *  
+     * @param srcPt point to be transformed
+     * @param dstPt destination point
+     * @return the location of the transformed source point.
+     */
+    public Point2D getPoint2D (Point2D srcPt, Point2D dstPt)
+    {
+      return transform.transform (srcPt, dstPt);
+    }
+
+    /** Returns rendering hints that are used during transformation.
+     *
+     * @return rendering hints
+     */
+    public RenderingHints getRenderingHints ()
+    {
+      return hints;
+    }
+
+    /** Returns transform used in transformation between source and destination
+     * image.
+     *
+     * @return transform
+     */
+    public AffineTransform getTransform ()
+    {
+      return transform;
+    }
+}
Index: java/awt/image/BufferedImage.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/BufferedImage.java,v
retrieving revision 1.9
diff -u -r1.9 BufferedImage.java
--- java/awt/image/BufferedImage.java	25 Sep 2003 18:35:44 -0000	1.9
+++ java/awt/image/BufferedImage.java	6 Sep 2004 16:35:50 -0000
@@ -39,6 +39,7 @@
 
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
 import java.awt.Image;
 import java.awt.Point;
 import java.awt.Rectangle;
@@ -46,6 +47,8 @@
 import java.awt.color.ColorSpace;
 import java.util.Hashtable;
 import java.util.Vector;
+import java.util.HashSet;
+import java.util.Iterator;
 import gnu.java.awt.ComponentDataBlitOp;
 
 /**
@@ -255,7 +258,8 @@
   public WritableRaster copyData(WritableRaster dest)
   {
     if (dest == null)
-      dest = raster.createCompatibleWritableRaster();
+      dest = raster.createCompatibleWritableRaster(getMinX(), getMinY(),
+                                                   getWidth(),getHeight());
 
     int x = dest.getMinX();
     int y = dest.getMinY();
@@ -282,8 +286,9 @@
 
   public Graphics2D createGraphics()
   {
-    throw new UnsupportedOperationException("not implemented");
-    // will require a lot of effort to implement
+    GraphicsEnvironment env;
+    env = GraphicsEnvironment.getLocalGraphicsEnvironment ();
+    return env.createGraphics (this);
   }
 
   public void flush() {
@@ -439,7 +444,57 @@
     
   public ImageProducer getSource()
   {
-    throw new UnsupportedOperationException("not implemented");
+    return new ImageProducer() {
+        
+        HashSet consumers = new HashSet();
+
+        public void addConsumer(ImageConsumer ic)
+        {
+          consumers.add(ic);
+        }
+
+        public boolean isConsumer(ImageConsumer ic)
+        {
+          return consumers.contains(ic);
+        }
+
+        public void removeConsumer(ImageConsumer ic)
+        {
+          consumers.remove(ic);
+        }
+
+        public void startProduction(ImageConsumer ic)
+        {
+          int x = 0;
+          int y = 0;
+          int width = getWidth();
+          int height = getHeight();
+          int stride = width;
+          int offset = 0;
+          int[] pixels = getRGB(x, y, 
+                                width, height, 
+                                (int[])null, offset, stride);
+          ColorModel model = getColorModel();
+
+          consumers.add(ic);
+
+          Iterator i = consumers.iterator();
+          while(i.hasNext())
+            {
+              ImageConsumer c = (ImageConsumer) i.next();
+              c.setHints(ImageConsumer.SINGLEPASS);
+              c.setDimensions(getWidth(), getHeight());
+              c.setPixels(x, y, width, height, model, pixels, offset, stride);
+              c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            }
+        }
+
+        public void requestTopDownLeftRightResend(ImageConsumer ic)
+        {
+          startProduction(ic);
+        }
+
+      };
   }
   
   public Vector getSources()
Index: java/awt/image/ByteLookupTable.java
===================================================================
RCS file: java/awt/image/ByteLookupTable.java
diff -N java/awt/image/ByteLookupTable.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/ByteLookupTable.java	6 Sep 2004 16:35:50 -0000
@@ -0,0 +1,162 @@
+/* ByteLookupTable.java -- Java class for a pixel translation table.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * ByteLookupTable represents translation arrays for pixel values.  It wraps
+ * one or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B.  When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @author <a href="mailto:jlquinn@optonline.net">Jerry Quinn</a>
+ * @version 1.0
+ */
+public class ByteLookupTable extends LookupTable
+{
+  // Array of translation tables.
+  private byte data[][];
+
+  /**
+   * Creates a new <code>ByteLookupTable</code> instance.
+   *
+   * Offset is subtracted from pixel values when looking up in the translation
+   * tables.  If data.length is one, the same table is applied to all pixel
+   * components.
+   * 
+   * @param offset Offset to be subtracted.
+   * @param data Array of lookup tables.
+   * @exception IllegalArgumentException if offset < 0 or data.length < 1.
+   */
+  public ByteLookupTable(int offset, byte[][] data)
+    throws IllegalArgumentException
+  {
+    super(offset, data.length);
+    this.data = data;
+  }
+
+  /**
+   * Creates a new <code>ByteLookupTable</code> instance.
+   *
+   * Offset is subtracted from pixel values when looking up in the translation
+   * table.  The same table is applied to all pixel components.
+   * 
+   * @param offset Offset to be subtracted.
+   * @param data Lookup table for all components.
+   * @exception IllegalArgumentException if offset < 0.
+   */
+  public ByteLookupTable(int offset, byte[] data)
+    throws IllegalArgumentException
+  {
+    super(offset, 1);
+    this.data = new byte[][] {data};
+  }
+
+  /** Return the lookup tables. */
+  public final byte[][] getTable()
+  {
+    return data;
+  }
+
+  /**
+   * Return translated values for a pixel.
+   *
+   * For each value in the pixel src, use the value minus offset as an index
+   * in the component array and copy the value there to the output for the
+   * component.  If dest is null, the output is a new array, otherwise the
+   * translated values are written to dest.  Dest can be the same array as
+   * src.
+   *
+   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+   * translation arrays.
+   *
+   * @param src Component values of a pixel.
+   * @param dest Destination array for values, or null.
+   * @return Translated values for the pixel.
+   */
+  public int[] lookupPixel(int[] src, int[] dst)
+    throws ArrayIndexOutOfBoundsException
+  {
+    if (dst == null)
+      dst = new int[numComponents];
+
+    if (data.length == 1)
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[0][src[i] - offset];
+    else
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[i][src[i] - offset];
+      
+    return dst;
+  }
+
+  /**
+   * Return translated values for a pixel.
+   *
+   * For each value in the pixel src, use the value minus offset as an index
+   * in the component array and copy the value there to the output for the
+   * component.  If dest is null, the output is a new array, otherwise the
+   * translated values are written to dest.  Dest can be the same array as
+   * src.
+   *
+   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+   * translation arrays.
+   *
+   * @param src Component values of a pixel.
+   * @param dest Destination array for values, or null.
+   * @return Translated values for the pixel.
+   */
+  public byte[] lookupPixel(byte[] src, byte[] dst)
+    throws ArrayIndexOutOfBoundsException
+  {
+    if (dst == null)
+      dst = new byte[numComponents];
+
+    if (data.length == 1)
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[0][((int)src[i]) - offset];
+    else
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[i][((int)src[i]) - offset];
+      
+    return dst;
+
+  }
+}
Index: java/awt/image/ColorModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/ColorModel.java,v
retrieving revision 1.13
diff -u -r1.13 ColorModel.java
--- java/awt/image/ColorModel.java	25 Jun 2003 11:23:33 -0000	1.13
+++ java/awt/image/ColorModel.java	6 Sep 2004 16:35:51 -0000
@@ -37,6 +37,7 @@
 
 package java.awt.image;
 
+import java.util.Arrays;
 import java.awt.Point;
 import java.awt.Transparency;
 import java.awt.color.ColorSpace;
@@ -166,7 +167,7 @@
    */
   public static ColorModel getRGBdefault()
   {
-    return new DirectColorModel(8, 0xff0000, 0xff00, 0xff, 0xff000000);
+    return new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
   }
 
   public final boolean hasAlpha()
@@ -551,8 +552,8 @@
       (transferType == o.transferType) &&
       (transparency == o.transparency) &&
       (hasAlpha == o.hasAlpha) &&
-      (isAlphaPremultiplied == isAlphaPremultiplied) &&
-      (bits.equals(o.bits)) &&
+      (isAlphaPremultiplied == o.isAlphaPremultiplied) &&
+      Arrays.equals(bits, o.bits) &&
       (cspace.equals(o.cspace));
   }
 
@@ -597,7 +598,11 @@
     return null;
   }
     
-  // Typically overridden
+  /**
+   * Checks if the given raster has a compatible data-layout (SampleModel).
+   * @param raster The Raster to test.
+   * @return true if raster is compatible.
+   */ 
   public boolean isCompatibleRaster(Raster raster)
   {
     SampleModel sampleModel = raster.getSampleModel();
Index: java/awt/image/ComponentColorModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/ComponentColorModel.java,v
retrieving revision 1.5
diff -u -r1.5 ComponentColorModel.java
--- java/awt/image/ComponentColorModel.java	5 Jun 2003 19:58:40 -0000	1.5
+++ java/awt/image/ComponentColorModel.java	6 Sep 2004 16:35:51 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002  Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004  Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -292,19 +292,56 @@
     return Raster.createWritableRaster(sm, origin);
   }
 
+
+  /**
+   * Creates a <code>SampleModel</code> whose arrangement of pixel
+   * data is compatible to this <code>ColorModel</code>.
+   *
+   * @param w the number of pixels in the horizontal direction.
+   * @param h the number of pixels in the vertical direction.
+   */
   public SampleModel createCompatibleSampleModel(int w, int h)
   {
-    int pixelStride = getNumComponents();
-    
-    /* TODO: Maybe we don't need to create a new offset array each
-       time, but rather use the same array every time. */
-    int[] bandOffsets = new int[pixelStride];
-    for (int i=0; i<pixelStride; i++) bandOffsets[i] = i;
-    return new ComponentSampleModel(transferType, w, h,
-				    pixelStride, pixelStride*w,
-				    bandOffsets);
+    int pixelStride, scanlineStride;
+    int[] bandOffsets;
+
+    pixelStride = getNumComponents();
+    scanlineStride = pixelStride * w;
+
+    /* We might be able to re-use the same bandOffsets array among
+     * multiple calls to this method. However, this optimization does
+     * not seem worthwile because setting up descriptive data
+     * structures (such as SampleModels) is neglectible in comparision
+     * to shuffling around masses of pixel data.
+     */
+    bandOffsets = new int[pixelStride];
+    for (int i = 0; i < pixelStride; i++)
+      bandOffsets[i] = i;
+
+    /* FIXME: Think about whether it would make sense to return the
+     * possibly more efficient PixelInterleavedSampleModel for other
+     * transferTypes as well. It seems unlikely that this would break
+     * any user applications, so the Mauve tests on this method
+     * might be too restrictive.
+     */
+    switch (transferType)
+      {
+      case DataBuffer.TYPE_BYTE:
+      case DataBuffer.TYPE_USHORT:
+        return new PixelInterleavedSampleModel(transferType, w, h,
+                                               pixelStride,
+                                               scanlineStride,
+                                               bandOffsets);
+
+      default:
+        return new ComponentSampleModel(transferType, w, h,
+                                        pixelStride,
+                                        scanlineStride,
+                                        bandOffsets);
+      }
   }
 
+
   public boolean isCompatibleSampleModel(SampleModel sm)
   {
     return 
Index: java/awt/image/ComponentSampleModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/ComponentSampleModel.java,v
retrieving revision 1.4
diff -u -r1.4 ComponentSampleModel.java
--- java/awt/image/ComponentSampleModel.java	22 Jan 2002 22:40:10 -0000	1.4
+++ java/awt/image/ComponentSampleModel.java	6 Sep 2004 16:35:51 -0000
@@ -349,7 +349,7 @@
     if (scanlineStride == rowSize)
       {
 	// Collapse scan lines:
-	scanlineStride = rowSize *= h;
+	rowSize *= h;
 	h = 1;
       }
 
Index: java/awt/image/CropImageFilter.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/CropImageFilter.java,v
retrieving revision 1.1
diff -u -r1.1 CropImageFilter.java
--- java/awt/image/CropImageFilter.java	24 Jan 2002 01:05:12 -0000	1.1
+++ java/awt/image/CropImageFilter.java	6 Sep 2004 16:35:51 -0000
@@ -39,6 +39,7 @@
 package java.awt.image;
 
 import java.util.Hashtable;
+import java.awt.Rectangle;
 
 /**
  * <br>
@@ -92,7 +93,7 @@
      */
     public void setProperties(Hashtable props)
     {
-//  	props.put("filters", "ReplicateScaleFilter");
+  	props.put("filters", "CropImageFilter");
 	consumer.setProperties(props);
     }
 
@@ -113,7 +114,27 @@
     public void setPixels(int x, int y, int w, int h, 
 	   ColorModel model, byte[] pixels, int offset, int scansize)
     {
-	consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+	Rectangle filterBounds = new Rectangle(this.x, this.y,
+	                                       this.width, this.height);
+	Rectangle pixelBounds = new Rectangle(x, y, w, h);
+
+	if (filterBounds.intersects(pixelBounds))
+	{
+	    Rectangle bounds = filterBounds.intersection(pixelBounds);
+
+	    byte[] cropped = new byte[bounds.width * bounds.height];
+	    for (int i = 0; i < bounds.height; i++)
+	    {
+		int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
+
+		for (int j = 0; j < bounds.width; j++)
+		    cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
+	    }
+	    
+	    consumer.setPixels(bounds.x, bounds.y,
+	                       bounds.width, bounds.height,
+	                       model, cropped, 0, bounds.width);
+	}
     }
 
     /**
@@ -133,7 +154,27 @@
     public void setPixels(int x, int y, int w, int h, 
            ColorModel model, int[] pixels, int offset, int scansize)
     {
-	consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+	Rectangle filterBounds = new Rectangle(this.x, this.y,
+	                                       this.width, this.height);
+	Rectangle pixelBounds = new Rectangle(x, y, w, h);
+
+	if (filterBounds.intersects(pixelBounds))
+	{
+	    Rectangle bounds = filterBounds.intersection(pixelBounds);
+
+	    int[] cropped = new int[bounds.width * bounds.height];
+	    for (int i = 0; i < bounds.height; i++)
+	    {
+		int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
+
+		for (int j = 0; j < bounds.width; j++)
+		    cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
+	    }
+	    
+	    consumer.setPixels(bounds.x, bounds.y,
+	                       bounds.width, bounds.height,
+	                       model, cropped, 0, bounds.width);
+	}
     }
 
 }
Index: java/awt/image/DataBufferDouble.java
===================================================================
RCS file: java/awt/image/DataBufferDouble.java
diff -N java/awt/image/DataBufferDouble.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/DataBufferDouble.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,174 @@
+/* Copyright (C) 2004  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+   should have a central template and generate all these files. This
+   is one of the cases where templates or macros would have been
+   useful to have in Java.
+
+   This file has been created using search-replace. My only fear is
+   that these classes will grow out-of-sync as of a result of changes
+   that are not propagated to the other files. As always, mirroring
+   code is a maintenance nightmare.  */
+
+/**
+ * @since 1.4
+ *
+ * @author <a href="mailto:rolfwr@ii.uib.no">Rolf W. Rasmussen</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public final class DataBufferDouble
+  extends DataBuffer
+{
+  private double[] data;
+  private double[][] bankData;
+  
+  public DataBufferDouble(int size)
+  {
+    super(TYPE_DOUBLE, size);
+    data = new double[size];
+  }
+
+  public DataBufferDouble(int size, int numBanks)
+  {
+    super(TYPE_DOUBLE, size, numBanks);
+    bankData = new double[numBanks][size];
+    data = bankData[0];
+  }
+
+  public DataBufferDouble(double[] dataArray, int size)
+  {
+    super(TYPE_DOUBLE, size);
+    data = dataArray;
+  }
+    
+  public DataBufferDouble(double[] dataArray, int size, int offset)
+  {
+    super(TYPE_DOUBLE, size, 1, offset);
+    data = dataArray;
+  }
+
+  public DataBufferDouble(double[][] dataArray, int size)
+  {
+    super(TYPE_DOUBLE, size, dataArray.length);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public DataBufferDouble(double[][] dataArray, int size, int[] offsets)
+  {
+    super(TYPE_DOUBLE, size, dataArray.length, offsets);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public double[] getData()
+  {
+    return data;
+  }
+    
+  public double[] getData(int bank)
+  {
+    return bankData[bank];
+  }
+    
+  public double[][] getBankData()
+  {
+    return bankData;
+  }
+  
+  public int getElem(int i)
+  {
+    return (int) data[i+offset];
+  }
+
+  public int getElem(int bank, int i)
+  {
+    return (int) bankData[bank][i+offsets[bank]];
+  }
+
+  public void setElem(int i, int val)
+  {
+    data[i+offset] = (double) val;
+  }
+
+  public void setElem(int bank, int i, int val)
+  {
+    bankData[bank][i+offsets[bank]] = (double) val;
+  }
+
+  public float getElemFloat(int i)
+  {
+    return (float) data[i+offset];
+  }
+    
+  public float getElemFloat(int bank, int i)
+  {
+    return (float) bankData[bank][i+offsets[bank]];
+  }
+
+  public void setElemFloat(int i, float val)
+  {
+    data[i+offset] = val;
+  }
+
+  public void setElemFloat(int bank, int i, float val)
+  {
+    bankData[bank][i+offsets[bank]] = val;
+  }
+
+  public double getElemDouble(int i)
+  {
+    return data[i + offset];
+  }
+    
+  public double getElemDouble(int bank, int i)
+  {
+    return bankData[bank][i + offsets[bank]];
+  }
+
+  public void setElemDouble(int i, double val)
+  {
+    data[i + offset] = val;
+  }
+
+  public void setElemDouble(int bank, int i, double val)
+  {
+    bankData[bank][i + offsets[bank]] = val;
+  }
+}
Index: java/awt/image/DataBufferFloat.java
===================================================================
RCS file: java/awt/image/DataBufferFloat.java
diff -N java/awt/image/DataBufferFloat.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/DataBufferFloat.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,172 @@
+/* Copyright (C) 2004  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+   should have a central template and generate all these files. This
+   is one of the cases where templates or macros would have been
+   useful to have in Java.
+
+   This file has been created using search-replace. My only fear is
+   that these classes will grow out-of-sync as of a result of changes
+   that are not propagated to the other files. As always, mirroring
+   code is a maintenance nightmare.  */
+
+/**
+ * @author <a href="mailto:rolfwr@ii.uib.no">Rolf W. Rasmussen</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public final class DataBufferFloat
+  extends DataBuffer
+{
+  private float[] data;
+  private float[][] bankData;
+  
+  public DataBufferFloat(int size)
+  {
+    super(TYPE_FLOAT, size);
+    data = new float[size];
+  }
+
+  public DataBufferFloat(int size, int numBanks)
+  {
+    super(TYPE_FLOAT, size, numBanks);
+    bankData = new float[numBanks][size];
+    data = bankData[0];
+  }
+
+  public DataBufferFloat(float[] dataArray, int size)
+  {
+    super(TYPE_FLOAT, size);
+    data = dataArray;
+  }
+    
+  public DataBufferFloat(float[] dataArray, int size, int offset)
+  {
+    super(TYPE_FLOAT, size, 1, offset);
+    data = dataArray;
+  }
+
+  public DataBufferFloat(float[][] dataArray, int size)
+  {
+    super(TYPE_FLOAT, size, dataArray.length);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public DataBufferFloat(float[][] dataArray, int size, int[] offsets)
+  {
+    super(TYPE_FLOAT, size, dataArray.length, offsets);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public float[] getData()
+  {
+    return data;
+  }
+    
+  public float[] getData(int bank)
+  {
+    return bankData[bank];
+  }
+    
+  public float[][] getBankData()
+  {
+    return bankData;
+  }
+  
+  public int getElem(int i)
+  {
+    return (int) data[i+offset];
+  }
+
+  public int getElem(int bank, int i)
+  {
+    return (int) bankData[bank][i+offsets[bank]];
+  }
+
+  public void setElem(int i, int val)
+  {
+    data[i+offset] = (float) val;
+  }
+
+  public void setElem(int bank, int i, int val)
+  {
+    bankData[bank][i+offsets[bank]] = (float) val;
+  }
+
+  public float getElemFloat(int i)
+  {
+    return data[i+offset];
+  }
+    
+  public float getElemFloat(int bank, int i)
+  {
+    return bankData[bank][i+offsets[bank]];
+  }
+
+  public void setElemFloat(int i, float val)
+  {
+    data[i+offset] = val;
+  }
+
+  public void setElemFloat(int bank, int i, float val)
+  {
+    bankData[bank][i+offsets[bank]] = val;
+  }
+
+  public double getElemDouble(int i)
+  {
+    return getElemFloat(i);
+  }
+    
+  public double getElemDouble(int bank, int i)
+  {
+    return getElemFloat(bank, i);
+  }
+
+  public void setElemDouble(int i, double val)
+  {
+    setElemFloat(i, (float) val);
+  }
+
+  public void setElemDouble(int bank, int i, double val)
+  {
+    setElemFloat(bank, i, (float) val);
+  }
+}
Index: java/awt/image/DataBufferShort.java
===================================================================
RCS file: java/awt/image/DataBufferShort.java
diff -N java/awt/image/DataBufferShort.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/DataBufferShort.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,130 @@
+/* Copyright (C) 2004  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+   should have a central template and generate all these files. This
+   is one of the cases where templates or macros would have been
+   useful to have in Java.
+
+   This file has been created using search-replace. My only fear is
+   that these classes will grow out-of-sync as of a result of changes
+   that are not propagated to the other files. As always, mirroring
+   code is a maintenance nightmare.  */
+
+/**
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public final class DataBufferShort extends DataBuffer
+{
+  private short[] data;
+  private short[][] bankData;
+  
+  public DataBufferShort(int size)
+  {
+    super(TYPE_SHORT, size);
+    data = new short[size];
+  }
+
+  public DataBufferShort(int size, int numBanks)
+  {
+    super(TYPE_SHORT, size, numBanks);
+    bankData = new short[numBanks][size];
+    data = bankData[0];
+  }
+
+  public DataBufferShort(short[] dataArray, int size)
+  {
+    super(TYPE_SHORT, size);
+    data = dataArray;
+  }
+    
+  public DataBufferShort(short[] dataArray, int size, int offset)
+  {
+    super(TYPE_SHORT, size, 1, offset);
+    data = dataArray;
+  }
+
+  public DataBufferShort(short[][] dataArray, int size)
+  {
+    super(TYPE_SHORT, size, dataArray.length);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public DataBufferShort(short[][] dataArray, int size, int[] offsets)
+  {
+    super(TYPE_SHORT, size, dataArray.length, offsets);
+    bankData = dataArray;
+    data = bankData[0];
+  }
+
+  public short[] getData()
+  {
+    return data;
+  }
+    
+  public short[] getData(int bank)
+  {
+    return bankData[bank];
+  }
+    
+  public short[][] getBankData()
+  {
+    return bankData;
+  }
+  
+  public int getElem(int i)
+  {
+    return data[i+offset];
+  }
+
+  public int getElem(int bank, int i)
+  {
+    return bankData[bank][i+offsets[bank]];
+  }
+
+  public void setElem(int i, int val)
+  {
+    data[i+offset] = (short) val;
+  }
+
+  public void setElem(int bank, int i, int val)
+  {
+    bankData[bank][i+offsets[bank]] = (short) val;
+  }
+}
Index: java/awt/image/DirectColorModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/DirectColorModel.java,v
retrieving revision 1.5
diff -u -r1.5 DirectColorModel.java
--- java/awt/image/DirectColorModel.java	27 Jun 2003 20:53:01 -0000	1.5
+++ java/awt/image/DirectColorModel.java	6 Sep 2004 16:35:51 -0000
@@ -60,7 +60,6 @@
    * @param rmask the bits describing the red component of a pixel
    * @param gmask the bits describing the green component of a pixel
    * @param bmask the bits describing the blue component of a pixel 
-   * @param amask the bits describing the alpha component of a pixel 
    */
   public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
   {
@@ -82,6 +81,7 @@
    * @param rmask the bits describing the red component of a pixel
    * @param gmask the bits describing the green component of a pixel
    * @param bmask the bits describing the blue component of a pixel 
+   * @param amask the bits describing the alpha component of a pixel 
    */
   public DirectColorModel(int pixelBits,
 			  int rmask, int gmask, int bmask, int amask)
Index: java/awt/image/Kernel.java
===================================================================
RCS file: java/awt/image/Kernel.java
diff -N java/awt/image/Kernel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/Kernel.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,143 @@
+/* Kernel.java -- Java class for an image processing kernel
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * Kernel represents an image processing kernel.  It gets used to hold
+ * convolution filters among other purposes.  It stores an array of float
+ * values representing a 2-dimensional array in row-major order.
+ *
+ * @author <a href="mailto:jlquinn@optonline.net">Jerry Quinn</a>
+ * @version 1.0
+ */
+public class Kernel implements Cloneable
+{
+  private final int width;
+  private final int height;
+  private final float[] data;
+
+  /**
+   * Creates a new <code>Kernel</code> instance.
+   *
+   * @param width The 2D width of data.
+   * @param height The 2D height of data.
+   * @param data The source data array.
+   * @exception IllegalArgumentException if width * height < data.length.
+   */
+  public Kernel(int width, int height, float[] data)
+    throws IllegalArgumentException
+  {
+    this.width = width;
+    this.height = height;
+    if (data.length < width * height || width < 0 || height < 0)
+      throw new IllegalArgumentException();
+    this.data = new float[width * height];
+    System.arraycopy(data, 0, this.data, 0, width * height);
+  }
+
+  /**
+   * Return the X origin: (width - 1) / 2
+   */
+  public final int getXOrigin()
+  {
+    return (width - 1) / 2;
+  }
+
+  /**
+   * Return the Y origin: (height - 1) / 2
+   */
+  public final int getYOrigin()
+  {
+    return (height - 1) / 2;
+  }
+
+  /**
+   * @return The kernel width.
+   */
+  public final int getWidth()
+  {
+    return width;
+  }
+
+  /**
+   * @return The kernel height.
+   */
+  public final int getHeight()
+  {
+    return height;
+  }
+
+  /**
+   * Return the kernel data.
+   *
+   * If data is null, allocates a new array and returns it.  Otherwise, the
+   * kernel values are copied into data.
+   *
+   * @param data Array to copy values into, or null.
+   * @return The array with copied values.
+   * @exception IllegalArgumentException if data != null and too small.
+   */
+  public final float[] getKernelData(float[] data)
+    throws IllegalArgumentException
+  {
+    if (data == null)
+      return (float[])this.data.clone();
+
+    if (data.length < this.data.length)
+      throw new IllegalArgumentException();
+
+    System.arraycopy(this.data, 0, data, 0, this.data.length);
+    return data;
+  }
+
+  /**
+   * @return a clone of this Kernel.
+   */
+  public Object clone()
+  {
+    try
+      {
+	return super.clone();
+      }
+    catch (CloneNotSupportedException e)
+      {
+        throw (Error) new InternalError().initCause(e); // Impossible
+      }
+  }
+}
Index: java/awt/image/LookupTable.java
===================================================================
RCS file: java/awt/image/LookupTable.java
diff -N java/awt/image/LookupTable.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/LookupTable.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,109 @@
+/* LookupTable.java -- Java class for a pixel translation table.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * LookupTable represents translation arrays for pixel values.  It wraps one
+ * or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B.  When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @see ByteLookupTable
+ * @see ShortLookupTable
+ *
+ * @author <a href="mailto:jlquinn@optonline.net">Jerry Quinn</a>
+ * @version 1.0
+ */
+public abstract class LookupTable
+{
+  // Not protected since that's part of the public API.
+  int offset;
+  int numComponents;
+
+  /**
+   * Creates a new <code>LookupTable</code> instance.
+   *
+   * If numComponents is 1, the same translation table is used for all pixel
+   * components.
+   * 
+   * @param offset Offset to be subtracted.
+   * @param numComponents Number of image components.
+   * @exception IllegalArgumentException if offset < 0 or numComponents < 1.
+   */
+  protected LookupTable(int offset, int numComponents)
+    throws IllegalArgumentException
+  {
+    if (offset < 0 || numComponents < 1)
+      throw new IllegalArgumentException();
+    this.offset = offset;
+    this.numComponents = numComponents;
+  }
+
+  /** Return the number of components. */
+  public int getNumComponents()
+  {
+    return numComponents;
+  }
+
+  /** Return the offset. */
+  public int getOffset()
+  {
+    return offset;
+  }
+
+  
+  /**
+   * Return translated values for a pixel.
+   *
+   * For each value in the pixel src, use the value minus offset as an index
+   * in the component array and copy the value there to the output for the
+   * component.  If dest is null, the output is a new array, otherwise the
+   * translated values are written to dest.  Dest can be the same array as
+   * src.
+   *
+   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+   * translation arrays.
+   *
+   * @param src Component values of a pixel.
+   * @param dest Destination array for values, or null.
+   * @return Translated values for the pixel.
+   */
+  public abstract int[] lookupPixel(int[] src, int[] dest);
+}
Index: java/awt/image/MemoryImageSource.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/MemoryImageSource.java,v
retrieving revision 1.5
diff -u -r1.5 MemoryImageSource.java
--- java/awt/image/MemoryImageSource.java	14 Jul 2003 05:33:30 -0000	1.5
+++ java/awt/image/MemoryImageSource.java	6 Sep 2004 16:35:51 -0000
@@ -41,6 +41,7 @@
 import java.awt.Image;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Vector;
 
 public class MemoryImageSource implements ImageProducer 
 {
@@ -49,7 +50,8 @@
     private int pixeli[], width, height, offset, scansize;
     private byte pixelb[];
     private ColorModel cm;
-    private Hashtable props, consumers = new Hashtable();
+    private Hashtable props = new Hashtable();
+    private Vector consumers = new Vector();
 
     /**
        Constructs an ImageProducer from memory
@@ -126,10 +128,10 @@
      * <code>ImageProducer</code>.  
      */
     public synchronized void addConsumer(ImageConsumer ic) {
-	if (consumers.containsKey(ic))
+	if (consumers.contains(ic))
 	    return;
 
-	consumers.put(ic, ic);
+	consumers.addElement(ic);
     }
 
     /**
@@ -137,7 +139,7 @@
      * already registered with this <code>ImageProducer</code>.  
      */
     public synchronized boolean isConsumer(ImageConsumer ic) {
-	if (consumers.containsKey(ic))
+	if (consumers.contains(ic))
 	    return true;
 	return false;
     }
@@ -147,7 +149,7 @@
      * registered consumers for this <code>ImageProducer</code>.  
      */
     public synchronized void removeConsumer(ImageConsumer ic) {
-	consumers.remove(ic);
+	consumers.removeElement(ic);
     }
 
     /**
@@ -157,16 +159,16 @@
      * registered consumers.  
      */
     public void startProduction(ImageConsumer ic) {
-	if (!(consumers.containsKey(ic))) {
-	    consumers.put(ic, ic);
+	if (!(consumers.contains(ic))) {
+	    consumers.addElement(ic);
 	}        
-	Enumeration e = consumers.elements();
-	for( ; e.hasMoreElements(); ) {
-		ic = (ImageConsumer)e.nextElement();
+
+	Vector list = (Vector) consumers.clone();
+	for(int i = 0; i < list.size(); i++) {
+	    ic = (ImageConsumer) list.elementAt(i);
 		sendPicture( ic );
-		ic.imageComplete( ImageConsumer.SINGLEFRAME );
+	    ic.imageComplete( ImageConsumer.STATICIMAGEDONE );
 	    }	
-
     }
 
     /**
@@ -210,9 +212,9 @@
     {
 	if( animated == true ) {
 		ImageConsumer ic;
-		Enumeration e = consumers.elements();
-		for( ; e.hasMoreElements(); ) {
-			ic = (ImageConsumer)e.nextElement();
+		Vector list = (Vector) consumers.clone();
+		for(int i = 0; i < list.size(); i++) {
+			ic = (ImageConsumer) list.elementAt(i);
 			sendPicture( ic );
 			ic.imageComplete( ImageConsumer.SINGLEFRAME );
 		    }	
@@ -227,6 +229,7 @@
 	    ic.setProperties( props );
 	}
 	ic.setDimensions(width, height);
+	ic.setColorModel(cm);
 	if( pixeli != null ) {
 	    ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
 	} else {
@@ -249,17 +252,23 @@
 		    newPixels();
 		} else {
 		    ImageConsumer ic;
-		    Enumeration e = consumers.elements();
-		    for( ; e.hasMoreElements(); ) {
-			    ic = (ImageConsumer)e.nextElement();
+		    Vector list = (Vector) consumers.clone();
+		    for(int i = 0; i < list.size(); i++) {
+			    ic = (ImageConsumer) list.elementAt(i);
 			    ic.setHints( ImageConsumer.TOPDOWNLEFTRIGHT );
 			    if( props != null ) {
 				ic.setProperties( props );
 			    }
 			    if( pixeli != null ) {
-				ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
+				int[] pixelbuf = new int[w * h];
+				for (int row = y; row < h; row++)
+				    System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, row * w, w);
+				ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
 			    } else {
-				ic.setPixels( 0, 0, width, height, cm, pixelb, offset, scansize );
+				byte[] pixelbuf = new byte[w * h];
+				for (int row = y; row < h; row++)
+				    System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, row * w, w);
+				ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
 			    }
 			    ic.imageComplete( ImageConsumer.SINGLEFRAME );
 		    }
@@ -288,17 +297,23 @@
 		    newPixels();
 		} else {
 		    ImageConsumer ic;
-		    Enumeration e = consumers.elements();
-		    for( ; e.hasMoreElements(); ) {
-			    ic = (ImageConsumer)e.nextElement();
+		    Vector list = (Vector) consumers.clone();
+		    for(int i = 0; i < list.size(); i++) {
+			    ic = (ImageConsumer) list.elementAt(i);
 			    ic.setHints( ImageConsumer.TOPDOWNLEFTRIGHT );
 			    if( props != null ) {
 				ic.setProperties( props );
 			    }
 			    if( pixeli != null ) {
-				ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
+				int[] pixelbuf = new int[w * h];
+				for (int row = y; row < h; row++)
+				    System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, row * w, w);
+				ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
 			    } else {
-				ic.setPixels( 0, 0, width, height, cm, pixelb, offset, scansize );
+				byte[] pixelbuf = new byte[w * h];
+				for (int row = y; row < h; row++)
+				    System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, row * w, w);
+				ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
 			    }
 			    if( framenotify == true )
 				ic.imageComplete( ImageConsumer.SINGLEFRAME );
@@ -313,9 +328,14 @@
 				       int scansize)
 
     {
+	pixeli = null;
+	pixelb = newpix;
+	cm = newmodel;
+	this.offset = offset;
+	this.scansize = scansize;
 	if( animated == true )
 	    {
-		//FIXME
+		newPixels();
 	    }
     }
 
@@ -325,9 +345,14 @@
 				       int scansize)
 
     {
+	pixelb = null;
+	pixeli = newpix;
+	cm = newmodel;
+	this.offset = offset;
+	this.scansize = scansize;
 	if( animated == true )
 	    {
-		//FIXME
+		newPixels();
 	    }
     }
 
Index: java/awt/image/PixelInterleavedSampleModel.java
===================================================================
RCS file: java/awt/image/PixelInterleavedSampleModel.java
diff -N java/awt/image/PixelInterleavedSampleModel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/PixelInterleavedSampleModel.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,98 @@
+/* PixelInterleavedSampleModel.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+
+/**
+ * A <code>SampleModel</code> that uses exactly one element of the
+ * raster&#x2019;s {@link DataBuffer} per pixel, holds all bands in a
+ * single bank, and stores band data in pixel-interleaved manner.
+ *
+ * @since 1.2
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public class PixelInterleavedSampleModel
+  extends ComponentSampleModel
+{
+  public PixelInterleavedSampleModel(int dataType, int width, int height,
+                                     int pixelStride, int scanlineStride,
+                                     int[] bandOffsets)
+  {
+    super(dataType, width, height, pixelStride, scanlineStride,
+          bandOffsets);
+  }
+
+  
+  /**
+   * Creates a new <code>SampleModel</code> that is like this one, but
+   * uses the specified width and height.
+   *
+   * @param width the number of pixels in the horizontal direction.
+   *
+   * @param height the number of pixels in the vertical direction.
+   */
+  public SampleModel createCompatibleSampleModel(int width, int height)
+  {
+    return new PixelInterleavedSampleModel(dataType, width, height,
+                                           pixelStride, scanlineStride,
+                                           bandOffsets);
+  }
+
+
+  /**
+   * Creates a new <code>SampleModel</code> that is like this one, but
+   * uses only a subset of its bands.
+   *
+   * @param bands an array whose elements indicate which bands shall
+   * be part of the subset. For example, <code>[0, 2, 3]</code> would
+   * create a SampleModel containing bands #0, #2 and #3.
+   */
+  public SampleModel createSubsetSampleModel(int[] bands)
+  {
+    int[] subOffsets;
+
+    subOffsets = new int[bands.length];
+    for (int i = 0; i < bands.length; i++)
+      subOffsets[i] = bandOffsets[bands[i]];
+
+    return new PixelInterleavedSampleModel(dataType, width, height,
+                                           pixelStride, scanlineStride,
+                                           subOffsets);
+  }
+}
Index: java/awt/image/RGBImageFilter.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/RGBImageFilter.java,v
retrieving revision 1.2
diff -u -r1.2 RGBImageFilter.java
--- java/awt/image/RGBImageFilter.java	11 Oct 2003 17:19:46 -0000	1.2
+++ java/awt/image/RGBImageFilter.java	6 Sep 2004 16:35:51 -0000
@@ -46,7 +46,7 @@
  */
 public abstract class RGBImageFilter extends ImageFilter
 {
-    protected ColorModel origmodel = ColorModel.getRGBdefault();
+    protected ColorModel origmodel;
 
     protected ColorModel newmodel;
     
@@ -79,6 +79,10 @@
 
 	if( ( model instanceof IndexColorModel) && canFilterIndexColorModel  ) {
 		newmodel = filterIndexColorModel( (IndexColorModel) model );
+		consumer.setColorModel(newmodel);
+	    }
+	else {
+		consumer.setColorModel(ColorModel.getRGBdefault());
 	    }
     }
     
@@ -126,7 +130,7 @@
 
     private int makeColor( byte a, byte r, byte g, byte b )
     {
-	return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (b << 8) | 0xff & g ); 
+	return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); 
     }
 
     /**
@@ -149,11 +153,15 @@
 				int off,
 				int scansize)
     {
-	int xp, yp;
+	int xp, yp, i;
 
+	i = 0;
 	for( xp = x; xp < ( x + w); xp++ )
 	    for( yp = y; yp < (y + h); yp++ )
-		 pixels[ off + yp * scansize + xp ] = filterRGB( xp, yp, pixels[ off + yp * scansize + xp ] );
+	    {
+		pixels[i] = filterRGB( xp, yp, pixels[i] );
+		i++;
+	    }
     }
 
 
@@ -172,15 +180,19 @@
      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
      */
     public void setPixels(int x, int y, int w, int h, 
-	   ColorModel model, byte[] pixels, int offset, int scansize)
+                          ColorModel model, byte[] pixels,
+                          int offset, int scansize)
     {
-	if( model == origmodel ) {
+	if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+	{
 	    consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
-	} else {
-	    //FIXME
-	    //convert to proper CM
-	    int pixelsi[] = new int[ pixels.length / 4 ];
-	    filterRGBPixels( x, y, w, h, pixelsi, offset, scansize );
+	}
+	else
+	{
+	    int intPixels[] =
+		convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
+	    filterRGBPixels( x, y, w, h, intPixels, offset, scansize );
+	    consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize);
 	}
     }
 
@@ -199,35 +211,53 @@
      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
      */
     public void setPixels(int x, int y, int w, int h, 
-           ColorModel model, int[] pixels, int offset, int scansize)
+                          ColorModel model, int[] pixels,
+                          int offset, int scansize)
     {
-	if( model == origmodel ) {
+	if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+	{
 	    consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
-	} else {
+	}
+	else
+	{
+	    //FIXME: Store the filtered pixels in a separate temporary buffer?
 	    convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
 	    filterRGBPixels( x, y, w, h, pixels, offset, scansize );
+	    consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize);
 	}
     }
 
-    private void convertColorModelToDefault( int x, int y, int w, int h, 
-	    ColorModel model, int pixels[], int offset, int scansize)
-	{
-	int xp, yp;
+    private int[] convertColorModelToDefault(int x, int y, int w, int h, 
+                                            ColorModel model, byte pixels[],
+                                            int offset, int scansize)
+    {
+	int intPixels[] = new int[pixels.length];
+	for (int i = 0; i < pixels.length; i++)
+	    intPixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+	return intPixels;
+    }
 
-	for( xp = x; xp < ( x + w); xp++ )
-	    for( yp = y; yp < (y + h); yp++ )
-		 pixels[ offset + yp * scansize + xp ] =  makeColorbyDefaultCM( pixels[ offset + yp * scansize + xp ] );
-	    
-	}
-    private int makeColorbyDefaultCM( int rgb ) 
-	{
-	    return makeColor( origmodel.getRed( rgb ), origmodel.getGreen( rgb ), origmodel.getGreen( rgb ), origmodel.getBlue( rgb ) );
-	}
+    private void convertColorModelToDefault(int x, int y, int w, int h, 
+                                            ColorModel model, int pixels[],
+                                            int offset, int scansize)
+    {
+	for (int i = 0; i < pixels.length; i++)
+	    pixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+    }
+
+    private int makeColorbyDefaultCM(ColorModel model, byte rgb) 
+    {
+	return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 );
+    }
 
+    private int makeColorbyDefaultCM(ColorModel model, int rgb) 
+    {
+	return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) );
+    }
 
     private int makeColor( int a, int r, int g, int b )
     {
-	return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (b << 8) | 0xff & g ); 
+	return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); 
     }
 
 
Index: java/awt/image/Raster.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/Raster.java,v
retrieving revision 1.6
diff -u -r1.6 Raster.java
--- java/awt/image/Raster.java	25 Sep 2003 18:35:44 -0000	1.6
+++ java/awt/image/Raster.java	6 Sep 2004 16:35:51 -0000
@@ -452,4 +452,25 @@
 				  y-sampleModelTranslateY,
 				  w, h, b, dArray, dataBuffer);
   }
+  
+  /**
+   * Create a String representing the stat of this Raster.
+   * @return A String representing the stat of this Raster.
+   * @see java.lang.Object#toString()
+   */
+  public String toString()
+  {
+    StringBuffer result = new StringBuffer();
+    
+    result.append(getClass().getName());
+    result.append("[(");
+    result.append(minX).append(",").append(minY).append("), ");
+    result.append(width).append(" x ").append(height).append(",");
+    result.append(sampleModel).append(",");
+    result.append(dataBuffer);
+    result.append("]");
+    
+    return result.toString();
+  }
+  
 }
Index: java/awt/image/ReplicateScaleFilter.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/ReplicateScaleFilter.java,v
retrieving revision 1.1
diff -u -r1.1 ReplicateScaleFilter.java
--- java/awt/image/ReplicateScaleFilter.java	24 Jan 2002 01:05:12 -0000	1.1
+++ java/awt/image/ReplicateScaleFilter.java	6 Sep 2004 16:35:51 -0000
@@ -104,7 +104,27 @@
      */
     public void setDimensions(int width, int height)
     {
-	consumer.setDimensions(width, height);
+	srcWidth = width;
+	srcHeight = height;
+
+	/* If either destHeight or destWidth is < 0, the image should
+	   maintain its original aspect ratio.  When both are < 0,
+	   just maintain the original width and height. */
+	if (destWidth < 0 && destHeight < 0)
+        {
+	    destWidth = width;
+	    destHeight = height;
+	}
+	else if (destWidth < 0)
+	{
+	    destWidth = (int) (width * ((double) destHeight / srcHeight));
+	}
+	else if (destHeight < 0)
+	{
+	    destHeight = (int) (height * ((double) destWidth / srcWidth));
+	}
+
+	consumer.setDimensions(destWidth, destHeight);
     }
 
     /**
@@ -136,7 +156,18 @@
     public void setPixels(int x, int y, int w, int h, 
 	   ColorModel model, byte[] pixels, int offset, int scansize)
     {
-	consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+	double rx = ((double) srcWidth) / destWidth;
+	double ry = ((double) srcHeight) / destHeight;
+
+	int destScansize = (int) Math.round(scansize / rx);
+
+	byte[] destPixels = replicatePixels(x, y, w, h,
+                                           model, pixels, offset, scansize,
+	                                   rx, ry, destScansize);
+
+	consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
+                           (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
+                           model, destPixels, 0, destScansize);
     }
 
     /**
@@ -156,8 +187,58 @@
     public void setPixels(int x, int y, int w, int h, 
            ColorModel model, int[] pixels, int offset, int scansize)
     {
-	consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
+	double rx = ((double) srcWidth) / destWidth;
+	double ry = ((double) srcHeight) / destHeight;
+
+	int destScansize = (int) Math.round(scansize / rx);
+
+	int[] destPixels = replicatePixels(x, y, w, h,
+                                           model, pixels, offset, scansize,
+	                                   rx, ry, destScansize);
+
+	consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
+                           (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
+                           model, destPixels, 0, destScansize);
     }
 
+    protected byte[] replicatePixels(int srcx, int srcy, int srcw, int srch,
+                                    ColorModel model, byte[] srcPixels,
+                                    int srcOffset, int srcScansize,
+                                    double rx, double ry, int destScansize)
+    {
+	byte[] destPixels =
+	  new byte[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
+
+	int a, b;
+	for (int i = 0; i < destPixels.length; i++)
+	{
+	    a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
+	    b = (int) ((i % destScansize) * rx);
+	    if ((a + b + srcOffset) < srcPixels.length)
+		destPixels[i] = srcPixels[a + b + srcOffset];
+	}
+
+	return destPixels;
+    }
+
+    protected int[] replicatePixels(int srcx, int srcy, int srcw, int srch,
+                                    ColorModel model, int[] srcPixels,
+                                    int srcOffset, int srcScansize,
+                                    double rx, double ry, int destScansize)
+    {
+	int[] destPixels =
+	  new int[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
+
+	int a, b;
+	for (int i = 0; i < destPixels.length; i++)
+	{
+	    a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
+	    b = (int) ((i % destScansize) * rx);
+	    if ((a + b + srcOffset) < srcPixels.length)
+		destPixels[i] = srcPixels[a + b + srcOffset];
+	}
+
+	return destPixels;
+    }
 }
 
Index: java/awt/image/SampleModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/SampleModel.java,v
retrieving revision 1.6
diff -u -r1.6 SampleModel.java
--- java/awt/image/SampleModel.java	22 Jan 2002 22:40:10 -0000	1.6
+++ java/awt/image/SampleModel.java	6 Sep 2004 16:35:51 -0000
@@ -58,7 +58,9 @@
 
   public SampleModel(int dataType, int w, int h, int numBands)
   {
-    if ((w<=0) || (h<=0)) throw new IllegalArgumentException();
+    if ((w <= 0) || (h <= 0)) 
+      throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
+                                         +(h <= 0 ? " height<=0" : " height is ok"));
 	
     // FIXME: How can an int be greater than Integer.MAX_VALUE?
     // FIXME: How do we identify an unsupported data type?
@@ -68,7 +70,7 @@
     this.height = h;
     this.numBands = numBands;  
   }
-
+  
   public final int getWidth()
   {
     return width;
Index: java/awt/image/ShortLookupTable.java
===================================================================
RCS file: java/awt/image/ShortLookupTable.java
diff -N java/awt/image/ShortLookupTable.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/awt/image/ShortLookupTable.java	6 Sep 2004 16:35:51 -0000
@@ -0,0 +1,162 @@
+/* ShortLookupTable.java -- Java class for a pixel translation table.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * ShortLookupTable represents translation arrays for pixel values.  It wraps
+ * one or more data arrays for each layer (or component) in an image, such as
+ * Alpha, R, G, and B.  When doing translation, the offset is subtracted from
+ * the pixel values to allow a subset of an array to be used.
+ *
+ * @author <a href="mailto:jlquinn@optonline.net">Jerry Quinn</a>
+ * @version 1.0
+ */
+public class ShortLookupTable extends LookupTable
+{
+  // Array of translation tables.
+  private short data[][];
+
+  /**
+   * Creates a new <code>ShortLookupTable</code> instance.
+   *
+   * Offset is subtracted from pixel values when looking up in the translation
+   * tables.  If data.length is one, the same table is applied to all pixel
+   * components.
+   * 
+   * @param offset Offset to be subtracted.
+   * @param data Array of lookup tables.
+   * @exception IllegalArgumentException if offset < 0 or data.length < 1.
+   */
+  public ShortLookupTable(int offset, short[][] data)
+    throws IllegalArgumentException
+  {
+    super(offset, data.length);
+    this.data = data;
+  }
+
+  /**
+   * Creates a new <code>ShortLookupTable</code> instance.
+   *
+   * Offset is subtracted from pixel values when looking up in the translation
+   * table.  The same table is applied to all pixel components.
+   * 
+   * @param offset Offset to be subtracted.
+   * @param data Lookup table for all components.
+   * @exception IllegalArgumentException if offset < 0.
+   */
+  public ShortLookupTable(int offset, short[] data)
+    throws IllegalArgumentException
+  {
+    super(offset, 1);
+    this.data = new short[][] {data};
+  }
+
+  /** Return the lookup tables. */
+  public final short[][] getTable()
+  {
+    return data;
+  }
+
+  /**
+   * Return translated values for a pixel.
+   *
+   * For each value in the pixel src, use the value minus offset as an index
+   * in the component array and copy the value there to the output for the
+   * component.  If dest is null, the output is a new array, otherwise the
+   * translated values are written to dest.  Dest can be the same array as
+   * src.
+   *
+   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+   * translation arrays.
+   *
+   * @param src Component values of a pixel.
+   * @param dest Destination array for values, or null.
+   * @return Translated values for the pixel.
+   */
+  public int[] lookupPixel(int[] src, int[] dst)
+    throws ArrayIndexOutOfBoundsException
+  {
+    if (dst == null)
+      dst = new int[numComponents];
+
+    if (data.length == 1)
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[0][src[i] - offset];
+    else
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[i][src[i] - offset];
+      
+    return dst;
+  }
+
+  /**
+   * Return translated values for a pixel.
+   *
+   * For each value in the pixel src, use the value minus offset as an index
+   * in the component array and copy the value there to the output for the
+   * component.  If dest is null, the output is a new array, otherwise the
+   * translated values are written to dest.  Dest can be the same array as
+   * src.
+   *
+   * For example, if the pixel src is [2, 4, 3], and offset is 1, the output
+   * is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
+   * translation arrays.
+   *
+   * @param src Component values of a pixel.
+   * @param dest Destination array for values, or null.
+   * @return Translated values for the pixel.
+   */
+  public short[] lookupPixel(short[] src, short[] dst)
+    throws ArrayIndexOutOfBoundsException
+  {
+    if (dst == null)
+      dst = new short[numComponents];
+
+    if (data.length == 1)
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[0][((int)src[i]) - offset];
+    else
+      for (int i=0; i < src.length; i++)
+	dst[i] = data[i][((int)src[i]) - offset];
+      
+    return dst;
+
+  }
+}
Index: java/awt/image/SinglePixelPackedSampleModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/SinglePixelPackedSampleModel.java,v
retrieving revision 1.6
diff -u -r1.6 SinglePixelPackedSampleModel.java
--- java/awt/image/SinglePixelPackedSampleModel.java	9 Jan 2004 08:58:57 -0000	1.6
+++ java/awt/image/SinglePixelPackedSampleModel.java	6 Sep 2004 16:35:51 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003  Free Software Foundation
+/* Copyright (C) 2000, 2002, 2003, 2004  Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -162,6 +162,63 @@
 			   1  // length
 			   );
   }
+  
+  /**
+   * This is a more efficient implementation of the default implementation in the super
+   * class. 
+   * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+   * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+   * @param w The width of the pixel rectangle to store in <code>obj</code>.
+   * @param h The height of the pixel rectangle to store in <code>obj</code>.
+   * @param obj The primitive array to store the pixels into or null to force creation.
+   * @param data The DataBuffer that is the source of the pixel data.
+   * @return The primitive array containing the pixel data.
+   * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+   */
+  public Object getDataElements(int x, int y, int w, int h, Object obj,
+							DataBuffer data)
+  {
+    int size = w*h;
+    int dataSize = size;
+    Object pixelData = null;
+    switch (getTransferType())
+    {
+      case DataBuffer.TYPE_BYTE:
+        pixelData = ((DataBufferByte) data).getData();
+        if (obj == null) obj = new byte[dataSize];
+        break;
+       case DataBuffer.TYPE_USHORT:
+         pixelData = ((DataBufferUShort) data).getData();
+         if (obj == null) obj = new short[dataSize];
+         break;
+        case DataBuffer.TYPE_INT:
+          pixelData = ((DataBufferInt) data).getData();
+          if (obj == null) obj = new int[dataSize];
+          break;
+         default:
+             // Seems like the only sensible thing to do.
+           throw new ClassCastException();
+      }
+      if(x==0 && scanlineStride == w)
+      { 
+        // The full width need to be copied therefore we can copy in one shot.
+        System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj, 0, size);
+      }
+      else
+      {  
+        // Since we do not need the full width we need to copy line by line.
+        int outOffset = 0;
+        int dataOffset = scanlineStride*y + x + data.getOffset();
+        for (int yy = y; yy<(y+h); yy++)
+        {
+          System.arraycopy(pixelData, dataOffset, obj, outOffset, w);
+          dataOffset += scanlineStride;
+          outOffset += w;
+        }
+      }
+    return obj;
+  }
+  
 
   public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
   {
@@ -201,7 +258,51 @@
     int samples = data.getElem(offset);
     return (samples & bitMasks[b]) >>> bitOffsets[b];
   }
-
+  
+  /**
+   * This method implements a more efficient way to set data elements than the default
+   * implementation of the super class. It sets the data elements line by line instead 
+   * of pixel by pixel.
+   * @param x The x-coordinate of the data elements in <code>obj</code>.
+   * @param y The y-coordinate of the data elements in <code>obj</code>.
+   * @param w The width of the data elements in <code>obj</code>.
+   * @param h The height of the data elements in <code>obj</code>.
+   * @param obj The primitive array containing the data elements to set.
+   * @param data The DataBuffer to store the data elements into.
+   * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+   */
+  public void setDataElements(int x, int y, int w, int h,
+				Object obj, DataBuffer data)
+  {
+    
+    Object pixelData;
+    switch (getTransferType())
+    {
+      case DataBuffer.TYPE_BYTE:
+        pixelData = ((DataBufferByte) data).getData();
+        break;
+       case DataBuffer.TYPE_USHORT:
+         pixelData = ((DataBufferUShort) data).getData();
+         break;
+       case DataBuffer.TYPE_INT:
+         pixelData = ((DataBufferInt) data).getData();
+         break;
+       default:
+          // Seems like the only sensible thing to do.
+          throw new ClassCastException();
+    }
+    
+    int inOffset = 0;
+    int dataOffset = scanlineStride*y + x + data.getOffset();
+    for (int yy=y; yy<(y+h); yy++)
+    {
+      System.arraycopy(obj,inOffset,pixelData,dataOffset,w);
+      dataOffset += scanlineStride;
+      inOffset += w;
+    }
+  }
+  
+  
   public void setDataElements(int x, int y, Object obj, DataBuffer data)
   {
     int offset = scanlineStride*y + x + data.getOffset();
@@ -273,6 +374,39 @@
     data.setElem(offset, samples);
   }
 
+  /**
+   * This method implements a more efficient way to set pixels than the default
+   * implementation of the super class. It copies the pixel components directly
+   * from the input array instead of creating a intermediate buffer.
+   * @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
+   * @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
+   * @param w The width of the pixel rectangle in <code>obj</code>.
+   * @param h The height of the pixel rectangle in <code>obj</code>.
+   * @param obj The primitive array containing the pixels to set.
+   * @param data The DataBuffer to store the pixels into.
+   * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
+   */
+  public void setPixels(int x, int y, int w, int h, int[] iArray,
+						DataBuffer data)
+  {
+    int inOffset = 0;
+    int[] pixel = new int[numBands];
+    for (int yy=y; yy<(y+h); yy++)
+     {
+      int offset = scanlineStride*yy + x;
+      for (int xx=x; xx<(x+w); xx++)
+       { 
+        int samples = 0;
+        for (int b=0; b<numBands; b++)
+          samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
+        data.setElem(0, offset, samples);
+        inOffset += numBands;
+        offset += 1;
+      }
+    }
+  }
+  
+  
   public void setSample(int x, int y, int b, int s, DataBuffer data)
   {
     int offset = scanlineStride*y + x;
@@ -282,4 +416,24 @@
     samples |= (s << bitOffsets[b]) & bitMask;
     data.setElem(offset, samples);
   }
+  
+  /**
+   * Creates a String with some information about this SampleModel.
+   * @return A String describing this SampleModel.
+   * @see java.lang.Object#toString()
+   */
+  public String toString()
+  {
+    StringBuffer result = new StringBuffer();
+    result.append(getClass().getName());
+    result.append("[");
+    result.append("scanlineStride=").append(scanlineStride);
+    for(int i=0; i < bitMasks.length; i+=1)
+    {
+      result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+    }
+    
+    result.append("]");
+    return result.toString();
+  }
 }
Index: java/awt/image/renderable/RenderContext.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/renderable/RenderContext.java,v
retrieving revision 1.1
diff -u -r1.1 RenderContext.java
--- java/awt/image/renderable/RenderContext.java	9 Aug 2002 04:29:59 -0000	1.1
+++ java/awt/image/renderable/RenderContext.java	6 Sep 2004 16:35:51 -0000
@@ -87,24 +87,24 @@
 
   public void preConcatenateTransform(AffineTransform pre)
   {
-    xform.preConcatenate(pre);
+    preConcetenateTransform (pre);
   }
 
-  /** @deprecated Sun can't spell concatenate */
+  /** @deprecated */
   public void preConcetenateTransform(AffineTransform pre)
   {
-    preConcetenateTransform(pre);
+    xform.preConcatenate (pre);
   }
 
   public void concatenateTransform(AffineTransform post)
   {
-    xform.concatenate(post);
+    concetenateTransform (post);
   }
 
-  /** @deprecated Sun can't spell concatenate */
+  /** @deprecated */
   public void concetenateTransform(AffineTransform post)
   {
-    concatenateTransform(post);
+    xform.concatenate (post);
   }
 
   public AffineTransform getTransform()
Index: java/awt/peer/MenuBarPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/peer/MenuBarPeer.java,v
retrieving revision 1.6
diff -u -r1.6 MenuBarPeer.java
--- java/awt/peer/MenuBarPeer.java	11 Oct 2003 18:11:03 -0000	1.6
+++ java/awt/peer/MenuBarPeer.java	6 Sep 2004 16:35:51 -0000
@@ -43,7 +43,6 @@
 public interface MenuBarPeer extends MenuComponentPeer
 {
   void addHelpMenu(Menu menu);
-  void addMenu(Menu menu);
   void delMenu(int index);
 } // interface MenuBarPeer 
 
Index: java/awt/peer/MenuPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/peer/MenuPeer.java,v
retrieving revision 1.6
diff -u -r1.6 MenuPeer.java
--- java/awt/peer/MenuPeer.java	11 Oct 2003 18:11:03 -0000	1.6
+++ java/awt/peer/MenuPeer.java	6 Sep 2004 16:35:51 -0000
@@ -43,7 +43,6 @@
 public interface MenuPeer extends MenuItemPeer
 {
   void addItem (MenuItem item);
-  void addSeparator ();
   void delItem (int index);
 }
 
Index: javax/swing/AbstractAction.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractAction.java,v
retrieving revision 1.4
diff -u -r1.4 AbstractAction.java
--- javax/swing/AbstractAction.java	9 Jan 2004 10:18:47 -0000	1.4
+++ javax/swing/AbstractAction.java	6 Sep 2004 16:35:52 -0000
@@ -56,157 +56,211 @@
 {
   static final long serialVersionUID = -6803159439231523484L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * enabled
-	 */
-	protected boolean enabled = true;
-
-	/**
-	 * changeSupport
-	 */
-	protected SwingPropertyChangeSupport changeSupport =
-				new SwingPropertyChangeSupport(this);
-
-	/**
-	 * store
-	 */
-	private transient HashMap store = new HashMap();
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor AbstractAction
-	 */
-	public AbstractAction() {
-		this(""); // TODO: default name
-	} // AbstractAction()
-
-	/**
-	 * Constructor AbstractAction
-	 * @param name TODO
-	 */
-	public AbstractAction(String name) {
-		this(name, null); // TODO: default icon??
-	} // AbstractAction()
-
-	/**
-	 * Constructor AbstractAction
-	 * @param name TODO
-	 * @param icon TODO
-	 */
-	public AbstractAction(String name, Icon icon) {
-		putValue(NAME, name);
-		putValue(SMALL_ICON, icon);
-	} // AbstractAction()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * readObject
-	 * @param stream TODO
-	 * @exception ClassNotFoundException TODO
-	 * @exception IOException TODO
-	 */
-	private void readObject(ObjectInputStream stream) 
-			throws ClassNotFoundException, IOException {
-		// TODO
-	} // readObject()
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * clone
-	 * @exception CloneNotSupportedException TODO
-	 * @returns Object
-	 */
-	protected Object clone() throws CloneNotSupportedException {
-		// What to do??
-		return null;
-	} // clone()
-
-	/**
-	 * getValue
-	 * @param key TODO
-	 * @returns Object
-	 */
-	public Object getValue(String key) {
-		return store.get(key);
-	} // getValue()
-
-	/**
-	 * putValue
-	 * @param key TODO
-	 * @param value TODO
-	 */
-	public void putValue(String key, Object value) {
-		store.put(key, value);
-	} // putValue()
-
-	/**
-	 * isEnabled
-	 * @returns boolean
-	 */
-	public boolean isEnabled() {
-		return enabled;
-	} // isEnabled()
-
-	/**
-	 * setEnabled
-	 * @param enabled TODO
-	 */
-	public void setEnabled(boolean enabled) {
-		this.enabled = enabled;
-	} // setEnabled()
-
-	/**
-	 * getKeys
-	 * @returns Object[]
-	 */
-	public Object[] getKeys() {
-		return store.keySet().toArray();
-	} // getKeys()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	protected void firePropertyChange(String propertyName,
-			Object oldValue, Object newValue) {
-		changeSupport.firePropertyChange(propertyName, oldValue, newValue);
-	} // firePropertyChange()
-
-	/**
-	 * addPropertyChangeListener
-	 * @param listener TODO
-	 */
-	public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
-		changeSupport.addPropertyChangeListener(listener);
-	} // addPropertyChangeListener()
-
-	/**
-	 * removePropertyChangeListener
-	 * @param listener TODO
-	 */
-	public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
-		changeSupport.removePropertyChangeListener(listener);
-	} // removePropertyChangeListener()
+  /**
+   * enabled
+   */
+  protected boolean enabled = true;
+  
+  public static final String ENABLED_PROPERTY = "enabled";
+
+  /**
+   * changeSupport
+   */
+  protected SwingPropertyChangeSupport changeSupport =
+    new SwingPropertyChangeSupport(this);
+
+  /**
+   * store
+   */
+  private transient HashMap store = new HashMap();
+
+  /**
+   * Constructor AbstractAction
+   */
+  public AbstractAction()
+  {
+    this(""); // TODO: default name
+  }
+
+  /**
+   * Constructor AbstractAction
+   *
+   * @param name TODO
+   */
+  public AbstractAction(String name)
+  {
+    this(name, null); // TODO: default icon??
+  }
+
+  /**
+   * Constructor AbstractAction
+   *
+   * @param name TODO
+   * @param icon TODO
+   */
+  public AbstractAction(String name, Icon icon)
+  {
+    putValue(NAME, name);
+    putValue(SMALL_ICON, icon);
+  }
+
+  /**
+   * readObject
+   *
+   * @param stream the stream to read from
+   *
+   * @exception ClassNotFoundException TODO
+   * @exception IOException if an error occurs
+   */
+  private void readObject(ObjectInputStream stream)
+    throws ClassNotFoundException, IOException
+  {
+    // TODO
+  }
+
+  /**
+   * writeObject
+   *
+   * @param stream the stream to write to
+   *
+   * @exception IOException if an error occurs
+   */
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+    // TODO
+  }
+
+  /**
+   * clone
+   *
+   * @return Object
+   *
+   * @exception CloneNotSupportedException TODO
+   */
+  protected Object clone() throws CloneNotSupportedException
+  {
+    AbstractAction copy = (AbstractAction) super.clone();
+    copy.store = (HashMap) store.clone();
+    return copy;
+  }
+
+  /**
+   * Returns a value for a given key from the built-in store.
+   *
+   * @param key the key to get the value for
+   *
+   * @return Object
+   */
+  public Object getValue(String key)
+  {
+    return store.get(key);
+  }
+
+  /**
+   * Puts a key/value pair into the built-in store.
+   *
+   * @param key the key
+   * @param value the value
+   */
+  public void putValue(String key, Object value)
+  {
+    Object old = getValue(key);
+    if (old != value)
+    {
+      store.put(key, value);
+      firePropertyChange(key, old, value);
+    }
+  }
+
+  /**
+   * isEnabled
+   *
+   * @return boolean
+   */
+  public boolean isEnabled()
+  {
+    return enabled;
+  }
+
+  /**
+   * setEnabled
+   *
+   * @param enabled TODO
+   */
+  public void setEnabled(boolean enabled)
+  {
+    if (enabled != this.enabled)
+    {
+      this.enabled = enabled;
+      firePropertyChange(ENABLED_PROPERTY, !this.enabled, this.enabled);
+    }
+  }
+
+  /**
+   * getKeys
+   * @returns Object[]
+   */
+  public Object[] getKeys()
+  {
+    return store.keySet().toArray();
+  }
+
+  /**
+   * This method fires a PropertyChangeEvent given the propertyName 
+   * and the old and new values.
+   *
+   * @param propertyName The property that changed.
+   * @param oldValue The old value of the property.
+   * @param newValue The new value of the property.
+   */
+  protected void firePropertyChange(String propertyName, Object oldValue,
+                                    Object newValue)
+  {
+    changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+  }
+  
+  /**
+   * This convenience method fires a PropertyChangeEvent given 
+   * the propertyName and the old and new values.
+   *
+   * @param propertyName The property that changed.
+   * @param oldValue The old value of the property.
+   * @param newValue The new value of the property.
+   */
+  private void firePropertyChange(String propertyName, boolean oldValue, boolean newValue)
+  {
+    changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+  }
+
+  /**
+   * addPropertyChangeListener
+   *
+   * @param listener the listener to add
+   */
+  public void addPropertyChangeListener(PropertyChangeListener listener)
+  {
+    changeSupport.addPropertyChangeListener(listener);
+  }
+
+  /**
+   * removePropertyChangeListener
+   *
+   * @param listener the listener to remove
+   */
+  public void removePropertyChangeListener(PropertyChangeListener listener)
+  {
+    changeSupport.removePropertyChangeListener(listener);
+  }
+
+  /**
+   * Returns all registered listeners.
+   *
+   * @return array of listeners.
+   * 
+   * @since 1.4
+   */
+  public PropertyChangeListener[] getPropertyChangeListeners()
+  {
+    return changeSupport.getPropertyChangeListeners();
+  }
 }
Index: javax/swing/AbstractButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractButton.java,v
retrieving revision 1.3
diff -u -r1.3 AbstractButton.java
--- javax/swing/AbstractButton.java	14 Jul 2003 05:33:30 -0000	1.3
+++ javax/swing/AbstractButton.java	6 Sep 2004 16:35:53 -0000
@@ -1,5 +1,5 @@
 /* AbstractButton.java -- Provides basic button functionality.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Graphics;
@@ -50,12 +49,13 @@
 import java.awt.event.FocusListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+
 import javax.accessibility.AccessibleAction;
 import javax.accessibility.AccessibleIcon;
-import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleRelationSet;
+import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleText;
 import javax.accessibility.AccessibleValue;
 import javax.swing.event.ChangeEvent;
@@ -63,739 +63,1864 @@
 import javax.swing.plaf.ButtonUI;
 import javax.swing.text.AttributeSet;
 
+
 /**
- * Provides basic button functionality
+ * <p>The purpose of this class is to serve as a facade over a number of
+ * classes which collectively represent the semantics of a button: the
+ * button's model, its listeners, its action, and its look and feel. Some
+ * parts of a button's state are stored explicitly in this class, other
+ * parts are delegates to the model. Some methods related to buttons are
+ * implemented in this class, other methods pass through to the current 
+ * model or look and feel.</p>
+ *
+ * <p>Furthermore this class is supposed to serve as a base class for
+ * several kinds of buttons with similar but non-identical semantics:
+ * toggle buttons (radio buttons and checkboxes), simple "push" buttons,
+ * menu items.</p>
+ *
+ * <p>Buttons have many properties, some of which are stored in this class
+ * while others are delegated to the button's model. The following properties
+ * are available:</p>
+ *
+ * <table>
+ * <tr><th>Property               </th><th>Stored in</th><th>Bound?</th></tr>
+ *
+ * <tr><td>action                 </td><td>button</td> <td>no</td></tr>
+ * <tr><td>actionCommand          </td><td>model</td>  <td>no</td></tr>
+ * <tr><td>borderPainted          </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>contentAreaFilled      </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>disabledIcon           </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>disabledSelectedIcon   </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr>
+ * <tr><td>enabled                </td><td>model</td>  <td>no</td></tr>
+ * <tr><td>focusPainted           </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>horizontalAlignment    </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>icon                   </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>iconTextGap            </td><td>button</td> <td>no</td></tr>
+ * <tr><td>label (same as text)   </td><td>model</td>  <td>yes</td></tr>
+ * <tr><td>margin                 </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>multiClickThreshold    </td><td>button</td> <td>no</td></tr>
+ * <tr><td>pressedIcon            </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverEnabled        </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverIcon           </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverSelectedIcon   </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>selected               </td><td>model</td>  <td>no</td></tr>
+ * <tr><td>selectedIcon           </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>selectedObjects        </td><td>button</td> <td>no</td></tr>
+ * <tr><td>text                   </td><td>model</td>  <td>yes</td></tr>
+ * <tr><td>UI                     </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>verticalAlignment      </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>verticalTextPosition   </td><td>button</td> <td>yes</td></tr>
+ *
+ * </table>
+ *
+ * <p>The various behavioral aspects of these properties follows:</p>
+ *
+ * <ul> 
+ *
+ * <li>When non-bound properties stored in the button change, the button
+ * fires ChangeEvents to its ChangeListeners.</li>
+ * 
+ * <li>When bound properties stored in the button change, the button fires
+ * PropertyChangeEvents to its PropertyChangeListeners</li>
+ *
+ * <li>If any of the model's properties change, it fires a ChangeEvent to
+ * its ChangeListeners, which include the button.</li>
+ *
+ * <li>If the button receives a ChangeEvent from its model, it will
+ * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's
+ * "source" property set to refer to the button, rather than the model. The
+ * the button will request a repaint, to paint its updated state.</li>
+ *
+ * <li>If the model's "selected" property changes, the model will fire an
+ * ItemEvent to its ItemListeners, which include the button, in addition to
+ * the ChangeEvent which models the property change. The button propagates
+ * ItemEvents directly to its ItemListeners.</li>
+ *
+ * <li>If the model's armed and pressed properties are simultaneously
+ * <code>true</code>, the model will fire an ActionEvent to its
+ * ActionListeners, which include the button. The button will propagate
+ * this ActionEvent to its ActionListeners, with the ActionEvent's "source"
+ * property set to refer to the button, rather than the model.</li>
+ *
+ * </ul>
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
+ * @author Graydon Hoare (graydon@redhat.com)
  */
+
 public abstract class AbstractButton extends JComponent
   implements ItemSelectable, SwingConstants
 {
-  Icon default_icon, pressed_button, disabled_button,
-    selected_button, disabled_selected_button, current_icon;
+  private static final long serialVersionUID = -937921345538462020L;
+  
+  /** The icon displayed by default. */
+  Icon default_icon;
+
+  /** The icon displayed when the button is pressed. */
+  Icon pressed_icon;
+
+  /** The icon displayed when the button is disabled. */
+  Icon disabeldIcon;
+
+  /** The icon displayed when the button is selected. */
+  Icon selectedIcon;
+
+  /** The icon displayed when the button is selected but disabled. */
+  Icon disabledSelectedIcon;
+
+  /** The icon displayed when the button is rolled over. */
+  Icon rolloverIcon;
+
+  /** The icon displayed when the button is selected and rolled over. */
+  Icon rolloverSelectedIcon;
+
+  /** The icon currently displayed. */
+  Icon current_icon;
+
+  /** The text displayed in the button. */
   String text;
 
-  int vert_align = CENTER;
-  int hori_align = CENTER;
-  int hori_text_pos = CENTER;
-  int vert_text_pos = CENTER;
-
-  boolean paint_border = true, paint_focus;
-  Action action_taken;
-  ButtonModel model;
+  /** The gap between icon and text, if both icon and text are non-<code>null</code>. */
+  int iconTextGap;
+
+  /** The vertical alignment of the button's text and icon. */
+  int verticalAlignment;
+
+  /** The horizontal alignment of the button's text and icon. */
+  int horizontalAlignment;
+
+  /** The horizontal position of the button's text relative to its icon. */
+  int horizontalTextPosition;
+
+  /** The vertical position of the button's text relative to its icon. */
+  int verticalTextPosition;
+
+  /** Whether or not the button paints its border. */
+  boolean borderPainted;
+
+  /** Whether or not the button paints its focus state. */
+  boolean focusPainted;
+
+  /** Whether or not the button fills its content area. */
+  boolean contentAreaFilled;
+  
+  /** Whether rollover is enabled. */
+  boolean rollOverEnabled;
+
+  /** The action taken when the button is clicked. */
+  Action action;
+
+  /** The button's current state. */
+  protected ButtonModel model;
+
+  /** The margin between the button's border and its label. */
   Insets margin;
 
+  /** A hint to the look and feel class, suggesting which character in the
+   * button's label should be underlined when drawing the label. */
+  int mnemonicIndex;
+
+  /** Listener the button uses to receive ActionEvents from its model.  */
+  protected ActionListener actionListener;
+
+  /** Listener the button uses to receive ItemEvents from its model.  */
+  protected ItemListener itemListener;
+
+  /** Listener the button uses to receive ChangeEvents from its model.  */  
+  protected ChangeListener changeListener;
+
+  /** The time in miliseconds in which clicks get coalesced into a single
+   * <code>ActionEvent</code>. */
+  long multiClickThreshhold;
+  
+  /** Listener the button uses to receive PropertyChangeEvents from its
+      Action. */
+  PropertyChangeListener actionPropertyChangeListener;
+  
+  /** ChangeEvent that is fired to button's ChangeEventListeners  */  
+  private ChangeEvent changeEvent = new ChangeEvent(this);
+  
+  /** Fired in a PropertyChangeEvent when the "borderPainted" property changes. */
+  public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
+  
+  /** Fired in a PropertyChangeEvent when the "contentAreaFilled" property changes. */
+  public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY = "contentAreaFilled";
+  
+  /** Fired in a PropertyChangeEvent when the "disabledIcon" property changes. */
+  public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon";
+  
+  /** Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property changes. */
+  public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY = "disabledSelectedIcon";
+  
+  /** Fired in a PropertyChangeEvent when the "focusPainted" property changes. */
   public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted";
 
+  /** Fired in a PropertyChangeEvent when the "horizontalAlignment" property changes. */
+  public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY = "horizontalAlignment";
+
+  /** Fired in a PropertyChangeEvent when the "horizontalTextPosition" property changes. */
+  public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY = "horizontalTextPosition";
+
+  /** Fired in a PropertyChangeEvent when the "icon" property changes. */
+  public static final String ICON_CHANGED_PROPERTY = "icon";
+
+  /** Fired in a PropertyChangeEvent when the "margin" property changes. */
+  public static final String MARGIN_CHANGED_PROPERTY = "margin";
+
+  /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */
+  public static final String MNEMONIC_CHANGED_PROPERTY = "mnemonic";
+
+  /** Fired in a PropertyChangeEvent when the "model" property changes. */
+  public static final String MODEL_CHANGED_PROPERTY = "model";
+
+  /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */
+  public static final String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon";
+
+  /** Fired in a PropertyChangeEvent when the "rolloverEnabled" property changes. */
+  public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY = "rolloverEnabled";
+
+  /** Fired in a PropertyChangeEvent when the "rolloverIcon" property changes. */
+  public static final String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon";
+  
+  /** Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property changes. */
+  public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY = "rolloverSelectedIcon";
+  
+  /** Fired in a PropertyChangeEvent when the "selectedIcon" property changes. */
+  public static final String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon";
+
+  /** Fired in a PropertyChangeEvent when the "text" property changes. */
+  public static final String TEXT_CHANGED_PROPERTY = "text";
+
+  /** Fired in a PropertyChangeEvent when the "verticalAlignment" property changes. */
+  public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY = "verticalAlignment";
+
+  /** Fired in a PropertyChangeEvent when the "verticalTextPosition" property changes. */
+  public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY = "verticalTextPosition";
+
   /**
-   * AccessibleAbstractButton
+   * A Java Accessibility extension of the AbstractButton.
    */
-  protected abstract class AccessibleAbstractButton 
-    extends AccessibleJComponent 
-    implements AccessibleAction, AccessibleValue, AccessibleText {
-
-    /**
-     * Constructor AccessibleAbstractButton
-     * @param component TODO
-     */
-    protected AccessibleAbstractButton(AbstractButton component) {
-      super(component);
-      // TODO
-    } // AccessibleAbstractButton()
-
-    /**
-     * getAccessibleStateSet
-     * @returns AccessibleStateSet
-     */
-    public AccessibleStateSet getAccessibleStateSet() {
-      return null; // TODO
-    } // getAccessibleStateSet()
-
-    /**
-     * getAccessibleName
-     * @returns String
-     */
-    public String getAccessibleName() {
-      return null; // TODO
-    } // getAccessibleName()
-
-    /**
-     * getAccessibleIcon
-     * @returns AccessibleIcon[]
-     */
-    public AccessibleIcon[] getAccessibleIcon() {
-      return null; // TODO
-    } // getAccessibleIcon()
-
-    /**
-     * getAccessibleRelationSet
-     * @returns AccessibleRelationSet
-     */
-    public AccessibleRelationSet getAccessibleRelationSet() {
-      return null; // TODO
-    } // getAccessibleRelationSet()
-
-    /**
-     * getAccessibleAction
-     * @returns AccessibleAction
-     */
-    public AccessibleAction getAccessibleAction() {
-      return null; // TODO
-    } // getAccessibleAction()
-
-    /**
-     * getAccessibleValue
-     * @returns AccessibleValue
-     */
-    public AccessibleValue getAccessibleValue() {
-      return null; // TODO
-    } // getAccessibleValue()
-
-    /**
-     * getAccessibleActionCount
-     * @returns int
-     */
-    public int getAccessibleActionCount() {
+  protected abstract class AccessibleAbstractButton
+    extends AccessibleJComponent implements AccessibleAction, AccessibleValue,
+                                            AccessibleText
+  {
+    private static final long serialVersionUID = -5673062525319836790L;
+    
+    protected AccessibleAbstractButton()
+    {
+    }
+
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null; // TODO
+    }
+
+    public String getAccessibleName()
+    {
+      return null; // TODO
+    }
+
+    public AccessibleIcon[] getAccessibleIcon()
+    {
+      return null; // TODO
+    }
+
+    public AccessibleRelationSet getAccessibleRelationSet()
+    {
+      return null; // TODO
+    }
+
+    public AccessibleAction getAccessibleAction()
+    {
+      return null; // TODO
+    }
+
+    public AccessibleValue getAccessibleValue()
+    {
+      return null; // TODO
+    }
+
+    public int getAccessibleActionCount()
+    {
       return 0; // TODO
-    } // getAccessibleActionCount()
+    }
 
-    /**
-     * getAccessibleActionDescription
-     * @param value0 TODO
-     * @returns String
-     */
-    public String getAccessibleActionDescription(int value0) {
-      return null; // TODO
-    } // getAccessibleActionDescription()
-
-    /**
-     * doAccessibleAction
-     * @param value0 TODO
-     * @returns boolean
-     */
-    public boolean doAccessibleAction(int value0) {
+    public String getAccessibleActionDescription(int value0)
+    {
+      return null; // TODO
+    }
+
+    public boolean doAccessibleAction(int value0)
+    {
       return false; // TODO
-    } // doAccessibleAction()
+    }
+
+    public Number getCurrentAccessibleValue()
+    {
+      return null; // TODO
+    }
 
-    /**
-     * getCurrentAccessibleValue
-     * @returns Number
-     */
-    public Number getCurrentAccessibleValue() {
-      return null; // TODO
-    } // getCurrentAccessibleValue()
-
-    /**
-     * setCurrentAccessibleValue
-     * @param value0 TODO
-     * @returns boolean
-     */
-    public boolean setCurrentAccessibleValue(Number value0) {
+    public boolean setCurrentAccessibleValue(Number value0)
+    {
       return false; // TODO
-    } // setCurrentAccessibleValue()
+    }
 
-    /**
-     * getMinimumAccessibleValue
-     * @returns Number
-     */
-    public Number getMinimumAccessibleValue() {
-      return null; // TODO
-    } // getMinimumAccessibleValue()
-
-    /**
-     * getMaximumAccessibleValue
-     * @returns Number
-     */
-    public Number getMaximumAccessibleValue() {
-      return null; // TODO
-    } // getMaximumAccessibleValue()
-
-    /**
-     * getAccessibleText
-     * @returns AccessibleText
-     */
-    public AccessibleText getAccessibleText() {
-      return null; // TODO
-    } // getAccessibleText()
-
-    /**
-     * getIndexAtPoint
-     * @param value0 TODO
-     * @returns int
-     */
-    public int getIndexAtPoint(Point value0) {
-      return 0; // TODO
-    } // getIndexAtPoint()
+    public Number getMinimumAccessibleValue()
+    {
+      return null; // TODO
+    }
 
-    /**
-     * getCharacterBounds
-     * @param value0 TODO
-     * @returns Rectangle
-     */
-    public Rectangle getCharacterBounds(int value0) {
-      return null; // TODO
-    } // getCharacterBounds()
-
-    /**
-     * getCharCount
-     * @returns int
-     */
-    public int getCharCount() {
-      return 0; // TODO
-    } // getCharCount()
+    public Number getMaximumAccessibleValue()
+    {
+      return null; // TODO
+    }
 
-    /**
-     * getCaretPosition
-     * @returns int
-     */
-    public int getCaretPosition() {
+    public AccessibleText getAccessibleText()
+    {
+      return null; // TODO
+    }
+
+    public int getIndexAtPoint(Point value0)
+    {
       return 0; // TODO
-    } // getCaretPosition()
+    }
+
+    public Rectangle getCharacterBounds(int value0)
+    {
+      return null; // TODO
+    }
 
-    /**
-     * getAtIndex
-     * @param value0 TODO
-     * @param value1 TODO
-     * @returns String
-     */
-    public String getAtIndex(int value0, int value1) {
-      return null; // TODO
-    } // getAtIndex()
-
-    /**
-     * getAfterIndex
-     * @param value0 TODO
-     * @param value1 TODO
-     * @returns String
-     */
-    public String getAfterIndex(int value0, int value1) {
-      return null; // TODO
-    } // getAfterIndex()
-
-    /**
-     * getBeforeIndex
-     * @param value0 TODO
-     * @param value1 TODO
-     * @returns String
-     */
-    public String getBeforeIndex(int value0, int value1) {
-      return null; // TODO
-    } // getBeforeIndex()
-
-    /**
-     * getCharacterAttribute
-     * @param value0 TODO
-     * @returns AttributeSet
-     */
-    public AttributeSet getCharacterAttribute(int value0) {
-      return null; // TODO
-    } // getCharacterAttribute()
-
-    /**
-     * getSelectionStart
-     * @returns int
-     */
-    public int getSelectionStart() {
+    public int getCharCount()
+    {
       return 0; // TODO
-    } // getSelectionStart()
+    }
 
-    /**
-     * getSelectionEnd
-     * @returns int
-     */
-    public int getSelectionEnd() {
+    public int getCaretPosition()
+    {
       return 0; // TODO
-    } // getSelectionEnd()
+    }
 
-    /**
-     * getSelectedText
-     * @returns String
-     */
-    public String getSelectedText() {
+    public String getAtIndex(int value0, int value1)
+    {
       return null; // TODO
-    } // getSelectedText()
+    }
 
-    /**
-     * getTextRectangle
-     * @returns Rectangle
-     */
-    private Rectangle getTextRectangle() {
+    public String getAfterIndex(int value0, int value1)
+    {
       return null; // TODO
-    } // getTextRectangle()
-
-
-  } // AccessibleAbstractButton
+    }
 
+    public String getBeforeIndex(int value0, int value1)
+    {
+      return null; // TODO
+    }
 
-  static private class JFocusListener implements FocusListener
-  {
-    AbstractButton c;
+    public AttributeSet getCharacterAttribute(int value0)
+    {
+      return null; // TODO
+    }
 
-    JFocusListener(AbstractButton c)
+    public int getSelectionStart()
     {
-      this.c = c;
+      return 0; // TODO
     }
 
-    public void focusLost(FocusEvent event)
+    public int getSelectionEnd()
     {
-      c.getModel().setArmed(false);
+      return 0; // TODO
+    }
 
-      System.out.println("LOST FOCUS");
-      if (c.isFocusPainted())
-        {
-          c.repaint();
-        }
+    public String getSelectedText()
+    {
+      return null; // TODO
     }
-    public void focusGained(FocusEvent event)
+
+    private Rectangle getTextRectangle()
     {
-      System.out.println("GAIN FOCUS");
+      return null; // TODO
     }
-  }
+    }
+
 
-  AbstractButton()
+  /**
+   * Creates a new AbstractButton object.
+   */
+  public AbstractButton()
   {
     this("",null);
   }
 
-  AbstractButton(String text,
-                 Icon icon)
+  /**
+   * Creates a new AbstractButton object.
+   *
+   * @param txt Value to use for the button's "text" property
+   * @param icon Value to use for the button's "defaultIcon" property
+   */
+  AbstractButton(String txt, Icon icon)
   {
-    this.text    = text;
-    setIcon(icon);
-
-    setAlignmentX(LEFT_ALIGNMENT);
-    setAlignmentY(CENTER_ALIGNMENT);
+    init (txt, icon);
+    updateUI();
+  }
 
-    addFocusListener( new JFocusListener(this) );
+  /**
+   * Get the model the button is currently using.
+   *
+   * @return The current model
+   */
+  public ButtonModel getModel()
+  {
+    return model;
+  }
 
-    setModel(new DefaultButtonModel(this));
+  /**
+   * Set the model the button is currently using. This un-registers all 
+   * listeners associated with the current model, and re-registers them
+   * with the new model.
+   *
+   * @param newModel The new model
+   */
+  public void setModel(ButtonModel newModel)
+  {
+    if (newModel == model)
+      return;
 
-    updateUI(); // get a proper ui
+    if (model != null)
+      {
+        model.removeActionListener(actionListener);
+        model.removeChangeListener(changeListener);
+        model.removeItemListener(itemListener);
+      }
+    ButtonModel old = model;
+    model = newModel;
+    if (model != null)
+      {
+        model.addActionListener(actionListener);
+        model.addChangeListener(changeListener);
+        model.addItemListener(itemListener);
+      }
+    firePropertyChange(MODEL_CHANGED_PROPERTY, old, model);
+    revalidate();
+    repaint();
   }
 
-  public ButtonModel getModel()
-  {	return model;    }
+ protected void init(String text, Icon icon) 
+ {
+    this.text = text;
+    default_icon = icon;
+    model = new DefaultButtonModel();
+    actionListener = createActionListener();
+    changeListener = createChangeListener();
+    itemListener = createItemListener();
+
+    model.addActionListener(actionListener);
+    model.addChangeListener(changeListener);
+    model.addItemListener(itemListener);
+
+    horizontalAlignment = CENTER;
+    horizontalTextPosition = TRAILING;
+    verticalAlignment = CENTER;
+    verticalTextPosition = CENTER;
+    borderPainted = true;
+    contentAreaFilled = true;
 
-  public void setModel(ButtonModel newModel)
-  {	model = newModel;    }
+    focusPainted = true;
+    setFocusable(true);
 
+    setAlignmentX(LEFT_ALIGNMENT);
+    setAlignmentY(CENTER_ALIGNMENT);
+
+    setDisplayedMnemonicIndex(-1);    
+ }
+ 
+  /**
+   * Get the action command string for this button's model.
+   *
+   * @return The current action command string from the button's model
+   */
   public String getActionCommand()
-  {	return getModel().getActionCommand();    }
+  {
+    return getModel().getActionCommand();
+  }
 
+  /**
+   * Set the action command string for this button's model.
+   *
+   * @param aCommand The new action command string to set in the button's
+   * model.
+   */
   public void setActionCommand(String aCommand)
-  {   getModel().setActionCommand(aCommand);   }
+  {
+    getModel().setActionCommand(aCommand);
+  }
 
+  /**
+   * Adds an ActionListener to the button's listener list. When the
+   * button's model is clicked it fires an ActionEvent, and these
+   * listeners will be called.
+   *
+   * @param l The new listener to add
+   */
   public void addActionListener(ActionListener l)
-  {	getModel().addActionListener(l);    }
+  {
+    listenerList.add(ActionListener.class, l);
+  }
 
+  /**
+   * Removes an ActionListener from the button's listener list.
+   *
+   * @param l The listener to remove
+   */
   public void removeActionListener(ActionListener l)
-  {	getModel().removeActionListener(l);    }
+  {
+    listenerList.remove(ActionListener.class, l);
+  }
+
+  /**
+   * Returns all added <code>ActionListener</code> objects.
+   * 
+   * @return an array of listeners
+   * 
+   * @since 1.4
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) listenerList.getListeners(ActionListener.class);
+  }
 
+  /**
+   * Adds an ItemListener to the button's listener list. When the button's
+   * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER
+   * or SELECTED) it fires an ItemEvent, and these listeners will be
+   * called.
+   *
+   * @param l The new listener to add
+   */
+  public void addItemListener(ItemListener l)
+  {
+    listenerList.add(ItemListener.class, l);
+  }
+
+  /**
+   * Removes an ItemListener from the button's listener list.
+   *
+   * @param l The listener to remove
+   */
+  public void removeItemListener(ItemListener l)
+  {
+    listenerList.remove(ItemListener.class, l);
+  }
+
+  /**
+   * Returns all added <code>ItemListener</code> objects.
+   * 
+   * @return an array of listeners
+   * 
+   * @since 1.4
+   */
+  public ItemListener[] getItemListeners()
+  {
+    return (ItemListener[]) listenerList.getListeners(ItemListener.class);
+  }
+
+  /**
+   * Adds a ChangeListener to the button's listener list. When the button's
+   * model changes any of its (non-bound) properties, these listeners will be
+   * called. 
+   *
+   * @param l The new listener to add
+   */
   public void addChangeListener(ChangeListener l)
-  {   getModel().addChangeListener(l);     }
+  {
+    listenerList.add(ChangeListener.class, l);
+  }
 
+  /**
+   * Removes a ChangeListener from the button's listener list.
+   *
+   * @param l The listener to remove
+   */
   public void removeChangeListener(ChangeListener l)
-  {  getModel().removeChangeListener(l);    }
+  {
+    listenerList.remove(ChangeListener.class, l);
+  }
 
-  public void addItemListener(ItemListener l)
-  {  getModel().addItemListener(l);    }
+  /**
+   * Returns all added <code>ChangeListener</code> objects.
+   * 
+   * @return an array of listeners
+   * 
+   * @since 1.4
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
 
-  public void removeItemListener(ItemListener l)
-  {  getModel().removeItemListener(l);  }
+  /**
+   * Calls {@link ItemListener.itemStateChanged} on each ItemListener in
+   * the button's listener list.
+   *
+   * @param e The event signifying that the button's model changed state
+   */
+  public void fireItemStateChanged(ItemEvent e)
+  {
+    e.setSource(this);
+    ItemListener[] listeners = getItemListeners();
+ 
+    for (int i = 0; i < listeners.length; i++)
+      listeners[i].itemStateChanged(e);
+  }
 
-  public int getHorizontalAlignment()
-  {	return hori_align;    }
+  /**
+   * Calls {@link ActionListener.actionPerformed} on each {@link
+   * ActionListener} in the button's listener list.
+   *
+   * @param e The event signifying that the button's model was clicked
+   */
+  public void fireActionPerformed(ActionEvent e)
+  {
+    e.setSource(this);
+    ActionListener[] listeners = getActionListeners();
+    
+    for (int i = 0; i < listeners.length; i++)
+      listeners[i].actionPerformed(e);
+  }
 
-  public int getHorizontalTextPosition()
-  {	return hori_text_pos;    }
+  /**
+   * Calls {@link ChangeEvent.stateChanged} on each {@link ChangeListener}
+   * in the button's listener list.
+   *
+   * @param e The event signifying a change in one of the (non-bound)
+   * properties of the button's model.
+   */
+  public void fireStateChanged(ChangeEvent e)
+  {
+    ChangeListener[] listeners = getChangeListeners();
 
-  public int getVerticalAlignment()
-  {	return vert_align;   }
+    for (int i = 0; i < listeners.length; i++)
+      listeners[i].stateChanged(changeEvent);
+  }
 
-  public int getVerticalTextPosition()
-  {	return vert_text_pos;  }
+  /**
+   * Get the current keyboard mnemonic value. This value corresponds to a
+   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+   * codes) and is used to activate the button when pressed in conjunction
+   * with the "mouseless modifier" of the button's look and feel class, and
+   * when focus is in one of the button's ancestors.
+   *
+   * @return The button's current keyboard mnemonic
+   */
+  public int getMnemonic()
+  {
+    return getModel().getMnemonic();
+  }
+
+  /**
+   * Set the current keyboard mnemonic value. This value corresponds to a
+   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+   * codes) and is used to activate the button when pressed in conjunction
+   * with the "mouseless modifier" of the button's look and feel class, and
+   * when focus is in one of the button's ancestors.
+   *
+   * @param mne A new mnemonic to use for the button
+   */
+  public void setMnemonic(char mne)
+  {
+    setMnemonic((int) mne);
+  }
+
+  /**
+   * Set the current keyboard mnemonic value. This value corresponds to a
+   * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+   * codes) and is used to activate the button when pressed in conjunction
+   * with the "mouseless modifier" of the button's look and feel class, and
+   * when focus is in one of the button's ancestors.
+   *
+   * @param mne A new mnemonic to use for the button
+   */
+  public void setMnemonic(int mne)
+  {
+    int old = getModel().getMnemonic();
+
+    if (old != mne)
+      {
+    getModel().setMnemonic(mne);
+
+	if (text != null && ! text.equals(""))
+      {
+	    // Since lower case char = upper case char for 
+	    // mnemonic, we will convert both text and mnemonic 
+	    // to upper case before checking if mnemonic character occurs
+	    // in the menu item text. 
+	    int upperCaseMne = Character.toUpperCase((char) mne);
+	    String upperCaseText = text.toUpperCase();
+	    setDisplayedMnemonicIndex(upperCaseText.indexOf(upperCaseMne));
+	  }
+
+        firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne);
+        revalidate();
+        repaint();
+      }
+  }
 
-  protected  void fireItemStateChanged(ItemEvent event)
+  /** 
+   * Sets the button's mnemonic index. The mnemonic index is a hint to the
+   * look and feel class, suggesting which character in the button's label
+   * should be underlined when drawing the label. If the mnemonic index is
+   * -1, no mnemonic will be displayed. 
+   * 
+   * If no mnemonic index is set, the button will choose a mnemonic index
+   * by default, which will be the first occurrence of the mnemonic
+   * character in the button's text.
+   *
+   * @param index An offset into the "text" property of the button
+   * @throws IllegalArgumentException If <code>index</code> is not within the
+   * range of legal offsets for the "text" property of the button.
+   * @since 1.4
+   */
+
+  public void setDisplayedMnemonicIndex(int index)
   {
+    if (index < -1 || (text != null && index >= text.length()))
+      throw new IllegalArgumentException();
+    else
+      mnemonicIndex = index;
   }
   
-  protected  void fireStateChanged(ChangeEvent event)
+  /** 
+   * Get the button's mnemonic index, which is an offset into the button's
+   * "text" property.  The character specified by this offset should be
+   * underlined when the look and feel class draws this button.
+   *
+   * @return An index into the button's "text" property
+   */
+  public int getDisplayedMnemonicIndex()
   {
+    return mnemonicIndex;
   }
   
-  protected void fireActionPerformed(ActionEvent event)
+
+  /**
+   * Set the "rolloverEnabled" property. When rollover is enabled, and the
+   * look and feel supports it, the button will change its icon to
+   * rolloverIcon, when the mouse passes over it.
+   *
+   * @param r Whether or not to enable rollover icon changes
+   */
+  public void setRolloverEnabled(boolean r)
   {
+    if (rollOverEnabled != r)
+  {
+        rollOverEnabled = r;
+        firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, !r, r);
+        revalidate();
+        repaint();
+      }
   }
 
-  public void setVerticalAlignment(int alignment)
-  {	vert_align = alignment;    }
+  /**
+   * Returns whether or not rollover icon changes are enabled on the
+   * button.
+   *
+   * @return The state of the "rolloverEnabled" property
+   */
+  public boolean isRolloverEnabled()
+  {
+    return rollOverEnabled;
+  }
 
-  public void setHorizontalAlignment(int alignment)
-  {   hori_align = alignment;   }
+  /**
+   * Set the value of the button's "selected" property. Selection is only
+   * meaningful for toggle-type buttons (check boxes, radio buttons).
+   *
+   * @param s New value for the property
+   */
+  public void setSelected(boolean s)
+  {
+    getModel().setSelected(s);
+  }
 
-  public void setVerticalTextPosition(int textPosition)
-  {	vert_text_pos = textPosition;    }
+  /**
+   * Get the value of the button's "selected" property. Selection is only
+   * meaningful for toggle-type buttons (check boxes, radio buttons).
+   *
+   * @return The value of the property
+   */
+  public boolean isSelected()
+  {
+    return getModel().isSelected();
+  }
 
-  public void setHorizontalTextPosition(int textPosition)
-  {   hori_text_pos = textPosition;   }
+  /**
+   * Enables or disables the button. A button will neither be selectable
+   * nor preform any actions unless it is enabled.
+   *
+   * @param b Whether or not to enable the button
+   */
+  public void setEnabled(boolean b)
+  {
+    super.setEnabled(b);
+    getModel().setEnabled(b);
+  }
 
-  public int getMnemonic()
-  {	return getModel().getMnemonic();    }
+  /** 
+   * Set the horizontal alignment of the button's text and icon. The
+   * alignment is a numeric constant from {@link SwingConstants}. It must
+   * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+   * <code>LEADING</code> or <code>TRAILING</code>.  The default is
+   * <code>RIGHT</code>.
+   * 
+   * @return The current horizontal alignment
+   */
+  public int getHorizontalAlignment()
+  {
+    return horizontalAlignment;
+  }
 
-  public void setMnemonic(char mne)
-  {	getModel().setMnemonic(mne);    }
+  /**
+   * Set the horizontal alignment of the button's text and icon. The
+   * alignment is a numeric constant from {@link SwingConstants}. It must
+   * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+   * <code>LEADING</code> or <code>TRAILING</code>.  The default is
+   * <code>RIGHT</code>.
+   *
+   * @param a The new horizontal alignment
+   * @throws IllegalArgumentException If alignment is not one of the legal
+   * constants.
+   */
+  public void setHorizontalAlignment(int a)
+  {
+    int old = horizontalAlignment;
+    horizontalAlignment = a;
+    if (old != a)
+      {
+        firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
+        revalidate();
+        repaint();
+      }
+  }
 
-  public void setMnemonic(int mne)
-  {	getModel().setMnemonic(mne);    }
+  /**
+   * Get the horizontal position of the button's text relative to its
+   * icon. The position is a numeric constant from {@link
+   * SwingConstants}. It must be one of: <code>RIGHT</code>,
+   * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
+   * <code>TRAILING</code>.  The default is <code>TRAILING</code>.
+   *
+   * @return The current horizontal text position
+   */
+  public int getHorizontalTextPosition()
+  {
+    return horizontalTextPosition;
+  }
 
-  public void setRolloverEnabled(boolean b)
-  {    getModel().setRollover(b);    }
+  /**
+   * Set the horizontal position of the button's text relative to its
+   * icon. The position is a numeric constant from {@link
+   * SwingConstants}. It must be one of: <code>RIGHT</code>,
+   * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
+   * <code>TRAILING</code>. The default is <code>TRAILING</code>.
+   *
+   * @param t The new horizontal text position
+   * @throws IllegalArgumentException If position is not one of the legal
+   * constants.
+   */
+  public void setHorizontalTextPosition(int t)
+  {
+    int old = horizontalTextPosition;
+    horizontalTextPosition = t;
+    if (old != t)
+      {
+        firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
+        revalidate();
+        repaint();
+      }
+  }
 
-  public boolean isRolloverEnabled()
-  {    return getModel().isRollover();     }
+  /**
+   * Get the vertical alignment of the button's text and icon. The
+   * alignment is a numeric constant from {@link SwingConstants}. It must
+   * be one of: <code>CENTER</code>, <code>TOP</code>, or
+   * <code>BOTTOM</code>. The default is <code>CENTER</code>.
+   *
+   * @return The current vertical alignment
+   */
+  public int getVerticalAlignment()
+  {
+    return verticalAlignment;
+  }
 
+  /**
+   * Set the vertical alignment of the button's text and icon. The
+   * alignment is a numeric constant from {@link SwingConstants}. It must
+   * be one of: <code>CENTER</code>, <code>TOP</code>, or
+   * <code>BOTTOM</code>. The default is <code>CENTER</code>.
+   *
+   * @param a The new vertical alignment
+   * @throws IllegalArgumentException If alignment is not one of the legal
+   * constants.
+   */
+  public void setVerticalAlignment(int a)
+  {
+    int old = verticalAlignment;
+    verticalAlignment = a;
+    if (old != a)
+      {
+        firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
+        revalidate();
+        repaint();
+      }
+  }
+
+  /**
+   * Get the vertical position of the button's text relative to its
+   * icon. The alignment is a numeric constant from {@link
+   * SwingConstants}. It must be one of: <code>CENTER</code>,
+   * <code>TOP</code>, or <code>BOTTOM</code>. The default is
+   * <code>CENTER</code>.
+   *
+   * @return The current vertical position
+   */
+  public int getVerticalTextPosition()
+  {
+    return verticalTextPosition;
+  }
+
+  /**
+   * Set the vertical position of the button's text relative to its
+   * icon. The alignment is a numeric constant from {@link
+   * SwingConstants}. It must be one of: <code>CENTER</code>,
+   * <code>TOP</code>, or <code>BOTTOM</code>. The default is
+   * <code>CENTER</code>.
+   *
+   * @param t The new vertical position
+   * @throws IllegalArgumentException If position is not one of the legal
+   * constants.
+   */
+  public void setVerticalTextPosition(int t)
+  {
+    int old = verticalTextPosition;
+    verticalTextPosition = t;
+    if (old != t)
+      {
+        firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
+        revalidate();
+        repaint();
+      }
+  }
+
+  /**
+   * Set the value of the "borderPainted" property. If set to
+   * <code>false</code>, the button's look and feel class should not paint
+   * a border for the button. The default is <code>true</code>.
+   *
+   * @return The current value of the property.
+   */
   public boolean isBorderPainted()
-  {	return paint_border;    }
+  {
+    return borderPainted;
+  }
 
+  /**
+   * Set the value of the "borderPainted" property. If set to
+   * <code>false</code>, the button's look and feel class should not paint
+   * a border for the button. The default is <code>true</code>.
+   *
+   * @param b The new value of the property.
+   */
   public void setBorderPainted(boolean b)
   {
-    if (b != paint_border)
+    boolean old = borderPainted;
+        borderPainted = b;
+    if (b != old)
       {
-        paint_border = b;
+        firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
         revalidate();
         repaint();
       }
   }
 
+  /**
+   * Get the value of the "action" property. 
+   *
+   * @return The current value of the "action" property
+   */
   public Action getAction()
-  {	return action_taken;    }
+  {
+    return action;
+  }
 
+  /**
+   * <p>Set the button's "action" property, subscribing the new action to the
+   * button, as an ActionListener, if it is not already subscribed. The old
+   * Action, if it exists, is unsubscribed, and the button is unsubscribed
+   * from the old Action if it was previously subscribed as a
+   * PropertyChangeListener.</p>
+   *
+   * <p>This method also configures several of the button's properties from
+   * the Action, by calling {@link configurePropertiesFromAction}, and
+   * subscribes the button to the Action as a PropertyChangeListener.
+   * Subsequent changes to the Action will thus reconfigure the button 
+   * automatically.</p>
+   *
+   * @param a The new value of the "action" property
+   */
   public void setAction(Action a)
   {
-    action_taken = a;
-    revalidate();
-    repaint();
-  }
+    if (action != null)
+      {
+        action.removePropertyChangeListener(actionPropertyChangeListener);
+        removeActionListener(action);
+        if (actionPropertyChangeListener != null)
+          {
+            action.removePropertyChangeListener(actionPropertyChangeListener);
+            actionPropertyChangeListener = null;
+          }
 
-  public void setSelected(boolean b)
-  {	getModel().setSelected(b);    }
 
-  public boolean isSelected()
-  {	return getModel().isSelected();     }
+  }
+  
 
-  public Icon getIcon()
-  {	return default_icon;    }
+    Action old = action;
+    action = a;
+    configurePropertiesFromAction(action);
+    if (action != null)
+      {
+        actionPropertyChangeListener = createActionPropertyChangeListener(a);      
+        action.addPropertyChangeListener(actionPropertyChangeListener);
+        addActionListener(action);
+      }
+  }
 
-  public void setIcon(Icon defaultIcon)
+  /**
+   * Return the button's default "icon" property.
+   *
+   * @return The current default icon
+   */
+  public Icon getIcon()
   {
-    if (default_icon == defaultIcon)
-      return;
+    return default_icon;
+  }
 
-    default_icon = defaultIcon;
-    if (default_icon != null)
+  /**
+   * Set the button's default "icon" property. This icon is used as a basis
+   * for the pressed and disabled icons, if none are explicitly set.
+   *
+   * @param i The new default icon
+   */
+  public void setIcon(Icon i)
+  {
+    if (default_icon != i)
       {
-        // XXX FIXME - icons do not know their parent
-        //  			default_icon.setParent(this);
-      }
+    Icon old = default_icon;      
+    default_icon = i;      
+    firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
     revalidate();
     repaint();
+      }
   }
 
+  /**
+   * Return the button's "text" property. This property is synonymous with
+   * the "label" property.
+   *
+   * @return The current "text" property
+   */
   public String getText()
-  {	return text;    }
+  {
+    return text;
+  }
 
+  /**
+   * Set the button's "label" property. This property is synonymous with the
+   * "text" property.
+   *
+   * @param label The new "label" property
+   */
   public void setLabel(String label)
-  {	setText(label);    }
+  {
+    setText(label);
+  }
 
+  /**
+   * Return the button's "label" property. This property is synonymous with
+   * the "text" property.
+   *
+   * @return The current "label" property
+   */
   public String getLabel()
-  {	return getText();    }
+  {
+    return getText();
+  }
 
-  public void setText(String text)
+  /**
+   * Set the button's "text" property. This property is synonymous with the
+   * "label" property.
+   *
+   * @param t The new "text" property
+   */
+  public void setText(String t)
   {
-    this.text = text;
+    String old = text;
+    text = t;
+    if (t != old)
+      {
+        firePropertyChange(TEXT_CHANGED_PROPERTY, old, t);
     revalidate();
     repaint();
   }
+  }
+
+  /**
+   * Set the value of the {@link #iconTextGap} property.
+   * 
+   * @param i The new value of the property
+   */
+  public void setIconTextGap(int i)
+  {
+    int old = iconTextGap;
+    iconTextGap = i;
+    if (old != i)
+      {
+        fireStateChanged(new ChangeEvent(this));
+        revalidate();
+        repaint();
+      }
+  }
+
+  /**
+   * Get the value of the {@link #iconTextGap} property.
+   *
+   * @return The current value of the property
+   */
+  public int getIconTextGap()
+  {
+    return iconTextGap;
+  }
 
+  /**
+   * Return the button's "margin" property, which is an {@link Insets} object
+   * describing the distance between the button's border and its text and
+   * icon.
+   *
+   * @return The current "margin" property
+   */
   public 	Insets getMargin()
-  {      return margin; }
+  {
+    return margin;
+  }
 
+  /**
+   * Set the button's "margin" property, which is an {@link Insets} object
+   * describing the distance between the button's border and its text and
+   * icon.
+   *
+   * @param m The new "margin" property
+   */
   public void setMargin(Insets m)
   {
+    Insets old = margin;
     margin = m;
-    revalidate();
+    if (m != old)
+      {
+        firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m);
+        revalidate();
     repaint();
   }
-
-  public void setEnabled(boolean b)
-  {
-    super.setEnabled(b);
-    getModel().setEnabled(b);
-    repaint();
   }
 
+  /**
+   * Return the button's "pressedIcon" property. The look and feel class
+   * should paint this icon when the "pressed" property of the button's
+   * {@link ButtonModel} is <code>true</code>. This property may be
+   * <code>null</code>, in which case the default icon is used.
+   *
+   * @return The current "pressedIcon" property
+   */
   public Icon getPressedIcon()
-  {	return pressed_button;    }
+  {
+    return pressed_icon;
+  }
 
+  /**
+   * Set the button's "pressedIcon" property. The look and feel class
+   * should paint this icon when the "pressed" property of the button's
+   * {@link ButtonModel} is <code>true</code>. This property may be
+   * <code>null</code>, in which case the default icon is used.
+   *
+   * @param pressedIcon The new "pressedIcon" property
+   */
   public void setPressedIcon(Icon pressedIcon)
   {
-    pressed_button = pressedIcon;
+    Icon old = pressed_icon;
+    pressed_icon = pressedIcon;
+    if (pressed_icon != old)
+      {
+        firePropertyChange(PRESSED_ICON_CHANGED_PROPERTY, old, pressed_icon);
     revalidate();
     repaint();
   }
+  }
 
+  /**
+   * Return the button's "disabledIcon" property. The look and feel class
+   * should paint this icon when the "enabled" property of the button's
+   * {@link ButtonModel} is <code>false</code>. This property may be
+   * <code>null</code>, in which case an icon is constructed, based on the
+   * default icon.
+   *
+   * @return The current "disabledIcon" property
+   */
   public Icon getDisabledIcon()
-  {	return disabled_button;    }
+  {
+    if (disabeldIcon == null
+	&& default_icon instanceof ImageIcon)
+      disabeldIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) default_icon).getImage()));
+      
+    return disabeldIcon;
+  }
 
-  public void setDisabledIcon(Icon disabledIcon)
+  /**
+   * Set the button's "disabledIcon" property. The look and feel class should
+   * paint this icon when the "enabled" property of the button's {@link
+   * ButtonModel} is <code>false</code>. This property may be
+   * <code>null</code>, in which case an icon is constructed, based on the
+   * default icon.
+   *
+   * @param disabledIcon The new "disabledIcon" property
+   */
+  public void setDisabledIcon(Icon d)
   {
-    disabled_button = disabledIcon;
+    disabeldIcon = d;
     revalidate();
     repaint();
   }
 
+  /**
+   * Return the button's "paintFocus" property. This property controls
+   * whether or not the look and feel class will paint a special indicator
+   * of focus state for the button. If it is false, the button still paints
+   * when focused, but no special decoration is painted to indicate the
+   * presence of focus.
+   *
+   * @return The current "paintFocus" property
+   */
   public boolean isFocusPainted()
-  {   return paint_focus;   }
+  {
+    return focusPainted;
+  }
 
-  public void setFocusPainted(boolean b)
+  /**
+   * Set the button's "paintFocus" property. This property controls whether
+   * or not the look and feel class will paint a special indicator of focus
+   * state for the button. If it is false, the button still paints when
+   * focused, but no special decoration is painted to indicate the presence
+   * of focus.
+   *
+   * @param b The new "paintFocus" property
+   */
+  public void setFocusPainted(boolean p)
   {
-    boolean old = paint_focus;
-    paint_focus = b;
+    boolean old = focusPainted;
+    focusPainted = p;
 
-    firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY,
-                       old,
-                       b);
-    if (hasFocus())
+    if (old != focusPainted)
       {
+        firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, p);
         revalidate();
         repaint();
       }
   }
 
+  /**
+   * Return the button's "focusTraversable" property. This property controls
+   * whether or not the button can receive focus when the user attempts to
+   * traverse the focus hierarchy.
+   *
+   * @return The current "focusTraversable" property
+   */
   public boolean isFocusTraversable()
   {
-    //Identifies whether or not this component can receive the focus.
     return true;
   }
 
-
+  /**
+   * Verifies that a particular key is one of the valid constants used for
+   * describing horizontal alignment and positioning. The valid constants
+   * are the following members of {@link SwingConstants}:
+   * <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+   * <code>LEADING</code> or <code>TRAILING</code>.
+   *
+   * @param key The key to check
+   * @param exception A message to include in an IllegalArgumentException
+   *
+   * @return the value of key
+   *
+   * @throws IllegalArgumentException If key is not one of the valid constants
+   *
+   * @see setHorizontalTextPosition()
+   * @see setHorizontalAlignment()
+   */
   protected  int checkHorizontalKey(int key, String exception)
   {
-    //       Verify that key is a legal value for the horizontalAlignment properties.
-    return 0;
+    switch (key)
+      {
+      case SwingConstants.RIGHT:
+      case SwingConstants.LEFT:
+      case SwingConstants.CENTER:
+      case SwingConstants.LEADING:
+      case SwingConstants.TRAILING:
+        break;
+      default:
+        throw new IllegalArgumentException(exception);
+      }
+    return key;
   }
 
+  /**
+   * Verifies that a particular key is one of the valid constants used for
+   * describing vertical alignment and positioning. The valid constants are
+   * the following members of {@link SwingConstants}: <code>TOP</code>,
+   * <code>BOTTOM</code> or <code>CENTER</code>.
+   *
+   * @param key The key to check
+   * @param exception A message to include in an IllegalArgumentException
+   *
+   * @return the value of key
+   *
+   * @throws IllegalArgumentException If key is not one of the valid constants
+   *
+   * @see setVerticalTextPosition()
+   * @see setVerticalAlignment()
+   */
   protected  int checkVerticalKey(int key, String exception)
   {
-    //       Ensures that the key is a valid.
-    return 0;
+    switch (key)
+      {
+      case SwingConstants.TOP:
+      case SwingConstants.BOTTOM:
+      case SwingConstants.CENTER:
+        break;
+      default:
+        throw new IllegalArgumentException(exception);
+      }
+    return key;
   }
 
+  /**
+   * Configure various properties of the button by reading properties
+   * of an {@link Action}. The mapping of properties is as follows:
+   *
+   * <table>
+   *
+   * <tr><th>Action keyed property</th> <th>AbstractButton property</th></tr>
+   *
+   * <tr><td>NAME                 </td> <td>text                   </td></tr>
+   * <tr><td>SMALL_ICON           </td> <td>icon                   </td></tr>
+   * <tr><td>SHORT_DESCRIPTION    </td> <td>toolTipText            </td></tr>
+   * <tr><td>MNEMONIC_KEY         </td> <td>mnemonic               </td></tr>
+   * <tr><td>ACTION_COMMAND_KEY   </td> <td>actionCommand          </td></tr>
+   *
+   * </table>
+   *
+   * <p>In addition, this method always sets the button's "enabled" property to
+   * the value of the Action's "enabled" property.</p>
+   *
+   * <p>If the provided Action is <code>null</code>, the text, icon, and
+   * toolTipText properties of the button are set to <code>null</code>, and
+   * the "enabled" property is set to <code>true</code>; the mnemonic and
+   * actionCommand properties are unchanged.</p>
+   *
+   * @param a An Action to configure the button from
+   */
   protected  void configurePropertiesFromAction(Action a)
   {
-    //Factory method which sets the ActionEvent source's properties according to values from the Action instance.
+    if (a == null)
+      {
+        setText(null);
+        setIcon(null);
+        setEnabled(true);
+        setToolTipText(null);
+      }
+    else
+      {
+        setText((String)(a.getValue(Action.NAME)));
+        setIcon((Icon)(a.getValue(Action.SMALL_ICON)));
+        setEnabled(a.isEnabled());
+        setToolTipText((String)(a.getValue(Action.SHORT_DESCRIPTION)));
+	if (a.getValue(Action.MNEMONIC_KEY) != null)
+          setMnemonic(((Integer)(a.getValue(Action.MNEMONIC_KEY))).intValue());
+        String actionCommand = (String)(a.getValue(Action.ACTION_COMMAND_KEY));
+
+        // Set actionCommand to button's text by default if it is not specified
+        if (actionCommand != null)
+        setActionCommand((String)(a.getValue(Action.ACTION_COMMAND_KEY)));
+	 else
+	   setActionCommand(getText());
+      }
   }
 
+  /**
+   * <p>A factory method which should return an {@link ActionListener} that
+   * propagates events from the button's {@link ButtonModel} to any of the
+   * button's ActionListeners. By default, this is an inner class which
+   * calls {@link AbstractButton.fireActionPerformed} with a modified copy
+   * of the incoming model {@link ActionEvent}.</p>
+   *
+   * <p>The button calls this method during construction, stores the
+   * resulting ActionListener in its <code>actionListener</code> member
+   * field, and subscribes it to the button's model. If the button's model
+   * is changed, this listener is unsubscribed from the old model and
+   * subscribed to the new one.</p>
+   *
+   * @return A new ActionListener 
+   */
   protected  ActionListener createActionListener()
   {
     return new ActionListener()
       {
-        public void actionPerformed(ActionEvent e) { }
+        public void actionPerformed(ActionEvent e)
+        {
+          AbstractButton.this.fireActionPerformed(e);
+        }
       };
   }
 
+  /**
+   * <p>A factory method which should return a {@link PropertyChangeListener}
+   * that accepts changes to the specified {@link Action} and reconfigure
+   * the {@link AbstractButton}, by default using the {@link
+   * configurePropertiesFromAction} method.</p>
+   *
+   * <p>The button calls this method whenever a new Action is assigned to
+   * the button's "action" property, via {@link setAction}, and stores the
+   * resulting PropertyChangeListener in its
+   * <code>actionPropertyChangeListener</code> member field. The button
+   * then subscribes the listener to the button's new action. If the
+   * button's action is changed subsequently, the listener is unsubscribed
+   * from the old action and subscribed to the new one.</p>
+   *
+   * @param a The Action which will be listened to, and which should be 
+   * the same as the source of any PropertyChangeEvents received by the
+   * new listener returned from this method.
+   *
+   * @return A new PropertyChangeListener
+   */
   protected  PropertyChangeListener createActionPropertyChangeListener(Action a)
   {
-    //Factory method which creates the PropertyChangeListener used to update the ActionEvent source as properties change on its Action instance.
-    return null;
+    return new PropertyChangeListener()
+      {
+        public void propertyChange(PropertyChangeEvent e)
+        {
+          Action act = (Action) (e.getSource());	
+	  if (e.getPropertyName().equals(AbstractAction.ENABLED_PROPERTY))
+	    setEnabled(act.isEnabled());
+	  else if (e.getPropertyName().equals(Action.NAME))
+            setText((String)(act.getValue(Action.NAME)));
+	  else if (e.getPropertyName().equals(Action.SMALL_ICON))
+	    setIcon((Icon)(act.getValue(Action.SMALL_ICON)));
+	  else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION))
+            setToolTipText((String)(act.getValue(Action.SHORT_DESCRIPTION)));
+	  else if (e.getPropertyName().equals(Action.MNEMONIC_KEY))
+            if (act.getValue(Action.MNEMONIC_KEY) != null)
+              setMnemonic(((Integer)(act.getValue(Action.MNEMONIC_KEY))).intValue());
+	  else if (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY))
+            setActionCommand((String)(act.getValue(Action.ACTION_COMMAND_KEY)));
+	}
+      };
   }
 
+  /**
+   * <p>Factory method which creates a {@link ChangeListener}, used to
+   * subscribe to ChangeEvents from the button's model. Subclasses of
+   * AbstractButton may wish to override the listener used to subscribe to
+   * such ChangeEvents. By default, the listener just propagates the
+   * {@link ChangeEvent} to the button's ChangeListeners, via the {@link
+   * AbstractButton.fireStateChanged} method.</p>
+   *
+   * <p>The button calls this method during construction, stores the
+   * resulting ChangeListener in its <code>changeListener</code> member
+   * field, and subscribes it to the button's model. If the button's model
+   * is changed, this listener is unsubscribed from the old model and
+   * subscribed to the new one.</p>
+   *
+   * @return The new ChangeListener
+   */
   protected  ChangeListener createChangeListener()
   {
-    //       Subclasses that want to handle ChangeEvents differently can override this to return another ChangeListener implementation.
     return new ChangeListener()
       {
-        public void stateChanged(ChangeEvent e) { }
+        public void stateChanged(ChangeEvent e)
+        {
+          AbstractButton.this.fireStateChanged(e);
+          AbstractButton.this.repaint();          
+        }
       };
   }
 
+  /**
+   * <p>Factory method which creates a {@link ItemListener}, used to
+   * subscribe to ItemEvents from the button's model. Subclasses of
+   * AbstractButton may wish to override the listener used to subscribe to
+   * such ItemEvents. By default, the listener just propagates the
+   * {@link ItemEvent} to the button's ItemListeners, via the {@link
+   * AbstractButton.fireItemStateChanged} method.</p>
+   *
+   * <p>The button calls this method during construction, stores the
+   * resulting ItemListener in its <code>changeListener</code> member
+   * field, and subscribes it to the button's model. If the button's model
+   * is changed, this listener is unsubscribed from the old model and
+   * subscribed to the new one.</p>
+   *
+   * <p>Note that ItemEvents are only generated from the button's model
+   * when the model's <em>selected</em> property changes. If you want to
+   * subscribe to other properties of the model, you must subscribe to
+   * ChangeEvents.
+   *
+   * @return The new ItemListener
+   */
   protected  ItemListener createItemListener()
   {
     return new ItemListener()
       {
-        public void itemStateChanged(ItemEvent e) { }
+        public void itemStateChanged(ItemEvent e)
+        {
+          AbstractButton.this.fireItemStateChanged(e);
+        }
       };
   }
 
+  /**
+   * Programmatically perform a "click" on the button: arming, pressing,
+   * waiting, un-pressing, and disarming the model.
+   */
   public void doClick()
   {
     doClick(100);
   }
 
+  /**
+   * Programmatically perform a "click" on the button: arming, pressing,
+   * waiting, un-pressing, and disarming the model.
+   *
+   * @param pressTime The number of milliseconds to wait in the pressed state
+   */
   public void doClick(int pressTime)
   {
-    //Toolkit.tlkBeep ();
-    //Programmatically perform a "click".
-  }
-
-  public Icon getDisabledSelectedIcon()
+    getModel().setArmed(true);
+    getModel().setPressed(true);
+    try
   {
-    //Returns the icon used by the button when it's disabled and selected.
-    return disabled_selected_button;
+        java.lang.Thread.sleep(pressTime);
   }
-
-  public Icon getRolloverIcon()
+    catch (java.lang.InterruptedException e)
   {
-    //       Returns the rollover icon for the button.
-    return null;
+        // probably harmless
   }
-
-  Icon getRolloverSelectedIcon()
-  {
-    //       Returns the rollover selection icon for the button.
-    return null;
+    getModel().setPressed(false);
+    getModel().setArmed(false);
   }
 
-  Icon getSelectedIcon()
+  /**
+   * Return the button's disabled selected icon. The look and feel class
+   * should paint this icon when the "enabled" property of the button's model
+   * is <code>false</code> and its "selected" property is
+   * <code>true</code>. This icon can be <code>null</code>, in which case
+   * it is synthesized from the button's selected icon.
+   *
+   * @return The current disabled selected icon
+   */
+  public Icon getDisabledSelectedIcon()
   {
-    //       Returns the selected icon for the button.
-    return selected_button;
+    return disabledSelectedIcon;
   }
 
-  public Object[] getSelectedObjects()
+  /**
+   * Set the button's disabled selected icon. The look and feel class
+   * should paint this icon when the "enabled" property of the button's model
+   * is <code>false</code> and its "selected" property is
+   * <code>true</code>. This icon can be <code>null</code>, in which case
+   * it is synthesized from the button's selected icon.
+   *
+   * @param disabledSelectedIcon The new disabled selected icon
+   */
+  public void setDisabledSelectedIcon(Icon disabledSelectedIcon)
   {
-    //Returns an array (length 1) containing the label or null if the button is not selected.
-    return null;
-  }
-
-  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
+    Icon old = disabledSelectedIcon;
+    disabledSelectedIcon = disabledSelectedIcon;
+    if (old != disabledSelectedIcon)
   {
-    //This is overridden to return false if the current Icon's Image is not equal to the passed in Image img.
-    return current_icon == img;
+        firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old, 
+                           disabledSelectedIcon);
+        revalidate();
+        repaint();        
   }
-
-  public boolean isContentAreaFilled()
-  {
-    //       Checks whether the "content area" of the button should be filled.
-    return false;
   }
 
-  protected  void paintBorder(Graphics g)
-  {
-    //       Paint the button's border if BorderPainted property is true.
-    if (isBorderPainted())
-      super.paintBorder(g);
-  }
 
-  protected  String paramString()
+  /**
+   * Return the button's rollover icon. The look and feel class should
+   * paint this icon when the "rolloverEnabled" property of the button is
+   * <code>true</code> and the mouse rolls over the button.
+   *
+   * @return The current rollover icon
+   */
+  public Icon getRolloverIcon()
   {
-    //        Returns a string representation of this AbstractButton.
-    return "AbstractButton";
+    return rolloverIcon;
   }
 
-  public void setContentAreaFilled(boolean b)
+  /**
+   * Set the button's rollover icon. The look and feel class should
+   * paint this icon when the "rolloverEnabled" property of the button is
+   * <code>true</code> and the mouse rolls over the button.
+   *
+   * @param rolloverIcon The new rollover icon
+   */
+  public void setRolloverIcon(Icon r)
   {
-    //Sets whether the button should paint the content area or leave it transparent.
+    Icon old = rolloverIcon;
+    rolloverIcon = r;
+    if (old != rolloverIcon)
+  {
+        firePropertyChange(ROLLOVER_ICON_CHANGED_PROPERTY, old, 
+                           rolloverIcon);
+        revalidate();
+        repaint();
+      }
   }
 
-  public void setDisabledSelectedIcon(Icon disabledSelectedIcon)
+  /**
+   * Return the button's rollover selected icon. The look and feel class
+   * should paint this icon when the "rolloverEnabled" property of the button
+   * is <code>true</code>, the "selected" property of the button's model is
+   * <code>true</code>, and the mouse rolls over the button.
+   *
+   * @return The current rollover selected icon
+   */
+  public Icon getRolloverSelectedIcon()
   {
-    //          Sets the disabled selection icon for the button.
+    return rolloverSelectedIcon;
   }
 
-  public void setRolloverIcon(Icon rolloverIcon)
+  /**
+   * Set the button's rollover selected icon. The look and feel class
+   * should paint this icon when the "rolloverEnabled" property of the button
+   * is <code>true</code>, the "selected" property of the button's model is
+   * <code>true</code>, and the mouse rolls over the button.
+   *
+   * @param rolloverSelectedIcon The new rollover selected icon
+   */
+  public void setRolloverSelectedIcon(Icon r)
   {
-    //       Sets the rollover icon for the button.
-  }
-  public void setRolloverSelectedIcon(Icon rolloverSelectedIcon)
+    Icon old = rolloverSelectedIcon;
+    rolloverSelectedIcon = r;
+    if (old != rolloverSelectedIcon)
   {
-    //       Sets the rollover selected icon for the button.
+        firePropertyChange(ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY, old, 
+                           rolloverSelectedIcon);
+        revalidate();
+        repaint();
   }
-
-  public void setSelectedIcon(Icon selectedIcon)
-  {
-    //       Sets the selected icon for the button.
   }
 
-  public void setUI(ButtonUI ui)
-  {	//       Sets the L&F object that renders this component.
-    super.setUI(ui);
-  }
 
-  public ButtonUI getUI()
+  /**
+   * Return the button's selected icon. The look and feel class should
+   * paint this icon when the "selected" property of the button's model is
+   * <code>true</code>, and either the "rolloverEnabled" property of the
+   * button is <code>false</code> or the mouse is not currently rolled
+   * over the button.
+   *
+   * @return The current selected icon
+   */
+  public Icon getSelectedIcon()
   {
-    //Returns the L&F object that renders this component.
-    return (ButtonUI) ui;
+    return selectedIcon;
   }
 
-  public void updateUI()
+  /**
+   * Set the button's selected icon. The look and feel class should
+   * paint this icon when the "selected" property of the button's model is
+   * <code>true</code>, and either the "rolloverEnabled" property of the
+   * button is <code>false</code> or the mouse is not currently rolled
+   * over the button.
+   *
+   * @param selectedIcon The new selected icon
+   */
+  public void setSelectedIcon(Icon s)
   {
-    /*
-    //          Notification from the UIFactory that the L&F has changed.
-    if (getUI() == null)
+    Icon old = selectedIcon;
+    selectedIcon = s;
+    if (old != selectedIcon)
     {
-    setUI(getUI());
+        firePropertyChange(SELECTED_ICON_CHANGED_PROPERTY, old, 
+                           selectedIcon);
+        revalidate();
+        repaint();
     }
-    */
   }
 
-  protected void processActionEvent(ActionEvent e)
+  /**
+   * Returns an single-element array containing the "text" property of the
+   * button if the "selected" property of the button's model is
+   * <code>true</code>, otherwise returns <code>null</code>.
+   *
+   * @return The button's "selected object" array
+   */
+  public Object[] getSelectedObjects()
   {
-    System.out.println("PROCESS-ACTION-EVENT: " + e);
+    if (isSelected())
+      {
+        Object[] objs = new Object[1];
+        objs[0] = getText();
+        return objs;
   }
-
-  protected void processMouseEvent(MouseEvent e)
+    else
   {
-    //	System.out.println("PROCESS-MOUSE-EVENT: " + e + ", PRESSED-IN-MODEL="+getModel().isPressed());
+        return null;
+      }
+  }
 
-    switch (e.getID())
-      {
-      case MouseEvent.MOUSE_MOVED:
+  /**
+   * Called when image data becomes available for one of the button's icons.
+   *
+   * @param img The image being updated
+   * @param infoflags One of the constant codes in {@link ImageObserver} used to describe
+   * updated portions of an image.
+   * @param x X coordinate of the region being updated
+   * @param y Y coordinate of the region being updated
+   * @param w Width of the region beign updated
+   * @param h Height of the region being updated
+   *
+   * @return <code>true</code> if img is equal to the button's current
+   * icon, otherwise <code>false</code>
+   */
+  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
+                             int h)
         {
-          break;
+    return current_icon == img;
         }
-      case MouseEvent.MOUSE_PRESSED:
-        {
-          if (! isEnabled())
+
+  /**
+   * Returns the value of the button's "contentAreaFilled" property. This
+   * property indicates whether the area surrounding the text and icon of
+   * the button should be filled by the look and feel class.  If this
+   * property is <code>false</code>, the look and feel class should leave
+   * the content area transparent.
+   *
+   * @return The current value of the "contentAreaFilled" property
+   */
+  public boolean isContentAreaFilled()
             {
-              System.out.println("button not enabled, ignoring press");
+    return contentAreaFilled;
             }
-          else
+
+  /**
+   * Sets the value of the button's "contentAreaFilled" property. This
+   * property indicates whether the area surrounding the text and icon of
+   * the button should be filled by the look and feel class.  If this
+   * property is <code>false</code>, the look and feel class should leave
+   * the content area transparent.
+   *
+   * @param b The new value of the "contentAreaFilled" property
+   */
+  public void setContentAreaFilled(boolean b)
             {
-              System.out.println("telling model:press: " + getModel());
-              getModel().setPressed(true);
+    boolean old = contentAreaFilled;
+    contentAreaFilled = b;
+    if (b != old)
+      {
+        firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b);
+        revalidate();
               repaint();
             }
-          break;
         }
 
-      case MouseEvent.MOUSE_RELEASED:
-        {
-          if (! isEnabled())
+  /**
+   * Paints the button's border, if the button's "borderPainted" property is
+   * <code>true</code>, by out calling to the button's look and feel class.
+   *
+   * @param g The graphics context used to paint the border
+   */
+  protected void paintBorder(Graphics g)
             {
-              System.out.println("button not enabled, ignoring release");
+    if (isBorderPainted())
+      super.paintBorder(g);
             }
-          else
-            {
-              int flags = 0;
 
-              System.out.println("        XXX--> " + getActionCommand());
+  /**
+   * Returns a string, used only for debugging, which identifies or somehow
+   * represents this button. The exact value is implementation-defined.
+   *
+   * @return A string representation of the button
+   */
+  protected String paramString()
+  {
+    return "AbstractButton";
+  }
 
-              fireActionPerformed(new ActionEvent(this,
-                                                  ActionEvent.ACTION_PERFORMED,
-                                                  getActionCommand(),
-                                                  flags));
 
-              //System.out.println("telling model:release");
-              getModel().setPressed(false);
-              repaint();
-            }
-          break;
-        }
-      case MouseEvent.MOUSE_CLICKED:
+  /**
+   * Set the "UI" property of the button, which is a look and feel class
+   * responsible for handling the button's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(ButtonUI ui)
         {
-          break;
+    super.setUI(ui);
         }
+  
+  /**
+   * Set the "UI" property of the button, which is a look and feel class
+   * responsible for handling the button's input events and painting it.
+   *
+   * @return The current "UI" property
+   */
+  public ButtonUI getUI()
+  {
+    return (ButtonUI) ui;
       }
+  
+  /**
+   * Set the "UI" property to a class constructed, via the {@link
+   * UIManager}, from the current look and feel. This should be overridden
+   * for each subclass of AbstractButton, to retrieve a suitable {@link
+   * ButtonUI} look and feel class.
+   */
+  public void updateUI()
+  {
+  }
+
+  /**
+   * Returns the current time in milliseconds in which clicks gets coalesced
+   * into a single <code>ActionEvent</code>.
+   *
+   * @return the time in milliseconds
+   * 
+   * @since 1.4
+   */
+  public long getMultiClickThreshhold()
+  {
+    return multiClickThreshhold;
+  }
+
+  /**
+   * Sets the time in milliseconds in which clicks gets coalesced into a single
+   * <code>ActionEvent</code>.
+   *
+   * @param threshhold the time in milliseconds
+   * 
+   * @since 1.4
+   */
+  public void setMultiClickThreshhold(long threshhold)
+  {
+    if (threshhold < 0)
+      throw new IllegalArgumentException();
+
+    multiClickThreshhold = threshhold;
   }
 }
Index: javax/swing/AbstractCellEditor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractCellEditor.java,v
retrieving revision 1.3
diff -u -r1.3 AbstractCellEditor.java
--- javax/swing/AbstractCellEditor.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/AbstractCellEditor.java	6 Sep 2004 16:35:53 -0000
@@ -1,5 +1,5 @@
 /* AbstractCellEditor.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -54,24 +54,15 @@
 {
   static final long serialVersionUID = -1048006551406220959L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * listenerList
-	 */
-	protected EventListenerList listenerList;
-
-	/**
-	 * changeEvent
-	 */
-	protected transient ChangeEvent changeEvent;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
+  /**
+   * listenerList
+   */
+  protected EventListenerList listenerList;
+
+  /**
+   * changeEvent
+   */
+  protected transient ChangeEvent changeEvent;
 
 	/**
 	 * Constructor AbstractCellEditor
@@ -80,11 +71,6 @@
 		// TODO
 	} // AbstractCellEditor()
 
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * isCellEditable
 	 * @param event TODO
@@ -118,41 +104,59 @@
 		// TODO
 	} // cancelCellEditing()
 
-	/**
-	 * addCellEditorListener
-	 * @param listener TODO
-	 */
-	public void addCellEditorListener(CellEditorListener listener) {
-		// TODO
-	} // addCellEditorListener()
-
-	/**
-	 * removeCellEditorListener
-	 * @param listener TODO
-	 */
-	public void removeCellEditorListener(CellEditorListener listener) {
-		// TODO
-	} // removeCellEditorListener()
-
-	/**
-	 * fireEditingStopped
-	 */
-	protected void fireEditingStopped() {
-		// TODO
-	} // fireEditingStopped()
-
-	/**
-	 * fireEditingCanceled
-	 */
-	protected void fireEditingCanceled() {
-		// TODO
-	} // fireEditingCanceled()
-
-	/**
-	 * getCellEditorValue
-	 * @returns Object
-	 */
-	public abstract Object getCellEditorValue();
-
-
-} // AbstractCellEditor
+  /**
+   * addCellEditorListener
+   *
+   * @param listener The listener to add
+   */
+  public void addCellEditorListener (CellEditorListener listener)
+  {
+    listenerList.add (CellEditorListener.class, listener);
+  }
+
+  /**
+   * removeCellEditorListener
+   *
+   * @param listener The listener to remove
+   */
+  public void removeCellEditorListener (CellEditorListener listener)
+  {
+    listenerList.remove (CellEditorListener.class, listener);
+  }
+	
+  /**
+   * getCellEditorListeners
+   *
+   * @since 1.4
+   */
+  public CellEditorListener[] getCellEditorListeners()
+  {
+    return (CellEditorListener[]) listenerList.getListeners (CellEditorListener.class);
+  }
+
+  /**
+   * fireEditingStopped
+   */
+  protected void fireEditingStopped()
+  {
+    CellEditorListener[] listeners = getCellEditorListeners();
+
+    for (int index = 0; index < listeners.length; index++)
+      {
+	listeners [index].editingStopped (changeEvent);
+      }
+  }
+
+  /**
+   * fireEditingCanceled
+   */
+  protected void fireEditingCanceled()
+  {
+    CellEditorListener[] listeners = getCellEditorListeners();
+
+    for (int index = 0; index < listeners.length; index++)
+      {
+	listeners [index].editingCanceled (changeEvent);
+      }
+  }
+}
Index: javax/swing/AbstractListModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractListModel.java,v
retrieving revision 1.5
diff -u -r1.5 AbstractListModel.java
--- javax/swing/AbstractListModel.java	11 Jun 2003 13:20:39 -0000	1.5
+++ javax/swing/AbstractListModel.java	6 Sep 2004 16:35:53 -0000
@@ -40,57 +40,64 @@
 import java.io.Serializable;
 import java.util.EventListener;
 import javax.swing.event.EventListenerList;
-import javax.swing.event.ListDataListener;
 import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+
 
 /**
  * AbstractListModel
- * A2uthor	Ronald Veldema
- * @author	Andrew Selkirk
- * @version	1.0
+ *
+ * @author Ronald Veldema
+ * @author Andrew Selkirk
+ * @version 1.0
  */
-public abstract class AbstractListModel
-  implements ListModel, Serializable
+public abstract class AbstractListModel implements ListModel, Serializable
 {
   static final long serialVersionUID = -3285184064379168730L;
 
-  /**
-   * listenerList
-   */
-  protected EventListenerList listenerList = new EventListenerList ();
-  
-  /**
-   * Constructor AbstractListModel
-   */
-  public AbstractListModel ()
+  /** List of ListDataListeners called for each change to the list. */
+  protected EventListenerList listenerList;
+
+  public AbstractListModel()
   {
+    listenerList = new EventListenerList();
   }
 
   /**
-   * addListDataListener
-   * @param listener TODO
+   * Add a listener object to this model. The listener will be called
+   * any time the set of elements in the model is changed.
+   *
+   * @param listener The listener to add
    */
-  public void addListDataListener(ListDataListener listener) 
+  public void addListDataListener(ListDataListener listener)
   {
-    listenerList.add (ListDataListener.class, listener);
+    listenerList.add(ListDataListener.class, listener);
   }
 
   /**
-   * removeListDataListener
-   * @param listener TODO
+   * Add a listener object to this model. The listener will no longer be
+   * called when the set of elements in the model is changed.
+   *
+   * @param listener The listener to remove
    */
   public void removeListDataListener(ListDataListener listener)
   {
-    listenerList.remove (ListDataListener.class, listener);
+    listenerList.remove(ListDataListener.class, listener);
   }
 
   /**
-   * fireContentsChanged
-   * @param source TODO
-   * @param startIndex TODO
-   * @param endIndex TODO
+   * Call {@link ListDataListener#contentsChanged} on each element of the
+   * {@link listenerList} which is a {@link ListDataListener}. The event
+   * fired has type {@ListDataEvent.CONTENTS_CHANGED} and represents a
+   * change to the data elements in the range [startIndex, endIndex]
+   * inclusive.
+   *
+   * @param source The source of the change, typically <code>this</code>
+   * @param startIndex The index of the first element which changed
+   * @param endIndex The index of the last element which changed
    */
-  protected void fireContentsChanged(Object source, int startIndex, int endIndex)
+  protected void fireContentsChanged(Object source, int startIndex,
+                                     int endIndex)
   {
     // Variables
     ListDataEvent event;
@@ -100,10 +107,10 @@
 
     // Create Event
     event = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED,
-    startIndex, endIndex);
+                              startIndex, endIndex);
 
     // Get Listeners
-    listeners = getListDataListeners ();
+    listeners = getListDataListeners();
 
     // Process Listeners
     for (index = 0; index < listeners.length; index++)
@@ -114,12 +121,17 @@
   }
 
   /**
-   * fireIntervalAdded
-   * @param source TODO
-   * @param startIndex TODO
-   * @param endIndex TODO
+   * Call {@link ListDataListener#intervalAdded} on each element of the
+   * {@link listenerList} which is a {@link ListDataListener}. The event
+   * fired has type {@ListDataEvent.INTERVAL_ADDED} and represents an
+   * addition of the data elements in the range [startIndex, endIndex]
+   * inclusive.
+   *
+   * @param source The source of the change, typically <code>this</code>
+   * @param startIndex The index of the first new element
+   * @param endIndex The index of the last new element
    */
-  protected void fireIntervalAdded (Object source, int startIndex, int endIndex)
+  protected void fireIntervalAdded(Object source, int startIndex, int endIndex)
   {
     // Variables
     ListDataEvent event;
@@ -128,27 +140,32 @@
     int index;
 
     // Create Event
-    event = new ListDataEvent (source, ListDataEvent.INTERVAL_ADDED, startIndex,
-                               endIndex);
+    event = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED,
+                              startIndex, endIndex);
 
     // Get Listeners
-    listeners = getListDataListeners ();
+    listeners = getListDataListeners();
 
     // Process Listeners
     for (index = 0; index < listeners.length; index++)
       {
-        listener = listeners [index];
-        listener.intervalAdded (event);
+        listener = listeners[index];
+        listener.intervalAdded(event);
       }
   }
 
   /**
-   * fireIntervalRemoved
-   * @param source TODO
-   * @param startIndex TODO
-   * @param endIndex TODO
+   * Call {@link ListDataListener#intervalRemoved} on each element of the
+   * {@link listenerList} which is a {@link ListDataListener}. The event
+   * fired has type {@ListDataEvent.INTERVAL_REMOVED} and represents a
+   * removal of the data elements in the range [startIndex, endIndex]
+   * inclusive.
+   *
+   * @param source The source of the change, typically <code>this</code>
+   * @param startIndex The index of the first element removed
+   * @param endIndex The index of the last element removed
    */
-  protected void fireIntervalRemoved (Object source, int startIndex,
+  protected void fireIntervalRemoved(Object source, int startIndex,
                                      int endIndex)
   {
     // Variables
@@ -158,35 +175,41 @@
     int index;
 
     // Create Event
-    event = new ListDataEvent (source, ListDataEvent.INTERVAL_REMOVED,
-                               startIndex, endIndex);
+    event = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED,
+                              startIndex, endIndex);
 
     // Get Listeners
-    listeners = getListDataListeners ();
+    listeners = getListDataListeners();
 
     // Process Listeners
     for (index = 0; index < listeners.length; index++)
       {
-        listener = listeners [index];
-        listener.intervalRemoved (event);
+        listener = listeners[index];
+        listener.intervalRemoved(event);
       }
   }
 
   /**
-   * getListeners
-   * @param listenerType TODO
-   * @returns EventListener[]
+   * Return the subset of {@link EventListener} objects found in this
+   * object's {@link listenerList} which are elements of the specified
+   * type.
+   *
+   * @param listenerType The type of listeners to select
+   *
+   * @return The set of listeners of the specified type
    */
-  public EventListener[] getListeners (Class listenerType)
+  public EventListener[] getListeners(Class listenerType)
   {
-    return listenerList.getListeners (listenerType);
+    return listenerList.getListeners(listenerType);
   }
 
   /**
-   * getListDataListeners
+   * A synonym for <code>getListeners(ListDataListener.class)</code>.
+   *
+   * @return The set of ListDataListeners found in the {@link listenerList}
    */
-  public ListDataListener[] getListDataListeners ()
+  public ListDataListener[] getListDataListeners()
   {
-    return (ListDataListener[]) getListeners (ListDataListener.class);
+    return (ListDataListener[]) getListeners(ListDataListener.class);
   }
 }
Index: javax/swing/AbstractSpinnerModel.java
===================================================================
RCS file: javax/swing/AbstractSpinnerModel.java
diff -N javax/swing/AbstractSpinnerModel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/AbstractSpinnerModel.java	6 Sep 2004 16:35:53 -0000
@@ -0,0 +1,115 @@
+/* AbstractSpinnerModel.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.util.EventListener;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+/**
+ * AbstractSpinnerModel
+ * @author	Ka-Hing Cheung
+ * @version	1.0
+ */
+public abstract class AbstractSpinnerModel implements SpinnerModel
+{
+  private ChangeEvent changeEvent = new ChangeEvent(this);
+  
+  protected EventListenerList listenerList = new EventListenerList();
+
+  /**
+   * Creates an <code>AbstractSpinnerModel</code>.
+   */
+  public AbstractSpinnerModel()
+  {
+  }
+
+  /**
+   * Adds a <code>ChangeListener</code>.
+   *
+   * @param listener the listener to add
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Gets all the listeners that are of a particular type.
+   *
+   * @param c the type of listener
+   * @return the listeners that are of the specific type
+   */
+  public EventListener[] getListeners(Class c)
+  {
+    return listenerList.getListeners(c);
+  }
+
+  /**
+   * Gets all the <code>ChangeListener</code>s.
+   *
+   * @return all the <code>ChangeListener</code>s
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Remove a particular listener.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s
+   * added to this model
+   */
+  protected void fireStateChanged()
+  {
+    ChangeListener[] listeners = getChangeListeners();
+
+    for(int i = 0; i < listeners.length; ++i)
+      listeners[i].stateChanged(changeEvent);
+  }
+}
Index: javax/swing/ActionMap.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ActionMap.java,v
retrieving revision 1.3
diff -u -r1.3 ActionMap.java
--- javax/swing/ActionMap.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/ActionMap.java	6 Sep 2004 16:35:53 -0000
@@ -42,25 +42,21 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+
 /**
- * ActionMap
  * @author	Andrew Selkirk
- * @version	1.0
+ * @author Michael Koch
  */
-public class ActionMap implements Serializable
+public class ActionMap
+  implements Serializable
 {
-  static final long serialVersionUID = -6277518704513986346L;
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+  private static final long serialVersionUID = -6277518704513986346L;
 
 	/**
 	 * actionMap
@@ -70,170 +66,146 @@
 	/**
 	 * parent
 	 */
-	private ActionMap parent = null;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
+  private ActionMap parent;
 
 	/**
-	 * Constructor ActionMap
+   * Creates a new <code>ActionMap</code> instance.
 	 */
-	public ActionMap() {
-	} // ActionMap()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  public ActionMap()
+  {
+  }
 
 	/**
-	 * get
-	 * @param key TODO
-	 * @returns Action
+   * Returns an action associated with an object.
+   *
+   * @param key the key of the enty
+   *
+   * @return the action associated with key, may be null
 	 */
-	public Action get(Object key) {
+  public Action get(Object key)
+  {
+    Object result = actionMap.get(key);
 
-		// Variables
-		Object	result;
-
-		// Check Local store
-		result = actionMap.get(key);
-
-		// Check Parent
-		if (result == null) {
-			result = parent.get(key);
-		} // if
+    if (result == null && parent != null)
+      result = parent.get(key);
 
 		return (Action) result;
-
-	} // get()
+  }
 
 	/**
-	 * put
-	 * @param key TODO
-	 * @param action TODO
-	 */
-	public void put(Object key, Action action) {
-		if (action == null) {
+   * Puts a new <code>Action</code> into the <code>ActionMap</code>.
+   * If action is null an existing entry will be removed.
+   *
+   * @param key the key for the entry
+   * @param action the action.
+	 */
+  public void put(Object key, Action action)
+  {
+    if (action == null)
 			actionMap.remove(key);
-		} else {
+    else
 			actionMap.put(key, action);
-		} // if
-	} // put()
+  }
 
 	/**
-	 * remove
-	 * @param key TODO
+   * Remove an entry from the <code>ActionMap</code>.
+   *
+   * @param key the key of the entry to remove
 	 */
-	public void remove(Object key) {
+  public void remove(Object key)
+  {
 		actionMap.remove(key);
-	} // remove()
+  }
 
 	/**
-	 * getParent
-	 * @returns ActionMap
+   * Returns the parent of this <code>ActionMap</code>.
+   *
+   * @return the parent, may be null.
 	 */
-	public ActionMap getParent() {
+  public ActionMap getParent()
+  {
 		return parent;
-	} // getParent()
+  }
 
 	/**
-	 * setParent
-	 * @param parentMap TODO
+   * Sets a parent for this <code>ActionMap</code>.
+   *
+   * @param parentMap the new parent
 	 */
-	public void setParent(ActionMap parentMap) {
+  public void setParent(ActionMap parentMap)
+  {
 		parent = parentMap;
-	} // setParent()
+  }
 
 	/**
-	 * size
-	 * @returns int
+   * Returns the number of entries in this <code>ActionMap</code>.
+   *
+   * @return the number of entries
 	 */
-	public int size() {
+  public int size()
+  {
 		return actionMap.size();
-	} // size()
+  }
 
 	/**
-	 * clear
+   * Clears the <code>ActionMap</code>.
 	 */
-	public void clear() {
+  public void clear()
+  {
 		actionMap.clear();
-	} // clear()
+  }
 
 	/**
-	 * keys
-	 * @returns Object[]
+   * Returns all keys of entries in this <code>ActionMap</code>.
+   *
+   * @return an array of keys
 	 */
-	public Object[] keys() {
-		return convertSet(actionMap.keySet());
-	} // keys()
+  public Object[] keys()
+  {
+    return actionMap.keySet().toArray();
+  }
 
 	/**
-	 * allKeys
-	 * @returns Object[]
+   * Returns all keys of entries in this <code>ActionMap</code>
+   * and all its parents.
+   *
+   * @return an array of keys
 	 */
-	public Object[] allKeys() {
-
-		// Variables
-		Set			set;
-
-		// Initialize
-		set = new HashSet();
+  public Object[] allKeys()
+  {
+    Set set = new HashSet();
 
-		// Get Key Sets
-		if (parent != null) {
+    if (parent != null)
 			set.addAll(Arrays.asList(parent.allKeys()));
-		} // if
-		set.addAll(actionMap.keySet());
 
-		return convertSet(set);
-
-	} // allKeys()
-
-	private Object[] convertSet(Set set) {
-
-		// Variables
-		int			index;
-		Iterator	iterator;
-		Object[]	keys;
-
-		// Create Final array
-		keys = new Object[set.size()];
-		iterator = set.iterator();
-		index = 0;
-		while (iterator.hasNext()) {
-			keys[index++] = iterator.next();
-		} // while
-
-		return keys;
-
-	} // convertSet()
-
-
-	//-------------------------------------------------------------
-	// Interface: Serializable ------------------------------------
-	//-------------------------------------------------------------
+    set.addAll(actionMap.keySet());
+    return set.toArray();
+  }
 
 	/**
 	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream value0) throws IOException {
+   *
+   * @param stream the stream to write to
+   *
+   * @exception IOException If an error occurs
+	 */
+  private void writeObject(ObjectOutputStream stream)
+    throws IOException
+  {
 		// TODO
-	} // writeObject()
+  }
 
 	/**
 	 * readObject
-	 * @param stream TODO
-	 * @exception ClassNotFoundException TODO
-	 * @exception IOException TODO
-	 */
-	private void readObject(ObjectInputStream value0) throws ClassNotFoundException, IOException {
+   *
+   * @param stream the stream to read from
+   *
+   * @exception ClassNotFoundException If the serialized class cannot be found
+   * @exception IOException If an error occurs
+	 */
+  private void readObject(ObjectInputStream stream)
+    throws ClassNotFoundException, IOException
+  {
 		// TODO
-	} // readObject()
-
-
-} // ActionMap
+  }
+}
Index: javax/swing/Box.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/Box.java,v
retrieving revision 1.2
diff -u -r1.2 Box.java
--- javax/swing/Box.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/Box.java	6 Sep 2004 16:35:53 -0000
@@ -1,5 +1,5 @@
 /* Box.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,17 +39,245 @@
 package javax.swing;
 
 import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import java.awt.LayoutManager;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.AWTError;
 
 /**
- * Needs some work I guess....
+ * A component that uses a {@link BoxLayout} as Layout Manager.
+ *
+ * In addition to that, this class provides a set of static methods for
+ * creating some filler components ('struts' and 'glue') for use in
+ * containers that are laid out using BoxLayout.
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
 public class Box extends JComponent implements Accessible
 {
-    Box(int a)
+  private static final long serialVersionUID = 1525417495883046342L;
+  
+  // FIXME: disable to make libjava compile; visibility rules are broken
+  protected class AccessibleBox // extends Container.AccessibleAWTContainer
+  {
+    private static final long serialVersionUID = -7775079816389931944L;
+  
+    protected AccessibleBox()
+    {
+    }
+    
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+  }
+
+  /**
+   * A component that servers as a filler in BoxLayout controlled containers.
+   */
+  public static class Filler extends JComponent implements Accessible
+  {
+    private static final long serialVersionUID = -1204263191910183998L;
+  
+    // FIXME: disable to make libjava compile; visibility rules are broken
+    protected class AccessibleBoxFiller // extends Component.AccessibleAWTComponent
+    {
+      private static final long serialVersionUID = 164963348357479321L;
+      
+      protected AccessibleBoxFiller()
+      {
+      }
+      
+      public AccessibleRole getAccessibleRole()
+      {
+        return null;
+      }
+    }
+    
+    protected AccessibleContext accessibleContext;
+    
+    private transient Dimension min, pref, max;
+    
+    /**
+     * Creates a new instance of Filler.
+     *
+     * @param min the minimum size of the filler.
+     * @param pref the preferred size of the filler.
+     * @param max the maximum size of the filler.
+     */
+    public Filler(Dimension min, Dimension pref, Dimension max)
+    {
+      changeShape(min, pref, max);
+    }
+    
+    /**
+     * Changes the dimensions of this Filler.
+     *
+     * @param min the new minimum size of the filler.
+     * @param pref the new preferred size of the filler.
+     * @param max the new maximum size of the filler.
+     */
+    public void changeShape(Dimension min, Dimension pref, Dimension max)
+    {
+      this.min = min;
+      this.pref = pref;
+      this.max = max;    
+    }
+    
+    public AccessibleContext getAccessibleContext()
+    {
+      // FIXME: disable to make libjava compile; visibility rules are broken      
+      //      if (accessibleContext == null)
+      //        accessibleContext = new AccessibleBoxFiller();
+      return accessibleContext;
+    }
+    
+    /**
+     * Returns the maximum size of this Filler.
+     *
+     * @return the maximum size of this Filler.
+     */
+    public Dimension getMaximumSize()
+    {
+      return max;
+    }
+    
+    /**
+     * Returns the minimum size of this Filler.
+     *
+     * @return the minimum size of this Filler.
+     */
+    public Dimension getMinimumSize()
+    {
+      return min;
+    }
+    
+    /**
+     * Returns the preferred size of this Filler.
+     *
+     * @return the preferred size of this Filler.
+     */
+    public Dimension getPreferredSize()
     {
-        setLayout(new BoxLayout(this, 
-				a));	
+      return pref;
     }
+  }
+  
+  /**
+   * Creates a new Box component, that lays out its children according
+   * to the <code>axis</code> parameter.
+   *
+   * @param axis the orientation of the BoxLayout.
+   *
+   * @see BoxLayout#X_AXIS
+   * @see BoxLayout#Y_AXIS
+   * @see BoxLayout#LINE_AXIS
+   * @see BoxLayout#PAGE_AXIS
+   */
+  public Box(int axis)
+  {
+    super.setLayout(new BoxLayout(this, axis));	
+  }
+  
+  /**
+   * Creates a filler component which acts as glue between components.
+   * It does not take space unless some extra space is available. If extra
+   * space is available, this component can expand in both X and Y directions.
+   *
+   * @return a glue-like filler component.
+   */
+  public static Component createGlue()
+  {
+    Filler glue = new Filler(new Dimension(0,0), new Dimension(0,0),
+                             new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE)
+                             );
+    return glue;
+  }
+  
+  public static Box createHorizontalBox()
+  {
+    return new Box(BoxLayout.X_AXIS);
+  }
+  
+  /**
+   * Creates a filler component which acts as glue between components.
+   * It does not take space unless some extra space is available. If extra
+   * space is available, this component can expand in the X direction.
+   *
+   * @return a glue-like filler component.
+   */
+  public static Component createHorizontalGlue()
+  {
+    return createGlue();
+  }
+  
+  /**
+   * Creates a filler component which acts as strut between components.
+   * It will fill exactly the specified horizontal size.
+   *
+   * @param width the width of this strut in pixels.
+   *
+   * @return a strut-like filler component.
+   */
+  public static Component createHorizontalStrut(int width)
+  {
+    Filler strut = new Filler(new Dimension(width, 0),
+                              new Dimension(width, 0),
+                              new Dimension(width, Integer.MAX_VALUE));
+    return strut;
+  }
+  
+  public static Component createRigidArea(Dimension d)
+  {
+    return new Filler(d, d, d);
+  }
+  
+  public static Box createVerticalBox()
+  {
+    return new Box(BoxLayout.Y_AXIS);
+  }
+  
+  /**
+   * Creates a filler component which acts as glue between components.
+   * It does not take space unless some extra space is available. If extra
+   * space is available, this component can expand in the Y direction.
+   *
+   * @return a glue-like filler component.
+   */
+  public static Component createVerticalGlue()
+  {
+    return createGlue();
+  }
+  
+  /**
+   * Creates a filler component which acts as strut between components.
+   * It will fill exactly the specified vertical size.
+   *
+   * @param height the height of this strut in pixels.
+   *
+   * @return a strut-like filler component.
+   */
+  public static Component createVerticalStrut(int height)
+  {
+    Filler strut = new Filler(new Dimension(0, height),
+                              new Dimension(0, height),
+                              new Dimension(Integer.MAX_VALUE, height));
+    return strut;
+  }
+  
+  public void setLayout(LayoutManager l)
+  {
+    throw new AWTError("Not allowed to set layout managers for boxes.");
+  }
+  
+  public AccessibleContext getAccessibleContext()
+  {
+    //     if (accessibleContext == null)
+    //       accessibleContext = new AccessibleBox();
+    return accessibleContext;
+  }
+  
+  
 }
Index: javax/swing/BoxLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/BoxLayout.java,v
retrieving revision 1.3
diff -u -r1.3 BoxLayout.java
--- javax/swing/BoxLayout.java	24 Nov 2003 16:55:43 -0000	1.3
+++ javax/swing/BoxLayout.java	6 Sep 2004 16:35:53 -0000
@@ -42,15 +42,11 @@
 import java.awt.ComponentOrientation;
 import java.awt.Container;
 import java.awt.Dimension;
-import java.awt.GridLayout;
 import java.awt.LayoutManager2;
 import java.io.Serializable;
 
-
 /**
  * A layout for swing components.
- * This implementation delegates its methods to
- * java.awt.GridLayout to do its work.
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
@@ -87,11 +83,6 @@
   private Container container;
   
   /*
-   * Internal layout.
-   */
-  private GridLayout grid;
-
-  /*
    * Current type of component layouting. Defaults to X_AXIS.
    */
   private int way = X_AXIS;
@@ -108,75 +99,41 @@
   {
     int width = 0;
     int height = 0;
-    ComponentOrientation orientation = container.getComponentOrientation();
-
     this.container = container;
     this.way = way;
-
-    switch (way)
-      {
-      case X_AXIS:
-	width = 1;
-	break;
-      case Y_AXIS:
-	height = 1;
-	break;
-      case LINE_AXIS:
-	if (orientation.isHorizontal())
-          height = 1;
-	else
-	  width = 1;
-	break;
-      case PAGE_AXIS:
-	if (!orientation.isHorizontal())
-          height = 1;
-	else
-	  width = 1;
-	break;
-      default:
-	throw new AWTError("Invalid value for way");
-      }
-
-    grid = new GridLayout(width, height);
   }
 
   /**
-   * Adds a component to the layout.
+   * Adds a component to the layout. Not used in BoxLayout.
    *
    * @param name The name of the component to add.
    * @param component the component to add to the layout.
    */
   public void addLayoutComponent(String name, Component component)
   {
-    if (way == X_AXIS
-        || (way == LINE_AXIS
-            && component.getComponentOrientation().isHorizontal())
-        || (way == PAGE_AXIS
-            && !component.getComponentOrientation().isHorizontal()))
-      grid.setColumns(grid.getColumns() + 1);
-    else
-      grid.setRows(grid.getRows() + 1);
   }
 
   /**
-   * Removes a component from the layout.
+   * Removes a component from the layout. Not used in BoxLayout.
    *
    * @param component The component to remove from the layout.
    */
   public void removeLayoutComponent(Component component)
   {
-    grid.removeLayoutComponent(component);
+  }
 
-    if (way == X_AXIS
-        || (way == LINE_AXIS
-            && component.getComponentOrientation().isHorizontal())
-        || (way == PAGE_AXIS
-            && !component.getComponentOrientation().isHorizontal()))
-      grid.setColumns(grid.getColumns() - 1);
-    else
-      grid.setRows(grid.getRows() - 1);
+  private boolean isHorizontalIn(Container parent)
+  {
+    ComponentOrientation orientation = parent.getComponentOrientation();
+    return this.way == X_AXIS 
+      || (this.way == LINE_AXIS 
+          && orientation.isHorizontal())
+      || (this.way == PAGE_AXIS
+          && (!orientation.isHorizontal()));
   }
 
+  
+
   /**
    * Returns the preferred size of the layout.
    *
@@ -188,8 +145,38 @@
   {
     if (parent != container)
       throw new AWTError("invalid parent");
+
+    int x = 0;
+    int y = 0;
+
+    Component[] children = parent.getComponents();
+
+    if (isHorizontalIn(parent))
+      {        
+        // sum up preferred widths of components, find maximum of preferred
+        // heights
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getPreferredSize();
+            x += sz.width;
+            y = Math.max(y, sz.height);
+          }
+      } 
+    else 
+      {        
+        // sum up preferred heights of components, find maximum of
+        //  preferred widths
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getPreferredSize();
+            y += sz.height;
+            x = Math.max(x, sz.width);
+          }
+      }
     
-    return grid.preferredLayoutSize(parent);
+    return new Dimension(x, y);
   }
 
   /**
@@ -203,8 +190,38 @@
   {
     if (parent != container)
       throw new AWTError("invalid parent");
+
+    int x = 0;
+    int y = 0;
+
+    Component[] children = parent.getComponents();
+
+    if (isHorizontalIn(parent))
+      {
+        // sum up preferred widths of components, find maximum of preferred
+        // heights
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getMinimumSize();
+            x += sz.width;
+            y = Math.max(y, sz.height);
+          }
+      }
+    else
+      {
+        // sum up preferred heights of components, find maximum of
+        //  preferred widths
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getMinimumSize();
+            y += sz.height;
+            x = Math.max(x, sz.width);
+          }
+      }
     
-    return grid.minimumLayoutSize(parent);
+    return new Dimension(x, y);
   }
 
   /**
@@ -216,19 +233,69 @@
   {
     if (parent != container)
       throw new AWTError("invalid parent");
-    
-    grid.layoutContainer(parent);
-  }
 
+    Dimension size = parent.getSize();
+
+    Component[] children = parent.getComponents();
+
+    if (isHorizontalIn(parent))
+      {
+        int x = 0;
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getPreferredSize();
+            int width = sz.width;
+            int height = sz.height;
+            int cy = 0;
+            if (height > size.height)
+              {
+                height = size.height;
+              }
+            else
+              {
+                cy = (int) ((size.height - height) * comp.getAlignmentY());
+              }
+            
+            comp.setSize(width, height);
+            comp.setLocation(x, cy);
+            x = x + width;            
+          }
+      }
+    else
+      {
+        int y = 0;        
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getPreferredSize();
+            int width = sz.width;
+            int height = sz.height;
+            int cx = 0;
+            if (width > size.width)
+              {
+                width = size.width;
+              }
+            else
+              {
+                cx = (int) ((size.width - width) * comp.getAlignmentX());
+              }
+            
+            comp.setSize(width, height);
+            comp.setLocation(cx, y);
+            y = y + height;            
+          }
+      }    
+  }
+  
   /**
-   * Adds a component to the layout.
+   * Adds a component to the layout. Not used in BoxLayout
    *
    * @param child The component to add to the layout.
    * @param constraints The constraints for the component in the layout.
    */
   public void addLayoutComponent(Component child, Object constraints)
   {
-    addLayoutComponent("", child);
   }
 
   /**
@@ -284,7 +351,37 @@
   {
     if (parent != container)
       throw new AWTError("invalid parent");
-    
-    return preferredLayoutSize(parent);
+
+    int x = 0;
+    int y = 0;
+
+    Component[] children = parent.getComponents();
+
+    if (isHorizontalIn(parent))
+      {
+        
+        // sum up preferred widths of components, find maximum of preferred
+        // heights
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getMaximumSize();
+            x += sz.width;
+            y = Math.max(y, sz.height);
+          }
+      }
+    else
+      {
+        // sum up preferred heights of components, find maximum of
+        //  preferred widths
+        for (int index = 0; index < children.length; index++)
+          {
+            Component comp = children[index];
+            Dimension sz = comp.getMaximumSize();
+            y += sz.height;
+            x = Math.max(x, sz.width);
+          }
+      } 
+    return new Dimension(x, y);
   }
 }
Index: javax/swing/ButtonGroup.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ButtonGroup.java,v
retrieving revision 1.3
diff -u -r1.3 ButtonGroup.java
--- javax/swing/ButtonGroup.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/ButtonGroup.java	6 Sep 2004 16:35:53 -0000
@@ -1,4 +1,4 @@
-/* ButtonGroup.java -- 
+/* ButtonGroup.java --
    Copyright (C) 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -35,105 +35,145 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.io.Serializable;
 import java.util.Enumeration;
 import java.util.Vector;
 
-public class ButtonGroup implements Serializable 
-{
-  static final long serialVersionUID = 4259076101881721375L;
-
-    Vector v = new Vector();
-    ButtonModel sel;
-    
-    public ButtonGroup() {}
-    
-    public void add(AbstractButton b) 
-    {
-	b.getModel().setGroup(this);
-	v.addElement(b);
-    }
-    
-    public void remove(AbstractButton b)
-    {
-	b.getModel().setGroup(null);
-	v.removeElement(b);
-    }
-
-
-    public Enumeration getElements() {
-        return v.elements();
-    }
-
-    public ButtonModel getSelection() {
-        return sel;
-    }
-
-    AbstractButton FindButton(ButtonModel m)
-    {
-	for (int i=0;i<v.size();i++)
-	    {
-	    AbstractButton a = (AbstractButton) v.get(i);
-	    if (a.getModel()== m)
-	    {
-		return a;
-	    }
-	}
-	return null;
-    }
-
-    public void setSelected(ButtonModel m, boolean b)
-    {
-	if ((m == sel) &&
-	    (b == true))
-	    {
-		// clicked on sam item twice.
-		System.out.println("PRESSED TWICE:" + m + ", sel="+sel);
-		return;
-	    }	
-	
-	if (sel != null)
-	    {
-
-		System.out.println("DESELECTING: " + sel);
-		sel.setSelected(!b);
-
-		AbstractButton but = FindButton(sel);
-		if (but != null)
-		    {
-			System.out.println("REPAINT-REQUIST: " + but.text);
-			//but.revalidate();
-			but.repaint();
-		    }
-	    }
-	else
-	    {
-		System.out.println("NO SELECTION YET");
-	    }
-	
-	sel = m;
-    }
-    
-    public boolean isSelected(ButtonModel m) 
-    {
-        return (m == sel);
-    }
-
-    public int getButtonCount() 
-    {
-	return v.size();
-    }
-
-}
-
-
-
-
 
+/**
+ * DOCUMENT ME!
+ */
+public class ButtonGroup implements Serializable
+{
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 4259076101881721375L;
 
+  /** The buttons added to this button group. */
+  protected Vector buttons = new Vector();
 
+  /** The currently selected button model. */
+  ButtonModel sel;
 
+  /**
+   * Creates a new button group.
+   */
+  public ButtonGroup()
+  {
+  }
+
+  /**
+   * Adds a button to this group.
+   *
+   * @param b the button to add
+   */
+  public void add(AbstractButton b)
+  {
+    b.getModel().setGroup(this);
+    buttons.addElement(b);
+  }
+
+  /**
+   * Removed a given button from this group.
+   *
+   * @param b the button to remove
+   */
+  public void remove(AbstractButton b)
+  {
+    b.getModel().setGroup(null);
+    buttons.removeElement(b);
+  }
+
+  /**
+   * Returns the currently added buttons.
+   *
+   * @return <code>Enumeration</code> over all added buttons
+   */
+  public Enumeration getElements()
+  {
+    return buttons.elements();
+  }
+
+  /**
+   * Returns the currently selected button model.
+   *
+   * @return the currently selected button model, null if none was selected
+   *         yet
+   */
+  public ButtonModel getSelection()
+  {
+    return sel;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param m DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  AbstractButton FindButton(ButtonModel m)
+  {
+    for (int i = 0; i < buttons.size(); i++)
+      {
+	AbstractButton a = (AbstractButton) buttons.get(i);
+	if (a.getModel() == m)
+	  return a;
+      }
+    return null;
+  }
+
+  /**
+   * Sets the currently selected button model. Only one button of a group can
+   * be selected at a time.
+   *
+   * @param m the model to select
+   * @param b true if this button is to be selected, false otherwise
+   */
+  public void setSelected(ButtonModel m, boolean b)
+  {
+    if ((sel != m || b) && (! b || sel == m))
+      return;
+
+    if (b && sel != m)
+      {
+	ButtonModel old = sel;
+	sel = m;
 
+	if (old != null)
+	  old.setSelected(false);
+	AbstractButton button = FindButton(old);
+	if (button != null)
+	  button.repaint();
+      }
+    else if (! b && sel == m)
+      m.setSelected(true);
+  }
+
+  /**
+   * Checks if the given <code>ButtonModel</code> is selected in this button
+   * group.
+   *
+   * @param m DOCUMENT ME!
+   *
+   * @return true of given <code>ButtonModel</code> is selected, false
+   *         otherwise
+   */
+  public boolean isSelected(ButtonModel m)
+  {
+    return m == sel;
+  }
+
+  /**
+   * Return the number of buttons in this button group.
+   *
+   * @return the number of buttons
+   *
+   * @since 1.3
+   */
+  public int getButtonCount()
+  {
+    return buttons.size();
+  }
+}
Index: javax/swing/CellEditor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/CellEditor.java,v
retrieving revision 1.3
diff -u -r1.3 CellEditor.java
--- javax/swing/CellEditor.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/CellEditor.java	6 Sep 2004 16:35:53 -0000
@@ -45,54 +45,49 @@
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public interface CellEditor {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getCellEditorValue
-	 * @returns Object
-	 */
-	Object getCellEditorValue();
-
-	/**
-	 * isCellEditable
-	 * @param event TODO
-	 * @returns boolean
-	 */
-	boolean isCellEditable(EventObject event);
-
-	/**
-	 * shouldSelectCell
-	 * @param event TODO
-	 * @returns boolean
-	 */
-	boolean shouldSelectCell(EventObject event);
-
-	/**
-	 * stopCellEditing
-	 * @returns boolean
-	 */
-	boolean stopCellEditing();
-
-	/**
-	 * cancelCellEditing
-	 */
-	void cancelCellEditing();
-
-	/**
-	 * addCellEditorListener
-	 * @param value0 TODO
-	 */
-	void addCellEditorListener(CellEditorListener listener);
-
-	/**
-	 * removeCellEditorListener
-	 * @param listener TODO
-	 */
-	void removeCellEditorListener(CellEditorListener listener);
-
+public interface CellEditor
+{
+  /**
+   * getCellEditorValue
+   * @returns Object
+   */
+  Object getCellEditorValue();
+
+  /**
+   * isCellEditable
+   * @param event TODO
+   * @returns boolean
+   */
+  boolean isCellEditable(EventObject event);
+
+  /**
+   * shouldSelectCell
+   * @param event TODO
+   * @returns boolean
+   */
+  boolean shouldSelectCell(EventObject event);
+
+  /**
+   * stopCellEditing
+   * @returns boolean
+   */
+  boolean stopCellEditing();
+
+  /**
+   * cancelCellEditing
+   */
+  void cancelCellEditing();
+
+  /**
+   * addCellEditorListener
+   * @param value0 TODO
+   */
+  void addCellEditorListener(CellEditorListener listener);
+
+  /**
+   * removeCellEditorListener
+   * @param listener TODO
+   */
+  void removeCellEditorListener(CellEditorListener listener);
 
 } // CellEditor
Index: javax/swing/CellRendererPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/CellRendererPane.java,v
retrieving revision 1.2
diff -u -r1.2 CellRendererPane.java
--- javax/swing/CellRendererPane.java	9 Jan 2004 10:18:47 -0000	1.2
+++ javax/swing/CellRendererPane.java	6 Sep 2004 16:35:53 -0000
@@ -52,50 +52,34 @@
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public class CellRendererPane extends Container implements Accessible {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleCellRendererPane
-	 */
-	protected class AccessibleCellRendererPane extends AccessibleAWTContainer {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleCellRendererPane
-		 * @param component TODO
-		 */
-		protected AccessibleCellRendererPane(CellRendererPane component) {
-			super();
-			// TODO
-		} // AccessibleCellRendererPane()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.PANEL;
-		} // getAccessibleRole()
-
-
-	} // AccessibleCellRendererPane
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+public class CellRendererPane extends Container implements Accessible
+{
+  private static final long serialVersionUID = -7642183829532984273L;
+
+  /**
+   * AccessibleCellRendererPane
+   */
+  protected class AccessibleCellRendererPane extends AccessibleAWTContainer
+  {
+    private static final long serialVersionUID = -8981090083147391074L;
+
+    /**
+     * Constructor AccessibleCellRendererPane
+     * @param component TODO
+     */
+    protected AccessibleCellRendererPane()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     * @returns AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PANEL;
+    }
+  }
 
 	/**
 	 * accessibleContext
@@ -205,16 +189,15 @@
 		// TODO
 	} // paintComponent()
 
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleCellRendererPane(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // CellRendererPane
+  /**
+   * getAccessibleContext
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleCellRendererPane();
+
+    return accessibleContext;
+  }
+}
Index: javax/swing/ComboBoxEditor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ComboBoxEditor.java,v
retrieving revision 1.3
diff -u -r1.3 ComboBoxEditor.java
--- javax/swing/ComboBoxEditor.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/ComboBoxEditor.java	6 Sep 2004 16:35:53 -0000
@@ -42,49 +42,56 @@
 
 /**
  * ComboBoxEditor
- * @author	Andrew Selkirk
- * @version	1.0
+ *
+ * @author Andrew Selkirk
+ * @author Olga Rodimina
+ * @version 1.0
  */
-public interface ComboBoxEditor {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getEditorComponent
-	 * @returns Component
-	 */
-	Component getEditorComponent();
-
-	/**
-	 * setItem
-	 * @param item TODO
-	 */
-	void setItem(Object item);
-
-	/**
-	 * getItem
-	 * @returns Object
-	 */
-	Object getItem();
-
-	/**
-	 * selectAll
-	 */
-	void selectAll();
-
-	/**
-	 * addActionListener
-	 * @param listener TODO
-	 */
-	void addActionListener(ActionListener listener);
-
-	/**
-	 * removeActionListener
-	 * @param listener TODO
-	 */
-	void removeActionListener(ActionListener listener);
-
-
+public interface ComboBoxEditor
+{
+  /**
+   * This method returns component that will be used by the combo box to
+   * display/edit currently selected item in the combo box.
+   *
+   * @return Component that will be used by the combo box to display/edit
+   *         currently selected item
+   */
+  Component getEditorComponent();
+
+  /**
+   * Sets item that should be editted when any editting operation is performed
+   * by the user. The value is always equal to the currently selected value
+   * in the combo box. Thus, whenever a different value is selected from the
+   * combo box list then this method should be called to change editting item
+   * to the new selected item.
+   *
+   * @param selectedItem item that is currently selected in the combo box
+   */
+  void setItem(Object item);
+
+  /**
+   * This method returns item that is currently editable.
+   *
+   * @return Item in the combo box that is currently editable
+   */
+  Object getItem();
+
+  /**
+   * selectAll
+   */
+  void selectAll();
+
+  /**
+   * This method adds specified ActionListener to this ComboBoxEditor.
+   *
+   * @param listener
+   */
+  void addActionListener(ActionListener listener);
+
+  /**
+   * This method removes given ActionListener from this ComboBoxEditor.
+   *
+   * @param listener TODO
+   */
+  void removeActionListener(ActionListener listener);
 } // ComboBoxEditor
Index: javax/swing/ComboBoxModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ComboBoxModel.java,v
retrieving revision 1.2
diff -u -r1.2 ComboBoxModel.java
--- javax/swing/ComboBoxModel.java	12 Oct 2003 13:20:49 -0000	1.2
+++ javax/swing/ComboBoxModel.java	6 Sep 2004 16:35:53 -0000
@@ -37,28 +37,32 @@
 
 package javax.swing;
 
+
 /**
- * ComboBoxModel
- * @author	Andrew Selkirk
- * @version	1.0
+ * ComboBoxModel is a data model for JComboBox. This model keeps
+ * track of elements contained in the JComboBox as well as the current
+ * combo box selection. Whenever selection in the JComboBox changes, the
+ * ComboBoxModel should fire ListDataEvents to ComboBox's ListDataListeners.
+ *
+ * @author        Andrew Selkirk
+ * @version        1.0
  */
-public interface ComboBoxModel extends ListModel {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * setSelectedItem
-	 * @param item TODO
-	 */
-	void setSelectedItem(Object item);
-
-	/**
-	 * getSelectedItem
-	 * @returns Object
-	 */
-	Object getSelectedItem();
-
+public interface ComboBoxModel extends ListModel
+{
+  /**
+   * This method sets the selected item in the combo box. Class
+   * implementing this interface should fire ListDataEvents to
+   * all registered ListDataListeners to indicated that the
+   * selection has changed.
+   *
+   * @param item item in the combo box that should be selected
+   */
+  void setSelectedItem(Object item);
 
+  /**
+   * The method returns currently selected item in the combo box
+   *
+   * @returns item that is currently selected in the combo box.
+   */
+  Object getSelectedItem();
 } // ComboBoxModel
Index: javax/swing/ComponentInputMap.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ComponentInputMap.java,v
retrieving revision 1.1
diff -u -r1.1 ComponentInputMap.java
--- javax/swing/ComponentInputMap.java	9 Aug 2002 04:26:10 -0000	1.1
+++ javax/swing/ComponentInputMap.java	6 Sep 2004 16:35:53 -0000
@@ -1,5 +1,5 @@
 /* ComponentInputMap.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,79 +37,94 @@
 
 package javax.swing;
 
+
 /**
- * ComponentInputMap
  * @author	Andrew Selkirk
- * @version	1.0
+ * @author Michael Koch
  */
-public class ComponentInputMap extends InputMap {
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
+public class ComponentInputMap extends InputMap
+{
 	/**
-	 * component
+   * The component to notify.
 	 */
 	private JComponent component;
 
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor ComponentInputMap
-	 * @param value0 TODO
-	 */
-	public ComponentInputMap(JComponent value0) {
-		// TODO
-	} // ComponentInputMap()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * put
-	 * @param keystroke TODO
-	 * @param value TODO
-	 */
-	public void put(KeyStroke keystroke, Object value) {
-		// TODO
-	} // put()
-
 	/**
-	 * clear
-	 */
-	public void clear() {
-		// TODO
-	} // clear()
-
-	/**
-	 * remove
-	 * @param keystroke TODO
-	 */
-	public void remove(KeyStroke keystroke) {
-		// TODO
-	} // remove()
-
-	/**
-	 * setParent
-	 * @param parent TODO
-	 */
-	public void setParent(InputMap parent) {
-		// TODO
-	} // setParent()
-
-	/**
-	 * getComponent
-	 * @returns JComponent
-	 */
-	public JComponent getComponent() {
-		return null; // TODO
-	} // getComponent()
-
-
-} // ComponentInputMap
+   * Creates <code>ComponentInputMap</code> object that notifies the given
+   * component about changes to it.
+   *
+   * @param comp the component to notify
+   *
+   * @exception IllegalArgumentException if comp is null
+   */
+  public ComponentInputMap(JComponent comp)
+  {
+    if (comp == null)
+      throw new IllegalArgumentException();
+    
+    this.component = comp;
+  }
+
+  /**
+   * Puts a new entry into the <code>InputMap</code>.
+   * If actionMapKey is null an existing entry will be removed.
+   *
+   * @param keystroke the keystroke for the entry
+   * @param actionMapKey the action.
+   */
+  public void put(KeyStroke keystroke, Object value)
+  {
+    super.put(keystroke, value);
+    // FIXME: Notify component.
+  }
+
+  /**
+   * Clears the <code>InputMap</code>.
+   */
+  public void clear()
+  {
+    super.clear();
+    // FIXME: Notify component.
+  }
+
+  /**
+   * Remove an entry from the <code>InputMap</code>.
+   *
+   * @param key the key of the entry to remove
+   */
+  public void remove(KeyStroke keystroke)
+  {
+    super.remove(keystroke);
+    // FIXME: Notify component.
+  }
+
+  /**
+   * Sets a parent for this <code>ComponentInputMap</code>.
+   *
+   * @param parentMap the new parent
+   *
+   * @exception IllegalArgument if parentMap is not a
+   * <code>ComponentInputMap</code> or not associated with the same component
+   */
+  public void setParent(InputMap parentMap)
+  {
+    if (! (parentMap instanceof ComponentInputMap))
+      throw new IllegalArgumentException();
+
+    if (((ComponentInputMap) parentMap).getComponent() != component)
+      throw new IllegalArgumentException();
+   
+    super.setParent(parentMap);
+    // FIXME: Notify component.
+  }
+
+  /**
+   * Returns the component to notify about changes.
+   *
+   * @return a <code>JComponent</code> object
+   */
+  public JComponent getComponent()
+  {
+    return component;
+  }
+}
Index: javax/swing/DefaultBoundedRangeModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultBoundedRangeModel.java,v
retrieving revision 1.5
diff -u -r1.5 DefaultBoundedRangeModel.java
--- javax/swing/DefaultBoundedRangeModel.java	7 Jan 2004 14:42:03 -0000	1.5
+++ javax/swing/DefaultBoundedRangeModel.java	6 Sep 2004 16:35:53 -0000
@@ -203,7 +203,7 @@
    * Changes the current value of this bounded range model. In a
    * scroll bar visualization of a {@link BoundedRangeModel}, the
    * <code>value</code> is displayed as the position of the thumb;
-   * changing the <code>value</code> of a scroll bar&#x2019;s model
+   * changing the <code>value</code> of a scroll bar's model
    * thus moves the thumb to a different position.
    */
   public void setValue(int value)
Index: javax/swing/DefaultButtonModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultButtonModel.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultButtonModel.java
--- javax/swing/DefaultButtonModel.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/DefaultButtonModel.java	6 Sep 2004 16:35:53 -0000
@@ -1,5 +1,5 @@
-/* DefaultButtonModel.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* DefaultButtonModel.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,144 +35,502 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
 import java.io.Serializable;
 import java.util.EventListener;
-import java.util.Vector;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.event.EventListenerList;
 
-public class DefaultButtonModel
-  implements ButtonModel, Serializable
+
+/**
+ * The purpose of this class is to model the dynamic state of an abstract
+ * button. The concrete button type holding this state may be a a "toggle"
+ * button (checkbox, radio button) or a "push" button (menu button, button).
+ * If the model is disabled, only the "selected" property can be changed. An
+ * attempt to change the "armed", "rollover" or "pressed" properties  while
+ * the model is disabled will be blocked. Any successful (non-blocked) change
+ * to the model's properties will trigger the firing of a ChangeEvent. Any
+ * change to the "selected" property will trigger the firing of an ItemEvent
+ * in addition to ChangeEvent. This is true whether the model is enabled or
+ * not. One other state change is special: the transition from "enabled,
+ * armed and pressd" to "enabled, armed and not-pressed". This is considered
+ * the "trailing edge" of a successful mouse click, and therefore fires an
+ * ActionEvent in addition to a ChangeEvent. In all other respects this class
+ * is just a container of boolean flags.
+ *
+ * @author Graydon Hoare (graydon_at_redhat.com)
+ */
+public class DefaultButtonModel implements ButtonModel, Serializable
 {
+  /** DOCUMENT ME! */
   static final long serialVersionUID = -5342609566534980231L;
 
-    Vector actions          = new Vector();
-
-    Vector items    = new Vector();
-    Vector changes  = new Vector();
-    ButtonGroup group;
-    JComponent comp;
-
-    
-    DefaultButtonModel(JComponent a)
-    {
-	comp = a;
-    }
-
-
-    public Object[] getSelectedObjects()
-    {
-	return null;
-    }
-
-
-    public void fireItemStateChanged(ItemEvent event)
-    {
-	for (int i=0;i<items.size();i++)
-	    {
-		ItemListener a = (ItemListener) items.get(i);
-		a.itemStateChanged(event);
-	    }
-    }
-    public void fireStateChanged(ChangeEvent event)
-    {
-	for (int i=0;i<changes.size();i++)
-	    {
-		ChangeListener a = (ChangeListener) changes.get(i);
-		a.stateChanged(event);
-	    }
-    }
-    public void fireActionPerformed(ActionEvent event)
-    {
-	for (int i=0;i<actions.size();i++)
-	    {
-		ActionListener a = (ActionListener) actions.get(i);
-		a.actionPerformed(event);
-	    }
-    }
-
-    boolean arm;
-    public boolean isArmed()          { return arm; }
-    public void setArmed(boolean b)   { arm = b; }
-
-    boolean enabled = true;
-    public boolean isEnabled()         { return enabled; }
-    public void setEnabled(boolean b)  { enabled = b; }
-
-    boolean pressed;
-    public void setPressed(boolean b)  
-    {
-	pressed = b; 
-    }
-    public boolean isPressed()         { return pressed; }
-
-
-    public void removeActionListener(ActionListener l) { actions.removeElement(l); }
-    public void addActionListener(ActionListener l)    
-    {	
-	//	comp.enableEvents( AWTEvent.ACTION_EVENT_MASK );
-	actions.addElement(l);    
-    }
-
-    public void addItemListener(ItemListener l)        { items.addElement(l); }
-    public void removeItemListener(ItemListener l)     { items.removeElement(l); }
-
-    public void addChangeListener(ChangeListener l)    { changes.addElement(l); }
-    public void removeChangeListener(ChangeListener l) { changes.removeElement(l); }
-
-    boolean roll;
-    public void setRollover(boolean b) { roll = b; }
-    public boolean isRollover()        { return roll; }
-
-    int mne;  
-    public int  getMnemonic()        { return mne; }
-    public void setMnemonic(int key) { mne = key; }
-
-    String com;
-    public void setActionCommand(String s) { com = s; }
-    public String getActionCommand()       { return com; }
-
-    public void setGroup(ButtonGroup group)
-    {
-	this.group = group;
-    }
-
-    boolean sel;
-    public void setSelected(boolean b) 
-    { 
-	if (group != null)
-	    {
-		if (b == true)
-		    {
-			System.out.println("selected button in group:"+this);
-			group.setSelected(this, b);
-			sel = true;
-		    }
-		else
-		    {
-			System.out.println("deselected button in group: " + this);
-			sel = false;
-		    }
-	    } 
-	else
-	    {
-		sel = b;
-	    }
-    }
-    public boolean isSelected()        { return sel; }
+  /**
+   * Indicates that the button is <em>partially</em> committed to being
+   * pressed, but not entirely. This usually happens when a user has pressed
+   * but not yet released the mouse button.
+   */
+  public static final int ARMED = 1;
+
+  /**
+   * State constant indicating that the button is enabled. Buttons cannot be
+   * pressed or selected unless they are enabled.
+   */
+  public static final int ENABLED = 8;
+
+  /**
+   * State constant indicating that the user is holding down the button. When
+   * this transitions from true to false, an ActionEvent may be fired,
+   * depending on the value of the "armed" property.
+   */
+  public static final int PRESSED = 4;
+
+  /**
+   * State constant indicating that the mouse is currently positioned over the
+   * button.
+   */
+  public static final int ROLLOVER = 16;
+
+  /**
+   * State constant indicating that the button is selected. This constant is
+   * only meaningful for toggle-type buttons (radio buttons, checkboxes).
+   */
+  public static final int SELECTED = 2;
+
+  /**
+   * Represents the "state properties" (armed, enabled, pressed, rollover and
+   * selected) by a bitwise combination of integer constants.
+   */
+  protected int stateMask = ENABLED;
+
+  /**
+   * List of ItemListeners, ChangeListeners, and ActionListeners registered on
+   * this model.
+   */
+  protected EventListenerList listenerList = new EventListenerList();
+  ;
+
+  /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
+  protected ChangeEvent changeEvent = new ChangeEvent(this);
+
+  /**
+   * The group this model belongs to. Only one button in a group may be
+   * selected at any given time.
+   */
+  protected ButtonGroup group;
+
+  /**
+   * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
+   * this button via a keyboard interface.
+   */
+  protected int mnemonic = KeyEvent.VK_UNDEFINED;
+
+  /**
+   * The string used as the "command" property of any ActionEvent this model
+   * sends.
+   */
+  protected String actionCommand;
+
+  /**
+   * Creates a new DefaultButtonModel object.
+   */
+  public DefaultButtonModel()
+  {
+  }
+
+  /**
+   * Return <code>null</code>. Use {@link AbstractButton} if you wish to
+   * interface with a button via an {@link ItemSelectable} interface.
+   *
+   * @return <code>null</code>
+   */
+  public Object[] getSelectedObjects()
+  {
+    return null;
+  }
+
+  /**
+   * Returns a specified class of listeners.
+   *
+   * @param listenerType the type of listener to return
+   *
+   * @return array of listeners
+   */
+  public EventListener[] getListeners(Class listenerType)
+  {
+    return listenerList.getListeners(listenerType);
+  }
+
+  /**
+   * Add an ActionListener to the model. Usually only called to subscribe an
+   * AbstractButton's listener to the model.
+   *
+   * @param l The listener to add
+   */
+  public void addActionListener(ActionListener l)
+  {
+    listenerList.add(ActionListener.class, l);
+  }
+
+  /**
+   * Remove an ActionListener to the model. Usually only called to unsubscribe
+   * an AbstractButton's listener to the model.
+   *
+   * @param l The listener to remove
+   */
+  public void removeActionListener(ActionListener l)
+  {
+    listenerList.remove(ActionListener.class, l);
+  }
+
+  /**
+   * Returns all registered <code>ActionListener</code> objects.
+   *
+   * @return array of <code>ActionListener</code> objects
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) listenerList.getListeners(ActionListener.class);
+  }
+
+  /**
+   * Add an ItemListener to the model. Usually only called to subscribe an
+   * AbstractButton's listener to the model.
+   *
+   * @param l The listener to add
+   */
+  public void addItemListener(ItemListener l)
+  {
+    listenerList.add(ItemListener.class, l);
+  }
+
+  /**
+   * Remove an ItemListener to the model. Usually only called to unsubscribe
+   * an AbstractButton's listener to the model.
+   *
+   * @param l The listener to remove
+   */
+  public void removeItemListener(ItemListener l)
+  {
+    listenerList.remove(ItemListener.class, l);
+  }
+
+  /**
+   * Returns all registered <code>ItemListener</code> objects.
+   *
+   * @return array of <code>ItemListener</code> objects
+   */
+  public ItemListener[] getItemListeners()
+  {
+    return (ItemListener[]) listenerList.getListeners(ItemListener.class);
+  }
+
+  /**
+   * Add a ChangeListener to the model. Usually only called to subscribe an
+   * AbstractButton's listener to the model.
+   *
+   * @param l The listener to add
+   */
+  public void addChangeListener(ChangeListener l)
+  {
+    listenerList.add(ChangeListener.class, l);
+  }
+
+  /**
+   * Remove a ChangeListener to the model. Usually only called to unsubscribe
+   * an AbstractButton's listener to the model.
+   *
+   * @param l The listener to remove
+   */
+  public void removeChangeListener(ChangeListener l)
+  {
+    listenerList.remove(ChangeListener.class, l);
+  }
+
+  /**
+   * Returns all registered <code>ChangeListener</code> objects.
+   *
+   * @return array of <code>ChangeListener</code> objects
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Inform each ItemListener in the {@link listenerList} that an ItemEvent
+   * has occurred. This happens in response to any change to the {@link
+   * stateMask} field.
+   *
+   * @param e The ItemEvent to fire
+   */
+  public void fireItemStateChanged(ItemEvent e)
+  {
+    ItemListener[] ll = getItemListeners();
+
+    for (int i = 0; i < ll.length; i++)
+      ll[i].itemStateChanged(e);
+  }
+
+  /**
+   * Inform each ActionListener in the {@link listenerList} that an
+   * ActionEvent has occurred. This happens in response to the any change to
+   * the {@link stateMask} field which makes the enabled, armed and pressed
+   * properties all simultaneously <code>true</code>.
+   *
+   * @param e The ActionEvent to fire
+   */
+  public void fireActionPerformed(ActionEvent e)
+  {
+    ActionListener[] ll = getActionListeners();
+
+    for (int i = 0; i < ll.length; i++)
+      ll[i].actionPerformed(e);
+  }
+
+  /**
+   * Inform each ChangeListener in the {@link listenerList} that a ChangeEvent
+   * has occurred. This happens in response to the any change to a property
+   * of the model.
+   */
+  public void fireStateChanged()
+  {
+    ChangeListener[] ll = getChangeListeners();
+
+    for (int i = 0; i < ll.length; i++)
+      ll[i].stateChanged(changeEvent);
+  }
+
+  /**
+   * Helper method to fire a ChangeEvent with the model as the event's source.
+   *
+   * @param stateflag DOCUMENT ME!
+   * @param b DOCUMENT ME!
+   */
+  protected void changeState(int stateflag, boolean b)
+  {
+    int oldstate = stateMask;
+    int newstate;
+
+    if (b)
+      newstate = oldstate | stateflag;
+    else
+      newstate = oldstate & ~ stateflag;
+
+    if (oldstate == newstate)
+      return;
+
+    if ((stateflag != SELECTED) && (stateflag != ENABLED)
+        && (stateMask & ENABLED) == 0)
+      return;
+
+    stateMask = newstate;
+
+    fireStateChanged();
+
+    if ((oldstate & SELECTED) == 0 && (newstate & SELECTED) == SELECTED)
+      {
+	fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+	                                   null, ItemEvent.SELECTED));
+        if (group != null)
+          group.setSelected(this, true);
+      }
+
+    else if ((oldstate & SELECTED) == SELECTED && (newstate & SELECTED) == 0)
+      {
+	fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+	                                   null, ItemEvent.DESELECTED));
+        if (group != null)
+          group.setSelected(this, false);
+      }
+
+    else if (((oldstate & ARMED) == ARMED && (oldstate & PRESSED) == PRESSED)
+             && ((newstate & ARMED) == ARMED && (newstate & PRESSED) == 0))
+      fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+                                          actionCommand));
+  }
+
+  /**
+   * Get the value of the model's "armed" property.
+   *
+   * @return The current "armed" property
+   */
+  public boolean isArmed()
+  {
+    return (stateMask & ARMED) == ARMED;
+  }
+
+  /**
+   * Set the value of the model's "armed" property.
+   *
+   * @param a The new "armed" property
+   */
+  public void setArmed(boolean a)
+  {
+    changeState(ARMED, a);
+  }
+
+  /**
+   * Get the value of the model's "enabled" property.
+   *
+   * @return The current "enabled" property.
+   */
+  public boolean isEnabled()
+  {
+    return (stateMask & ENABLED) == ENABLED;
+  }
+
+  /**
+   * Set the value of the model's "enabled" property.
+   *
+   * @param e The new "enabled" property
+   */
+  public void setEnabled(boolean e)
+  {
+    changeState(ENABLED, e);
+  }
+
+  /**
+   * Set the value of the model's "pressed" property.
+   *
+   * @param p The new "pressed" property
+   */
+  public void setPressed(boolean p)
+  {
+    changeState(PRESSED, p);
+  }
+
+  /**
+   * Get the value of the model's "pressed" property.
+   *
+   * @return The current "pressed" property
+   */
+  public boolean isPressed()
+  {
+    return (stateMask & PRESSED) == PRESSED;
+  }
+
+  /**
+   * Set the value of the model's "rollover" property.
+   *
+   * @param r The new "rollover" property
+   */
+  public void setRollover(boolean r)
+  {
+    changeState(ROLLOVER, r);
+  }
+
+  /**
+   * Set the value of the model's "selected" property.
+   *
+   * @param s The new "selected" property
+   */
+  public void setSelected(boolean s)
+  {
+    changeState(SELECTED, s);
+  }
+
+  /**
+   * Get the value of the model's "selected" property.
+   *
+   * @return The current "selected" property
+   */
+  public boolean isSelected()
+  {
+    return (stateMask & SELECTED) == SELECTED;
+  }
+
+  /**
+   * Get the value of the model's "rollover" property.
+   *
+   * @return The current "rollover" property
+   */
+  public boolean isRollover()
+  {
+    return (stateMask & ROLLOVER) == ROLLOVER;
+  }
+
+  /**
+   * Get the value of the model's "mnemonic" property.
+   *
+   * @return The current "mnemonic" property
+   */
+  public int getMnemonic()
+  {
+    return mnemonic;
+  }
+
+  /**
+   * Set the value of the model's "mnemonic" property.
+   *
+   * @param key The new "mnemonic" property
+   */
+  public void setMnemonic(int key)
+  {
+    if (mnemonic != key)
+      {
+	mnemonic = key;
+	fireStateChanged();
+      }
+  }
+
+  /**
+   * Set the value of the model's "actionCommand" property. This property is
+   * used as the "command" property of the {@link ActionEvent} fired from the
+   * model.
+   *
+   * @param s The new "actionCommand" property.
+   */
+  public void setActionCommand(String s)
+  {
+    if (actionCommand != s)
+      {
+	actionCommand = s;
+	fireStateChanged();
+      }
+  }
+
+  /**
+   * Returns the current value of the model's "actionCommand" property.
+   *
+   * @return The current "actionCommand" property
+   */
+  public String getActionCommand()
+  {
+    return actionCommand;
+  }
+
+  /**
+   * Set the value of the model's "group" property. The model is said to be a
+   * member of the {@link ButtonGroup} held in its "group" property, and only
+   * one model in a given group can have their "selected" property be
+   * <code>true</code> at a time.
+   *
+   * @param g The new "group" property
+   */
+  public void setGroup(ButtonGroup g)
+  {
+    if (group != g)
+      {
+	group = g;
+	fireStateChanged();
+      }
+  }
+
+  /**
+   * Returns the current value of the model's "group" property.
+   *
+   * @return The value of the "group" property
+   */
+  public ButtonGroup getGroup()
+  {
+    return group;
+  }
 }
-
-
-
-
-
-
-
Index: javax/swing/DefaultCellEditor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultCellEditor.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultCellEditor.java
--- javax/swing/DefaultCellEditor.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/DefaultCellEditor.java	6 Sep 2004 16:35:53 -0000
@@ -58,50 +58,34 @@
 {
   static final long serialVersionUID = 3564035141373880027L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * EditorDelegate
-	 */
-	protected class EditorDelegate implements ActionListener, 
-			ItemListener, Serializable {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * value
-		 */
-		protected Object value;
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor EditorDelegate
-		 * @param value0 TODO
-		 */
-		protected EditorDelegate(DefaultCellEditor editor) {
-			// TODO
-		} // EditorDelegate()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * setValue
-		 * @param event TODO
-		 */
-		public void setValue(Object event) {
-			// TODO
-		} // setValue()
+  /**
+   * EditorDelegate
+   */
+  protected class EditorDelegate
+    implements ActionListener, ItemListener, Serializable
+  {
+    private static final long serialVersionUID = -1420007406015481933L;
+
+    /**
+     * value
+     */
+    protected Object value;
+
+    /**
+     * Constructor EditorDelegate
+     * @param value0 TODO
+     */
+    protected EditorDelegate()
+    {
+    }
+
+    /**
+     * setValue
+     * @param event TODO
+     */
+    public void setValue(Object event)
+    {
+    }
 
 		/**
 		 * getCellEditorValue
@@ -172,11 +156,6 @@
 
 	} // EditorDelegate
 
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * editorComponent
 	 */
@@ -192,11 +171,6 @@
 	 */
 	protected int clickCountToStart;
 
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * Constructor DefaultCellEditor
 	 * @param textfield TODO
@@ -221,11 +195,6 @@
 		// TODO
 	} // DefaultCellEditor()
 
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * getComponent
 	 * @returns Component
@@ -320,6 +289,4 @@
 			Object value, boolean isSelected, int row, int column) {
 		return null; // TODO
 	} // getTableCellEditorComponent()
-
-
-} // DefaultCellEditor
+}
Index: javax/swing/DefaultComboBoxModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultComboBoxModel.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultComboBoxModel.java
--- javax/swing/DefaultComboBoxModel.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/DefaultComboBoxModel.java	6 Sep 2004 16:35:53 -0000
@@ -38,146 +38,191 @@
 package javax.swing;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Vector;
 
+
 /**
- * DefaultComboBoxModel
- * @author	Andrew Selkirk
- * @version	1.0
+ * DefaultComboBoxModel is a data model for JComboBox. This model keeps track
+ * of elements contained in the JComboBox as well as the current combo box
+ * selection. Whenever selection in the JComboBox changes, the ComboBoxModel
+ * will fire ListDataEvents to ComboBox's ListDataListeners.
+ *
+ * @author Andrew Selkirk
+ * @author Olga Rodimina
+ * @version 1.0
  */
-public class DefaultComboBoxModel extends AbstractListModel 
-		implements MutableComboBoxModel, Serializable
+public class DefaultComboBoxModel extends AbstractListModel
+  implements MutableComboBoxModel, Serializable
 {
   static final long serialVersionUID = 6698657703676921904L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * list
-	 */
-	private Vector list;
-
-	/**
-	 * selectedItem
-	 */
-	private Object selectedItem;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultComboBoxModel
-	 */
-	public DefaultComboBoxModel() {
-		// TODO
-	} // DefaultComboBoxModel()
-
-	/**
-	 * Constructor DefaultComboBoxModel
-	 * @param items TODO
-	 */
-	public DefaultComboBoxModel(Object[] items) {
-		// TODO
-	} // DefaultComboBoxModel()
-
-	/**
-	 * Constructor DefaultComboBoxModel
-	 * @param vector TODO
-	 */
-	public DefaultComboBoxModel(Vector vector) {
-		// TODO
-	} // DefaultComboBoxModel()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * addElement
-	 * @param object TODO
-	 */
-	public void addElement(Object object) {
-		// TODO
-	} // addElement()
-
-	/**
-	 * removeElementAt
-	 * @param index TODO
-	 */
-	public void removeElementAt(int index) {
-		// TODO
-	} // removeElementAt()
-
-	/**
-	 * insertElementAt
-	 * @param object TODO
-	 * @param index TODO
-	 */
-	public void insertElementAt(Object object, int index) {
-		// TODO
-	} // insertElementAt()
-
-	/**
-	 * removeElement
-	 * @param object TODO
-	 */
-	public void removeElement(Object object) {
-		// TODO
-	} // removeElement()
-
-	/**
-	 * removeAllElements
-	 */
-	public void removeAllElements() {
-		// TODO
-	} // removeAllElements()
-
-	/**
-	 * getSize
-	 * @returns int
-	 */
-	public int getSize() {
-		return 0; // TODO
-	} // getSize()
-
-	/**
-	 * setSelectedItem
-	 * @param object TODO
-	 */
-	public void setSelectedItem(Object object) {
-		// TODO
-	} // setSelectedItem()
-
-	/**
-	 * getSelectedItem
-	 * @returns Object
-	 */
-	public Object getSelectedItem() {
-		return null; // TODO
-	} // getSelectedItem()
-
-	/**
-	 * getElementAt
-	 * @param index TODO
-	 * @returns Object
-	 */
-	public Object getElementAt(int index) {
-		return null; // TODO
-	} // getElementAt()
-
-	/**
-	 * getIndexOf
-	 * @param object TODO
-	 * @returns int
-	 */
-	public int getIndexOf(Object object) {
-		return 0; // TODO
-	} // getIndexOf()
-
-
-} // DefaultComboBoxModel
+  /**
+   * List containing items in the combo box
+   */
+  private Vector list;
+
+  /**
+   * Currently selected item in the combo box list
+   */
+  private Object selectedItem = null;
+
+  /**
+   * Constructor DefaultComboBoxModel. Create empty JComboBox.
+   */
+  public DefaultComboBoxModel()
+  {
+    list = new Vector();
+  }
+
+  /**
+   * Constructs new DefaultComboBoxModel object and initializes its item list
+   * to values in the given array.
+   *
+   * @param items array containing items of the combo box.
+   */
+  public DefaultComboBoxModel(Object[] items)
+  {
+    list = new Vector(Arrays.asList(items));
+  }
+
+  /**
+   * Consturcts new DefaultComboBoxModel object and initializes its item list
+   * to values in the given vector.
+   *
+   * @param vector Vector containing items for this combo box.
+   */
+  public DefaultComboBoxModel(Vector vector)
+  {
+    this.list = vector;
+  }
+
+  /**
+   * This method adds element to the combo box list. It fires ListDataEvent
+   * indicating that component was added to the combo box  to all of the
+   * JComboBox's registered ListDataListeners.
+   *
+   * @param object item to add to the combo box list
+   */
+  public void addElement(Object object)
+  {
+    list.add(object);
+    fireIntervalAdded(this, list.size(), list.size());
+  }
+
+  /**
+   * This method removes element at the specified index from the combo box
+   * list. It fires ListDataEvent indicating that component was removed from
+   * the combo box list to all of the JComboBox's registered
+   * ListDataListeners.
+   *
+   * @param index index specifying location of the element to remove in the
+   *        combo box list.
+   */
+  public void removeElementAt(int index)
+  {
+    list.remove(index);
+    fireIntervalRemoved(this, index, index);
+  }
+
+  /**
+   * This method inserts given object to the combo box list at the specified
+   * index. It fires ListDataEvent indicating that component was inserted to
+   * the combo box list to all of the JComboBox's registered
+   * ListDataListeners.
+   *
+   * @param object element to insert
+   * @param index index specifing position in the list where given element
+   *        should be inserted.
+   */
+  public void insertElementAt(Object object, int index)
+  {
+    list.insertElementAt(object, index);
+    fireIntervalAdded(this, index, index);
+  }
+
+  /**
+   * Removes given object from the combo box list. It fires ListDataEvent
+   * indicating that component was removed from the combo box list to all of
+   * the JComboBox's registered ListDataListeners.
+   *
+   * @param object Element that will be removed from the combo box list
+   */
+  public void removeElement(Object object)
+  {
+    int index = getIndexOf(object);
+    if (index != -1)
+      removeElementAt(index);
+  }
+
+  /**
+   * Removes all the items from the JComboBox's item list. It fires
+   * ListDataEvent indicating that all the elements were removed from the
+   * combo box list to all of the JComboBox's registered ListDataListeners.
+   */
+  public void removeAllElements()
+  {
+    int listSize = getSize();
+    list.clear();
+    fireIntervalAdded(this, 0, listSize - 1);
+  }
+
+  /**
+   * Returns number of items in the combo box list
+   *
+   * @return number of items in the combo box list
+   */
+  public int getSize()
+  {
+    return list.size();
+  }
+
+  /**
+   * Selects given object in the combo box list. This method fires
+   * ListDataEvent to all registered ListDataListeners of the JComboBox. The
+   * start and end index of the event is set to -1 to indicate combo box's
+   * selection has changed, and not its contents.
+   *
+   * @param object item to select in the JComboBox
+   */
+  public void setSelectedItem(Object object)
+  {
+    selectedItem = object;
+    fireContentsChanged(this, -1, -1);
+  }
+
+  /**
+   * Returns currently selected item in the combo box list
+   *
+   * @return currently selected item in the combo box list
+   */
+  public Object getSelectedItem()
+  {
+    return selectedItem;
+  }
+
+  /**
+   * Returns element in the combo box list located at the given index
+   *
+   * @param index specifying location of the element in the list
+   *
+   * @return return element in the combo box list located at the given index
+   */
+  public Object getElementAt(int index)
+  {
+    return list.elementAt(index);
+  }
+
+  /**
+   * Returns index of the specified object in the combo box list.
+   *
+   * @param object element to look for in the combo box list .
+   *
+   * @return Index specifying position of the specified element in combo box
+   *         list.
+   */
+  public int getIndexOf(Object object)
+  {
+    return list.indexOf(object);
+  }
+}
Index: javax/swing/DefaultDesktopManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultDesktopManager.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultDesktopManager.java
--- javax/swing/DefaultDesktopManager.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/DefaultDesktopManager.java	6 Sep 2004 16:35:54 -0000
@@ -37,249 +37,594 @@
 
 package javax.swing;
 
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
 import java.awt.Rectangle;
+import java.beans.PropertyVetoException;
 import java.io.Serializable;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+
 
 /**
- * DefaultDesktopManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * DefaultDesktopManager is the default implementation of DesktopManager for
+ * swing. It implements the basic beaviours for JInternalFrames in arbitrary
+ * parents. The methods provided by the class are not meant to be called by
+ * the user, instead, the JInternalFrame methods will call these methods.
  */
 public class DefaultDesktopManager implements DesktopManager, Serializable
 {
+  /** DOCUMENT ME! */
   static final long serialVersionUID = 4657624909838017887L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * HAS_BEEN_ICONIFIED_PROPERTY
-	 */
-	static final String HAS_BEEN_ICONIFIED_PROPERTY = ""; // TODO
-
-	/**
-	 * DEFAULT_DRAG_MODE
-	 */
-	static final int DEFAULT_DRAG_MODE = 0; // TODO
-
-	/**
-	 * OUTLINE_DRAG_MODE
-	 */
-	static final int OUTLINE_DRAG_MODE = 0; // TODO
-
-	/**
-	 * FASTER_DRAG_MODE
-	 */
-	static final int FASTER_DRAG_MODE = 0; // TODO
-
-	/**
-	 * dragMode
-	 */
-	int dragMode;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultDesktopManager
-	 */
-	public DefaultDesktopManager() {
-		// TODO
-	} // DefaultDesktopManager()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * openFrame
-	 * @param frame TODO
-	 */
-	public void openFrame(JInternalFrame frame) {
-		// TODO
-	} // openFrame()
-
-	/**
-	 * closeFrame
-	 * @param frame TODO
-	 */
-	public void closeFrame(JInternalFrame frame) {
-		// TODO
-	} // closeFrame()
-
-	/**
-	 * maximizeFrame
-	 * @param frame TODO
-	 */
-	public void maximizeFrame(JInternalFrame frame) {
-		// TODO
-	} // maximizeFrame()
-
-	/**
-	 * minimizeFrame
-	 * @param frame TODO
-	 */
-	public void minimizeFrame(JInternalFrame frame) {
-		// TODO
-	} // minimizeFrame()
-
-	/**
-	 * iconifyFrame
-	 * @param frame TODO
-	 */
-	public void iconifyFrame(JInternalFrame frame) {
-		// TODO
-	} // iconifyFrame()
-
-	/**
-	 * deiconifyFrame
-	 * @param frame TODO
-	 */
-	public void deiconifyFrame(JInternalFrame frame) {
-		// TODO
-	} // deiconifyFrame()
-
-	/**
-	 * activateFrame
-	 * @param frame TODO
-	 */
-	public void activateFrame(JInternalFrame frame) {
-		// TODO
-	} // activateFrame()
-
-	/**
-	 * deactivateFrame
-	 * @param frame TODO
-	 */
-	public void deactivateFrame(JInternalFrame frame) {
-		// TODO
-	} // deactivateFrame()
-
-	/**
-	 * beginDraggingFrame
-	 * @param component TODO
-	 */
-	public void beginDraggingFrame(JComponent component) {
-		// TODO
-	} // beginDraggingFrame()
-
-	/**
-	 * dragFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 */
-	public void dragFrame(JComponent component, int newX, int newY) {
-		// TODO
-	} // dragFrame()
-
-	/**
-	 * endDraggingFrame
-	 * @param component TODO
-	 */
-	public void endDraggingFrame(JComponent component) {
-		// TODO
-	} // endDraggingFrame()
-
-	/**
-	 * beginResizingFrame
-	 * @param component TODO
-	 * @param direction TODO
-	 */
-	public void beginResizingFrame(JComponent component, int direction) {
-		// TODO
-	} // beginResizingFrame()
-
-	/**
-	 * resizeFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 * @param newWidth TODO
-	 * @param newHeight TODO
-	 */
-	public void resizeFrame(JComponent component, int newX, int newY,
-			int newWidth, int newHeight) {
-		// TODO
-	} // resizeFrame()
-
-	/**
-	 * endResizingFrame
-	 * @param component TODO
-	 */
-	public void endResizingFrame(JComponent component) {
-		// TODO
-	} // endResizingFrame()
-
-	/**
-	 * setBoundsForFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 * @param newWidth TODO
-	 * @param newHeight TODO
-	 */
-	public void setBoundsForFrame(JComponent component, int newX,
-			int newY, int newWidth, int newHeight) {
-		// TODO
-	} // setBoundsForFrame()
-
-	/**
-	 * removeIconFor
-	 * @param frame TODO
-	 */
-	protected void removeIconFor(JInternalFrame frame) {
-		// TODO
-	} // removeIconFor()
-
-	/**
-	 * getBoundsForIconOf
-	 * @param frame TODO
-	 * @returns Rectangle
-	 */
-	protected Rectangle getBoundsForIconOf(JInternalFrame frame) {
-		return null; // TODO
-	} // getBoundsForIconOf()
-
-	/**
-	 * setPreviousBounds
-	 * @param frame TODO
-	 * @param rect TODO
-	 */
-	protected void setPreviousBounds(JInternalFrame frame, Rectangle rect) {
-		// TODO
-	} // setPreviousBounds()
-
-	/**
-	 * getPreviousBounds
-	 * @param frame TODO
-	 * @returns Rectangle
-	 */
-	protected Rectangle getPreviousBounds(JInternalFrame frame) {
-		return null; // TODO
-	} // getPreviousBounds()
-
-	/**
-	 * setWasIcon
-	 * @param frame TODO
-	 * @param value TODO
-	 */
-	protected void setWasIcon(JInternalFrame frame, Boolean value) {
-		// TODO
-	} // setWasIcon()
-
-	/**
-	 * wasIcon
-	 * @param frame TODO
-	 * @returns boolean
-	 */
-	protected boolean wasIcon(JInternalFrame frame) {
-		return false; // TODO
-	} // wasIcon()
-
+  /** The property change event fired when the wasIcon property changes. */
+  static final String WAS_ICON_ONCE_PROPERTY = "wasIconOnce";
 
+  /**
+   * The method of dragging used by the JDesktopPane that parents the
+   * JInternalFrame that is being dragged.
+   */
+  private int currentDragMode = 0;
+
+  /**
+   * The cache of the bounds used to draw the outline rectangle when
+   * OUTLINE_DRAG_MODE is used.
+   */
+  private transient Rectangle dragCache = new Rectangle();
+
+  /**
+   * A cached JDesktopPane that is stored when the JInternalFrame is initially
+   * dragged.
+   */
+  private transient Container pane;
+
+  /**
+   * An array of Rectangles that holds the bounds of the JDesktopIcons in the 
+   * JDesktopPane when looking for where to place a new icon.
+   */
+  private transient Rectangle[] iconRects;
+
+  /**
+   * This creates a new DefaultDesktopManager object.
+   */
+  public DefaultDesktopManager()
+  {
+  } // DefaultDesktopManager()
+
+  /**
+   * This method is not normally called since the user will typically add the
+   * JInternalFrame to a Container. If this is called, it will try to
+   * determine the parent of the JInternalFrame and remove any icon that
+   * represents this JInternalFrame and add this JInternalFrame.
+   *
+   * @param frame The JInternalFrame to open.
+   */
+  public void openFrame(JInternalFrame frame)
+  {
+    Container c = frame.getParent();
+    if (c == null)
+      c = frame.getDesktopIcon().getParent();
+    if (c == null)
+      return;
+
+    c.remove(frame.getDesktopIcon());
+    c.add(frame);
+    frame.setVisible(true);
+  } // openFrame()
+
+  /**
+   * This method removes the JInternalFrame and JDesktopIcon (if one is
+   * present) from their parents.
+   *
+   * @param frame The JInternalFrame to close.
+   */
+  public void closeFrame(JInternalFrame frame)
+  {
+    Container c = frame.getParent();
+    frame.doDefaultCloseAction();
+
+    if (c != null)
+      {
+	if (frame.isIcon())
+	  c.remove(frame.getDesktopIcon());
+	else
+	  c.remove(frame);
+	c.repaint();
+      }
+  } // closeFrame()
+
+  /**
+   * This method resizes the JInternalFrame to match its parent's bounds.
+   *
+   * @param frame The JInternalFrame to maximize.
+   */
+  public void maximizeFrame(JInternalFrame frame)
+  {
+    // Can't maximize from iconified state.
+    // It can only return to maximized state, but that would fall under
+    // deiconify.
+    if (frame.isIcon())
+      return;
+    frame.setNormalBounds(frame.getBounds());
+
+    Container p = frame.getParent();
+    if (p != null)
+      {
+	Rectangle pBounds = p.getBounds();
+	Insets insets = p.getInsets();
+	pBounds.width -= insets.left + insets.right;
+	pBounds.height -= insets.top + insets.bottom;
+
+	setBoundsForFrame(frame, 0, 0, pBounds.width, pBounds.height);
+      }
+    if (p instanceof JDesktopPane)
+      ((JDesktopPane) p).setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+  } // maximizeFrame()
+
+  /**
+   * This method restores the JInternalFrame's bounds to what they were
+   * previous to the setMaximize call.
+   *
+   * @param frame The JInternalFrame to minimize.
+   */
+  public void minimizeFrame(JInternalFrame frame)
+  {
+    Rectangle normalBounds = frame.getNormalBounds();
+
+    JDesktopPane p = frame.getDesktopPane();
+    if (p != null)
+      p.setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+
+    setBoundsForFrame(frame, normalBounds.x, normalBounds.y,
+                      normalBounds.width, normalBounds.height);
+  } // minimizeFrame()
+
+  /**
+   * This method removes the JInternalFrame from its parent and adds its
+   * JDesktopIcon representation.
+   *
+   * @param frame The JInternalFrame to iconify.
+   */
+  public void iconifyFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+    JDesktopIcon icon = frame.getDesktopIcon();
+    if (p != null && p.getSelectedFrame() == frame)
+      p.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+
+    Container c = frame.getParent();
+
+    if (! wasIcon(frame))
+      {
+	Rectangle r = getBoundsForIconOf(frame);
+	icon.setBounds(r);
+	setWasIcon(frame, true);
+      }
+
+    if (c != null)
+      {
+	if (icon != null)
+	  {
+	    c.add(icon);
+	    icon.setVisible(true);
+	  }
+	c.remove(frame);
+      }
+  } // iconifyFrame()
+
+  /**
+   * This method removes the JInternalFrame's JDesktopIcon representation and
+   * adds the JInternalFrame back to its parent.
+   *
+   * @param frame The JInternalFrame to deiconify.
+   */
+  public void deiconifyFrame(JInternalFrame frame)
+  {
+    JDesktopIcon icon = frame.getDesktopIcon();
+    Container c = icon.getParent();
+
+    removeIconFor(frame);
+    c.add(frame);
+    frame.setVisible(true);
+
+    if (! frame.isSelected())
+      {
+	JDesktopPane p = frame.getDesktopPane();
+	if (p != null)
+	  p.setSelectedFrame(frame);
+	else
+	  {
+	    try
+	      {
+		frame.setSelected(true);
+	      }
+	    catch (PropertyVetoException e)
+	      {
+		// Do nothing.
+	      }
+	  }
+      }
+
+    c.invalidate();
+  } // deiconifyFrame()
+
+  /**
+   * This method activates the JInternalFrame by moving it to the front and
+   * selecting it.
+   *
+   * @param frame The JInternalFrame to activate.
+   */
+  public void activateFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+
+    if (p != null)
+      p.setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+
+    frame.toFront();
+  } // activateFrame()
+
+  /**
+   * This method is called when the JInternalFrame loses focus.
+   *
+   * @param frame The JInternalFram to deactivate.
+   */
+  public void deactivateFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+    if (p != null)
+      {
+	if (p.getSelectedFrame() == frame)
+	  p.setSelectedFrame(null);
+      }
+    else
+      {
+	try
+	  {
+	    frame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+  } // deactivateFrame()
+
+  /**
+   * This method is called to indicate that the DesktopManager should prepare
+   * to drag the JInternalFrame. Any state information needed to drag the
+   * frame will be prepared now.
+   *
+   * @param component The JComponent to drag, usually a JInternalFrame.
+   */
+  public void beginDraggingFrame(JComponent component)
+  {
+    if (component instanceof JDesktopIcon)
+      pane = ((JDesktopIcon) component).getInternalFrame().getDesktopPane();
+    else
+      pane = ((JInternalFrame) component).getDesktopPane();
+    if (pane == null)
+      return;
+
+    dragCache = component.getBounds();
+
+    if (! (pane instanceof JDesktopPane))
+      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
+    else
+      currentDragMode = ((JDesktopPane) pane).getDragMode();
+  } // beginDraggingFrame()
+
+  /**
+   * This method is called to drag the JInternalFrame to a new location.
+   *
+   * @param component The JComponent to drag, usually a JInternalFrame.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   */
+  public void dragFrame(JComponent component, int newX, int newY)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	// FIXME: Do outline drag mode painting.
+      }
+    else
+      {
+	Rectangle b = component.getBounds();
+	if (component instanceof JDesktopIcon)
+	  component.setBounds(newX, newY, b.width, b.height);
+	else
+	  setBoundsForFrame((JInternalFrame) component, newX, newY, b.width,
+	                    b.height);
+      }
+  } // dragFrame()
+
+  /**
+   * This method indicates that the dragging is done. Any state information
+   * stored by the DesktopManager can be cleared.
+   *
+   * @param component The JComponent that has finished dragging.
+   */
+  public void endDraggingFrame(JComponent component)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	setBoundsForFrame((JInternalFrame) component, dragCache.x,
+	                  dragCache.y, dragCache.width, dragCache.height);
+	pane = null;
+	dragCache = null;
+      }
+    component.repaint();
+  } // endDraggingFrame()
+
+  /**
+   * This method is called to indicate that the given JComponent will be
+   * resized. Any state information necessary to resize the JComponent will
+   * be prepared now.
+   *
+   * @param component The JComponent to resize, usually a JInternalFrame.
+   * @param direction The direction to drag in (a SwingConstant).
+   */
+  public void beginResizingFrame(JComponent component, int direction)
+  {
+    pane = ((JInternalFrame) component).getDesktopPane();
+    if (pane == null)
+      return;
+
+    dragCache = component.getBounds();
+    if (! (pane instanceof JDesktopPane))
+      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
+    else
+      currentDragMode = ((JDesktopPane) pane).getDragMode();
+  } // beginResizingFrame()
+
+  /**
+   * This method resizes the give JComponent.
+   *
+   * @param component The JComponent to resize.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   * @param newWidth The new width.
+   * @param newHeight The new height.
+   */
+  public void resizeFrame(JComponent component, int newX, int newY,
+                          int newWidth, int newHeight)
+  {
+    dragCache.setBounds(newX, newY, newWidth, newHeight);
+
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	// FIXME: Do outline drag painting.
+      }
+    else
+      setBoundsForFrame(component, dragCache.x, dragCache.y, dragCache.width,
+                        dragCache.height);
+  } // resizeFrame()
+
+  /**
+   * This method is called to indicate that the given JComponent has finished
+   * dragging. Any state information stored by the DesktopManager can be
+   * cleared.
+   *
+   * @param component The JComponent that finished resizing.
+   */
+  public void endResizingFrame(JComponent component)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	setBoundsForFrame((JInternalFrame) component, dragCache.x,
+	                  dragCache.y, dragCache.width, dragCache.height);
+	pane = null;
+	dragCache = null;
+      }
+    component.repaint();
+  } // endResizingFrame()
+
+  /**
+   * This method calls setBounds with the given parameters and repaints the
+   * JComponent.
+   *
+   * @param component The JComponent to set bounds for.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   * @param newWidth The new width.
+   * @param newHeight The new height.
+   */
+  public void setBoundsForFrame(JComponent component, int newX, int newY,
+                                int newWidth, int newHeight)
+  {
+    component.setBounds(newX, newY, newWidth, newHeight);
+    component.revalidate();
+
+    // If not null, I'd rather repaint the parent
+    if (component.getParent() != null)
+      component.getParent().repaint();
+    else
+      component.repaint();
+  } // setBoundsForFrame()
+
+  /**
+   * This is a helper method that removes the JDesktopIcon of the given
+   * JInternalFrame from the parent.
+   *
+   * @param frame The JInternalFrame to remove an icon for.
+   */
+  protected void removeIconFor(JInternalFrame frame)
+  {
+    JDesktopIcon icon = frame.getDesktopIcon();
+    Container c = icon.getParent();
+    if (c != null && icon != null)
+      c.remove(icon);
+  } // removeIconFor()
+
+  /**
+   * This method is called by iconifyFrame to determine the bounds of the
+   * JDesktopIcon for the given JInternalFrame.
+   *
+   * @param frame The JInternalFrame to find the bounds of its JDesktopIcon
+   *        for.
+   *
+   * @return The bounds of the JDesktopIcon.
+   */
+  protected Rectangle getBoundsForIconOf(JInternalFrame frame)
+  {
+    // IconRects has no order to it.
+    // The icon _must_ be placed in the first free slot (working from 
+    // the bottom left corner)
+    // The icon also must not be placed where another icon is placed 
+    // (regardless whether that frame is an icon currently or not)
+    JDesktopPane desktopPane = frame.getDesktopPane();
+    Rectangle paneBounds = desktopPane.getBounds();
+    Insets insets = desktopPane.getInsets();
+    Dimension pref = frame.getDesktopIcon().getPreferredSize();
+
+    if (desktopPane == null)
+      return frame.getDesktopIcon().getBounds();
+
+    Component[] frames = desktopPane.getComponents();
+
+    int count = 0;
+    for (int i = 0, j = 0; i < frames.length; i++)
+      if (frames[i] instanceof JDesktopIcon
+          || frames[i] instanceof JInternalFrame
+          && ((JInternalFrame) frames[i]).getWasIcon() && frames[i] != frame)
+	count++;
+    iconRects = new Rectangle[count];
+    for (int i = 0, j = 0; i < frames.length; i++)
+      if (frames[i] instanceof JDesktopIcon)
+	iconRects[--count] = frames[i].getBounds();
+      else if (frames[i] instanceof JInternalFrame
+               && ((JInternalFrame) frames[i]).getWasIcon()
+               && frames[i] != frame)
+	iconRects[--count] = ((JInternalFrame) frames[i]).getDesktopIcon()
+	                      .getBounds();
+
+    int startingX = insets.left;
+    int startingY = paneBounds.height - insets.bottom - pref.height;
+    Rectangle ideal = new Rectangle(startingX, startingY, pref.width,
+                                    pref.height);
+    boolean clear = true;
+
+    while (iconRects.length > 0)
+      {
+	clear = true;
+	for (int i = 0; i < iconRects.length; i++)
+	  {
+	    if (iconRects[i] != null && iconRects[i].intersects(ideal))
+	      {
+		clear = false;
+		break;
+	      }
+	  }
+	if (clear)
+	  return ideal;
+
+	startingX += pref.width;
+	if (startingX + pref.width > paneBounds.width - insets.right)
+	  {
+	    startingX = insets.left;
+	    startingY -= pref.height;
+	  }
+	ideal.setBounds(startingX, startingY, pref.width, pref.height);
+      }
+
+    return ideal;
+  } // getBoundsForIconOf()
+
+  /**
+   * This method sets the bounds of the JInternalFrame right before the
+   * maximizeFrame call.
+   *
+   * @param frame The JInternalFrame being maximized.
+   * @param rect The normal bounds.
+   */
+  protected void setPreviousBounds(JInternalFrame frame, Rectangle rect)
+  {
+    frame.setNormalBounds(rect);
+  } // setPreviousBounds()
+
+  /**
+   * This method returns the normal bounds of the JInternalFrame from before
+   * the maximize call.
+   *
+   * @param frame The JInternalFrame that is being restored.
+   *
+   * @return The previous bounds of the JInternalFrame.
+   */
+  protected Rectangle getPreviousBounds(JInternalFrame frame)
+  {
+    return frame.getNormalBounds();
+  } // getPreviousBounds()
+
+  /**
+   * This method sets the value to true if the given JInternalFrame has been
+   * iconized and the bounds of its DesktopIcon are valid.
+   *
+   * @param frame The JInternalFrame for the JDesktopIcon.
+   * @param value True if the JInternalFrame has been iconized and the bounds
+   *        of the JDesktopIcon are valid.
+   */
+  protected void setWasIcon(JInternalFrame frame, boolean value)
+  {
+    frame.setWasIcon(value, WAS_ICON_ONCE_PROPERTY);
+  } // setWasIcon()
+
+  /**
+   * This method returns true if the given JInternalFrame has been iconized
+   * and the bounds of its DesktopIcon are valid.
+   *
+   * @param frame The JInternalFrame for the JDesktopIcon.
+   *
+   * @return True if the given JInternalFrame has been iconized and the bounds
+   *         of its DesktopIcon are valid.
+   */
+  protected boolean wasIcon(JInternalFrame frame)
+  {
+    return frame.getWasIcon();
+  } // wasIcon()
 } // DefaultDesktopManager
Index: javax/swing/DefaultListCellRenderer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultListCellRenderer.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultListCellRenderer.java
--- javax/swing/DefaultListCellRenderer.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/DefaultListCellRenderer.java	6 Sep 2004 16:35:54 -0000
@@ -41,214 +41,137 @@
 import java.awt.Rectangle;
 import java.io.Serializable;
 import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+
 
 /**
- * DefaultListCellRenderer
- * @author	Andrew Selkirk
- * @version	1.0
+ * DefaultListCellRenderer. This class is responsible for rendering  list
+ * cells.
+ *
+ * @author Andrew Selkirk
+ * @version 1.0
  */
-public class DefaultListCellRenderer extends JLabel 
-		implements ListCellRenderer, Serializable
+public class DefaultListCellRenderer extends JLabel implements ListCellRenderer,
+                                                               Serializable
 {
   static final long serialVersionUID = 7708947179685189462L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * UIResource
-	 */
-	public static class UIResource extends DefaultListCellRenderer 
-			implements javax.swing.plaf.UIResource {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor UIResource
-		 */
-		public UIResource() {
-			// TODO
-		} // UIResource()
-
-
-	} // UIResource
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * noFocusBorder
-	 */
-	protected static Border noFocusBorder = null; // TODO
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultListCellRenderer
-	 */
-	public DefaultListCellRenderer() {
-		// TODO
-	} // DefaultListCellRenderer()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getListCellRendererComponent
-	 * @param list TODO
-	 * @param value TODO
-	 * @param index TODO
-	 * @param isSelected TODO
-	 * @param cellHasFocus TODO
-	 * @returns Component
-	 */
-	public Component getListCellRendererComponent(JList list,
-			Object value, int index, boolean isSelected, boolean cellHasFocus) {
-		return null; // TODO
-	} // getListCellRendererComponent()
-
-	/**
-	 * validate
-	 */
-	public void validate() {
-		// TODO
-	} // validate()
-
-	/**
-	 * revalidate
-	 */
-	public void revalidate() {
-		// TODO
-	} // revalidate()
-
-	/**
-	 * repaint
-	 * @param tm TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param w TODO
-	 * @param h TODO
-	 */
-	public void repaint(long tm, int x, int y, int w, int h) {
-		// TODO
-	} // repaint()
-
-	/**
-	 * repaint
-	 * @param rect TODO
-	 */
-	public void repaint(Rectangle rect) {
-		// TODO
-	} // repaint()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	protected void firePropertyChange(String propertyName,
-			Object oldValue, Object newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			byte oldValue, byte newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			char oldValue, char newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			short oldValue, short newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			int oldValue, int newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			long oldValue, long newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			float oldValue, float newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			double oldValue, double newValue) {
-		// TODO
-	} // firePropertyChange()
-
-	/**
-	 * firePropertyChange
-	 * @param propertyName TODO
-	 * @param oldValue TODO
-	 * @param newValue TODO
-	 */
-	public void firePropertyChange(String propertyName, 
-			boolean oldValue, boolean newValue) {
-		// TODO
-	} // firePropertyChange()
-
-
-} // DefaultListCellRenderer
+  public static class UIResource extends DefaultListCellRenderer
+    implements javax.swing.plaf.UIResource
+  {
+    public UIResource()
+    {
+    }
+  }
+
+  /**
+   * This border is used whenever renderer doesn't have a focus.
+   */
+  protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
+
+  /**
+   * getListCellRendererComponent
+   *
+   * @param list JList list for the 'value'
+   * @param value object that should be rendered in the cell
+   * @param index index of the cell
+   * @param isSelected draw cell highlighted if isSelected is true
+   * @param cellHasFocus draw focus rectangle around cell if the cell has
+   *        focus
+   *
+   * @return Component that will be painted to the desired cell.
+   */
+  public Component getListCellRendererComponent(JList list, Object value,
+                                                int index, boolean isSelected,
+                                                boolean cellHasFocus)
+  {
+    String s = value.toString();
+    setText(s);
+    setOpaque(true);
+
+    if (isSelected)
+      {
+	setBackground(list.getSelectionBackground());
+	setForeground(list.getSelectionForeground());
+      }
+    else
+      {
+	setBackground(list.getBackground());
+	setForeground(list.getForeground());
+      }
+
+    setEnabled(list.isEnabled());
+    setFont(list.getFont());
+
+    // Use focusCellHighlightBorder when renderer has focus and 
+    // noFocusBorder otherwise
+    
+    if (cellHasFocus)
+      setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
+    else
+      setBorder(noFocusBorder);
+
+    return this;
+  }
+
+  public void validate()
+  {
+  }
+
+  public void revalidate()
+  {
+  }
+
+  public void repaint(long tm, int x, int y, int w, int h)
+  {
+  }
+
+  public void repaint(Rectangle rect)
+  {
+  }
+
+  protected void firePropertyChange(String propertyName, Object oldValue,
+                                    Object newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, byte oldValue,
+                                 byte newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, char oldValue,
+                                 char newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, short oldValue,
+                                 short newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, int oldValue,
+                                 int newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, long oldValue,
+                                 long newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, float oldValue,
+                                 float newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, double oldValue,
+                                 double newValue)
+  {
+  }
+
+  public void firePropertyChange(String propertyName, boolean oldValue,
+                                 boolean newValue)
+  {
+  }
+}
Index: javax/swing/DefaultListModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultListModel.java,v
retrieving revision 1.2
diff -u -r1.2 DefaultListModel.java
--- javax/swing/DefaultListModel.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/DefaultListModel.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* DefaultListModel.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,499 +35,473 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
-import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.NoSuchElementException;
 import java.util.Vector;
 
 /**
- * DefaultListModel
- * @author	Andrew Selkirk
- * @version	1.0
+ * This is a default subclass of the {@link AbstractListModel}, used by
+ * {@link javax.swing.JList} and similar objects as the model of a list of
+ * values. The implementation is based on an underlying {@link
+ * java.util.Vector}.
+ *
+ * @author Andrew Selkirk
+ * @author Graydon Hoare (graydon@redhat.com)
  */
+
 public class DefaultListModel extends AbstractListModel
 {
+  private static final long serialVersionUID = 2315945659722172272L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * elements.  Note: Sun obviously implemented the storage as a
-	 * Vector according to the similar API on this class.  I choose
-	 * instead to implement the model with a proper collection object.
-	 * Is this a good choice?  Probably not (ya..I know there are
-	 * sync issues by doing this)
-	 */
-	private ArrayList elements = new ArrayList();
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultListModel
-	 */
-	public DefaultListModel() {
-		// TODO
-	} // DefaultListModel()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * elementAt
-	 * @param index TODO
-	 * @returns Object
-	 */
-	public Object elementAt(int index) {
-		return elements.get(index);
-	} // elementAt()
-
-	/**
-	 * toString
-	 * @returns String
-	 */
-	public String toString() {
-		return elements.toString();
-	} // toString()
-
-	/**
-	 * indexOf
-	 * @param element TODO
-	 * @returns int
-	 */
-	public int indexOf(Object element) {
-		return elements.indexOf(element);
-	} // indexOf()
-
-	/**
-	 * indexOf
-	 * @param element TODO
-	 * @param startIndex TODO
-	 * @returns int
-	 */
-	public int indexOf(Object element, int startIndex) {
-
-		// Variables
-		int		index;
-		Object	test;
-
-		// Process Elements
-		for (index = startIndex; index < elements.size(); index++) {
-			test = elements.get(index);
-			if (test.equals(element) == true) {
-				return index;
-			} // if
-		} // for
-		return -1;
-
-	} // indexOf()
-
-	/**
-	 * lastIndexOf
-	 * @param element TODO
-	 * @returns int
-	 */
-	public int lastIndexOf(Object element) {
-		return elements.lastIndexOf(element);
-	} // lastIndexOf()
-
-	/**
-	 * lastIndexOf
-	 * @param element TODO
-	 * @param endIndex TODO
-	 * @returns int
-	 */
-	public int lastIndexOf(Object element, int endIndex) {
-
-		// Variables
-		int		index;
-		Object	test;
-
-		// Process Elements
-		for (index = endIndex; index >= 0; index--) {
-			test = elements.get(index);
-			if (test.equals(element) == true) {
-				return index;
-			} // if
-		} // for
-		return -1;
-
-	} // lastIndexOf()
-
-	/**
-	 * get
-	 * @param index TODO
-	 * @returns Object
-	 */
-	public Object get(int index) {
-		return elements.get(index);
-	} // get()
-
-	/**
-	 * set
-	 * @param index TODO
-	 * @param element TODO
-	 * @returns Object
-	 */
-	public Object set(int index, Object element) {
-
-		// Variables
-		Object	result;
-
-		// Process Action
-		result = elements.set(index, element);
-
-		// Send event
-		fireContentsChanged(this, index, index);
-
-		return result;
-
-	} // set()
-
-	/**
-	 * add
-	 * @param index TODO
-	 * @param element TODO
-	 */
-	public void add(int index, Object element) {
-
-		// Process Action
-		elements.add(index, element);
-
-		// Send event
-		fireContentsChanged(this, index, index);
-
-	} // add()
-
-	/**
-	 * addElement
-	 * @param element TODO
-	 */
-	public void addElement(Object element) {
-
-		// Process Action
-		elements.add(element);
-
-		// Send event
-		fireIntervalAdded(this, elements.size(), elements.size());
-
-	} // addElement()
-
-	/**
-	 * size
-	 * @returns int
-	 */
-	public int size() {
-		return elements.size();
-	} // size()
-
-	/**
-	 * toArray
-	 * @returns Object[]
-	 */
-	public Object[] toArray() {
-		return elements.toArray();
-	} // toArray()
-
-	/**
-	 * contains
-	 * @param element TODO
-	 * @returns boolean
-	 */
-	public boolean contains(Object element) {
-		return elements.contains(element);
-	} // contains()
-
-	/**
-	 * copyInto
-	 * @param array TODO
-	 */
-	public void copyInto(Object[] array) {
-
-		// Variables
-		int		index;
-		int		size;
-		Object[]	srcArray;
-
-		// Initialize
-		size = size();
-		srcArray = toArray();
-
-		// Process Elements
-		for (index = 0; index < size; index++) {
-			array[index] = srcArray[index];
-		} // for
-
-	} // copyInto()
-
-	/**
-	 * clear
-	 */
-	public void clear() {
-
-		// Process Action
-		elements.clear();
-
-		// Send event
-		fireIntervalRemoved(this, 0, elements.size());
-
-	} // clear()
-
-	/**
-	 * remove
-	 * @param index TODO
-	 * @returns Object
-	 */
-	public Object remove(int index) {
-
-		// Variables
-		Object	result;
-
-		// Process Action
-		result = elements.remove(index);
-
-		// Send event
-		fireIntervalRemoved(this, index, index);
-
-		return result;
-
-	} // remove()
-
-	/**
-	 * isEmpty
-	 * @returns boolean
-	 */
-	public boolean isEmpty() {
-		return elements.isEmpty();
-	} // isEmpty()
-
-	/**
-	 * elements
-	 * @returns Enumeration
-	 */
-	public Enumeration elements() {
-
-		// TODO
-		// Note: This is a pathetic implementation.  If Vector
-		// was used for storage, this wouldn't be an issue.  I'll
-		// have to implement an Enumeration inner class sometime.
-
-		// Variables
-		Vector	vector;
-
-		// Get Enumeration
-		vector = new Vector(elements);
-		return vector.elements();
-
-	} // elements()
-
-	/**
-	 * trimToSize
-	 */
-	public void trimToSize() {
-		elements.trimToSize();
-	} // trimToSize()
-
-	/**
-	 * ensureCapacity
-	 * @param size TODO
-	 */
-	public void ensureCapacity(int size) {
-		elements.ensureCapacity(size);
-	} // ensureCapacity()
-
-	/**
-	 * setSize
-	 * @param size TODO
-	 */
-	public void setSize(int size) {
-		elements.ensureCapacity(size);
-	} // setSize()
-
-	/**
-	 * capacity
-	 * @returns int
-	 */
-	public int capacity() {
-		return elements.size();
-	} // capacity()
-
-	/**
-	 * firstElement
-	 * @returns Object
-	 */
-	public Object firstElement() {
-
-		// Variables
-		Object	element;
-
-		try {
-			element = elements.get(0);
-			return element;
-		} catch (IndexOutOfBoundsException e) {
-			throw new NoSuchElementException();
-		} // try
-
-	} // firstElement()
-
-	/**
-	 * lastElement
-	 * @returns Object
-	 */
-	public Object lastElement() {
-
-		// Variables
-		Object	element;
-
-		try {
-			element = elements.get(elements.size() - 1);
-			return element;
-		} catch (ArrayIndexOutOfBoundsException e) {
-			throw new NoSuchElementException();
-		} // try
-
-	} // lastElement()
-
-	/**
-	 * setElementAt
-	 * @param element TODO
-	 * @param index TODO
-	 */
-	public void setElementAt(Object element, int index) {
-
-		// Process Action
-		elements.set(index, element);
-
-		// Send event
-		fireContentsChanged(this, index, index);
-
-	} // setElementAt()
-
-	/**
-	 * removeElementAt
-	 * @param index TODO
-	 */
-	public void removeElementAt(int index) {
-
-		// Process Action
-		elements.remove(index);
-
-		// Send event
-		fireIntervalRemoved(this, index, index);
-
-	} // removeElementAt()
-
-	/**
-	 * insertElementAt
-	 * @param element TODO
-	 * @param index TODO
-	 */
-	public void insertElementAt(Object element, int index) {
-
-		// Process Action
-		elements.add(index, element);
-
-		// Send event
-		fireIntervalRemoved(this, index, index);
-
-	} // insertElementAt()
-
-	/**
-	 * removeElement
-	 * @param element TODO
-	 * @returns boolean
-	 */
-	public boolean removeElement(Object element) {
-
-		// Variables
-		int		index;
-
-		index = elements.indexOf(element);
-		if (index != -1) {
-			elements.remove(index);
-
-			// Send event
-			fireIntervalRemoved(this, index, index);
-
-			return true;
-
-		} // if
-
-		return false;
-
-	} // removeElement()
-
-	/**
-	 * removeAllElements
-	 */
-	public void removeAllElements() {
-
-		// Variables
-		int		size;
-
-		size = size();
-
-		if (size > 0) {
-
-			// Process Action
-			elements.clear();
-
-			// Send event
-			fireIntervalRemoved(this, 0, size - 1);
-
-		} // if
-
-	} // removeAllElements()
-
-	/**
-	 * removeRange
-	 * @param startIndex TODO
-	 * @param endIndex TODO
-	 */
-	public void removeRange(int startIndex, int endIndex) {
-
-		// Variables
-		int		index;
-
-		// Check Indices
-		if (startIndex > endIndex) {
-			throw new IllegalArgumentException();
-		} // if
-
-		// Process Elements
-		for (index = endIndex; index >= startIndex; index--) {
-			elements.remove(index);
-		} // for
-
-		// Send event
-		fireIntervalRemoved(this, startIndex, endIndex);
-
-	} // removeRange()
-
-	/**
-	 * getSize
-	 * @returns int
-	 */
-	public int getSize() {
-		return elements.size();
-	} // getSize()
-
-	/**
-	 * getElementAt
-	 * @param index TODO
-	 * @returns Object
-	 */
-	public Object getElementAt(int index) {
-		return elements.get(index);
-	} // getElementAt()
-
-
-} // DefaultListModel
+  /**
+   * The vector of elements in this list model.
+   */
+  private Vector elements = new Vector();
+
+  /**
+   * Gets an element of the list at the provided index.
+   *
+   * @param index The index of the element to get
+   *
+   * @return The object at the given index
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public Object elementAt(int index)
+  {
+    return elements.elementAt(index);
+  }
+
+  /**
+   * Convert the list to a string representation.
+   *
+   * @return A string representation of the list
+   */
+  public String toString()
+  {
+    return elements.toString();
+  }
+
+  /**
+   * Gets the first index of a particular element in the list.
+   *
+   * @param element The element to search for
+   *
+   * @return The first index in the list at which an object
+   * <code>obj</code> exists such that <code>obj.equals(element)</code> is
+   * <code>true</code>; if no such object exists, the method returns
+   * <code>-1</code>
+   */
+  public int indexOf(Object element)
+  {
+    return elements.indexOf(element);
+  }
+
+  /**
+   * Gets the first index of a particular element in a list which occurs
+   * <em>at or after</em> a particular index.
+   *
+   * @param element The element to search for
+   * @param startIndex The index to begin searching at
+   *
+   * @return The first index in the list, greater than or equal to
+   * <code>startIndex</code>, at which an object <code>obj</code> exists
+   * such that <code>obj.equals(element)</code> is <code>true</code>; if no
+   * such object exists, the method returns <code>-1</code>
+   */
+  public int indexOf(Object element, int startIndex)
+  {
+    return elements.indexOf(element, startIndex);
+  }
+
+  /**
+   * Gets the last index of a particular element in the list.
+   *
+   * @param element The element to search for
+   *
+   * @return The last index in the list at which an object
+   * <code>obj</code> exists such that <code>obj.equals(element)</code> is
+   * <code>true</code>; if no such object exists, the method returns
+   * <code>-1</code>
+   */
+  public int lastIndexOf(Object element)
+  {
+    return elements.lastIndexOf(element);
+  }
+
+  /**
+   * Gets the last index of a particular element in a list which occurs
+   * <em>at or before</em> a particular index.
+   *
+   * @param element The element to search for
+   * @param endIndex The index to finish searching at
+   *
+   * @return The last index in the list, less than to or equal to
+   * <code>endIndexIndex</code>, at which an object <code>obj</code> exists
+   * such that <code>obj.equals(element)</code> is <code>true</code>; if no
+   * such object exists, the method returns <code>-1</code>
+   */
+  public int lastIndexOf(Object element, int endIndex)
+  {
+    return elements.lastIndexOf(element, endIndex);
+  }
+
+  /**
+   * Gets the list element at a particular index.
+   *
+   * @param index The index to get the list value at
+   *
+   * @return The list value at the provided index
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public Object get(int index)
+  {
+    return elements.get(index);
+  }
+
+  /**
+   * Sets the list element at a particular index.
+   *
+   * @param index The list index at which to set a value 
+   * @param element The value to set at the specified index
+   *
+   * @return The value previously held at the specified index
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public Object set(int index, Object element)
+  {
+    Object result;
+    result = elements.set(index, element);
+    fireContentsChanged(this, index, index);
+    return result;
+  }
+
+  /**
+   * Inserts an element at a particular index in the list. Each element at
+   * index <code>i >= index</code> is shifted to position <code>i+1</code>.
+   * If <code>index</code> is equal to <code>size()</code>, this is
+   * equivalent to appending an element to the array. Any
+   * <code>index</code> greater than <code>size()</code> is illegal.
+   *
+   * @param index The index to insert the element at
+   * @param element The element to insert at the index
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds <code>[0, size()]</code>
+   */
+  public void add(int index, Object element)
+  {
+    elements.add(index, element);
+    fireContentsChanged(this, index, index);
+  }
+
+  /**
+   * Inserts an element at the end of the list. This is equivalent to
+   * calling <code>list.add(list.size(), element)</code>.
+   *
+   * @param element The element to add to the list
+   */
+  public void addElement(Object element)
+  {
+    elements.add(element);
+    fireIntervalAdded(this, elements.size(), elements.size());
+  }
+
+  /**
+   * Gets the number of elements in the list.
+   *
+   * @return The number of elements in the list
+   */
+  public int size()
+  {
+    return elements.size();
+  }
+
+  /**
+   * Gets an array containing the elements of the list.
+   *
+   * @return An array of the objects in the list, in the order they occur
+   * in the list
+   */
+  public Object[] toArray()
+  {
+    return elements.toArray();
+  }
+
+  /**
+   * Determines whether a particular element is a member of the list.
+   *
+   * @param element The element to search for
+   *
+   * @return <code>true</code> if <code>element</code> is a member of the
+   * list, otherwise <code>false</code>
+   */
+  public boolean contains(Object element)
+  {
+    return elements.contains(element);
+  }
+
+  /**
+   * Copies the list into a provided array. The provided array must be at
+   * least as large as the list.
+   *
+   * @param array The array to copy the list into
+   * 
+   * @throws IndexOutOfBoundsException if the array is too small to hold the
+   * elements of the list
+   */
+  public void copyInto(Object[] array)
+  {
+    elements.copyInto(array);
+  }
+
+  /**
+   * Erases all the elements of the list, setting the list's size to 0.
+   */
+  public void clear()
+  {
+    elements.clear();
+    fireIntervalRemoved(this, 0, elements.size());
+  }
+
+  /**
+   * Removes the element at a particular index from the list.
+   *
+   * @param index The index of the element to remove
+   *
+   * @return The value at the index, which has been removed from the list
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public Object remove(int index)
+  {
+    Object result;
+    result = elements.remove(index);
+    fireIntervalRemoved(this, index, index);
+    return result;
+  }
+
+  /**
+   * Determines whether the list is empty.
+   *
+   * @return <code>true</code> if the list is empty, otherwise
+   * <code>false</code>
+   */
+  public boolean isEmpty()
+  {
+    return elements.isEmpty();
+  }
+
+  /**
+   * Returns an {@link java.util.Enumeration} over the elements of the list.
+   *
+   * @return A new enumeration which iterates over the list
+   */
+  public Enumeration elements()
+  {
+    return elements.elements();
+  }
+
+  /**
+   * Sets the capacity of the list to be equal to its size. The list's capacity
+   * is the number of elements it can hold before it needs to be reallocated.
+   * The list's size is the number of elements it currently holds. 
+   */
+  public void trimToSize()
+  {
+    elements.trimToSize();
+  }
+
+  /**
+   * Ensures that the list's capacity is at least equal to
+   * <code>size</code>. The list's capacity is the number of elements it
+   * can hold before it needs to be reallocated.
+   *
+   * @param size The capacity to ensure the list can hold
+   */
+  public void ensureCapacity(int size)
+  {
+    elements.ensureCapacity(size);
+  }
+
+  /**
+   * Sets the size of the list to a particular value. If the specified size
+   * is greater than the current size, the values at the excess list
+   * indices are set to <code>null</code>.  If the specified size is less
+   * than the current size, the excess elements are removed from the list.
+   *
+   * @param size The new size to set the list to
+   */
+  public void setSize(int size)
+  {
+    elements.setSize(size);
+  }
+
+  /**
+   * Gets the capacity of the list. The list's capacity is the number of
+   * elements it can hold before it needs to be reallocated. 
+   *
+   * @return The capacity of the list
+   */
+  public int capacity()
+  {
+    return elements.capacity();
+  }
+
+  /**
+   * Gets the first element in the list.
+   *
+   * @return The first element in the list
+   */
+  public Object firstElement()
+  {
+    return elements.firstElement();
+  }
+
+  /**
+   * Gets the last element in the list.
+   *
+   * @return The last element in the list
+   */
+  public Object lastElement()
+  {
+    return elements.lastElement();
+  }
+
+  /**
+   * Sets the list element at a particular index.
+   *
+   * @param element The value to set at the specified index
+   * @param index The list index at which to set a value 
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public void setElementAt(Object element, int index)
+  {
+    elements.setElementAt(element, index);
+    fireContentsChanged(this, index, index);
+  }
+
+  /**
+   * Removes the element at a particular index from the list.
+   *
+   * @param index The index of the element to remove
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public void removeElementAt(int index)
+  {
+    elements.remove(index);
+    fireIntervalRemoved(this, index, index);
+  }
+
+  /**
+   * Inserts an element at a particular index in the list. Each element at
+   * index <code>i >= index</code> is shifted to position <code>i+1</code>.
+   * If <code>index</code> is equal to <code>size()</code>, this is
+   * equivalent to appending an element to the array. Any
+   * <code>index</code> greater than <code>size()</code> is illegal.
+   *
+   * @param element The element to insert at the index
+   * @param index The index to insert the element at
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds <code>[0, size()]</code>
+   */
+  public void insertElementAt(Object element, int index)
+  {
+    elements.insertElementAt(element, index);
+    fireIntervalAdded(this, index, index);
+  }
+
+  /**
+   * Removes the first occurrence of a particular element in the list. If the
+   * element does not exist in the list, nothing happens.
+   *
+   * @param element The element to remove
+   *
+   * @return <code>true</code> if the element existed in the list (and was
+   * removed), <code>false</code> otherwise
+   */
+  public boolean removeElement(Object element)
+  {
+    int index;
+    index = elements.indexOf(element);
+    if (index != -1)
+      {
+        elements.remove(index);
+        fireIntervalRemoved(this, index, index);
+        return true;
+      }
+    return false;
+  }
+
+  /**
+   * Remove all elements in the list.
+   */
+  public void removeAllElements()
+  {
+    int size;
+    size = size();
+    if (size > 0)
+      {
+        elements.clear();
+        fireIntervalRemoved(this, 0, size - 1);
+      }
+  }
+
+  /**
+   * Remove all elements between <code>startIndex</code> and
+   * <code>endIndex</code> inclusive.
+   *
+   * @param startIndex The first index in the range to remove
+   * @param endIndex The last index in the range to remove
+   *
+   * @throws ArrayIndexOutOfBoundsException if either index is outside the
+   * valid range of indices for this list <code>[0, size())</code>
+   * @throws IllegalArgumentException if <code>startIndex > endIndex</code>
+   */
+  public void removeRange(int startIndex, int endIndex)
+  {
+    int index;
+    if (startIndex > endIndex)
+      throw new IllegalArgumentException();
+    for (index = endIndex; index >= startIndex; index--)
+      elements.remove(index);
+    fireIntervalRemoved(this, startIndex, endIndex);
+  }
+
+  /**
+   * Gets the size of the list.
+   *
+   * @return The number of elements currently in the list
+   */
+  public int getSize()
+  {
+    return elements.size();
+  }
+
+  /**
+   * Gets the list element at a particular index.
+   *
+   * @param index The index to get the list value at
+   *
+   * @return The list value at the provided index
+   *
+   * @throws ArrayIndexOutOfBoundsException If the provided index is
+   * outside the bounds of the list <code>[0, size())</code>
+   */
+  public Object getElementAt(int index)
+  {
+    return elements.get(index);
+  }
+}
Index: javax/swing/DefaultListSelectionModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultListSelectionModel.java,v
retrieving revision 1.2
diff -u -r1.2 DefaultListSelectionModel.java
--- javax/swing/DefaultListSelectionModel.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/DefaultListSelectionModel.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
-/* DefaultListSelectionModel.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* DefaultListSelectionModel.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,151 +35,556 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.io.Serializable;
 import java.util.EventListener;
-import java.util.Vector;
+import java.util.BitSet;
 import javax.swing.event.EventListenerList;
+import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 
-public class DefaultListSelectionModel implements Cloneable, ListSelectionModel, Serializable
+
+/**
+ * <p>This class provides a default implementation of {@link
+ * ListSelectioModel}, which is used by {@link javax.swing.JList} and
+ * similar classes to manage the selection status of a number of data
+ * elements. </p>
+ *
+ * <p>The class is organized <em>abstractly</em> as a set of intervals of
+ * integers. Each interval indicates an inclusive range of indices in a
+ * list -- held by some other object and unknown to this class -- which is
+ * considered "selected". There are various accessors for querying and
+ * modifying the set of intervals, with simplified forms accepting a single
+ * index, representing an interval with only one element. </p>
+ */
+public class DefaultListSelectionModel implements Cloneable,
+                                                  ListSelectionModel,
+                                                  Serializable
 {
-    int mode = SINGLE_SELECTION;
+  private static final long serialVersionUID = -5718799865110415860L;
+
+  /** The list of ListSelectionListeners subscribed to this selection model. */
+  protected EventListenerList listenerList = new EventListenerList();
 
-    Vector sel = new Vector();
 
-    Vector listeners;
+  /** 
+   * The current list selection mode. Must be one of the numeric constants
+   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>
+   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from {@link
+   * ListSelectionModel}. The default value is
+   * <code>MULTIPLE_INTERVAL_SELECTION</code>.
+   */
+  int selectionMode = MULTIPLE_INTERVAL_SELECTION;
+
+
+  /**
+   * The index of the "lead" of the most recent selection. The lead is the
+   * second argument in any call to {@link #setSelectionInterval}, {@link
+   * #addSelectionInterval} or {@link #removeSelectionInterval}. Generally
+   * the lead refers to the most recent position a user dragged their mouse
+   * over.
+   */
+  int leadSelectionIndex = -1;
+
+
+  /**
+   * The index of the "anchor" of the most recent selection. The anchor is
+   * the first argument in any call to {@link #setSelectionInterval},
+   * {@link #addSelectionInterval} or {@link
+   * #removeSelectionInterval}. Generally the anchor refers to the first
+   * recent position a user clicks when they begin to drag their mouse over
+   * a list.
+   *
+   * @see #getAnchorSelectionIndex
+   * @see #setAnchorSelectionIndex
+   */
+  int anchorSelectionIndex = -1;
+
+
+  /**
+   * controls the range of indices provided in any {@link
+   * ListSelectionEvent} fired by the selectionModel. Let
+   * <code>[A,L]</code> be the range of indices between {@link
+   * anchorSelectionIndex} and {@link leadSelectionIndex} inclusive, and
+   * let <code>[i0,i1]</code> be the range of indices changed in a given
+   * call which generates a {@link ListSelectionEvent}. Then when this
+   * property is <code>true</code>, the {@link ListSelectionEvent} contains
+   * the range <code>[A,L] union [i0,i1]</code>; when <code>false</code> it
+   * will contain only <code>[i0,i1]</code>. The default is
+   * <code>true</code>.
+   *
+   * @see #isLeadAnchorNotificationEnabled
+   * @see #setLeadAnchorNotificationEnabled
+   */
+  boolean leadAnchorNotificationEnabled = true;
+
+
+  /**
+   * Whether the selection is currently "adjusting". Any {@link
+   * ListSelectionEvent} events constructed in response to changes in this
+   * list selection model will have their {@link
+   * ListSelectionEvent#isAdjusting} field set to this value.
+   *
+   * @see #getValueIsAdjusting
+   * @see #setValueIsAdjusting
+   */
+  boolean valueIsAdjusting = false;
+
+
+  /** 
+   * The current set of "intervals", represented simply by a {@link
+   * java.util.BitSet}. A set bit indicates a selected index, whereas a
+   * cleared bit indicates a non-selected index.
+   */
+  BitSet sel = new BitSet();
+
+
+  /**
+   * Gets the value of the {@link #selectionMode} property.
+   *
+   * @return The current value of the property
+   */
+  public int getSelectionMode()
+  {
+    return selectionMode;
+  }
+
+  /**
+   * Sets the value of the {@link #selectionMode} property.
+   *
+   * @param a The new value of the property
+   */
+  public void setSelectionMode(int a)
+  {
+    selectionMode = a;
+  }
+
+  /**
+   * Gets the value of the {@link #anchorSelectionIndex} property.
+   * 
+   * @return The current property value
+   *
+   * @see #setAnchorSelectionIndex
+   */
+  public int getAnchorSelectionIndex()
+  {
+    return anchorSelectionIndex;
+  }
+
+  /**
+   * Sets the value of the {@link #anchorSelectionIndex} property.
+   * 
+   * @param anchorIndex The new property value
+   *
+   * @see #getAnchorSelectionIndex
+   */
+  public void setAnchorSelectionIndex(int anchorIndex)
+  {
+    anchorSelectionIndex = anchorIndex;
+  }
+  
+  /**
+   * Gets the value of the {@link #leadSelectionIndex} property.
+   * 
+   * @return The current property value
+   *
+   * @see #setLeadSelectionIndex
+   */
+  public int getLeadSelectionIndex()
+  {
+    return leadSelectionIndex;
+  }
+
+  /**
+   * <p>Sets the value of the {@link #anchorSelectionIndex} property. As a
+   * side effect, alters the selection status of two ranges of indices. Let
+   * <code>OL</code> be the old lead selection index, <code>NL</code> be
+   * the new lead selection index, and <code>A</code> be the anchor
+   * selection index. Then if <code>A</code> is a valid selection index,
+   * one of two things happens depending on the seleciton status of
+   * <code>A</code>:</p>
+   *
+   * <ul>
+   *
+   * <li><code>isSelectedIndex(A) == true</code>: set <code>[A,OL]</code>
+   * to <em>deselected</em>, then set <code>[A,NL]</code> to
+   * <em>selected</em>.</li>
+   *
+   * <li><code>isSelectedIndex(A) == false</code>: set <code>[A,OL]</code>
+   * to <em>selected</em>, then set <code>[A,NL]</code> to
+   * <em>deselected</em>.</li>
+   *
+   * </ul>
+   *
+   * <p>This method generates at most a single {@link ListSelectionEvent}
+   * despite changing multiple ranges. The range of values provided to the
+   * {@link ListSelectionEvent} includes only the minimum range of values
+   * which changed selection status between the beginning and end of the
+   * method.</p>
+   * 
+   * @param anchorIndex The new property value
+   *
+   * @see #getAnchorSelectionIndex
+   */
+  public void setLeadSelectionIndex(int leadIndex)
+  {
+    int oldLeadIndex = leadSelectionIndex;
+    leadSelectionIndex = leadIndex;
+
+    if (anchorSelectionIndex == -1)
+      return;
+
+    int R1 = Math.min(anchorSelectionIndex, oldLeadIndex);
+    int R2 = Math.max(anchorSelectionIndex, oldLeadIndex);
+    int S1 = Math.min(anchorSelectionIndex, leadIndex);
+    int S2 = Math.max(anchorSelectionIndex, leadIndex);
+    
+    int lo = Math.min(R1, S1);
+    int hi = Math.max(R2, S2);
+
+    BitSet oldRange = sel.get(lo, hi+1);
 
-    Vector get_listeners()
-    {
-	if (listeners == null)
-	    listeners = new Vector();
-	return listeners;
-    }
+    if (isSelectedIndex(anchorSelectionIndex))
+      {
+        sel.clear(R1, R2+1);
+        sel.set(S1, S2+1);
+      }
+    else
+      {
+        sel.set(R1, R2+1);
+        sel.clear(S1, S2+1);
+      }
     
+    BitSet newRange = sel.get(lo, hi+1);
+    newRange.xor(oldRange);
 
-    public void addListSelectionListener(ListSelectionListener listener)
-    {
-	get_listeners().addElement(listener);
-    }
-
-    public void removeListSelectionListener(ListSelectionListener listener)
-    {
-	get_listeners().removeElement(listener);
-    }
+    int beg = sel.nextSetBit(0), end = -1;
+    for(int i=beg; i >= 0; i=sel.nextSetBit(i+1)) 
+      { 
+        end = i;
+      }
+    fireValueChanged(beg, end, valueIsAdjusting);    
+  }
+
+  /**
+   * Gets the value of the {@link #leadAnchorNotificationEnabled} property.
+   * 
+   * @return The current property value
+   *
+   * @see #setLeadAnchorNotificationEnabled
+   */
+  public boolean isLeadAnchorNotificationEnabled()
+  {
+    return leadAnchorNotificationEnabled;
+  }
+
+  /**
+   * Sets the value of the {@link #leadAnchorNotificationEnabled} property.
+   * 
+   * @param flag The new property value
+   *
+   * @see #getLeadAnchorNotificationEnabled
+   */
+  public void setLeadAnchorNotificationEnabled(boolean l)
+  {
+    leadAnchorNotificationEnabled = l;
+  }
+
+
+  /**
+   * Gets the value of the {@link #valueIsAdjusting} property.
+   *
+   * @return The current property value
+   *
+   * @see #setValueIsAdjusting
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return valueIsAdjusting;
+  }
+
+  /**
+   * Sets the value of the {@link #valueIsAdjusting} property.
+   *
+   * @param v The new property value
+   *
+   * @see #getValueIsAdjusting
+   */
+  public void setValueIsAdjusting(boolean v)
+  {
+    valueIsAdjusting = v;
+  }
+
+  /**
+   * Determines whether the selection is empty.
+   *
+   * @return <code>true</code> if the selection is empty, otherwise
+   * <code>false</code>
+   */
+  public boolean isSelectionEmpty()
+  {
+    return sel.isEmpty();
+  }
+
+
+  /**
+   * Gets the smallest index which is currently a member of a selection
+   * interval.
+   *
+   * @return The least integer <code>i</code> such that <code>i >=
+   * 0</code> and <code>i</code> is a member of a selected interval, or
+   * <code>-1</code> if there are no selected intervals
+   *
+   * @see #getMaxSelectionIndex
+   */
+  public int getMinSelectionIndex()
+  {
+    if (isSelectionEmpty())
+      return -1;
     
-    class Range
-    {
-	int i0, i1;
-
-	Range(int a, int b)
-	{
-	    if (a > b)
-		{
-		    i0 = b;
-		    i1 = a;
-		}
-	    else
-		{
-		    i0 = a; 
-		    i1 = b;
-		}
-	}
-    }
+    return sel.nextSetBit(0);
+  }
 
+  /**
+   * Gets the largest index which is currently a member of a selection
+   * interval.
+   *
+   * @return The greatest integer <code>i</code> such that <code>i >=
+   * 0</code> and <code>i</code> is a member of a selected interval, or
+   * <code>-1</code> if there are no selected intervals
+   *
+   * @see #getMinSelectionIndex
+   */
+  public int getMaxSelectionIndex()
+  {
+    if (isSelectionEmpty())
+      return -1;
+
+    int mx = -1;
+    for(int i=sel.nextSetBit(0); i >= 0; i=sel.nextSetBit(i+1)) 
+      { 
+        mx = i;
+      }
+    return mx;
+  }
+
+  /**
+   * Determines whether a particular index is a member of a selection
+   * interval.
+   *
+   * @param a The index to search for
+   *
+   * @return <code>true</code> if the index is a member of a selection interval,
+   * otherwise <code>false</code>
+   */
+  public boolean isSelectedIndex(int a)
+  {
+    return sel.get(a);
+  }
+
+  /**
+   * If the {@link #selectionMode} property is equal to
+   * <code>SINGLE_SELECTION</code> or
+   * <code>SINGLE_INTERVAL_SELECTION</code>, equivalent to calling
+   * <code>setSelectionInterval(index1, index2)</code>; otherwise adds the
+   * range <code>[index0, index1]</code> to the selection interval set.
+   *
+   * @param index0 The beginning of the range of indices to select
+   * @param index1 The end of the range of indices to select
+   *
+   * @see #setSelectionInterval
+   * @see #removeSelectionInterval
+   */
+  public void addSelectionInterval(int index0, int index1) 
+  {
+    if (selectionMode == SINGLE_SELECTION
+        || selectionMode == SINGLE_INTERVAL_SELECTION)
+      sel.clear();
     
-    public int getMinSelectionIndex()
-    {
-	if (isSelectionEmpty())
-	    return -1;
-	
-	boolean first = true;
-	int min = -1;
-	for (int i=0;i<sel.size();i++)
-	    {
-		Range r = (Range) sel.get(i);
-
-		if (first)
-		    {
-			min = r.i0;
-			first = false;
-		    }	
-		else
-		    {
-			if (r.i0 > min)
-			    {
-				min = r.i0;
-			    }
-		    }
-	    }
-	return min;
-    }
-
-    public int getMaxSelectionIndex()
-    {
-	if (isSelectionEmpty())
-	    return -1;
-
-	boolean first = true;
-	int max = -1;
-	for (int i=1;i<sel.size();i++)
-	    {
-		Range r = (Range) sel.get(i);
-		
-		if (first)
-		    {
-			max = r.i1;
-		    }
-		else
-		    {
-			if (r.i1 > max)
-			    {
-				max = r.i1;
-			    }
-		    }
-	    }
-	return max;
-    }
-
-    public boolean isSelectedIndex(int a)
-    {
-	for (int i=0;i<sel.size();i++)
-	    {
-		Range r = (Range) sel.get(i);
-		if (r.i0 <= a &&
-		    r.i1 >= a)
-		    {
-			return true;
-		    }
-	    }
-	return false;
-    }
-
-
-    public int getSelectionMode()
-    { return mode; }
-    public void setSelectionMode(int a)
-    {	mode = a;    }
-
-    boolean isSelectionEmpty() 
-    {
-	return sel.size() == 0;
-    }
-
-    public void clearSelection()
-    {
-	sel.removeAllElements();
-    }
-
-    public void setSelectionInterval(int index0, int index1) 
-    {
-	if (mode == SINGLE_SELECTION)
-	    {
-		sel.removeAllElements();
-	    }
+    if (selectionMode == SINGLE_SELECTION)
+      index0 = index1;
+
+    int lo = Math.min(index0, index1);
+    int hi = Math.max(index0, index1);
 
-	sel.addElement(new Range(index0, index1));
-    }
+    sel.set(lo, hi+1);
+    fireValueChanged(lo, hi, valueIsAdjusting);
+  }
+
+
+  /**
+   * Deselects all indices in the inclusive range
+   * <code>[index0,index1]</code>.
+   *
+   * @param index0 The beginning of the range of indices to deselect
+   * @param index1 The end of the range of indices to deselect
+   *
+   * @see #addSelectionInterval
+   * @see #setSelectionInterval
+   */
+  public void removeSelectionInterval(int index0,
+                                      int index1)
+  {
+    int lo = Math.min(index0, index1);
+    int hi = Math.max(index0, index1);
+    sel.clear(lo, hi+1); 
+    fireValueChanged(lo, hi, valueIsAdjusting);
+  }
+
+  /**
+   * Removes all intervals in the selection set.
+   */
+  public void clearSelection()
+  {
+    int sz = sel.size();
+    sel.clear();
+    fireValueChanged(0, sz, valueIsAdjusting);
+  }
+  
+  /**
+   * Clears the current selection and marks a given interval as
+   * "selected". If the current selection mode is
+   * <code>SINGLE_SELECTION</code> only the index <code>index2</code> is
+   * selected.
+   *
+   * @param index0 The low end of the new selection 
+   * @param index1 The high end of the new selection
+   */
+  public void setSelectionInterval(int index0, int index1)
+  {
+    sel.clear();
+    if (selectionMode == SINGLE_SELECTION)
+      index0 = index1;
+
+    int lo = Math.min(index0, index1);
+    int hi = Math.max(index0, index1);
+    sel.set(lo, hi+1);
+    fireValueChanged(lo, hi, valueIsAdjusting);
+  }
+
+  /**
+   * Inserts a number of indices either before or after a particular
+   * position in the set of indices. Renumbers all indices after the
+   * inserted range. The new indices in the inserted range are not
+   * selected. This method is typically called to synchronize the selection
+   * model with an inserted range of elements in a {@link ListModel}.
+   *
+   * @param index The position to insert indices at
+   * @param length The number of indices to insert
+   * @param before Indicates whether to insert the indices before the index
+   * or after it
+   */
+  public void insertIndexInterval(int index,
+                                  int length,
+                                  boolean before)
+  {
+    if (!before)
+      {        
+        index++;
+        length--;
+      }
+    BitSet tmp = sel.get(index, sel.size());
+    sel.clear(index, sel.size());
+    int n = tmp.size();
+    for (int i = 0; i < n; ++i)
+      sel.set(index + length + i, tmp.get(i));
+  }
+
+  /**
+   * Removes a range from the set of indices. Renumbers all indices after
+   * the removed range. This method is typically called to synchronize the
+   * selection model with a deleted range of elements in a {@link
+   * ListModel}.
+   *
+   * @param index0 The first index to remove (inclusive)
+   * @param index1 The last index to remove (inclusive)
+   */
+  public void removeIndexInterval(int index0,
+                                  int index1)
+  {
+    int lo = Math.min(index0, index1);
+    int hi = Math.max(index0, index1);
+
+    BitSet tmp = sel.get(hi, sel.size());
+    sel.clear(lo, sel.size());
+    int n = tmp.size();
+    for (int i = 0; i < n; ++i)
+      sel.set(lo + i, tmp.get(i));
+  }
+
+  /**
+   * Fires a {@link ListSelectionEvent} to all the listeners of type {@link
+   * ListSelectionListener} registered with this selection model.
+   *
+   * @param firstIndex The low index of the changed range
+   * @param lastIndex The high index of the changed range
+   * @param isAdjusting Whether this change is part of a seqence of adjustments
+   * made to the selection, such as during interactive scrolling
+   */
+  protected void fireValueChanged(int firstIndex, int lastIndex,
+				  boolean isAdjusting)
+  {
+    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex,
+                                                    lastIndex, isAdjusting);
+    ListSelectionListener[] listeners = getListSelectionListeners();
+    for (int i = 0; i < listeners.length; ++i)
+      listeners[i].valueChanged(evt);
+  }
+
+  /**
+   * Adds a listener.
+   *
+   * @param listener The listener to add
+   *
+   * @see removeListSelectionListener
+   * @see getListSelectionListeners
+   */
+  public void addListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.add(ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Removes a registered listener.
+   *
+   * @param listener The listener to remove
+   *
+   * @see addListSelectionListener
+   * @see getListSelectionListeners
+   */
+  public void removeListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.remove(ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Returns an array of all registerers listeners.
+   *
+   * @param listenerType The type of listener to retrieve
+   *
+   * @return The array
+   *
+   * @see getListSelectionListener
+   * @since 1.3
+   */
+  public EventListener[] getListeners(Class listenerType)
+  {
+    return listenerList.getListeners(listenerType);
+  }
+
+  /**
+   * Returns an array of all registerd list selection listeners.
+   *
+   * @return the array
+   *
+   * @see addListSelectionListener
+   * @see removeListSelectionListener
+   * @see getListeners
+   * @since 1.4
+   */
+  public ListSelectionListener[] getListSelectionListeners()
+  {
+    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
+  }
 }
Index: javax/swing/DefaultSingleSelectionModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultSingleSelectionModel.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultSingleSelectionModel.java
--- javax/swing/DefaultSingleSelectionModel.java	29 Apr 2003 09:26:29 -0000	1.4
+++ javax/swing/DefaultSingleSelectionModel.java	6 Sep 2004 16:35:54 -0000
@@ -115,7 +115,7 @@
    */
   public boolean isSelected ()
   {
-    return (index == -1);
+    return (index != -1);
   }
 
   /**
Index: javax/swing/DesktopManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DesktopManager.java,v
retrieving revision 1.2
diff -u -r1.2 DesktopManager.java
--- javax/swing/DesktopManager.java	12 Oct 2003 13:20:49 -0000	1.2
+++ javax/swing/DesktopManager.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* DesktopManager.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,118 +38,140 @@
 package javax.swing;
 
 /**
- * DesktopManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * DesktopManagers are responsible for implementing the behaviours for the
+ * JInternalFrames that belong to JDesktopPanes. Actions such as maximizing,
+ * minimizing, iconifying, etc will be delegated to the DesktopManager.
  */
-public interface DesktopManager {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * openFrame
-	 * @param frame TODO
-	 */
-	void openFrame(JInternalFrame frame);
-
-	/**
-	 * closeFrame
-	 * @param frame TODO
-	 */
-	void closeFrame(JInternalFrame frame);
-
-	/**
-	 * maximizeFrame
-	 * @param frame TODO
-	 */
-	void maximizeFrame(JInternalFrame frame);
-
-	/**
-	 * minimizeFrame
-	 * @param frame TODO
-	 */
-	void minimizeFrame(JInternalFrame frame);
-
-	/**
-	 * iconifyFrame
-	 * @param frame TODO
-	 */
-	void iconifyFrame(JInternalFrame frame);
-
-	/**
-	 * deiconifyFrame
-	 * @param frame TODO
-	 */
-	void deiconifyFrame(JInternalFrame frame);
-
-	/**
-	 * activateFrame
-	 * @param frame TODO
-	 */
-	void activateFrame(JInternalFrame vframe);
-
-	/**
-	 * deactivateFrame
-	 * @param frame TODO
-	 */
-	void deactivateFrame(JInternalFrame frame);
-
-	/**
-	 * beginDraggingFrame
-	 * @param frame TODO
-	 */
-	void beginDraggingFrame(JComponent frame);
-
-	/**
-	 * dragFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	void dragFrame(JComponent frame, int x, int y);
-
-	/**
-	 * endDraggingFrame
-	 * @param frame TODO
-	 */
-	void endDraggingFrame(JComponent frame);
-
-	/**
-	 * beginResizingFrame
-	 * @param frame TODO
-	 * @param direction TODO
-	 */
-	void beginResizingFrame(JComponent frame, int direction);
-
-	/**
-	 * resizeFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param width TODO
-	 * @param height TODO
-	 */
-	void resizeFrame(JComponent frame, int x, int y, 
-					int width, int height);
-
-	/**
-	 * endResizingFrame
-	 * @param frame TODO
-	 */
-	void endResizingFrame(JComponent frame);
-
-	/**
-	 * setBoundsForFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param width TODO
-	 * @param height TODO
-	 */
-	void setBoundsForFrame(JComponent frame, int x, int y, 
-					int width, int height);
-
-
+public interface DesktopManager
+{
+  /**
+   * This method will cause the JInternalFrame to be displayed in the set
+   * location. This usually is not needed since the user will add the
+   * JInternalFrame to a Container separately.
+   *
+   * @param frame The JInternalFrame to open.
+   */
+  void openFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JInternalFrame from its parent.
+   *
+   * @param frame The JInternalFrame to close.
+   */
+  void closeFrame(JInternalFrame frame);
+
+  /**
+   * This method should maximize the JInternalFrame to match its parent's
+   * bounds.
+   *
+   * @param frame The JInternalFrame to maximize.
+   */
+  void maximizeFrame(JInternalFrame frame);
+
+  /**
+   * This method should restore the JInternalFrame to its normal bounds.
+   *
+   * @param frame The JInternalFrame to minimize.
+   */
+  void minimizeFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JInternalFrame from its parent and replace
+   * it with a JDesktopIcon.
+   *
+   * @param frame The JInternalFrame to iconify.
+   */
+  void iconifyFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JDesktopIcon from its parent and replace it
+   * with the JInternalFrame that the JDesktopIcon represents.
+   *
+   * @param frame The JInternalFrame to deiconify.
+   */
+  void deiconifyFrame(JInternalFrame frame);
+
+  /**
+   * This method should give focus to the JInternalFrame and its default focus
+   * owner.
+   *
+   * @param frame The JInternalFrame to activate.
+   */
+  void activateFrame(JInternalFrame vframe);
+
+  /**
+   * This method should be called when the JInternalFrame gets deselected and
+   * subsequently loses focus.
+   *
+   * @param frame The JInternalFrame to deactivate.
+   */
+  void deactivateFrame(JInternalFrame frame);
+
+  /**
+   * This method should be called in preparation for dragging. This needs to
+   * be called prior to dragFrame calls so that the DesktopManager can
+   * prepare any state information.
+   *
+   * @param frame The JInternalFrame to prepare for dragging.
+   */
+  void beginDraggingFrame(JComponent frame);
+
+  /**
+   * This method drags the given JInternalFrame to the given x and y
+   * coordinates.
+   *
+   * @param frame The JInternalFrame to drag.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   */
+  void dragFrame(JComponent frame, int x, int y);
+
+  /**
+   * This method should be called after dragFrame calls. Any information used
+   * by the DesktopManager for dragging the JInternalFrame can be cleared.
+   *
+   * @param frame The JInternalFrame that finished dragging.
+   */
+  void endDraggingFrame(JComponent frame);
+
+  /**
+   * This method should be called prior to any resizeFrame calls. Any state
+   * information needed by the DesktopManager to resize the JInternalFrame
+   * will be prepared here.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param direction One of eight directions specified by SwingConstants.
+   */
+  void beginResizingFrame(JComponent frame, int direction);
+
+  /**
+   * This method is called to resize the given JInternalFrame to the given
+   * bounds.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   * @param width The new width.
+   * @param height The new height.
+   */
+  void resizeFrame(JComponent frame, int x, int y, int width, int height);
+
+  /**
+   * This method is called to signify that the resize is finished. Any
+   * information used to resize the JInternalFrame can now be cleared.
+   *
+   * @param frame The JInternalFrame that just finished dragging.
+   */
+  void endResizingFrame(JComponent frame);
+
+  /**
+   * This method does the actual work for reshaping the JInternalFrame.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   * @param width The new width.
+   * @param height The new height.
+   */
+  void setBoundsForFrame(JComponent frame, int x, int y, int width, int height);
 } // DesktopManager
Index: javax/swing/GrayFilter.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/GrayFilter.java,v
retrieving revision 1.1
diff -u -r1.1 GrayFilter.java
--- javax/swing/GrayFilter.java	9 Aug 2002 04:26:10 -0000	1.1
+++ javax/swing/GrayFilter.java	6 Sep 2004 16:35:54 -0000
@@ -45,41 +45,41 @@
 
 public class GrayFilter extends RGBImageFilter
 {
-    private boolean b;
-    private int p;
+  private boolean b;
+  private int p;
 
-    /**
-       Create a GrayFilter. If b is true then brighten. Also, indicate how much gray.
-       
-       @param b if brighten
-       @param p percent of gray, 0 - 100
-    */
-    public GrayFilter(boolean b, int p)
-    {
-	this.b = b; //FIXME - HANDLE THIS
-	this.p = p;
-    }
+  /**
+   * Create a GrayFilter. If b is true then brighten. Also, indicate how much gray.
+   *    
+   * @param b if brighten
+   * @param p percent of gray, 0 - 100
+   */
+  public GrayFilter(boolean b, int p)
+  {
+    this.b = b; //FIXME - HANDLE THIS
+    this.p = p;
+  }
 
-    /**
-       Create grayed image
-
-       @param i image to gray
-
-       @return a grayed image
-     */
-    public static Image createDisabledImage(Image src)
-    {
-	return Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(src.getSource(),
-										new GrayFilter(false, 100)));
-    }
-
-    /**
-       Filter RGB to gray
-     */
-    public int filterRGB(int x,
-			 int y,
-			 int rgb)
-    {
-	return (int) ( ( p * ( 0.299 * ( (0xff0000 & rgb) >> 16) + 0.587 * ( (0xff00 & rgb) >> 8 ) + 0.114 * (0xff & rgb ) ) ));
-    }
+  /**
+   * Create grayed image
+   *
+   * @param src image to gray
+   *
+   * @return a grayed image
+   */
+  public static Image createDisabledImage(Image src)
+  {
+    return (Toolkit.getDefaultToolkit().
+	    createImage(new FilteredImageSource(src.getSource(),
+						new GrayFilter(false, 100))));
+  }
+  
+  /**
+   * Filter RGB to gray
+   */
+  public int filterRGB(int x, int y, int rgb)
+  {
+    return (int) (p * (0.299 * ((0xff0000 & rgb) >> 16)
+		       + 0.587 * ((0xff00 & rgb) >> 8) + 0.114 * (0xff & rgb)));
+  }
 }
Index: javax/swing/ImageIcon.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ImageIcon.java,v
retrieving revision 1.2
diff -u -r1.2 ImageIcon.java
--- javax/swing/ImageIcon.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/ImageIcon.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* ImageIcon.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,67 +35,107 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Image;
-import java.awt.MediaTracker;
 import java.awt.Toolkit;
+import java.awt.image.ImageObserver;
 import java.io.Serializable;
 import java.net.URL;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleContext;
 
-public class ImageIcon implements Icon
+
+public class ImageIcon
+  implements Icon, Serializable
 {
-    Image image;
-    String file, descr;
-    Component observer;
-
-  public ImageIcon(String s)
-    {
-	this(s, "");
-    }
-
-  public ImageIcon(String file,
-	      String descr)
-    {
-        this.file = file;
-        this.descr = descr;
-
-        image = Toolkit.getDefaultToolkit().getImage(file);
-        if (image == null) {
-            return;
-        }
-        //loadImage(image);
-    }
-
-    // not in SUN's spec !!!
-    public void setParent(Component p)
-    {
-	observer = p;
-    }
-
-    public Image getImage() 
-    {  return image;    }
-
-    public String getDescription() 
-    {  return descr;    }
-    public void setDescription(String description) 
-    {  this.descr = description;    }
-
-    public int getIconHeight()
-    {	return image.getHeight(observer);    }
-    public int getIconWidth()
-    {	return image.getWidth(observer);    }
-
-    public void paintIcon(Component c, 
-			  Graphics g,
-			  int x, 
-			  int y)
-    {
-	g.drawImage(image, x, y, observer);
-    }
+  private static final long serialVersionUID = 532615968316031794L;
+  Image image;
+  String description;
+  ImageObserver observer;
+
+  public ImageIcon()
+  {
+  }
+
+  public ImageIcon(String file)
+  {
+    this(file, file);
+  }
+
+  public ImageIcon(String file, String description)
+  {
+    this(Toolkit.getDefaultToolkit().getImage(file), description);
+  }
+
+  public ImageIcon(byte[] imageData)
+  {
+    this(imageData, null);
+  }
+  
+  public ImageIcon(byte[] imageData, String description)
+  {
+    this(Toolkit.getDefaultToolkit().createImage(imageData), description);
+  }
+
+  public ImageIcon(URL url)
+  {
+    this(url, null);
+  }
+
+  public ImageIcon(URL url, String description)
+  {
+    this(Toolkit.getDefaultToolkit().getImage(url), description);
+  }
+
+  public ImageIcon(Image image)
+  {
+    this(image, null);
+  }
+
+  public ImageIcon(Image image, String description)
+  {
+    this.image = Toolkit.getDefaultToolkit().createImage(image.getSource());
+    this.description = description;
+  }
+
+  public ImageObserver getImageObserver()
+  {
+    return observer;
+  }
+
+  public void setImageObserver(ImageObserver newObserver)
+  {
+    observer = newObserver;
+  }
+
+  public Image getImage()
+  {
+    return image;
+  }
+
+  public String getDescription()
+  {
+    return description;
+  }
+
+  public void setDescription(String description)
+  {
+    this.description = description;
+  }
+
+  public int getIconHeight()
+  {
+    return image.getHeight(observer);
+  }
+
+  public int getIconWidth()
+  {
+    return image.getWidth(observer);
+  }
+
+  public void paintIcon(Component c, Graphics g, int x, int y)
+  {
+    g.drawImage(image, x, y, observer != null ? observer : c);
+  }
 }
Index: javax/swing/InputMap.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/InputMap.java,v
retrieving revision 1.3
diff -u -r1.3 InputMap.java
--- javax/swing/InputMap.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/InputMap.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* InputMap.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.io.IOException;
@@ -43,24 +42,23 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+
 /**
- * InputMap
  * @author	Andrew Selkirk
- * @version	1.0
+ * @author Michael Koch
+ *
+ * @since 1.3
  */
-public class InputMap implements Serializable
+public class InputMap
+  implements Serializable
 {
-  static final long serialVersionUID = -5429059542008604257L;
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+  private static final long serialVersionUID = -5429059542008604257L;
 
 	/**
 	 * inputMap
@@ -70,171 +68,147 @@
 	/**
 	 * parent
 	 */
-	private InputMap parent = null;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
+  private InputMap parent;
 
 	/**
-	 * Constructor InputMap
+   * Creates a new <code>InputMap</code> instance.
 	 */
-	public InputMap() {
+  public InputMap()
+  {
 		// TODO
-	} // InputMap()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  }
 
 	/**
-	 * get
-	 * @param value0 TODO
-	 * @returns Object
-	 */
-	public Object get(KeyStroke keystroke) {
-
-		// Variables
-		Object	result;
-
-		// Check Local store
-		result = inputMap.get(keystroke);
-
-		// Check Parent
-		if (result == null) {
-			result = parent.get(keystroke);
-		} // if
-
-		return result;
-
-	} // get()
-
-	/**
-	 * put
-	 * @param keystroke TODO
-	 * @param actionMapKey TODO
-	 */
-	public void put(KeyStroke keystroke, Object actionMapKey) {
-		if (actionMapKey == null) {
+   * Returns the binding for keystroke.
+   *
+   * @param key the key of the enty
+   *
+   * @return the binding associated with keystroke may be null
+	 */
+  public Object get(KeyStroke keystroke)
+  {
+    Object result = inputMap.get(keystroke);
+
+    if (result == null && parent != null)
+      result = parent.get(keystroke);
+    return result;
+  }
+
+	/**
+   * Puts a new entry into the <code>InputMap</code>.
+   * If actionMapKey is null an existing entry will be removed.
+   *
+   * @param keystroke the keystroke for the entry
+   * @param actionMapKey the action.
+	 */
+  public void put(KeyStroke keystroke, Object actionMapKey)
+  {
+    if (actionMapKey == null)
 			inputMap.remove(keystroke);
-		} else {
+    else
 			inputMap.put(keystroke, actionMapKey);
-		} // if
-	} // put()
+  }
 
 	/**
-	 * remove
-	 * @param keystroke TODO
+   * Remove an entry from the <code>InputMap</code>.
+   *
+   * @param key the key of the entry to remove
 	 */
-	public void remove(KeyStroke keystroke) {
+  public void remove(KeyStroke keystroke)
+  {
 		inputMap.remove(keystroke);
-	} // remove()
+  }
 
 	/**
-	 * getParent
-	 * @returns InputMap
+   * Returns the parent of this <code>InputMap</code>.
+   *
+   * @return the parent, may be null.
 	 */
-	public InputMap getParent() {
+  public InputMap getParent()
+  {
 		return parent;
-	} // getParent()
+  }
 
 	/**
-	 * setParent
-	 * @param parentMap TODO
+   * Sets a parent for this <code>InputMap</code>.
+   *
+   * @param parentMap the new parent
 	 */
-	public void setParent(InputMap parentMap) {
+  public void setParent(InputMap parentMap)
+  {
 		parent = parentMap;
-	} // setParent()
+  }
 
 	/**
-	 * size
-	 * @returns int
+   * Returns the number of entries in this <code>InputMap</code>.
+   *
+   * @return the number of entries
 	 */
-	public int size() {
+  public int size()
+  {
 		return inputMap.size();
-	} // size()
+  }
 
 	/**
-	 * clear
+   * Clears the <code>InputMap</code>.
 	 */
-	public void clear() {
+  public void clear()
+  {
 		inputMap.clear();
-	} // clear()
+  }
 
 	/**
-	 * keys
-	 * @returns KeyStroke[]
+   * Returns all keys of entries in this <code>InputMap</code>.
+   *
+   * @return an array of keys
 	 */
-	public KeyStroke[] keys() {
-		return convertSet(inputMap.keySet());
-	} // keys()
+  public KeyStroke[] keys()
+  {
+    KeyStroke[] array = new KeyStroke[size()];
+    return (KeyStroke[]) inputMap.keySet().toArray(array);
+  }
 
 	/**
-	 * allKeys
-	 * @returns KeyStroke[]
+   * Returns all keys of entries in this <code>InputMap</code>
+   * and all its parents.
+   *
+   * @return an array of keys
 	 */
-	public KeyStroke[] allKeys() {
-
-		// Variables
-		Set			set;
-
-		// Initialize
-		set = new HashSet();
+  public KeyStroke[] allKeys()
+  {
+    Set set = new HashSet();
 
-		// Get Key Sets
-		if (parent != null) {
+    if (parent != null)
 			set.addAll(Arrays.asList(parent.allKeys()));
-		} // if
-		set.addAll(inputMap.keySet());
-
-		return convertSet(set);
-
-	} // allKeys()
-
-	private KeyStroke[] convertSet(Set set) {
-
-		// Variables
-		int			index;
-		Iterator	iterator;
-		KeyStroke[]	keys;
 
-		// Create Final array
-		keys = new KeyStroke[set.size()];
-		iterator = set.iterator();
-		index = 0;
-		while (iterator.hasNext()) {
-			keys[index++] = (KeyStroke) iterator.next();
-		} // while
-
-		return keys;
-
-	} // convertSet()
-
-
-	//-------------------------------------------------------------
-	// Interface: Serializable ------------------------------------
-	//-------------------------------------------------------------
+    set.addAll(inputMap.keySet());
+    KeyStroke[] array = new KeyStroke[size()];
+    return (KeyStroke[]) set.toArray(array);
+  }
 
 	/**
 	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
+   *
+   * @param stream the stream to write to
+   *
+   * @exception IOException If an error occurs
 	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
 		// TODO
-	} // writeObject()
+  }
 
 	/**
 	 * readObject
-	 * @param stream TODO
-	 * @exception ClassNotFoundException TODO
-	 * @exception IOException TODO
-	 */
-	private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
+   *
+   * @param stream the stream to read from
+   *
+   * @exception ClassNotFoundException If the serialized class cannot be found
+   * @exception IOException If an error occurs
+	 */
+  private void readObject(ObjectInputStream stream)
+    throws ClassNotFoundException, IOException
+  {
 		// TODO
-	} // readObject()
-
-
-} // InputMap
+  }
+}
Index: javax/swing/JApplet.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JApplet.java,v
retrieving revision 1.2
diff -u -r1.2 JApplet.java
--- javax/swing/JApplet.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JApplet.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* JApplet.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -49,8 +49,9 @@
 import java.awt.event.WindowEvent;
 import javax.accessibility.AccessibleContext;
 
-public class JApplet extends Applet
+public class JApplet extends Applet implements RootPaneContainer
 {
+  private static final long serialVersionUID = 7269359214497372587L;
 
     public final static int HIDE_ON_CLOSE        = 0;
     public final static int EXIT_ON_CLOSE        = 1;
@@ -80,27 +81,27 @@
   public Dimension getPreferredSize()
   {
     Dimension d = super.getPreferredSize();
-    System.out.println("JFrame.getPrefSize(): " + d + " , comp="+countComponents() + ", layout=" + getLayout());
+    System.out.println("JFrame.getPrefSize(): " + d + " , comp="+ getComponentCount () + ", layout=" + getLayout());
     return d;
   }
 
   public  void setLayout(LayoutManager manager)
   {    super.setLayout(manager);  }
 
-    void setLayeredPane(JLayeredPane layeredPane) 
+   public void setLayeredPane(JLayeredPane layeredPane) 
     {   getRootPane().setLayeredPane(layeredPane);   }
   
-    JLayeredPane getLayeredPane()
+   public JLayeredPane getLayeredPane()
     {   return getRootPane().getLayeredPane();     }
   
-    JRootPane getRootPane()
+   public JRootPane getRootPane()
     {
         if (rootPane == null)
             setRootPane(createRootPane());
         return rootPane;          
     }
 
-    void setRootPane(JRootPane root)
+   public void setRootPane(JRootPane root)
     {
         if (rootPane != null)
             remove(rootPane);
@@ -109,19 +110,19 @@
         add(rootPane, BorderLayout.CENTER);
     }
 
-    JRootPane createRootPane()
+   public JRootPane createRootPane()
     {   return new JRootPane();    }
 
-    Container getContentPane()
+   public Container getContentPane()
     {    return getRootPane().getContentPane();     }
 
-    void setContentPane(Container contentPane)
+   public void setContentPane(Container contentPane)
     {    getRootPane().setContentPane(contentPane);    }
   
-    Component getGlassPane()
+   public  Component getGlassPane()
     {    return getRootPane().getGlassPane();   }
   
-    void setGlassPane(Component glassPane)
+   public void setGlassPane(Component glassPane)
     {   getRootPane().setGlassPane(glassPane);   }
 
 
@@ -136,10 +137,10 @@
     {    return close_action;   }
 
     
-    JMenuBar getJMenuBar()
+    public JMenuBar getJMenuBar()
     {    return getRootPane().getJMenuBar();   }
     
-    void setJMenuBar(JMenuBar menubar)
+    public void setJMenuBar(JMenuBar menubar)
     {    getRootPane().setJMenuBar(menubar); }
     
     
Index: javax/swing/JButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JButton.java,v
retrieving revision 1.3
diff -u -r1.3 JButton.java
--- javax/swing/JButton.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JButton.java	6 Sep 2004 16:35:54 -0000
@@ -41,17 +41,18 @@
 import javax.accessibility.AccessibleContext;
 import javax.swing.plaf.ButtonUI;
 
+
 /**
  * An instance of JButton can be added to a panel, frame etc
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
-public class JButton extends AbstractButton implements Accessible 
+public class JButton extends AbstractButton
+  implements Accessible
 {
   private static final long serialVersionUID = -1907255238954382202L;
-
-    boolean def, is_def;
-
+  boolean def;
+  boolean is_def;
     
     public JButton()
     {
@@ -87,6 +88,7 @@
     protected  void configurePropertiesFromAction(Action a)
     {
 	//Factory method which sets the AbstractButton's properties according to values from the Action instance. 
+	super.configurePropertiesFromAction(a);
     }
     
     public AccessibleContext getAccessibleContext()
@@ -97,8 +99,8 @@
   
     public String getUIClassID()
     {
-	//Returns a string that specifies the name of the L&F class that renders this component.  
-	return "JButton";
+    //Returns a string that specifies the name of the L&F class that renders this component.  
+	return "ButtonUI";
     }
   
     public boolean isDefaultButton()
@@ -118,17 +120,23 @@
 	return "JButton";
     }
     
+  /**
+   * Overrides JComponent.removeNotify to check if this button is currently
+   * set as the default button on the RootPane, and if so, sets the RootPane's
+   * default button to null to ensure the RootPane doesn't hold onto an invalid
+   * button reference.
+   */
     public void removeNotify()
     {
-	//Overrides JComponent.removeNotify to check if this button is currently set as the default button on the RootPane, and if so, sets the RootPane's default button to null to ensure the RootPane doesn't hold onto an invalid button reference.  
     }
     
     public void setDefaultCapable(boolean defaultCapable)
-    {	def = defaultCapable;    }
+  {
+    def = defaultCapable;
+  }
     
     public void updateUI()
     {
-	ButtonUI b = (ButtonUI)UIManager.getUI(this);
-	setUI(b);
+    setUI((ButtonUI) UIManager.getUI(this));
     }
 }
Index: javax/swing/JCheckBox.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JCheckBox.java,v
retrieving revision 1.2
diff -u -r1.2 JCheckBox.java
--- javax/swing/JCheckBox.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JCheckBox.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* JCheckBox.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -47,46 +47,94 @@
  */
 public class JCheckBox extends JToggleButton
 {
+  private static final long serialVersionUID = -5246739313864538930L;
+  
+  private boolean borderPaintedFlat;
+
+  private void init()
+  {
+    borderPainted = false;
+    contentAreaFilled = false;
+  }
+  
     public JCheckBox()
     {
-	this(null, null);
+    super();
+    init();
     }
-    public JCheckBox(Action a)
+
+  public JCheckBox(Action action)
     {
-	this();
-	setAction(a);
+    super(action);
+    init();
     }
 
     public JCheckBox(Icon icon)
     { 
-	this(null, icon);
+    super(icon);
+    init();
+  }    
+  
+  public JCheckBox(Icon icon, boolean selected)
+  { 
+    super(icon, selected);
+    init();
     }    
   
     public JCheckBox(String text)
     {
-	this(text, null);
+    super(text);
+    init();
+  }
+      
+  public JCheckBox(String text, boolean selected)
+  {
+    super(text, selected);
+    init();
     }
       
     public JCheckBox(String text, Icon icon)
     {
 	super(text, icon);
+    init();
     }
 
+  public JCheckBox(String text, Icon icon, boolean selected)
+  {
+    super(text, icon, selected);
+    init();
+  }
     
+  /**
+   * Gets the AccessibleContext associated with this JCheckBox.
+   */
     public AccessibleContext getAccessibleContext()
     {
-	//Gets the AccessibleContext associated with this JCheckBox. 
 	return null;
     }
   
+  /**
+   * Returns a string that specifies the name of the Look and Feel class
+   * that renders this component.
+   */
     public String getUIClassID()
     {
-	//Returns a string that specifies the name of the L&F class that renders this component.  
-	return "JCheckBox";
+	return "CheckBoxUI";
     }
   
     protected  String paramString()
     {
 	return "JCheckBox";
     }
+
+  public boolean isBorderPaintedFlat()
+  {
+    return borderPaintedFlat;
+  }
+
+  public void setBorderPaintedFlat(boolean newValue)
+  {
+    firePropertyChange("borderPaintedFlat", borderPaintedFlat, newValue);
+    borderPaintedFlat = newValue;
+  }
 }
Index: javax/swing/JCheckBoxMenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JCheckBoxMenuItem.java,v
retrieving revision 1.3
diff -u -r1.3 JCheckBoxMenuItem.java
--- javax/swing/JCheckBoxMenuItem.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JCheckBoxMenuItem.java	6 Sep 2004 16:35:54 -0000
@@ -43,202 +43,207 @@
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 
+
 /**
- * JCheckBoxMenuItem
- * @author	Andrew Selkirk
- * @version	1.0
+ * This class represents JCheckBoxMenuItem. Its behaviour is very similar
+ * to JCheckBoxButton. Just like the JCheckBoxButton, user can check and
+ * uncheck this menu item by clicking on it. Also setSelected()/setState()
+ * can be use used for the same purpose. JCheckBoxMenuItem uses
+ * ToggleButtonModel to keep track of its selection.
  */
-public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, Accessible
+public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
+                                                            Accessible
 {
+  private static final long serialVersionUID = -6676402307973384715L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJCheckBoxMenuItem
-	 */
-	protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJCheckBoxMenuItem
-		 * @param component TODO
-		 */
-		protected AccessibleJCheckBoxMenuItem(JCheckBoxMenuItem component) {
-			super(component);
-			// TODO
-		} // AccessibleJCheckBoxMenuItem()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.CHECK_BOX;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJCheckBoxMenuItem
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "CheckBoxMenuItemUI";
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 */
-	public JCheckBoxMenuItem() {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param icon TODO
-	 */
-	public JCheckBoxMenuItem(Icon icon) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param text TODO
-	 */
-	public JCheckBoxMenuItem(String text) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param action TODO
-	 */
-	public JCheckBoxMenuItem(Action action) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param text TODO
-	 * @param icon TODO
-	 */
-	public JCheckBoxMenuItem(String text, Icon icon) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param text TODO
-	 * @param state TODO
-	 */
-	public JCheckBoxMenuItem(String text, boolean state) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-	/**
-	 * Constructor JCheckBoxMenuItem
-	 * @param text TODO
-	 * @param icon TODO
-	 * @param state TODO
-	 */
-	public JCheckBoxMenuItem(String text, Icon icon, boolean state) {
-		// TODO
-	} // JCheckBoxMenuItem()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getState
-	 * @returns boolean
-	 */
-	public boolean getState() {
-		return false; // TODO
-	} // getState()
-
-	/**
-	 * setState
-	 * @param state TODO
-	 */
-	public synchronized void setState(boolean state) {
-		// TODO
-	} // setState()
-
-	/**
-	 * getSelectedObjects
-	 * @returns Object[]
-	 */
-	public Object[] getSelectedObjects() {
-		return null; // TODO
-	} // getSelectedObjects()
-
-	/**
-	 * requestFocus
-	 */
-	public void requestFocus() {
-		// TODO
-	} // requestFocus()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJCheckBoxMenuItem(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
+  /** name for the UI delegate for this menuItem. */
+  private static final String uiClassID = "CheckBoxMenuItemUI";
 
+  /** Indicates whether this menu item is checked. */
+  private boolean state;
 
-} // JCheckBoxMenuItem
+  /**
+   * This array contains text of this menu item if this menu item is in
+   * checked state and null it is not.
+   */
+  private Object[] selectedObjects = new Object[1];
+
+  /**
+   * Creates a new JCheckBoxMenuItem object.
+   */
+  public JCheckBoxMenuItem()
+  {
+    this(null, null);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem with given icon
+   *
+   * @param icon Icon for this menu item
+   */
+  public JCheckBoxMenuItem(Icon icon)
+  {
+    this(null, icon);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem with given label
+   *
+   * @param text Label for this menu item
+   */
+  public JCheckBoxMenuItem(String text)
+  {
+    this(text, null);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem using given action
+   *
+   * @param action Action for this menu item.
+   */
+  public JCheckBoxMenuItem(Action action)
+  {
+    this();
+    setAction(action);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem object with given label and icon
+   *
+   * @param text Label for this menu item
+   * @param icon Icon for this menu item
+   */
+  public JCheckBoxMenuItem(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem object using specified label and
+   * marked as checked if given 'state' is true
+   *
+   * @param text Label for this menu item
+   * @param state True if this item should be in checked state and false otherwise
+   */
+  public JCheckBoxMenuItem(String text, boolean state)
+  {
+    this(text, null, state);
+  }
+
+  /**
+   * Creates a new JCheckBoxMenuItem object with given label, icon,
+   * and marked as checked if given 'state' is true
+   *
+   * @param text Label for this menu item
+   * @param icon icon for this menu item
+   * @param state  True if this item should be in checked state and false otherwise
+   */
+  public JCheckBoxMenuItem(String text, Icon icon, boolean state)
+  {
+    super(text, icon);
+    setModel(new JToggleButton.ToggleButtonModel());
+    this.state = state;
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "JCheckBoxMenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * Returns checked state for this check box menu item.
+   *
+   * @return Returns true if this menu item is in checked state
+   * and false otherwise.
+   */
+  public boolean getState()
+  {
+    return state;
+  }
+
+  /**
+   * Sets state for this check box menu item. If
+   * given 'state' is true, then mark menu item as checked,
+   * and uncheck this menu item otherwise.
+   *
+   * @param state new state for this menu item
+   *
+   */
+  public synchronized void setState(boolean state)
+  {
+    this.state = state;
+  }
+
+  /**
+   * This method returns array containing label of this
+   * menu item if it is selected and null otherwise.
+   *
+   * @return Array containing label of this
+   * menu item if this menu item is selected or null otherwise.
+   */
+  public Object[] getSelectedObjects()
+  {
+    if (state == true)
+      selectedObjects[0] = this.getText();
+    else
+      selectedObjects[0] = null;
+
+    return selectedObjects;
+  }
+
+  /**
+    * This method overrides JComponent.requestFocus with an empty
+    * implementation, since JCheckBoxMenuItems should not
+    * receve focus in general.
+   */
+  public void requestFocus()
+  {
+    //  Should do nothing here
+  }
+
+  /**
+   * A string that describes this JCheckBoxMenuItem. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JCheckBoxMenuItem
+   */
+  protected String paramString()
+  {
+    return "JCheckBoxMenuItem";
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJCheckBoxMenuItem();
+
+    return accessibleContext;
+  }
+
+  protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem
+  {
+    private static final long serialVersionUID = 1079958073579370777L;
+
+    /**
+     * Creates a new AccessibleJCheckBoxMenuItem object.
+     */
+    protected AccessibleJCheckBoxMenuItem()
+    {
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.CHECK_BOX;
+    }
+  }
+}
Index: javax/swing/JColorChooser.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JColorChooser.java,v
retrieving revision 1.2
diff -u -r1.2 JColorChooser.java
--- javax/swing/JColorChooser.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JColorChooser.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* JColorChooser.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,11 +35,16 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.AWTError;
+import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
@@ -47,324 +52,654 @@
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.swing.colorchooser.AbstractColorChooserPanel;
+import javax.swing.colorchooser.ColorChooserComponentFactory;
 import javax.swing.colorchooser.ColorSelectionModel;
+import javax.swing.colorchooser.DefaultColorSelectionModel;
 import javax.swing.plaf.ColorChooserUI;
 
+
 /**
- * JColorChooser
- * @author	Andrew Selkirk
- * @version	1.0
+ * The JColorChooser is a Swing widget that offers users different ways to
+ * select a color. By default, three different panels are presented to the
+ * user that are capable of changing the selected color. There are three ways
+ * to utilize JColorChooser. The first is to build a JColorChooser and add it
+ * to the content pane. The second is to use the createDialog method to
+ * create a JDialog that holds a JColorChooser. The third is to show a
+ * JColorChooser in a JDialog directly using the showDialog method.
  */
-public class JColorChooser extends JComponent implements Accessible {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJColorChooser
-	 */
-	protected class AccessibleJColorChooser extends JComponent.AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJColorChooser
-		 * @param component TODO
-		 */
-		protected AccessibleJColorChooser(JColorChooser component) {
-			super(component);
-			// TODO
-		} // AccessibleJColorChooser()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.COLOR_CHOOSER;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJColorChooser
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "ColorChooserUI";
-
-	/**
-	 * selectionModel
-	 */
-	private ColorSelectionModel selectionModel;
-
-	/**
-	 * previewPanel
-	 */
-	private JComponent previewPanel;
-
-	/**
-	 * chooserPanels
-	 */
-	private AbstractColorChooserPanel[] chooserPanels;
-
-	/**
-	 * SELECTION_MODEL_PROPERTY
-	 */
-	public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
-
-	/**
-	 * PREVIEW_PANEL_PROPERTY
-	 */
-	public static final String PREVIEW_PANEL_PROPERTY = "previewPanel";
-
-	/**
-	 * CHOOSER_PANELS_PROPERTY
-	 */
-	public static final String CHOOSER_PANELS_PROPERTY = "chooserPanels";
-
-	/**
-	 * accessibleContext
-	 */
-	protected AccessibleContext accessibleContext;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JColorChooser
-	 */
-	public JColorChooser() {
-		// TODO
-	} // JColorChooser()
-
-	/**
-	 * Constructor JColorChooser
-	 * @param initial TODO
-	 */
-	public JColorChooser(Color initial) {
-		// TODO
-	} // JColorChooser()
-
-	/**
-	 * Constructor JColorChooser
-	 * @param model TODO
-	 */
-	public JColorChooser(ColorSelectionModel model) {
-		// TODO
-	} // JColorChooser()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * setColor
-	 * @param color TODO
-	 */
-	public void setColor(Color color) {
-		// TODO
-	} // setColor()
-
-	/**
-	 * setColor
-	 * @param r TODO
-	 * @param g TODO
-	 * @param b TODO
-	 */
-	public void setColor(int r, int g, int b) {
-		// TODO
-	} // setColor()
-
-	/**
-	 * setColor
-	 * @param color TODO
-	 */
-	public void setColor(int color) {
-		// TODO
-	} // setColor()
-
-	/**
-	 * showDialog
-	 * @param component TODO
-	 * @param title TODO
-	 * @param initial TODO
-	 * @returns Color
-	 */
-	public static Color showDialog(Component component, String title,
-			Color initial) {
-		return null; // TODO
-	} // showDialog()
-
-	/**
-	 * createDialog
-	 * @param component TODO
-	 * @param title TODO
-	 * @param modal TODO
-	 * @param chooserPane TODO
-	 * @param okListener TODO
-	 * @param cancelListener TODO
-	 * @returns JDialog
-	 */
-	public static JDialog createDialog(Component component, String title,
-			boolean modal, JColorChooser chooserPane,
-			ActionListener okListener, ActionListener cancelListener) {
-		return null; // TODO
-	} // createDialog()
-
-	/**
-	 * getUI
-	 * @returns ColorChooserUI
-	 */
-	public ColorChooserUI getUI() {
-		return (ColorChooserUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(ColorChooserUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((ColorChooserUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getColor
-	 * @returns Color
-	 */
-	public Color getColor() {
-		return null; // TODO
-	} // getColor()
-
-	/**
-	 * setPreviewPanel
-	 * @param component TODO
-	 */
-	public void setPreviewPanel(JComponent component) {
-		// TODO
-	} // setPreviewPanel()
-
-	/**
-	 * getPreviewPanel
-	 * @returns JComponent
-	 */
-	public JComponent getPreviewPanel() {
-		return null; // TODO
-	} // getPreviewPanel()
-
-	/**
-	 * addChooserPanel
-	 * @param panel TODO
-	 */
-	public void addChooserPanel(AbstractColorChooserPanel panel) {
-		// TODO
-	} // addChooserPanel()
-
-	/**
-	 * removeChooserPanel
-	 * @param panel TODO
-	 * @returns AbstractColorChooserPanel
-	 */
-	public AbstractColorChooserPanel removeChooserPanel(
-			AbstractColorChooserPanel panel) {
-		return null; // TODO
-	} // removeChooserPanel()
-
-	/**
-	 * setChooserPanels
-	 * @param panels TODO
-	 */
-	public void setChooserPanels(AbstractColorChooserPanel[] panels) {
-		// TODO
-	} // setChooserPanels()
-
-	/**
-	 * getChooserPanels
-	 * @returns AbstractColorChooserPanel[]
-	 */
-	public AbstractColorChooserPanel[] getChooserPanels() {
-		return null; // TODO
-	} // getChooserPanels()
-
-	/**
-	 * getSelectionModel
-	 * @returns ColorSelectionModel
-	 */
-	public ColorSelectionModel getSelectionModel() {
-		return null; // TODO
-	} // getSelectionModel()
-
-	/**
-	 * setSelectionModel
-	 * @param model TODO
-	 */
-	public void setSelectionModel(ColorSelectionModel model) {
-		// TODO
-	} // setSelectionModel()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJColorChooser(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JColorChooser
+public class JColorChooser extends JComponent implements Accessible
+{
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 9168066781620640889L;
+
+  /**
+   * AccessibleJColorChooser
+   */
+  protected class AccessibleJColorChooser
+    extends JComponent.AccessibleJComponent
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -2038297864782299082L;
+
+    /**
+     * Constructor AccessibleJColorChooser
+     */
+    protected AccessibleJColorChooser()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     *
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.COLOR_CHOOSER;
+    } // getAccessibleRole()
+  } // AccessibleJColorChooser
+
+  /** The model used with the JColorChooser. */
+  private ColorSelectionModel selectionModel;
+
+  /** The preview panel associated with the JColorChooser. */
+  private JComponent previewPanel;
+
+  /**
+   * The set of AbstractColorChooserPanels associated with the JColorChooser.
+   */
+  private AbstractColorChooserPanel[] chooserPanels;
+
+  /** A Drag and Drop property. */
+  private boolean dragEnabled;
+
+  /**
+   * The property fired by the JColorChooser when the selectionModel property
+   * changes.
+   */
+  public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
+
+  /**
+   * The property fired by the JColorChooser when the previewPanel property
+   * changes.
+   */
+  public static final String PREVIEW_PANEL_PROPERTY = "previewPanel";
+
+  /**
+   * The property fired by the JColorChooser when the chooserPanels property
+   * changes.
+   */
+  public static final String CHOOSER_PANELS_PROPERTY = "chooserPanels";
+
+  /** accessibleContext */
+  protected AccessibleContext accessibleContext;
+
+  /**
+   * This method creates a new JColorChooser with the default initial color.
+   */
+  public JColorChooser()
+  {
+    this(new DefaultColorSelectionModel());
+  } // JColorChooser()
+
+  /**
+   * This method creates a new JColorChooser with the given initial color.
+   *
+   * @param initial The initial color.
+   */
+  public JColorChooser(Color initial)
+  {
+    this(new DefaultColorSelectionModel(initial));
+  } // JColorChooser()
+
+  /**
+   * This method creates a new JColorChooser with the given model. The model
+   * will dictate what the initial color for the JColorChooser is.
+   *
+   * @param model The Model to use with the JColorChooser.
+   */
+  public JColorChooser(ColorSelectionModel model)
+  {
+    if (model == null)
+      model = new DefaultColorSelectionModel();
+    selectionModel = model;
+    updateUI();
+  } // JColorChooser()
+
+  /**
+   * This method sets the current color for the JColorChooser.
+   *
+   * @param color The new color for the JColorChooser.
+   */
+  public void setColor(Color color)
+  {
+    if (color != null)
+      selectionModel.setSelectedColor(color);
+  } // setColor()
+
+  /**
+   * This method sets the current color for the JColorChooser using RGB
+   * values.
+   *
+   * @param r The red value.
+   * @param g The green value.
+   * @param b The blue value.
+   */
+  public void setColor(int r, int g, int b)
+  {
+    selectionModel.setSelectedColor(new Color(r, g, b));
+  } // setColor()
+
+  /**
+   * This method sets the current color for the JColorChooser using the
+   * integer value. Bits 0-7 represent the blue value. Bits 8-15 represent
+   * the green value. Bits 16-23 represent the red value.
+   *
+   * @param color The new current color of the JColorChooser.
+   */
+  public void setColor(int color)
+  {
+    setColor(new Color(color, false));
+  } // setColor()
+
+  /**
+   * This method shows a JColorChooser inside a JDialog. The JDialog will
+   * block until it is hidden. The JDialog comes with three buttons: OK,
+   * Cancel, and Reset. Pressing OK or Cancel hide the JDialog. Pressing
+   * Reset will reset the JColorChooser to its initial value.
+   *
+   * @param component The Component that parents the JDialog.
+   * @param title The title displayed in the JDialog.
+   * @param initial The initial color.
+   *
+   * @return The selected color.
+   */
+  public static Color showDialog(Component component, String title,
+                                 Color initial)
+  {
+    JColorChooser choose = new JColorChooser(initial);
+
+    JDialog dialog = createDialog(component, title, true, choose, null, null);
+
+    dialog.getContentPane().add(choose);
+    dialog.pack();
+    dialog.show();
+
+    return choose.getColor();
+  } // showDialog()
+
+  /**
+   * This is a helper method to make the given JDialog block until it is
+   * hidden.
+   *
+   * @param dialog The JDialog to block.
+   */
+  private static void makeModal(JDialog dialog)
+  {
+    try
+      {
+	synchronized (dialog)
+	  {
+	    while (dialog.isVisible())
+	      dialog.wait();
+	  }
+      }
+    catch (InterruptedException e)
+      {
+      }
+  }
+
+  /**
+   * This is a helper method to find the first Frame or Dialog ancestor of the
+   * given Component.
+   *
+   * @param c The Component to find ancestors for.
+   *
+   * @return A Frame or Dialog ancestor. Null if none are found.
+   */
+  private static Component findParent(Component c)
+  {
+    Component parent = SwingUtilities.getAncestorOfClass(Frame.class, c);
+    if (parent != null)
+      return parent;
+    parent = SwingUtilities.getAncestorOfClass(Dialog.class, c);
+    return parent;
+  }
+
+  /**
+   * This method will take the given JColorChooser and place it in a JDialog
+   * with the given modal property. Three buttons are displayed in the
+   * JDialog: OK, Cancel and Reset. If OK or Cancel are pressed, the JDialog
+   * is hidden. If Reset is pressed, then the JColorChooser will take on its
+   * default color value. The given okListener will be registered to the OK
+   * button and the cancelListener will be registered to the Cancel button.
+   * If the modal property is set, then the JDialog will block until it is
+   * hidden.
+   *
+   * @param component The Component that will parent the JDialog.
+   * @param title The title displayed in the JDialog.
+   * @param modal The modal property.
+   * @param chooserPane The JColorChooser to place in the JDialog.
+   * @param okListener The ActionListener to register to the OK button.
+   * @param cancelListener The ActionListener to register to the Cancel
+   *        button.
+   *
+   * @return A JDialog with the JColorChooser inside of it.
+   *
+   * @throws AWTError If the component is not a suitable parent.
+   */
+  public static JDialog createDialog(Component component, String title,
+                                     boolean modal, JColorChooser chooserPane,
+                                     ActionListener okListener,
+                                     ActionListener cancelListener)
+  {
+    Component parent = findParent(component);
+    if (parent == null)
+      throw new AWTError("No suitable parent found for Component.");
+    JDialog dialog;
+    if (parent instanceof Frame)
+      dialog = new ModalDialog((Frame) parent, title);
+    else
+      dialog = new ModalDialog((Dialog) parent, title);
+    dialog.setModal(modal);
+
+    dialog.getContentPane().setLayout(new BorderLayout());
+
+    JPanel panel = new JPanel();
+    panel.setLayout(new FlowLayout());
+
+    ActionListener al = new DefaultOKCancelListener(dialog);
+
+    JButton ok = new JButton("OK");
+    ok.addActionListener(okListener);
+    ok.addActionListener(al);
+
+    JButton cancel = new JButton("Cancel");
+    cancel.addActionListener(cancelListener);
+    cancel.addActionListener(al);
+
+    JButton reset = new JButton("Reset");
+    reset.addActionListener(new DefaultResetListener(chooserPane));
+
+    dialog.getContentPane().add(chooserPane, BorderLayout.NORTH);
+
+    panel.add(ok);
+    panel.add(cancel);
+    panel.add(reset);
+
+    dialog.getContentPane().add(panel, BorderLayout.SOUTH);
+
+    return dialog;
+  } // createDialog()
+
+  /**
+   * This method returns the UI Component used for this JColorChooser.
+   *
+   * @return The UI Component for this JColorChooser.
+   */
+  public ColorChooserUI getUI()
+  {
+    return (ColorChooserUI) ui;
+  } // getUI()
+
+  /**
+   * This method sets the UI Component used for this JColorChooser.
+   *
+   * @param ui The UI Component to use with this JColorChooser.
+   */
+  public void setUI(ColorChooserUI ui)
+  {
+    super.setUI(ui);
+  } // setUI()
+
+  /**
+   * This method resets the UI Component property to the Look and Feel
+   * default.
+   */
+  public void updateUI()
+  {
+    setUI((ColorChooserUI) UIManager.getUI(this));
+    revalidate();
+  } // updateUI()
+
+  /**
+   * This method returns a String identifier for the UI Class to be used with
+   * the JColorChooser.
+   *
+   * @return The String identifier for the UI Class.
+   */
+  public String getUIClassID()
+  {
+    return "ColorChooserUI";
+  } // getUIClassID()
+
+  /**
+   * This method returns the current color for the JColorChooser.
+   *
+   * @return The current color for the JColorChooser.
+   */
+  public Color getColor()
+  {
+    return selectionModel.getSelectedColor(); // TODO
+  } // getColor()
+
+  /**
+   * This method changes the previewPanel property for the JTabbedPane. The
+   * previewPanel is responsible for indicating the current color of the
+   * JColorChooser.
+   *
+   * @param component The Component that will act as the previewPanel.
+   */
+  public void setPreviewPanel(JComponent component)
+  {
+    if (component != previewPanel)
+      {
+	JComponent old = previewPanel;
+	previewPanel = component;
+	firePropertyChange(PREVIEW_PANEL_PROPERTY, old, previewPanel);
+      }
+  } // setPreviewPanel()
+
+  /**
+   * This method returns the current previewPanel used with this
+   * JColorChooser.
+   *
+   * @return The current previewPanel.
+   */
+  public JComponent getPreviewPanel()
+  {
+    return previewPanel; // TODO
+  } // getPreviewPanel()
+
+  /**
+   * This method adds the given AbstractColorChooserPanel to the list of the
+   * JColorChooser's chooserPanels.
+   *
+   * @param panel The AbstractColorChooserPanel to add.
+   */
+  public void addChooserPanel(AbstractColorChooserPanel panel)
+  {
+    if (panel == null)
+      return;
+    AbstractColorChooserPanel[] old = chooserPanels;
+    AbstractColorChooserPanel[] newPanels = new AbstractColorChooserPanel[(old == null)
+                                                                          ? 1
+                                                                          : old.length
+                                                                          + 1];
+    if (old != null)
+      System.arraycopy(old, 0, newPanels, 0, old.length);
+    newPanels[newPanels.length - 1] = panel;
+    chooserPanels = newPanels;
+    panel.installChooserPanel(this);
+    firePropertyChange(CHOOSER_PANELS_PROPERTY, old, newPanels);
+  } // addChooserPanel()
+
+  /**
+   * This method removes the given AbstractColorChooserPanel from the
+   * JColorChooser's list of chooserPanels.
+   *
+   * @param panel The AbstractColorChooserPanel to remove.
+   *
+   * @return The AbstractColorChooserPanel that was removed.
+   */
+  public AbstractColorChooserPanel removeChooserPanel(AbstractColorChooserPanel panel)
+  {
+    int index = -1;
+    for (int i = 0; i < chooserPanels.length; i++)
+      if (panel == chooserPanels[i])
+        {
+	  index = i;
+	  break;
+        }
+
+    if (index == -1)
+      return null;
+
+    AbstractColorChooserPanel[] old = chooserPanels;
+    if (chooserPanels.length == 1)
+      chooserPanels = null;
+    else
+      {
+	AbstractColorChooserPanel[] newPanels = new AbstractColorChooserPanel[chooserPanels.length
+	                                        - 1];
+	System.arraycopy(chooserPanels, 0, newPanels, 0, index);
+	System.arraycopy(chooserPanels, index, newPanels, index - 1,
+	                 chooserPanels.length - index);
+	chooserPanels = newPanels;
+      }
+    panel.uninstallChooserPanel(this);
+    firePropertyChange(CHOOSER_PANELS_PROPERTY, old, chooserPanels);
+    return panel;
+  }
+
+  /**
+   * This method sets the chooserPanels property for this JColorChooser.
+   *
+   * @param panels The new set of AbstractColorChooserPanels to use.
+   */
+  public void setChooserPanels(AbstractColorChooserPanel[] panels)
+  {
+    if (panels != chooserPanels)
+      {
+	if (chooserPanels != null)
+	  for (int i = 0; i < chooserPanels.length; i++)
+	    if (chooserPanels[i] != null)
+	      chooserPanels[i].uninstallChooserPanel(this);
+
+	AbstractColorChooserPanel[] old = chooserPanels;
+	chooserPanels = panels;
+
+	if (panels != null)
+	  for (int i = 0; i < panels.length; i++)
+	    if (panels[i] != null)
+	      panels[i].installChooserPanel(this);
+
+	firePropertyChange(CHOOSER_PANELS_PROPERTY, old, chooserPanels);
+      }
+  } // setChooserPanels()
+
+  /**
+   * This method returns the AbstractColorChooserPanels used with this
+   * JColorChooser.
+   *
+   * @return The AbstractColorChooserPanels used with this JColorChooser.
+   */
+  public AbstractColorChooserPanel[] getChooserPanels()
+  {
+    return chooserPanels;
+  } // getChooserPanels()
+
+  /**
+   * This method returns the ColorSelectionModel used with this JColorChooser.
+   *
+   * @return The ColorSelectionModel.
+   */
+  public ColorSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  } // getSelectionModel()
+
+  /**
+   * This method sets the ColorSelectionModel to be used with this
+   * JColorChooser.
+   *
+   * @param model The ColorSelectionModel to be used with this JColorChooser.
+   *
+   * @throws AWTError If the given model is null.
+   */
+  public void setSelectionModel(ColorSelectionModel model)
+  {
+    if (model == null)
+      throw new AWTError("ColorSelectionModel is not allowed to be null.");
+    selectionModel = model;
+  } // setSelectionModel()
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean getDragEnabled()
+  {
+    return dragEnabled;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  public void setDragEnabled(boolean b)
+  {
+    dragEnabled = b;
+  }
+
+  /**
+   * This method returns a String describing the JColorChooser.
+   *
+   * @return A String describing the JColorChooser.
+   */
+  protected String paramString()
+  {
+    return "JColorChooser";
+  } // paramString()
+
+  /**
+   * getAccessibleContext
+   *
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJColorChooser();
+
+    return accessibleContext;
+  }
+
+  /**
+   * A helper class that hides a JDialog when the action is performed.
+   */
+  static class DefaultOKCancelListener implements ActionListener
+  {
+    /** The JDialog to hide. */
+    private JDialog dialog;
+
+    /**
+     * Creates a new DefaultOKCancelListener with the given JDialog to hide.
+     *
+     * @param dialog The JDialog to hide.
+     */
+    public DefaultOKCancelListener(JDialog dialog)
+    {
+      super();
+      this.dialog = dialog;
+    }
+
+    /**
+     * This method hides the JDialog when called.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      dialog.hide();
+    }
+  }
+
+  /**
+   * This method resets the JColorChooser color to the initial color when the
+   * action is performed.
+   */
+  static class DefaultResetListener implements ActionListener
+  {
+    /** The JColorChooser to reset. */
+    private JColorChooser chooser;
+
+    /** The initial color. */
+    private Color init;
+
+    /**
+     * Creates a new DefaultResetListener with the given JColorChooser.
+     *
+     * @param chooser The JColorChooser to reset.
+     */
+    public DefaultResetListener(JColorChooser chooser)
+    {
+      super();
+      this.chooser = chooser;
+      init = chooser.getColor();
+    }
+
+    /**
+     * This method resets the JColorChooser to its initial color.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      chooser.setColor(init);
+    }
+  }
+
+  /**
+   * This is a custom JDialog that will notify when it is hidden and the modal
+   * property is set.
+   */
+  static class ModalDialog extends JDialog
+  {
+    /** The modal property. */
+    private boolean modal;
+
+    /**
+     * Creates a new ModalDialog object with the given parent and title.
+     *
+     * @param parent The parent of the JDialog.
+     * @param title The title of the JDialog.
+     */
+    public ModalDialog(Frame parent, String title)
+    {
+      super(parent, title);
+    }
+
+    /**
+     * Creates a new ModalDialog object with the given parent and title.
+     *
+     * @param parent The parent of the JDialog.
+     * @param title The title of the JDialog.
+     */
+    public ModalDialog(Dialog parent, String title)
+    {
+      super(parent, title);
+    }
+
+    /**
+     * This method sets the modal property.
+     *
+     * @param modal The modal property.
+     */
+    public void setModal(boolean modal)
+    {
+      this.modal = modal;
+    }
+
+    /**
+     * This method shows the ModalDialog.
+     */
+    public void show()
+    {
+      super.show();
+      if (modal)
+	makeModal(this);
+    }
+
+    /**
+     * This method hides the ModalDialog.
+     */
+    public synchronized void hide()
+    {
+      super.hide();
+      notifyAll();
+    }
+  }
+}
Index: javax/swing/JComboBox.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JComboBox.java,v
retrieving revision 1.3
diff -u -r1.3 JComboBox.java
--- javax/swing/JComboBox.java	12 Oct 2003 13:20:49 -0000	1.3
+++ javax/swing/JComboBox.java	6 Sep 2004 16:35:54 -0000
@@ -1,5 +1,5 @@
 /* JComboBox.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,805 +35,1139 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
-import java.awt.*;
-import java.awt.event.*;
-import java.beans.*;
-import java.io.*;
-import java.util.*;
-import javax.accessibility.*;
-import javax.swing.event.*;
-import javax.swing.plaf.*;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.ItemSelectable;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Vector;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.swing.JComponent;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.ComboBoxUI;
+
 
 /**
- * JComboBox
- * @author	Andrew Selkirk
- * @version	1.0
+ * JComboBox. JComboBox is a container, that keeps track of elements added to
+ * it by the user. JComboBox allows user to select any item in its list and
+ * displays the selected item to the user. JComboBox also can show/hide popup
+ * menu containing its list of item whenever the mouse is pressed over it.
+ *
+ * @author Andrew Selkirk
+ * @author Olga Rodimina
  */
-public class JComboBox extends JComponent
-  implements ItemSelectable, ListDataListener, ActionListener, Accessible
+public class JComboBox extends JComponent implements ItemSelectable,
+                                                     ListDataListener,
+                                                     ActionListener,
+                                                     Accessible
 {
   private static final long serialVersionUID = 5654585963292734470L;
 
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJComboBox
-	 */
-	protected class AccessibleJComboBox extends AccessibleJComponent 
-			implements AccessibleAction, AccessibleSelection {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJComboBox
-		 * @param component TODO
-		 */
-		protected AccessibleJComboBox(JComboBox component) {
-			super(component);
-			// TODO
-		} // AccessibleJComboBox()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleChildrenCount
-		 * @returns int
-		 */
-		public int getAccessibleChildrenCount() {
-			return 0; // TODO
-		} // getAccessibleChildrenCount()
-
-		/**
-		 * getAccessibleChild
-		 * @param value0 TODO
-		 * @returns Accessible
-		 */
-		public Accessible getAccessibleChild(int value0) {
-			return null; // TODO
-		} // getAccessibleChild()
-
-		/**
-		 * getAccessibleSelection
-		 * @returns AccessibleSelection
-		 */
-		public AccessibleSelection getAccessibleSelection() {
-			return null; // TODO
-		} // getAccessibleSelection()
-
-		/**
-		 * getAccessibleSelection
-		 * @param value0 TODO
-		 * @returns Accessible
-		 */
-		public Accessible getAccessibleSelection(int value0) {
-			return null; // TODO
-		} // getAccessibleSelection()
-
-		/**
-		 * isAccessibleChildSelected
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean isAccessibleChildSelected(int value0) {
-			return false; // TODO
-		} // isAccessibleChildSelected()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.COMBO_BOX;
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleAction
-		 * @returns AccessibleAction
-		 */
-		public AccessibleAction getAccessibleAction() {
-			return null; // TODO
-		} // getAccessibleAction()
-
-		/**
-		 * getAccessibleActionDescription
-		 * @param value0 TODO
-		 * @returns String
-		 */
-		public String getAccessibleActionDescription(int value0) {
-			return null; // TODO
-		} // getAccessibleActionDescription()
-
-		/**
-		 * getAccessibleActionCount
-		 * @returns int
-		 */
-		public int getAccessibleActionCount() {
-			return 0; // TODO
-		} // getAccessibleActionCount()
-
-		/**
-		 * doAccessibleAction
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean doAccessibleAction(int value0) {
-			return false; // TODO
-		} // doAccessibleAction()
-
-		/**
-		 * getAccessibleSelectionCount
-		 * @returns int
-		 */
-		public int getAccessibleSelectionCount() {
-			return 0; // TODO
-		} // getAccessibleSelectionCount()
-
-		/**
-		 * addAccessibleSelection
-		 * @param value0 TODO
-		 */
-		public void addAccessibleSelection(int value0) {
-			// TODO
-		} // addAccessibleSelection()
-
-		/**
-		 * removeAccessibleSelection
-		 * @param value0 TODO
-		 */
-		public void removeAccessibleSelection(int value0) {
-			// TODO
-		} // removeAccessibleSelection()
-
-		/**
-		 * clearAccessibleSelection
-		 */
-		public void clearAccessibleSelection() {
-			// TODO
-		} // clearAccessibleSelection()
-
-		/**
-		 * selectAllAccessibleSelection
-		 */
-		public void selectAllAccessibleSelection() {
-			// TODO
-		} // selectAllAccessibleSelection()
-
-
-	} // AccessibleJComboBox
-
-	/**
-	 * KeySelectionManager
-	 */
-	public static interface KeySelectionManager {
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * selectionForKey
-		 * @param value0 TODO
-		 * @param value1 TODO
-		 * @returns int
-		 */
-		int selectionForKey(char value0, ComboBoxModel value1);
-
-
-	} // KeySelectionManager
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "ComboBoxUI";
-
-	/**
-	 * dataModel
-	 */
-	protected ComboBoxModel dataModel;
-
-	/**
-	 * renderer
-	 */
-	protected ListCellRenderer renderer;
-
-	/**
-	 * editor
-	 */
-	protected ComboBoxEditor editor;
-
-	/**
-	 * maximumRowCount
-	 */
-	protected int maximumRowCount;
-
-	/**
-	 * isEditable
-	 */
-	protected boolean isEditable;
-
-	/**
-	 * selectedItemReminder
-	 */
-	protected Object selectedItemReminder;
-
-	/**
-	 * keySelectionManager
-	 */
-	protected JComboBox.KeySelectionManager keySelectionManager;
-
-	/**
-	 * actionCommand
-	 */
-	protected String actionCommand;
-
-	/**
-	 * lightWeightPopupEnabled
-	 */
-	protected boolean lightWeightPopupEnabled;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JComboBox
-	 * @param value0 TODO
-	 */
-	public JComboBox(ComboBoxModel value0) {
-		// TODO
-	} // JComboBox()
-
-	/**
-	 * Constructor JComboBox
-	 * @param value0 TODO
-	 */
-	public JComboBox(Object[] value0) {
-		// TODO
-	} // JComboBox()
-
-	/**
-	 * Constructor JComboBox
-	 * @param value0 TODO
-	 */
-	public JComboBox(Vector value0) {
-		// TODO
-	} // JComboBox()
-
-	/**
-	 * Constructor JComboBox
-	 */
-	public JComboBox() {
-		// TODO
-	} // JComboBox()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * isEditable
-	 * @returns boolean
-	 */
-	public boolean isEditable() {
-		return false; // TODO
-	} // isEditable()
-
-	/**
-	 * installAncestorListener
-	 */
-	protected void installAncestorListener() {
-		// TODO
-	} // installAncestorListener()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(ComboBoxUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((ComboBoxUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getUI
-	 * @returns ComboBoxUI
-	 */
-	public ComboBoxUI getUI() {
-		return (ComboBoxUI) ui;
-	} // getUI()
-
-	/**
-	 * setModel
-	 * @param value0 TODO
-	 */
-	public void setModel(ComboBoxModel value0) {
-		// TODO
-	} // setModel()
-
-	/**
-	 * getModel
-	 * @returns ComboBoxModel
-	 */
-	public ComboBoxModel getModel() {
-		return null; // TODO
-	} // getModel()
-
-	/**
-	 * setLightWeightPopupEnabled
-	 * @param value0 TODO
-	 */
-	public void setLightWeightPopupEnabled(boolean value0) {
-		// TODO
-	} // setLightWeightPopupEnabled()
-
-	/**
-	 * isLightWeightPopupEnabled
-	 * @returns boolean
-	 */
-	public boolean isLightWeightPopupEnabled() {
-		return false; // TODO
-	} // isLightWeightPopupEnabled()
-
-	/**
-	 * setEditable
-	 * @param value0 TODO
-	 */
-	public void setEditable(boolean value0) {
-		// TODO
-	} // setEditable()
-
-	/**
-	 * setMaximumRowCount
-	 * @param value0 TODO
-	 */
-	public void setMaximumRowCount(int value0) {
-		// TODO
-	} // setMaximumRowCount()
-
-	/**
-	 * getMaximumRowCount
-	 * @returns int
-	 */
-	public int getMaximumRowCount() {
-		return 0; // TODO
-	} // getMaximumRowCount()
-
-	/**
-	 * setRenderer
-	 * @param value0 TODO
-	 */
-	public void setRenderer(ListCellRenderer value0) {
-		// TODO
-	} // setRenderer()
-
-	/**
-	 * getRenderer
-	 * @returns ListCellRenderer
-	 */
-	public ListCellRenderer getRenderer() {
-		return null; // TODO
-	} // getRenderer()
-
-	/**
-	 * setEditor
-	 * @param value0 TODO
-	 */
-	public void setEditor(ComboBoxEditor value0) {
-		// TODO
-	} // setEditor()
-
-	/**
-	 * getEditor
-	 * @returns ComboBoxEditor
-	 */
-	public ComboBoxEditor getEditor() {
-		return null; // TODO
-	} // getEditor()
-
-	/**
-	 * setSelectedItem
-	 * @param value0 TODO
-	 */
-	public void setSelectedItem(Object value0) {
-		// TODO
-	} // setSelectedItem()
-
-	/**
-	 * getSelectedItem
-	 * @returns Object
-	 */
-	public Object getSelectedItem() {
-		return null; // TODO
-	} // getSelectedItem()
-
-	/**
-	 * setSelectedIndex
-	 * @param value0 TODO
-	 */
-	public void setSelectedIndex(int value0) {
-		// TODO
-	} // setSelectedIndex()
-
-	/**
-	 * getSelectedIndex
-	 * @returns int
-	 */
-	public int getSelectedIndex() {
-		return 0; // TODO
-	} // getSelectedIndex()
-
-	/**
-	 * addItem
-	 * @param value0 TODO
-	 */
-	public void addItem(Object value0) {
-		// TODO
-	} // addItem()
-
-	/**
-	 * insertItemAt
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void insertItemAt(Object value0, int value1) {
-		// TODO
-	} // insertItemAt()
-
-	/**
-	 * removeItem
-	 * @param value0 TODO
-	 */
-	public void removeItem(Object value0) {
-		// TODO
-	} // removeItem()
-
-	/**
-	 * removeItemAt
-	 * @param value0 TODO
-	 */
-	public void removeItemAt(int value0) {
-		// TODO
-	} // removeItemAt()
-
-	/**
-	 * removeAllItems
-	 */
-	public void removeAllItems() {
-		// TODO
-	} // removeAllItems()
-	
-	/**
-	 * showPopup
-	 */
-	public void showPopup() {
-		// TODO
-	} // showPopup()
-
-	/**
-	 * hidePopup
-	 */
-	public void hidePopup() {
-		// TODO
-	} // hidePopup()
-
-	/**
-	 * setPopupVisible
-	 * @param value0 TODO
-	 */
-	public void setPopupVisible(boolean value0) {
-		// TODO
-	} // setPopupVisible()
-
-	/**
-	 * isPopupVisible
-	 * @returns boolean
-	 */
-	public boolean isPopupVisible() {
-		return false; // TODO
-	} // isPopupVisible()
-
-	/**
-	 * addItemListener
-	 * @param value0 TODO
-	 */
-	public void addItemListener(ItemListener value0) {
-		// TODO
-	} // addItemListener()
-
-	/**
-	 * removeItemListener
-	 * @param value0 TODO
-	 */
-	public void removeItemListener(ItemListener value0) {
-		// TODO
-	} // removeItemListener()
-
-	/**
-	 * addActionListener
-	 * @param value0 TODO
-	 */
-	public void addActionListener(ActionListener value0) {
-		// TODO
-	} // addActionListener()
-
-	/**
-	 * removeActionListener
-	 * @param value0 TODO
-	 */
-	public void removeActionListener(ActionListener value0) {
-		// TODO
-	} // removeActionListener()
-
-	/**
-	 * setActionCommand
-	 * @param value0 TODO
-	 */
-	public void setActionCommand(String value0) {
-		// TODO
-	} // setActionCommand()
-
-	/**
-	 * getActionCommand
-	 * @returns String
-	 */
-	public String getActionCommand() {
-		return null; // TODO
-	} // getActionCommand()
-
-	/**
-	 * setAction
-	 * @param value0 TODO
-	 */
-	public void setAction(Action value0) {
-		// TODO
-	} // setAction()
-
-	/**
-	 * isListener
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @returns boolean
-	 */
-	private boolean isListener(Class value0, ActionListener value1) {
-		return false; // TODO
-	} // isListener()
-
-	/**
-	 * getAction
-	 * @returns Action
-	 */
-	public Action getAction() {
-		return null; // TODO
-	} // getAction()
-
-	/**
-	 * configurePropertiesFromAction
-	 * @param value0 TODO
-	 */
-	protected void configurePropertiesFromAction(Action value0) {
-		// TODO
-	} // configurePropertiesFromAction()
-
-	/**
-	 * createActionPropertyChangeListener
-	 * @param value0 TODO
-	 * @returns PropertyChangeListener
-	 */
-	protected PropertyChangeListener createActionPropertyChangeListener(Action value0) {
-		return null; // TODO
-	} // createActionPropertyChangeListener()
-
-	/**
-	 * fireItemStateChanged
-	 * @param value0 TODO
-	 */
-	protected void fireItemStateChanged(ItemEvent value0) {
-		// TODO
-	} // fireItemStateChanged()
-
-	/**
-	 * fireActionEvent
-	 */
-	protected void fireActionEvent() {
-		// TODO
-	} // fireActionEvent()
-
-	/**
-	 * selectedItemChanged
-	 */
-	protected void selectedItemChanged() {
-		// TODO
-	} // selectedItemChanged()
-
-	/**
-	 * getSelectedObjects
-	 * @returns Object[]
-	 */
-	public Object[] getSelectedObjects() {
-		return null; // TODO
-	} // getSelectedObjects()
-
-	/**
-	 * actionPerformed
-	 * @param value0 TODO
-	 */
-	public void actionPerformed(ActionEvent value0) {
-		// TODO
-	} // actionPerformed()
-
-	/**
-	 * contentsChanged
-	 * @param value0 TODO
-	 */
-	public void contentsChanged(ListDataEvent value0) {
-		// TODO
-	} // contentsChanged()
-
-	/**
-	 * selectWithKeyChar
-	 * @param value0 TODO
-	 * @returns boolean
-	 */
-	public boolean selectWithKeyChar(char value0) {
-		return false; // TODO
-	} // selectWithKeyChar()
-
-	/**
-	 * intervalAdded
-	 * @param value0 TODO
-	 */
-	public void intervalAdded(ListDataEvent value0) {
-		// TODO
-	} // intervalAdded()
-
-	/**
-	 * intervalRemoved
-	 * @param value0 TODO
-	 */
-	public void intervalRemoved(ListDataEvent value0) {
-		// TODO
-	} // intervalRemoved()
-
-	/**
-	 * setEnabled
-	 * @param value0 TODO
-	 */
-	public void setEnabled(boolean value0) {
-		// TODO
-	} // setEnabled()
-
-	/**
-	 * configureEditor
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void configureEditor(ComboBoxEditor value0, Object value1) {
-		// TODO
-	} // configureEditor()
-
-	/**
-	 * processKeyEvent
-	 * @param value0 TODO
-	 */
-	public void processKeyEvent(KeyEvent value0) {
-		// TODO
-	} // processKeyEvent()
-
-	/**
-	 * isFocusTraversable
-	 * @returns boolean
-         * @deprecated
-	 */
-	public boolean isFocusTraversable() {
-		return false; // TODO
-	} // isFocusTraversable()
-
-	/**
-	 * setKeySelectionManager
-	 * @param value0 TODO
-	 */
-	public void setKeySelectionManager(KeySelectionManager value0) {
-		// TODO
-	} // setKeySelectionManager()
-
-	/**
-	 * getKeySelectionManager
-	 * @returns JComboBox.KeySelectionManager
-	 */
-	public JComboBox.KeySelectionManager getKeySelectionManager() {
-		return null; // TODO
-	} // getKeySelectionManager()
-
-	/**
-	 * getItemCount
-	 * @returns int
-	 */
-	public int getItemCount() {
-		return 0; // TODO
-	} // getItemCount()
-
-	/**
-	 * getItemAt
-	 * @param value0 TODO
-	 * @returns Object
-	 */
-	public Object getItemAt(int value0) {
-		return null; // TODO
-	} // getItemAt()
-
-	/**
-	 * createDefaultKeySelectionManager
-	 * @returns KeySelectionManager
-	 */
-	protected KeySelectionManager createDefaultKeySelectionManager() {
-		return null; // TODO
-	} // createDefaultKeySelectionManager()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJComboBox(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JComboBox
+  /**
+   * KeySelectionManager interface. Class implementing this interface are
+   * responsible for matching key characters typed by the user with combo
+   * box's items.
+   */
+  public static interface KeySelectionManager
+  {
+    int selectionForKey(char aKey, ComboBoxModel aModel);
+  }
+
+  /**
+   * Maximum number of rows that should be visible by default  in the
+   * JComboBox's popup
+   */
+  public static final int DEFAULT_MAXIMUM_ROW_COUNT = 8;
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'editable' property changes.
+   */
+  public static final String EDITABLE_CHANGED_PROPERTY = "editable";
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'maximumRowCount' property
+   * changes.
+   */
+  public static final String MAXIMUM_ROW_COUNT_CHANGED_PROPERTY = "maximumRowCount";
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'enabled' property changes.
+   */
+  public static final String ENABLED_CHANGED_PROPERTY = "enabled";
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'renderer' property changes.
+   */
+  public static final String RENDERER_CHANGED_PROPERTY = "renderer";
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'editor' property changes.
+   */
+  public static final String EDITOR_CHANGED_PROPERTY = "editor";
+
+  /**
+   * Fired in a PropertyChangeEvent when the 'dataModel' property changes.
+   */
+  public static final String MODEL_CHANGED_PROPERTY = "dataModel";
+
+  /**
+   * name for the UI delegate for this combo box.
+   */
+  private static final String uiClassID = "ComboBoxUI";
+
+  /**
+   * dataModel used by JComboBox to keep track of its list data and currently
+   * selected element in the list.
+   */
+  protected ComboBoxModel dataModel;
+
+  /**
+   * Renderer renders(paints) every object in the combo box list in its
+   * associated list cell. This ListCellRenderer is used only when  this
+   * JComboBox is uneditable.
+   */
+  protected ListCellRenderer renderer;
+
+  /**
+   * editor that is responsible for editting an object in a combo box list
+   */
+  protected ComboBoxEditor editor;
+
+  /**
+   * Number of rows that will be visible in the JComboBox's popup.
+   */
+  protected int maximumRowCount;
+
+  /**
+   * This field indicates if textfield of this JComboBox is editable or not.
+   */
+  protected boolean isEditable;
+
+  /**
+   * This field is reference to the current selection of the combo box.
+   */
+  protected Object selectedItemReminder;
+
+  /**
+   * keySelectionManager
+   */
+  protected KeySelectionManager keySelectionManager;
+
+  /**
+   * This actionCommand is used in ActionEvent that is fired to JComboBox's
+   * ActionListeneres.
+   */
+  protected String actionCommand;
+
+  /**
+   * This property indicates if heavyweight popup or lightweight popup will be
+   * used to diplay JComboBox's elements.
+   */
+  protected boolean lightWeightPopupEnabled;
+
+  /**
+   * The action taken when new item is selected in the JComboBox
+   */
+  private Action action;
+
+  /**
+   * since 1.4  If this field is set then comboBox's display area for the
+   * selected item  will be set by default to this value.
+   */
+  private Object prototypeDisplayValue;
+
+  /**
+   * Constructs JComboBox object with specified data model for it. The first
+   * item in the specified data model is selected by default.
+   *
+   * @param model Data model that will be used by this JComboBox to keep track
+   *        of its list of items.
+   */
+  public JComboBox(ComboBoxModel model)
+  {
+    setEditable(false);
+    setEnabled(true);
+    setMaximumRowCount(DEFAULT_MAXIMUM_ROW_COUNT);
+    setModel(model);
+    setActionCommand("comboBoxChanged");
+
+    // by default set selected item to the first element in the combo box    
+    if (getItemCount() != 0)
+      setSelectedItem(getItemAt(0));
+
+    lightWeightPopupEnabled = true;
+    isEditable = false;
+
+    updateUI();
+  }
+
+  /**
+   * Constructs JComboBox with specified list of items.
+   *
+   * @param itemArray array containing list of items for this JComboBox
+   */
+  public JComboBox(Object[] itemArray)
+  {
+    this(new DefaultComboBoxModel(itemArray));
+  }
+
+  /**
+   * Constructs JComboBox object with specified list of items.
+   *
+   * @param itemVector vector containing list of items for this JComboBox.
+   */
+  public JComboBox(Vector itemVector)
+  {
+    this(new DefaultComboBoxModel(itemVector));
+  }
+
+  /**
+   * Constructor. Creates new empty JComboBox. ComboBox's data model is set to
+   * DefaultComboBoxModel.
+   */
+  public JComboBox()
+  {
+    this(new DefaultComboBoxModel());
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * This method returns true JComboBox is editable and false otherwise
+   *
+   * @return boolean true if JComboBox is editable and false otherwise
+   */
+  public boolean isEditable()
+  {
+    return isEditable;
+  }
+
+  /*
+   * This method adds ancestor listener to this JComboBox.
+   */
+  protected void installAncestorListener()
+  {
+    /* FIXME: Need to implement.
+     *
+     * Need to add ancestor listener to this JComboBox. This listener
+     * should close combo box's popup list of items whenever it
+     * receives an AncestorEvent.
+     */
+  }
+
+  /**
+   * Set the "UI" property of the combo box, which is a look and feel class
+   * responsible for handling comboBox's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(ComboBoxUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets this comboBox's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((ComboBoxUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns the String identifier for the UI class to the used
+   * with the JComboBox.
+   *
+   * @return The String identifier for the UI class.
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * This method returns the UI used to display the JComboBox.
+   *
+   * @return The UI used to display the JComboBox.
+   */
+  public ComboBoxUI getUI()
+  {
+    return (ComboBoxUI) ui;
+  }
+
+  /**
+   * Set the data model for this JComboBox. This un-registers all  listeners
+   * associated with the current model, and re-registers them with the new
+   * model.
+   *
+   * @param newDataModel The new data model for this JComboBox
+   */
+  public void setModel(ComboBoxModel newDataModel)
+  {
+    if (this.dataModel == newDataModel)
+      return;
+
+    if (this.dataModel != null)
+      // remove all listeners currently registered with the model.
+      dataModel.removeListDataListener(this);
+
+    ComboBoxModel oldDataModel = this.dataModel;
+    this.dataModel = newDataModel;
+
+    if (this.dataModel != null)
+      // register all listeners with the new data model
+      dataModel.addListDataListener(this);
+
+    firePropertyChange(MODEL_CHANGED_PROPERTY, oldDataModel, this.dataModel);
+  }
+
+  /**
+   * This method returns data model for this comboBox.
+   *
+   * @return ComboBoxModel containing items for this combo box.
+   */
+  public ComboBoxModel getModel()
+  {
+    return dataModel;
+  }
+
+  /**
+   * This method sets JComboBox's popup to be either lightweight or
+   * heavyweight. If 'enabled' is true then lightweight popup is  used and
+   * heavyweight otherwise. By default lightweight popup is  used to display
+   * this JComboBox's elements.
+   *
+   * @param enabled indicates if lightweight popup or heavyweight popup should
+   *        be used to display JComboBox's elements.
+   */
+  public void setLightWeightPopupEnabled(boolean enabled)
+  {
+    this.lightWeightPopupEnabled = enabled;
+  }
+
+  /**
+   * This method returns whether popup menu that is used to display list of
+   * combo box's item is lightWeight or not.
+   *
+   * @return boolean true if popup menu is lightweight and false otherwise.
+   */
+  public boolean isLightWeightPopupEnabled()
+  {
+    return lightWeightPopupEnabled;
+  }
+
+  /**
+   * This method sets editability of the combo box. If combo box  is editable
+   * the user can choose component from the combo box list by typing
+   * component's name in the editor(JTextfield by default).  Otherwise if not
+   * editable, the user should use the list to choose   the component. This
+   * method fires PropertyChangeEvents to JComboBox's registered
+   * PropertyChangeListeners to indicate that 'editable' property of the
+   * JComboBox has changed.
+   *
+   * @param editable indicates if the JComboBox's textfield should be editable
+   *        or not.
+   */
+  public void setEditable(boolean editable)
+  {
+    if (this.isEditable != editable)
+      {
+	this.isEditable = editable;
+	firePropertyChange(EDITABLE_CHANGED_PROPERTY, ! isEditable, isEditable);
+      }
+  }
+
+  /**
+   * Sets number of rows that should be visible in this JComboBox's popup. If
+   * this JComboBox's popup has more elements that maximum number or rows
+   * then popup will have a scroll pane to allow users to view other
+   * elements.
+   *
+   * @param rowCount number of rows that will be visible in JComboBox's popup.
+   */
+  public void setMaximumRowCount(int rowCount)
+  {
+    if (maximumRowCount != rowCount)
+      {
+	int oldMaximumRowCount = this.maximumRowCount;
+	this.maximumRowCount = rowCount;
+	firePropertyChange(MAXIMUM_ROW_COUNT_CHANGED_PROPERTY,
+	                   oldMaximumRowCount, this.maximumRowCount);
+      }
+  }
+
+  /**
+   * This method returns number of rows visible in the JComboBox's list of
+   * items.
+   *
+   * @return int maximun number of visible rows in the JComboBox's list.
+   */
+  public int getMaximumRowCount()
+  {
+    return maximumRowCount;
+  }
+
+  /**
+   * This method sets cell renderer for this JComboBox that will be used to
+   * paint combo box's items. The Renderer should only be used only when
+   * JComboBox is not editable.  In the case when JComboBox is editable  the
+   * editor must be used.  This method also fires PropertyChangeEvent when
+   * cellRendered for this JComboBox has changed.
+   *
+   * @param aRenderer cell renderer that will be used by this JComboBox to
+   *        paint its elements.
+   */
+  public void setRenderer(ListCellRenderer aRenderer)
+  {
+    if (this.renderer != aRenderer)
+      {
+	ListCellRenderer oldRenderer = this.renderer;
+	this.renderer = aRenderer;
+	firePropertyChange(RENDERER_CHANGED_PROPERTY, oldRenderer,
+	                   this.renderer);
+      }
+  }
+
+  /**
+   * This method returns renderer responsible for rendering selected item in
+   * the combo box
+   *
+   * @return ListCellRenderer
+   */
+  public ListCellRenderer getRenderer()
+  {
+    return renderer;
+  }
+
+  /**
+   * Sets editor for this JComboBox
+   *
+   * @param newEditor ComboBoxEditor for this JComboBox. This method fires
+   *        PropertyChangeEvent when 'editor' property is changed.
+   */
+  public void setEditor(ComboBoxEditor newEditor)
+  {
+    if (editor == newEditor)
+      return;
+
+    if (editor != null)
+      editor.removeActionListener(this);
+
+    ComboBoxEditor oldEditor = editor;
+    editor = newEditor;
+
+    if (editor != null)
+      editor.addActionListener(this);
+
+    firePropertyChange(EDITOR_CHANGED_PROPERTY, oldEditor, editor);
+  }
+
+  /**
+   * Returns editor component that is responsible for displaying/editting
+   * selected item in the combo box.
+   *
+   * @return ComboBoxEditor
+   */
+  public ComboBoxEditor getEditor()
+  {
+    return editor;
+  }
+
+  /**
+   * Forces combo box to select given item
+   *
+   * @param item element in the combo box to select.
+   */
+  public void setSelectedItem(Object item)
+  {
+    dataModel.setSelectedItem(item);
+  }
+
+  /**
+   * Returns currently selected item in the combo box.
+   *
+   * @return element that is currently selected in this combo box.
+   */
+  public Object getSelectedItem()
+  {
+    Object item = dataModel.getSelectedItem();
+
+    if (item == null && getItemCount() != 0)
+      item = getItemAt(0);
+
+    return item;
+  }
+
+  /**
+   * Forces JComboBox to select component located in the  given index in the
+   * combo box.
+   *
+   * @param index index specifying location of the component that  should be
+   *        selected.
+   */
+  public void setSelectedIndex(int index)
+  {
+    // FIXME: if index == -1 then nothing should be selected
+    setSelectedItem(dataModel.getElementAt(index));
+  }
+
+  /**
+   * Returns index of the item that is currently selected  in the combo box.
+   * If no item is currently selected, then -1 is returned.
+   *
+   * @return int index specifying location of the currently  selected item in
+   *         the combo box or -1 if nothing is selected in the combo box.
+   */
+  public int getSelectedIndex()
+  {
+    Object selectedItem = getSelectedItem();
+    if (selectedItem != null && (dataModel instanceof DefaultComboBoxModel))
+      return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem);
+
+    return -1;
+  }
+
+  public Object getPrototypeDisplayValue()
+  {
+    return prototypeDisplayValue;
+  }
+
+  public void setPrototypeDisplayValue(Object prototypeDisplayValue)
+  {
+    this.prototypeDisplayValue = prototypeDisplayValue;
+  }
+
+  /**
+   * This method adds given element to this JComboBox.
+   *
+   * @param element element to add
+   */
+  public void addItem(Object element)
+  {
+    ((MutableComboBoxModel) dataModel).addElement(element);
+  }
+
+  /**
+   * Inserts given element at the specified index to this JComboBox
+   *
+   * @param element element to insert
+   * @param index position where to insert the element
+   */
+  public void insertItemAt(Object element, int index)
+  {
+    ((MutableComboBoxModel) dataModel).insertElementAt(element, index);
+  }
+
+  /**
+   * This method removes given element from this JComboBox.
+   *
+   * @param element element to remove
+   */
+  public void removeItem(Object element)
+  {
+    ((MutableComboBoxModel) dataModel).removeElement(element);
+  }
+
+  /**
+   * This method remove element location in the specified index in the
+   * JComboBox.
+   *
+   * @param index index specifying position of the element to remove
+   */
+  public void removeItemAt(int index)
+  {
+    ((MutableComboBoxModel) dataModel).removeElementAt(index);
+  }
+
+  /**
+   * This method removes all elements from this JComboBox.
+   */
+  public void removeAllItems()
+  {
+    if (dataModel instanceof DefaultComboBoxModel)
+      ((DefaultComboBoxModel) dataModel).removeAllElements();
+  }
+
+  /**
+   * This method displays popup with list of combo box's items on the screen
+   */
+  public void showPopup()
+  {
+    setPopupVisible(true);
+  }
+
+  /**
+   * This method hides popup containing list of combo box's items
+   */
+  public void hidePopup()
+  {
+    setPopupVisible(false);
+  }
+
+  /**
+   * This method either displayes or hides the popup containing  list of combo
+   * box's items.
+   *
+   * @param visible show popup if 'visible' is true and hide it otherwise
+   */
+  public void setPopupVisible(boolean visible)
+  {
+    getUI().setPopupVisible(this, visible);
+  }
+
+  /**
+   * Checks if popup is currently visible on the screen.
+   *
+   * @return boolean true if popup is visible and false otherwise
+   */
+  public boolean isPopupVisible()
+  {
+    return getUI().isPopupVisible(this);
+  }
+
+  /**
+   * This method sets actionCommand to the specified string. ActionEvent fired
+   * to this JComboBox  registered ActionListeners will contain this
+   * actionCommand.
+   *
+   * @param aCommand new action command for the JComboBox's ActionEvent
+   */
+  public void setActionCommand(String aCommand)
+  {
+    actionCommand = aCommand;
+  }
+
+  /**
+   * Returns actionCommand associated with the ActionEvent fired by the
+   * JComboBox to its registered ActionListeners.
+   *
+   * @return String actionCommand for the ActionEvent
+   */
+  public String getActionCommand()
+  {
+    return actionCommand;
+  }
+
+  /**
+   * setAction
+   *
+   * @param a action to set
+   */
+  public void setAction(Action a)
+  {
+    Action old = action;
+    action = a;
+    configurePropertiesFromAction(action);
+    if (action != null)
+      // FIXME: remove from old action and add to new action 
+      // PropertyChangeListener to listen to changes in the action
+      addActionListener(action);
+  }
+
+  /**
+   * This method returns Action that is invoked when selected item is changed
+   * in the JComboBox.
+   *
+   * @return Action
+   */
+  public Action getAction()
+  {
+    return action;
+  }
+
+  /**
+   * Configure properties of the JComboBox by reading properties of specified
+   * action. This method always sets the comboBox's "enabled" property to the
+   * value of the Action's "enabled" property.
+   *
+   * @param a An Action to configure the combo box from
+   */
+  protected void configurePropertiesFromAction(Action a)
+  {
+    if (a == null)
+      {
+	setEnabled(true);
+	setToolTipText(null);
+      }
+    else
+      {
+	setEnabled(a.isEnabled());
+	setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
+      }
+  }
+
+  /**
+   * Creates PropertyChangeListener to listen for the changes in comboBox's
+   * action properties.
+   *
+   * @param action action to listen to for property changes
+   *
+   * @return $PropertyChangeListener$ Listener that listens to changes in
+   *         action properties.
+   */
+  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
+  {
+    return new PropertyChangeListener()
+      {
+	public void propertyChange(PropertyChangeEvent e)
+	{
+	  Action act = (Action) (e.getSource());
+	  configurePropertiesFromAction(act);
+	}
+      };
+  }
+
+  /**
+   * This method fires ItemEvent to this JComboBox's registered ItemListeners.
+   * This method is invoked when currently selected item in this combo box
+   * has changed.
+   *
+   * @param e the ItemEvent describing the change in the combo box's
+   *        selection.
+   */
+  protected void fireItemStateChanged(ItemEvent e)
+  {
+    ItemListener[] ll = getItemListeners();
+
+    for (int i = 0; i < ll.length; i++)
+      ll[i].itemStateChanged(e);
+  }
+
+  /**
+   * This method fires ActionEvent to this JComboBox's registered
+   * ActionListeners. This method is invoked when user explicitly changes
+   * currently selected item.
+   */
+  protected void fireActionEvent()
+  {
+    ActionListener[] ll = getActionListeners();
+
+    for (int i = 0; i < ll.length; i++)
+      ll[i].actionPerformed(new ActionEvent(this,
+                                            ActionEvent.ACTION_PERFORMED,
+                                            actionCommand));
+  }
+
+  /**
+   * This method is invoked whenever selected item changes in the combo box's
+   * data model. It fires ItemEvent and ActionEvent to all registered
+   * ComboBox's ItemListeners and ActionListeners respectively, indicating
+   * the change.
+   */
+  protected void selectedItemChanged()
+  {
+    // Fire ItemEvent to indicated that previously selected item is now
+    // deselected        
+    if (selectedItemReminder != null)
+      fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+                                         selectedItemReminder,
+                                         ItemEvent.DESELECTED));
+
+    // Fire ItemEvent to indicate that new item is selected    
+    Object newSelection = getSelectedItem();
+    fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+                                       newSelection, ItemEvent.SELECTED));
+
+    // Fire Action Event to JComboBox's registered listeners					 				 
+    fireActionEvent();
+
+    selectedItemReminder = newSelection;
+  }
+
+  /**
+   * Returns Object array of size 1 containing currently selected element in
+   * the JComboBox.
+   *
+   * @return Object[] Object array of size 1 containing currently selected
+   *         element in the JComboBox.
+   */
+  public Object[] getSelectedObjects()
+  {
+    Object selectedObject = getSelectedItem();
+    return new Object[] { selectedObject };
+  }
+
+  /**
+   * This method handles actionEvents fired by the ComboBoxEditor. It changes
+   * this JComboBox's selection to the new value currently in the editor and
+   * hides list of combo box items.
+   *
+   * @param e the ActionEvent
+   */
+  public void actionPerformed(ActionEvent e)
+  {
+    setSelectedItem(((ComboBoxEditor) e.getSource()).getItem());
+    setPopupVisible(false);
+  }
+
+  /**
+   * This method selects item in this combo box that matches specified
+   * specified keyChar and returns true if such item is found. Otherwise
+   * false is returned.
+   *
+   * @param keyChar character indicating which item in the combo box should be
+   *        selected.
+   *
+   * @return boolean true if item corresponding to the specified keyChar
+   *         exists in the combo box. Otherwise false is returned.
+   */
+  public boolean selectWithKeyChar(char keyChar)
+  {
+    // FIXME: Need to implement
+    return false;
+  }
+
+  /**
+   * The part of implementation of ListDataListener interface. This method is
+   * invoked when some items where added to the JComboBox's data model.
+   *
+   * @param event ListDataEvent describing the change
+   */
+  public void intervalAdded(ListDataEvent event)
+  {
+    // FIXME: Need to implement
+    repaint();
+  }
+
+  /**
+   * The part of implementation of ListDataListener interface. This method is
+   * invoked when some items where removed from the JComboBox's data model.
+   *
+   * @param event ListDataEvent describing the change.
+   */
+  public void intervalRemoved(ListDataEvent event)
+  {
+    // FIXME: Need to implement
+    repaint();
+  }
+
+  /**
+   * The part of implementation of ListDataListener interface. This method is
+   * invoked when contents of the JComboBox's  data model changed.
+   *
+   * @param event ListDataEvent describing the change
+   */
+  public void contentsChanged(ListDataEvent event)
+  {
+    // if first and last index of the given ListDataEvent are both -1,
+    // then it indicates that selected item in the combo box data model
+    // have changed. 
+    if (event.getIndex0() == -1 && event.getIndex1() == -1)
+      selectedItemChanged();
+  }
+
+  /**
+   * This method disables or enables JComboBox. If the JComboBox is enabled,
+   * then user is able to make item choice, otherwise if JComboBox is
+   * disabled then user is not able to make a selection.
+   *
+   * @param enabled if 'enabled' is true then enable JComboBox and disable it
+   */
+  public void setEnabled(boolean enabled)
+  {
+    boolean oldEnabled = super.isEnabled();
+    if (enabled != oldEnabled)
+      {
+	super.setEnabled(enabled);
+	firePropertyChange(ENABLED_CHANGED_PROPERTY, oldEnabled,
+	                   (boolean) enabled);
+      }
+  }
+
+  /**
+   * This method initializes specified ComboBoxEditor to display given item.
+   *
+   * @param anEditor ComboBoxEditor to initialize
+   * @param anItem Item that should displayed in the specified editor
+   */
+  public void configureEditor(ComboBoxEditor anEditor, Object anItem)
+  {
+    anEditor.setItem(anItem);
+  }
+
+  /**
+   * This method hides  combo box's popup whenever TAB key is pressed.
+   *
+   * @param e The KeyEvent indicating which key was pressed.
+   */
+  public void processKeyEvent(KeyEvent e)
+  {
+  }
+
+  /**
+   * This method always returns false to indicate that JComboBox  itself is
+   * not focus traversable.
+   *
+   * @return false to indicate that JComboBox itself is not focus traversable.
+   *
+   * @deprecated
+   */
+  public boolean isFocusTraversable()
+  {
+    return false;
+  }
+
+  /**
+   * setKeySelectionManager
+   *
+   * @param aManager
+   */
+  public void setKeySelectionManager(KeySelectionManager aManager)
+  {
+  }
+
+  /**
+   * getKeySelectionManager
+   *
+   * @return JComboBox.KeySelectionManager
+   */
+  public KeySelectionManager getKeySelectionManager()
+  {
+    return null;
+  }
+
+  /**
+   * This method returns number of elements in this JComboBox
+   *
+   * @return int number of elements in this JComboBox
+   */
+  public int getItemCount()
+  {
+    return ((DefaultComboBoxModel) dataModel).getSize();
+  }
+
+  /**
+   * Returns elements located in the combo box at the given index.
+   *
+   * @param index index specifying location of the component to  return.
+   *
+   * @return component in the combo box that is located in  the given index.
+   */
+  public Object getItemAt(int index)
+  {
+    return ((MutableComboBoxModel) dataModel).getElementAt(index);
+  }
+
+  /**
+   * createDefaultKeySelectionManager
+   *
+   * @return KeySelectionManager
+   */
+  protected KeySelectionManager createDefaultKeySelectionManager()
+  {
+    return null;
+  }
+
+  /**
+   * A string that describes this JComboBox. Normally only used for debugging.
+   *
+   * @return A string describing this JComboBox
+   */
+  protected String paramString()
+  {
+    return "JComboBox";
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJComboBox();
+
+    return accessibleContext;
+  }
+
+  /**
+   * This methods adds specified ActionListener to this JComboBox.
+   *
+   * @param listener to add
+   */
+  public void addActionListener(ActionListener listener)
+  {
+    listenerList.add(ActionListener.class, listener);
+  }
+
+  /**
+   * This method removes specified ActionListener from this JComboBox.
+   *
+   * @param listener ActionListener
+   */
+  public void removeActionListener(ActionListener listener)
+  {
+    listenerList.remove(ActionListener.class, listener);
+  }
+
+  /**
+   * This method returns array of ActionListeners that are registered with
+   * this JComboBox.
+   *
+   * @since 1.4
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) getListeners(ActionListener.class);
+  }
+
+  /**
+   * This method registers given ItemListener with this JComboBox
+   *
+   * @param listener to remove
+   */
+  public void addItemListener(ItemListener listener)
+  {
+    listenerList.add(ItemListener.class, listener);
+  }
+
+  /**
+   * This method unregisters given ItemListener from this JComboBox
+   *
+   * @param listener to remove
+   */
+  public void removeItemListener(ItemListener listener)
+  {
+    listenerList.remove(ItemListener.class, listener);
+  }
+
+  /**
+   * This method returns array of ItemListeners that are registered with this
+   * JComboBox.
+   *
+   * @since 1.4
+   */
+  public ItemListener[] getItemListeners()
+  {
+    return (ItemListener[]) getListeners(ItemListener.class);
+  }
+
+  /**
+   * Adds PopupMenuListener to combo box to listen to the events fired by the
+   * combo box's popup menu containing its list of items
+   *
+   * @param listener to add
+   */
+  public void addPopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.add(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Removes PopupMenuListener to combo box to listen to the events fired by
+   * the combo box's popup menu containing its list of items
+   *
+   * @param listener to add
+   */
+  public void removePopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.remove(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Returns array of PopupMenuListeners that are registered with  combo box.
+   */
+  public PopupMenuListener[] getPopupMenuListeners()
+  {
+    return (PopupMenuListener[]) getListeners(PopupMenuListener.class);
+  }
+
+  /**
+   * AccessibleJComboBox
+   */
+  protected class AccessibleJComboBox extends AccessibleJComponent
+    implements AccessibleAction, AccessibleSelection
+  {
+    private static final long serialVersionUID = 8217828307256675666L;
+
+    protected AccessibleJComboBox()
+    {
+    }
+
+    public int getAccessibleChildrenCount()
+    {
+      return 0;
+    }
+
+    public Accessible getAccessibleChild(int value0)
+    {
+      return null;
+    }
+
+    public AccessibleSelection getAccessibleSelection()
+    {
+      return null;
+    }
+
+    public Accessible getAccessibleSelection(int value0)
+    {
+      return null;
+    }
+
+    public boolean isAccessibleChildSelected(int value0)
+    {
+      return false;
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.COMBO_BOX;
+    }
+
+    public AccessibleAction getAccessibleAction()
+    {
+      return null;
+    }
+
+    public String getAccessibleActionDescription(int value0)
+    {
+      return null;
+    }
+
+    public int getAccessibleActionCount()
+    {
+      return 0;
+    }
+
+    public boolean doAccessibleAction(int value0)
+    {
+      return false;
+    }
+
+    public int getAccessibleSelectionCount()
+    {
+      return 0;
+    }
+
+    public void addAccessibleSelection(int value0)
+    {
+    }
+
+    public void removeAccessibleSelection(int value0)
+    {
+    }
+
+    public void clearAccessibleSelection()
+    {
+    }
+
+    public void selectAllAccessibleSelection()
+    {
+    }
+  }
+}
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JComponent.java,v
retrieving revision 1.4
diff -u -r1.4 JComponent.java
--- javax/swing/JComponent.java	19 Jun 2003 16:30:09 -0000	1.4
+++ javax/swing/JComponent.java	6 Sep 2004 16:35:55 -0000
@@ -1,5 +1,5 @@
 /* JComponent.java -- Every component in swing inherits from this class.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.AWTEvent;
@@ -46,9 +45,11 @@
 import java.awt.FlowLayout;
 import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.Image;
 import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
@@ -56,947 +57,2066 @@
 import java.awt.event.FocusListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ImageObserver;
 import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyVetoException;
 import java.beans.VetoableChangeListener;
 import java.io.Serializable;
-import java.util.Vector;
+import java.util.EventListener;
 import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
-import javax.accessibility.AccessibleExtendedComponent;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleStateSet;
+import javax.swing.border.Border;
 import javax.swing.event.AncestorListener;
 import javax.swing.event.EventListenerList;
-import javax.swing.border.Border;
+import javax.swing.event.SwingPropertyChangeSupport;
 import javax.swing.plaf.ComponentUI;
 
+
 /**
  * Every component in swing inherits from this class (JLabel, JButton, etc).
- * It contains generic methods to manage events, properties and sizes.
- * Actual drawing of the component is channeled to a look-and-feel class
- * that is implemented elsewhere.
+ * It contains generic methods to manage events, properties and sizes. Actual
+ * drawing of the component is channeled to a look-and-feel class that is
+ * implemented elsewhere.
  *
- * @author Ronald Veldema (rveldema@cs.vu.nl)
+ * @author Ronald Veldema (rveldema&064;cs.vu.nl)
+ * @author Graydon Hoare (graydon&064;redhat.com)
  */
 public abstract class JComponent extends Container implements Serializable
 {
-  static final long serialVersionUID = -5242478962609715464L;
-        /**
-         * accessibleContext
-         */
-        protected AccessibleContext accessibleContext;
-
-	Dimension pref,min,max;
-	Border border;
-	JToolTip tooltip;
-	String tool_tip_text;
-	boolean use_double_buffer, opaque;
-	protected ComponentUI ui;
-
-	Vector ancestor_list;
-	Vector veto_list;
-	Vector change_list;
-	Hashtable prop_hash;
-
-	/**
-	 * AccessibleJComponent
-	 */
-	public abstract class AccessibleJComponent 
-		extends AccessibleAWTContainer {
-
-		//-------------------------------------------------------------
-		// Classes ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * AccessibleFocusHandler
-		 */
-		protected class AccessibleFocusHandler implements FocusListener {
-			/**
-			 * Constructor AccessibleFocusHandler
-			 * @param component TODO
-			 */
-			protected AccessibleFocusHandler(AccessibleJComponent component) {
-				// TODO
-			} // AccessibleFocusHandler()
-
-			/**
-			 * focusGained
-			 * @param event TODO
-			 */
-			public void focusGained(FocusEvent event) {
-				// TODO
-			} // focusGained()
-
-			/**
-			 * focusLost
-			 * @param event TODO
-			 */
-			public void focusLost(FocusEvent valevent) {
-				// TODO
-			} // focusLost()
-		} // AccessibleFocusHandler
-
-		/**
-		 * AccessibleContainerHandler
-		 */
-		protected class AccessibleContainerHandler implements ContainerListener {
-			/**
-			 * Constructor AccessibleContainerHandler
-			 * @param component TODO
-			 */
-			protected AccessibleContainerHandler(AccessibleJComponent component) {
-				// TODO
-			} // AccessibleContainerHandler()
-
-			/**
-			 * componentAdded
-			 * @param event TODO
-			 */
-			public void componentAdded(ContainerEvent event) {
-				// TODO
-			} // componentAdded()
-
-			/**
-			 * componentRemoved
-			 * @param event TODO
-			 */
-			public void componentRemoved(ContainerEvent valevent) {
-				// TODO
-			} // componentRemoved()
-		} // AccessibleContainerHandler
-
-		/**
-		 * accessibleContainerHandler
-		 */
-		protected ContainerListener accessibleContainerHandler;
-
-		/**
-		 * accessibleFocusHandler
-		 */
-		protected FocusListener accessibleFocusHandler;
-
-		/**
-		 * Constructor AccessibleJComponent
-		 * @param component TODO
-		 */
-		protected AccessibleJComponent(JComponent component) {
-//			super((Container)component);
-			// TODO
-		} // AccessibleJComponent()
-
-		/**
-		 * addPropertyChangeListener
-		 * @param listener TODO
-		 */
-		public void addPropertyChangeListener(PropertyChangeListener listener) {
-			// TODO
-		} // addPropertyChangeListener()
-
-		/**
-		 * removePropertyChangeListener
-		 * @param listener TODO
-		 */
-		public void removePropertyChangeListener(PropertyChangeListener listener) {
-			// TODO
-		} // removePropertyChangeListener()
-
-		/**
-		 * getAccessibleChildrenCount
-		 * @returns int
-		 */
-		public int getAccessibleChildrenCount() {
-			return 0; // TODO
-		} // getAccessibleChildrenCount()
-
-		/**
-		 * getAccessibleChild
-		 * @param value0 TODO
-		 * @returns Accessible
-		 */
-		public Accessible getAccessibleChild(int value0) {
-			return null; // TODO
-		} // getAccessibleChild()
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleName
-		 * @returns String
-		 */
-		public String getAccessibleName() {
-			return null; // TODO
-		} // getAccessibleName()
-
-		/**
-		 * getAccessibleDescription
-		 * @returns String
-		 */
-		public String getAccessibleDescription() {
-			return null; // TODO
-		} // getAccessibleDescription()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return null; // TODO
-		} // getAccessibleRole()
-
-		/**
-		 * getBorderTitle
-		 * @param value0 TODO
-		 * @returns String
-		 */
-		protected String getBorderTitle(Border value0) {
-			return null; // TODO
-		} // getBorderTitle()
-
-
-	} // AccessibleJComponent
-
-
-        public JComponent()
-	{
-		super();
-		super.setLayout(new FlowLayout());
+  private static final long serialVersionUID = -7908749299918704233L;
+
+  /** 
+   * Accessibility support is currently missing.
+   */
+
+  protected AccessibleContext accessibleContext;
+
+  public abstract class AccessibleJComponent 
+    extends AccessibleAWTContainer
+  {
+    protected class AccessibleFocusHandler 
+      implements FocusListener
+    {
+      protected AccessibleFocusHandler(){}
+      public void focusGained(FocusEvent event){}
+      public void focusLost(FocusEvent valevent){}
+    }
+
+    protected class AccessibleContainerHandler 
+      implements ContainerListener
+    {
+      protected AccessibleContainerHandler() {}
+      public void componentAdded(ContainerEvent event) {}
+      public void componentRemoved(ContainerEvent valevent) {}
+    }
+
+    private static final long serialVersionUID = -7047089700479897799L;
+  
+    protected ContainerListener accessibleContainerHandler;
+    protected FocusListener accessibleFocusHandler;
+
+    protected AccessibleJComponent() {}
+    public void addPropertyChangeListener(PropertyChangeListener listener) {}
+    public void removePropertyChangeListener(PropertyChangeListener listener) {}
+    public int getAccessibleChildrenCount() { return 0; }
+    public Accessible getAccessibleChild(int value0) { return null; }
+    public AccessibleStateSet getAccessibleStateSet() { return null; } 
+    public String getAccessibleName() { return null; }
+    public String getAccessibleDescription() { return null; }
+    public AccessibleRole getAccessibleRole() { return null; }
+    protected String getBorderTitle(Border value0) { return null; }
+  }
+
+  /** 
+   * An explicit value for the component's preferred size; if not set by a
+   * user, this is calculated on the fly by delegating to the {@link
+   * ComponentUI.getPreferredSize} method on the {@link #ui} property. 
+   */
+  Dimension preferredSize;
+
+  /** 
+   * An explicit value for the component's minimum size; if not set by a
+   * user, this is calculated on the fly by delegating to the {@link
+   * ComponentUI.getMinimumSize} method on the {@link #ui} property. 
+   */
+  Dimension minimumSize;
+
+  /** 
+   * An explicit value for the component's maximum size; if not set by a
+   * user, this is calculated on the fly by delegating to the {@link
+   * ComponentUI.getMaximumSize} method on the {@link #ui} property.
+   */
+  Dimension maximumSize;
+
+
+  /**
+   * A value between 0.0 and 1.0 indicating the preferred horizontal
+   * alignment of the component, relative to its siblings. The values
+   * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
+   * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
+   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
+   * managers use this property.
+   *
+   * @see #getAlignmentX
+   * @see #setAlignmentX
+   * @see javax.swing.OverlayLayout
+   * @see javax.swing.BoxLayout
+   */
+  float alignmentX = 0.0f;
+
+  /**
+   * A value between 0.0 and 1.0 indicating the preferred vertical
+   * alignment of the component, relative to its siblings. The values
+   * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
+   * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
+   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
+   * managers use this property.
+   *
+   * @see #getAlignmentY
+   * @see #setAlignmentY
+   * @see javax.swing.OverlayLayout
+   * @see javax.swing.BoxLayout
+   */
+  float alignmentY = 0.0f;
+
+  /** 
+   * The border painted around this component.
+   * 
+   * @see #paintBorder
+   */
+  Border border;
+
+  /** 
+   * The text to show in the tooltip associated with this component.
+   * 
+   * @see #setToolTipText
+   * @see #getToolTipText
+   */
+   String toolTipText;
+
+  /** 
+   * <p>Whether to double buffer this component when painting. This flag
+   * should generally be <code>false</code>, except for top level
+   * components such as {@link JFrame} or {@link JApplet}.</p>
+   *
+   * <p>All children of a double buffered component are painted into the
+   * double buffer automatically, so only the top widget in a window needs
+   * to be double buffered.</p>
+   *
+   * @see #setDoubleBuffered
+   * @see #isDoubleBuffered
+   * @see #paintLock
+   * @see #paint
+   */
+  boolean doubleBuffered = false;
+
+  /**
+   * A set of flags indicating which debugging graphics facilities should
+   * be enabled on this component. The values should be a combination of
+   * {@link DebugGraphics.NONE_OPTION}, {@link DebugGraphics.LOG_OPTION},
+   * {@link DebugGraphics.FLASH_OPTION}, or {@link
+   * DebugGraphics.BUFFERED_OPTION}.
+   *
+   * @see setDebugGraphicsOptions
+   * @see getDebugGraphicsOptions
+   * @see DebugGraphics
+   * @see getComponentGraphics
+   */
+  int debugGraphicsOptions;
+
+  /** 
+   * <p>This property controls two independent behaviors simultaneously.</p>
+   *
+   * <p>First, it controls whether to fill the background of this widget
+   * when painting its body. This affects calls to {@link
+   * JComponent#paintComponent}, which in turn calls {@link
+   * ComponentUI#update} on the component's {@link #ui} property. If the
+   * component is opaque during this call, the background will be filled
+   * before calling {@link ComponentUI#paint}. This happens merely as a
+   * convenience; you may fill the component's background yourself too,
+   * but there is no need to do so if you will be filling with the same
+   * color.</p>
+   *
+   * <p>Second, it the opaque property informs swing's repaint system
+   * whether it will be necessary to paint the components "underneath" this
+   * component, in Z-order. If the component is opaque, it is considered to
+   * completely occlude components "underneath" it, so they will not be
+   * repainted along with the opaque component.</p>
+   *
+   * <p>The default value for this property is <code>false</code>, but most
+   * components will want to set it to <code>true</code> when installing UI
+   * defaults in {@link ComponentUI#installUI}.</p>
+   *
+   * @see #setOpaque
+   * @see #isOpaque
+   * @see #paintComponent
+   */
+  boolean opaque = false;
+
+  /** 
+   * The user interface delegate for this component. Event delivery and
+   * repainting of the component are usually delegated to this object. 
+   *
+   * @see #setUI
+   * @see #getUI
+   * @see #updateUI
+   */
+  protected ComponentUI ui;
+
+  /**
+   * A hint to the focus system that this component should or should not
+   * get focus. If this is <code>false</code>, swing will not try to
+   * request focus on this component; if <code>true</code>, swing might
+   * try to request focus, but the request might fail. Thus it is only 
+   * a hint guiding swing's behavior.
+   *
+   * @see #requestFocus
+   * @see #isRequestFocusEnabled
+   * @see #setRequestFocusEnabled
+   */
+  boolean requestFocusEnabled;
+
+  /**
+   * Flag indicating behavior of this component when the mouse is dragged
+   * outside the component and the mouse <em>stops moving</em>. If
+   * <code>true</code>, synthetic mouse events will be delivered on regular
+   * timed intervals, continuing off in the direction the mouse exited the
+   * component, until the mouse is released or re-enters the component.
+   *
+   * @see setAutoscrolls
+   * @see getAutoscrolls
+   */
+  boolean autoscrolls = false;
+
+  /**
+   * Listeners for events other than {@link PropertyChangeEvent} are
+   * handled by this listener list. PropertyChangeEvents are handled in
+   * {@link #changeSupport}.
+   */
+  protected EventListenerList listenerList = new EventListenerList();
+
+  /** 
+   * Support for {@link PropertyChangeEvent} events. This is constructed
+   * lazily when the component gets its first {@link
+   * PropertyChangeListener} subscription; until then it's an empty slot.
+   */
+  private SwingPropertyChangeSupport changeSupport;
+
+
+  /** 
+   * Storage for "client properties", which are key/value pairs associated
+   * with this component by a "client", such as a user application or a
+   * layout manager. This is lazily constructed when the component gets its
+   * first client property.
+   */
+  private Hashtable clientProperties;
+  
+  private InputMap inputMap_whenFocused;
+  private InputMap inputMap_whenAncestorOfFocused;
+  private InputMap inputMap_whenInFocusedWindow;
+  private ActionMap actionMap;
+
+  /** 
+   * A lock held during recursive painting; this is used to serialize
+   * access to the double buffer, and also to select the "top level" 
+   * object which should acquire the double buffer in a given widget
+   * tree (which may have multiple double buffered children).
+   *
+   * @see #doubleBuffered
+   * @see #paint
+   */
+  private static final Object paintLock = new Object();
+
+
+  /**
+   * The default locale of the component.
+   * 
+   * @see #getDefaultLocale
+   * @see #setDefaultLocale
+   */
+  private static Locale defaultLocale;
+  
+  public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
+
+  /**
+   * Constant used to indicate that no condition has been assigned to a
+   * particular action.
+   *
+   * @see #registerKeyboardAction
+   */
+  public static final int UNDEFINED_CONDITION = -1;
+
+  /**
+   * Constant used to indicate that an action should be performed only when 
+   * the component has focus.
+   *
+   * @see #registerKeyboardAction
+   */
+  public static final int WHEN_FOCUSED = 0;
+
+  /**
+   * Constant used to indicate that an action should be performed only when 
+   * the component is an ancestor of the component which has focus.
+   *
+   * @see #registerKeyboardAction
+   */
+  public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
+
+  /**
+   * Constant used to indicate that an action should be performed only when 
+   * the component is in the window which has focus.
+   *
+   * @see #registerKeyboardAction
+   */
+  public static final int WHEN_IN_FOCUSED_WINDOW = 2;
+
+
+  public JComponent()
+  {
+    super();
+    super.setLayout(new FlowLayout());
+    defaultLocale = Locale.getDefault();
+    debugGraphicsOptions = DebugGraphics.NONE_OPTION;
+  }
+
+  /**
+   * Helper to lazily construct and return the client properties table.
+   * 
+   * @return The current client properties table
+   *
+   * @see #clientProperties
+   * @see #getClientProperty
+   * @see #putClientProperty
+   */
+  private Hashtable getClientProperties()
+  {
+    if (clientProperties == null)
+      clientProperties = new Hashtable();
+    return clientProperties;
+  }
+
+  /**
+   * Get a client property associated with this component and a particular
+   * key.
+   *
+   * @param key The key with which to look up the client property
+   *
+   * @return A client property associated with this object and key
+   *
+   * @see #clientProperties
+   * @see #getClientProperties
+   * @see #putClientProperty
+   */
+  public Object getClientProperty(Object key)
+  {
+    return getClientProperties().get(key);
+  }
+
+  /**
+   * Add a client property <code>value</code> to this component, associated
+   * with <code>key</code>. If there is an existing client property
+   * associated with <code>key</code>, it will be replaced.
+   *
+   * @param key The key of the client property association to add
+   * @param value The value of the client property association to add
+   *
+   * @see #clientProperties
+   * @see #getClientProperties
+   * @see #getClientProperty
+   */
+  public void putClientProperty(Object key, Object value)
+  {
+    getClientProperties().put(key, value);
+  }
+
+  /**
+   * Unregister an <code>AncestorListener</code>.
+   *
+   * @param listener The listener to unregister
+   * 
+   * @see addAncestorListener
+   */
+  public void removeAncestorListener(AncestorListener listener)
+  {
+    listenerList.remove(AncestorListener.class, listener);
+  }
+
+  /**
+   * Unregister a <code>PropertyChangeListener</code>.
+   *
+   * @param listener The listener to register
+   *
+   * @see #addPropertyChangeListener
+   * @see #changeSupport
+   */
+  public void removePropertyChangeListener(PropertyChangeListener listener)
+  {
+    if (changeSupport != null)
+      changeSupport.removePropertyChangeListener(listener);
+  }
+
+  /**
+   * Unregister a <code>PropertyChangeListener</code>.
+   *
+   * @param propertyName The property name to unregister the listener from
+   * @param listener The listener to unregister
+   *
+   * @see #addPropertyChangeListener
+   * @see #changeSupport
+   */
+  public void removePropertyChangeListener(String propertyName,
+                                           PropertyChangeListener listener)
+  {
+    if (changeSupport != null)
+      changeSupport.removePropertyChangeListener(propertyName, listener);
+  }
+
+  /**
+   * Unregister a <code>VetoableChangeChangeListener</code>.
+   *
+   * @param listener The listener to unregister
+   *
+   * @see #addVetoableChangeListener
+   */
+  public void removeVetoableChangeListener(VetoableChangeListener listener)
+  {
+    listenerList.remove(VetoableChangeListener.class, listener);
+  }
+
+  /**
+   * Register an <code>AncestorListener</code>.
+   *
+   * @param listener The listener to register
+   *
+   * @see #removeVetoableChangeListener
+   */
+  public void addAncestorListener(AncestorListener listener)
+  {
+    listenerList.add(AncestorListener.class, listener);
+  }
+
+  /**
+   * Register a <code>PropertyChangeListener</code>. This listener will
+   * receive any PropertyChangeEvent, regardless of property name. To
+   * listen to a specific property name, use {@link
+   * #addPropertyChangeListener(String,PropertyChangeListener)} instead.
+   *
+   * @param listener The listener to register
+   *
+   * @see #removePropertyChangeListener
+   * @see #changeSupport
+   */
+  public void addPropertyChangeListener(PropertyChangeListener listener)
+  {
+    if (changeSupport == null)
+      changeSupport = new SwingPropertyChangeSupport(this);
+    changeSupport.addPropertyChangeListener(listener);
+  }
+
+  /**
+   * Register a <code>PropertyChangeListener</code> for a specific, named
+   * property. To listen to all property changes, regardless of name, use
+   * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
+   *
+   * @param propertyName The property name to listen to
+   * @param listener The listener to register
+   *
+   * @see #removePropertyChangeListener
+   * @see #changeSupport
+   */
+  public void addPropertyChangeListener(String propertyName,
+                                        PropertyChangeListener listener)
+  {
+    listenerList.add(PropertyChangeListener.class, listener);
+  }
+
+  /**
+   * Register a <code>VetoableChangeListener</code>.
+   *
+   * @param listener The listener to register
+   *
+   * @see #removeVetoableChangeListener
+   * @see #listenerList
+   */
+  public void addVetoableChangeListener(VetoableChangeListener listener)
+  {
+    listenerList.add(VetoableChangeListener.class, listener);
+  }
+
+  /**
+   * Return all registered listeners of a particular type.
+   *
+   * @param listenerType The type of listener to return
+   *
+   * @return All listeners in the {@link #listenerList} which 
+   * are of the specified type
+   *
+   * @see #listenerList
+   */
+  public EventListener[] getListeners(Class listenerType)
+  {
+    return listenerList.getListeners(listenerType);
+  }
+
+  /**
+   * Return all registered <code>AncestorListener</code> objects.
+   *
+   * @return The set of <code>AncestorListener</code> objects in {@link
+   * #listenerList}
+   */
+  public AncestorListener[] getAncestorListeners()
+  {
+    return (AncestorListener[]) getListeners(AncestorListener.class);
+  }
+
+  /**
+   * Return all registered <code>VetoableChangeListener</code> objects.
+   *
+   * @return The set of <code>VetoableChangeListener</code> objects in {@link
+   * #listenerList}
+   */
+  public VetoableChangeListener[] getVetoableChangeListeners()
+  {
+    return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
+  }
+
+  /**
+   * Return all <code>PropertyChangeListener</code> objects registered to listen
+   * for a particular property.
+   *
+   * @param property The property to return the listeners of
+   *
+   * @return The set of <code>PropertyChangeListener</code> objects in 
+   * {@link #changeSupport} registered to listen on the specified propert
+   */
+  public PropertyChangeListener[] getPropertyChangeListeners(String property)
+  {
+    return changeSupport == null ? new PropertyChangeListener[0]
+                                 : changeSupport.getPropertyChangeListeners(property);
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>boolean</code> values.
+   */
+  public void firePropertyChange(String propertyName, boolean oldValue,
+                                 boolean newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Boolean(oldValue),
+                                       new Boolean(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>byte</code> values.
+   */
+  public void firePropertyChange(String propertyName, byte oldValue,
+                                 byte newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
+                                       new Byte(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>char</code> values.
+   */
+  public void firePropertyChange(String propertyName, char oldValue,
+                                 char newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Character(oldValue),
+                                       new Character(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>double</code> values.
+   */
+  public void firePropertyChange(String propertyName, double oldValue,
+                                 double newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Double(oldValue),
+                                       new Double(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>float</code> values.
+   */
+  public void firePropertyChange(String propertyName, float oldValue,
+                                 float newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Float(oldValue),
+                                       new Float(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>int</code> values.
+   */
+  public void firePropertyChange(String propertyName, int oldValue,
+                                 int newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Integer(oldValue),
+                                       new Integer(newValue));
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>long</code> values.
+   */
+  public void firePropertyChange(String propertyName, long oldValue,
+                                 long newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Long(oldValue),
+                                       new Long(newValue));
+  }
+
+  /**
+   * Call {@link PropertyChangeListener#propertyChange} on all listeners
+   * registered to listen to a given property. Any method which changes
+   * the specified property of this component should call this method.
+   *
+   * @param propertyName The property which changed
+   * @param oldValue The old value of the property
+   * @param newValue The new value of the property
+   *
+   * @see #changeSupport
+   * @see #addPropertyChangeListener
+   * @see #removePropertyChangeListener
+   */
+  protected void firePropertyChange(String propertyName, Object oldValue,
+                                    Object newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+  }
+
+  /**
+   * A variant of {@link #firePropertyChange(String,Object,Object)} 
+   * for properties with <code>short</code> values.
+   */
+  public void firePropertyChange(String propertyName, short oldValue,
+                                 short newValue)
+  {
+    if (changeSupport != null)
+      changeSupport.firePropertyChange(propertyName, new Short(oldValue),
+                                       new Short(newValue));
+  }
+
+  /**
+   * Call {@link VetoableChangeListener#vetoableChange} on all listeners
+   * registered to listen to a given property. Any method which changes
+   * the specified property of this component should call this method.
+   *
+   * @param propertyName The property which changed
+   * @param oldValue The old value of the property
+   * @param newValue The new value of the property
+   *
+   * @throws PropertyVetoException if the change was vetoed by a listener
+   *
+   * @see addVetoableChangeListener
+   * @see removeVetoableChangeListener
+   */
+  protected void fireVetoableChange(String propertyName, Object oldValue,
+                                    Object newValue)
+    throws PropertyVetoException
+  {
+    VetoableChangeListener[] listeners = getVetoableChangeListeners();
+    
+    PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
+    
+    for (int i = 0; i < listeners.length; i++)
+      listeners[i].vetoableChange(evt);
+  }
+
+  /**
+   * Get the value of the accessibleContext property for this component.
+   *
+   * @return the current value of the property
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+
+  /**
+   * Get the value of the {@link #alignmentX} property.
+   *
+   * @return The current value of the property.
+   *
+   * @see #setAlignmentX
+   * @see #alignmentY
+   */
+  public float getAlignmentX()
+  {
+    return alignmentX;
+  }
+
+  /**
+   * Get the value of the {@link #alignmentY} property.
+   *
+   * @return The current value of the property.
+   *
+   * @see #setAlignmentY
+   * @see #alignmentX
+   */
+  public float getAlignmentY()
+  {
+    return alignmentY;
+  }
+
+  /**
+   * Get the current value of the {@link #autoscrolls} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getAutoscrolls()
+  {
+    return autoscrolls;
+  }
+
+  /**
+   * Set the value of the {@link #border} property, revalidate
+   * and repaint this component.
+   *   
+   * @param border The new value of the property
+   *
+   * @see #getBorder
+   */
+  public void setBorder(Border border)
+  {
+    this.border = border;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Get the value of the {@link #border} property.
+   *
+   * @return The property's current value
+   *
+   * @see #setBorder
+   */
+  public Border getBorder()
+  {
+    return border;
+  }
+
+  /**
+   * Get the component's current bounding box. If a rectangle is provided,
+   * use this as the return value (adjusting its fields in place);
+   * otherwise (of <code>null</code> is provided) return a new {@link
+   * Rectangle}.
+   *
+   * @param rv Optional return value to use
+   *
+   * @return A rectangle bounding the component
+   */
+  public Rectangle getBounds(Rectangle rv)
+  {
+    if (rv == null)
+      return new Rectangle(getX(), getY(), getWidth(), getHeight());
+    else
+      {
+        rv.setBounds(getX(), getY(), getWidth(), getHeight());
+        return rv;
+      }
+  }
+
+  /**
+   * Prepares a graphics context for painting this object. If {@link
+   * #debugGraphicsOptions} is not equal to {@link
+   * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
+   * wrapping the parameter. Otherwise configure the parameter with this
+   * component's foreground color and font.
+   *
+   * @param g The graphics context to wrap or configure
+   *
+   * @return A graphics context to paint this object with
+   *
+   * @see #debugGraphicsOptions
+   * @see #paint
+   */
+  protected Graphics getComponentGraphics(Graphics g)
+  {    
+    g.setFont(this.getFont());
+    g.setColor(this.getForeground());
+    return g;
+  }
+
+
+  /**
+   * Get the value of the {@link #debugGraphicsOptions} property.
+   *
+   * @return The current value of the property.
+   *
+   * @see #setDebugGraphicsOptions
+   * @see #debugGraphicsOptions
+   */
+  public int getDebugGraphicsOptions()
+  {
+    return 0;
+  }
+
+  /**
+   * Get the component's insets, which are calculated from
+   * the {@link #border} property. If the border is <code>null</code>,
+   * calls {@link Container#getInsets}.
+   *
+   * @return The component's current insets
+   */
+  public Insets getInsets()
+  {
+    if (border == null)
+      return super.getInsets();
+    return getBorder().getBorderInsets(this);
+  }
+
+  /**
+   * Get the component's insets, which are calculated from the {@link
+   * #border} property. If the border is <code>null</code>, calls {@link
+   * Container#getInsets}. The passed-in {@link Insets} value will be
+   * used as the return value, if possible.
+   *
+   * @param insets Return value object to reuse, if possible
+   *
+   * @return The component's current insets
+   */
+  public Insets getInsets(Insets insets)
+  {
+    Insets t = getInsets();
+
+    if (insets == null)
+      return t;
+
+    insets.left = t.left;
+    insets.right = t.right;
+    insets.top = t.top;
+    insets.bottom = t.bottom;
+    return insets;
+  }
+
+  /**
+   * Get the component's location. The passed-in {@link Point} value
+   * will be used as the return value, if possible.
+   *
+   * @param rv Return value object to reuse, if possible
+   *
+   * @return The component's current location
+   */
+  public Point getLocation(Point rv)
+  {
+    if (rv == null)
+      return new Point(getX(), getY());
+
+    rv.setLocation(getX(), getY());
+    return rv;
+  }
+
+  /**
+   * Get the component's maximum size. If the {@link #maximumSize} property
+   * has been explicitly set, it is returned. If the {@link #maximumSize}
+   * property has not been set but the {@link ui} property has been, the
+   * result of {@link ComponentUI#getMaximumSize} is returned. If neither
+   * property has been set, the result of {@link Container#getMaximumSize}
+   * is returned.
+   *
+   * @return The maximum size of the component
+   *
+   * @see #maximumSize
+   * @see #setMaximumSize
+   */
+  public Dimension getMaximumSize()
+  {
+    if (maximumSize != null)
+      return maximumSize;
+
+    if (ui != null)
+      {
+        Dimension s = ui.getMaximumSize(this);
+        if (s != null)
+          return s;
+      }
+
+    Dimension p = super.getMaximumSize();
+    return p;
+  }
+
+  /**
+   * Get the component's minimum size. If the {@link #minimumSize} property
+   * has been explicitly set, it is returned. If the {@link #minimumSize}
+   * property has not been set but the {@link ui} property has been, the
+   * result of {@link ComponentUI#getMinimumSize} is returned. If neither
+   * property has been set, the result of {@link Container#getMinimumSize}
+   * is returned.
+   *
+   * @return The minimum size of the component
+   *
+   * @see #minimumSize
+   * @see #setMinimumSize
+   */
+  public Dimension getMinimumSize()
+  {
+    if (minimumSize != null)
+      return minimumSize;
+
+    if (ui != null)
+      {
+        Dimension s = ui.getMinimumSize(this);
+        if (s != null)
+          return s;
+      }
+
+    Dimension p = super.getMinimumSize();
+    return p;
+  }
+
+  /**
+   * Get the component's preferred size. If the {@link #preferredSize}
+   * property has been explicitly set, it is returned. If the {@link
+   * #preferredSize} property has not been set but the {@link ui} property
+   * has been, the result of {@link ComponentUI#getPreferredSize} is
+   * returned. If neither property has been set, the result of {@link
+   * Container#getPreferredSize} is returned.
+   *
+   * @return The preferred size of the component
+   *
+   * @see #preferredSize
+   * @see #setPreferredSize
+   */
+  public Dimension getPreferredSize()
+  {
+    if (preferredSize != null)
+      return preferredSize;
+
+    if (ui != null)
+      {
+        Dimension s = ui.getPreferredSize(this);
+        if (s != null)
+          return s;
+      }
+    Dimension p = super.getPreferredSize();
+    return p;
+  }
+
+  /**
+   * Return the value of the {@link #nextFocusableComponent} property.
+   * 
+   * @deprecated See {@link java.awt.FocusTraversalPolicy}
+   *
+   * @return The current value of the property, or <code>null</code>
+   * if none has been set.
+   */
+  public Component getNextFocusableComponent()
+  {
+    return null;
+  }
+
+  /**
+   * Return the set of {@link KeyStroke} objects which are registered
+   * to initiate actions on this component.
+   *
+   * @return An array of the registered keystrokes
+   */
+  public KeyStroke[] getRegisteredKeyStrokes()
+  {
+    return null;
+  }
+
+  /**
+   * Returns the first ancestor of this component which is a {@link JRootPane}.
+   * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
+   *
+   * @return An ancestral JRootPane, or <code>null</code> if none exists.
+   */
+  public JRootPane getRootPane()
+  {
+    JRootPane p = SwingUtilities.getRootPane(this);
+    return p;
+  }
+
+  /**
+   * Get the component's size. The passed-in {@link Dimension} value
+   * will be used as the return value, if possible.
+   *
+   * @param rv Return value object to reuse, if possible
+   *
+   * @return The component's current size
+   */
+  public Dimension getSize(Dimension rv)
+  {
+    if (rv == null)
+      return new Dimension(getWidth(), getHeight());
+    else
+      {
+        rv.setSize(getWidth(), getHeight());
+        return rv;
+      }
+  }
+
+  /**
+   * Return the {@link #toolTip} property of this component, creating it and
+   * setting it if it is currently <code>null</code>. This method can be
+   * overridden in subclasses which wish to control the exact form of
+   * tooltip created.
+   *
+   * @return The current toolTip
+   */
+  public JToolTip createToolTip()
+  {
+	JToolTip toolTip = new JToolTip();
+	toolTip.setComponent(this);
+	toolTip.setTipText(toolTipText);
+    
+    return toolTip;
+  }
+
+  /**
+   * Return the location at which the {@link #toolTip} property should be
+   * displayed, when triggered by a particular mouse event. 
+   *
+   * @param event The event the tooltip is being presented in response to
+   *
+   * @return The point at which to display a tooltip, or <code>null</code>
+   * if swing is to choose a default location.
+   */
+  public Point getToolTipLocation(MouseEvent event)
+  {
+    return null;
+  }
+
+  /**
+   * Set the value of the {@link #toolTipText} property.
+   *
+   * @param text The new property value
+   *
+   * @see #getToolTipText
+   */
+  public void setToolTipText(String text)
+  {
+    if (text == null)
+    {
+      ToolTipManager.sharedInstance().unregisterComponent(this);
+      toolTipText = null;
+      return;
+    }
 		
-		//eventMask |= AWTEvent.COMP_KEY_EVENT_MASK;
-		enableEvents( AWTEvent.KEY_EVENT_MASK );
+    // XXX: The tip text doesn't get updated unless you set it to null
+    // and then to something not-null. This is consistent with the behaviour
+    // of Sun's ToolTipManager.
+			
+    String oldText = toolTipText;
+    toolTipText = text;
+		
+    if (oldText == null)
+      ToolTipManager.sharedInstance().registerComponent(this);
+  }
+
+  /**
+   * Get the value of the {@link #toolTipText} property.
+   *
+   * @return The current property value
+   *
+   * @see #setToolTipText
+   */
+  public String getToolTipText()
+  {
+    return toolTipText;
+  }
+
+  /**
+   * Get the value of the {@link #toolTipText} property, in response to a
+   * particular mouse event.
+   *
+   * @param event The mouse event which triggered the tooltip
+   *
+   * @return The current property value
+   *
+   * @see #setToolTipText
+   */
+  public String getToolTipText(MouseEvent event)
+  {
+    return getToolTipText();
+  }
+
+  /**
+   * Return the top level ancestral container (usually a {@link
+   * java.awt.Window} or {@link java.awt.Applet}) which this component is
+   * contained within, or <code>null</code> if no ancestors exist.
+   *
+   * @return The top level container, if it exists
+   */
+  public Container getTopLevelAncestor()
+  {
+    Container c = getParent();
+    for (Container peek = c; peek != null; peek = peek.getParent())
+      c = peek;
+    return c;
+  }
+
+  /**
+   * Compute the component's visible rectangle, which is defined
+   * recursively as either the component's bounds, if it has no parent, or
+   * the intersection of the component's bounds with the visible rectangle
+   * of its parent.
+   *
+   * @param rect The return value slot to place the visible rectangle in
+   */
+  public void computeVisibleRect(Rectangle rect)
+  {
+    Component c = getParent();
+    if (c != null && c instanceof JComponent)
+      {
+        ((JComponent) c).computeVisibleRect(rect);
+        rect.translate(-getX(), -getY());
+        Rectangle2D.intersect(rect,
+                              new Rectangle(0, 0, getWidth(), getHeight()),
+                              rect);
+      }
+    else
+      rect.setRect(0, 0, getWidth(), getHeight());
+  }
+
+  /**
+   * Return the component's visible rectangle in a new {@link Rectangle},
+   * rather than via a return slot.
+   *
+   * @return The component's visible rectangle
+   *
+   * @see #computeVisibleRect(Rectangle)
+   */
+  public Rectangle getVisibleRect()
+  {
+    Rectangle r = new Rectangle();
+    computeVisibleRect(r);
+    return r;
+  }
+
+  /**
+   * <p>Requests that this component receive input focus, giving window
+   * focus to the top level ancestor of this component. Only works on
+   * displayable, focusable, visible components.</p>
+   *
+   * <p>This method should not be called by clients; it is intended for
+   * focus implementations. Use {@link Component#requestFocus} instead.</p>
+   *
+   * @see {@link Component#requestFocus}
+   */
+  public void grabFocus()
+  {
+  }
+
+  /**
+   * Get the value of the {@link #doubleBuffered} property.
+   *
+   * @return The property's current value
+   */
+  public boolean isDoubleBuffered()
+  {
+    return doubleBuffered;
+  }
+
+  /**
+   * Return <code>true</code> if the provided component has no native peer;
+   * in other words, if it is a "lightweight component".
+   *
+   * @param c The component to test for lightweight-ness
+   *
+   * @return Whether or not the component is lightweight
+   */
+  public static boolean isLightweightComponent(Component c)
+  {
+    return c.getPeer() instanceof LightweightPeer;
+  }
+
+  /**
+   * Return <code>true<code> if you wish this component to manage its own
+   * focus. In particular: if you want this component to be sent
+   * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
+   * have its children considered as focus transfer targets. If
+   * <code>true</code>, focus traversal around this component changes to
+   * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
+   *
+   * @return <code>true</code> if you want this component to manage its own
+   * focus, otherwise (by default) <code>false</code>
+   *
+   * @deprecated Use {@link Component.setFocusTraversalKeys(int,Set)} and
+   * {@link Container.setFocusCycleRoot(boolean)} instead
+   */
+  public boolean isManagingFocus()
+  {
+    return false;
+  }
+
+  /**
+   * Return the current value of the {@link opaque} property. 
+   *
+   * @return The current property value
+   */
+  public boolean isOpaque()
+  {
+    return opaque;
+  }
+
+  /**
+   * Return <code>true</code> if the component can guarantee that none of its
+   * children will overlap in Z-order. This is a hint to the painting system.
+   * The default is to return <code>true</code>, but some components such as
+   * {@link JLayeredPane} should override this to return <code>false</code>.
+   *
+   * @return Whether the component tiles its children
+   */
+  public boolean isOptimizedDrawingEnabled()
+  {
+    return true;
+  }
+
+  /**
+   * Return <code>true</code> if this component is currently painting a tile.
+   *
+   * @return Whether the component is painting a tile
+   */
+  public boolean isPaintingTile()
+  {
+    return false;
+  }
+
+  /**
+   * Get the value of the {@link #requestFocusEnabled} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean isRequestFocusEnabled()
+  {
+    return requestFocusEnabled;
+  }
+
+  /**
+   * Return <code>true</code> if this component is a validation root; this
+   * will cause calls to {@link #invalidate} in this component's children
+   * to be "captured" at this component, and not propagate to its parents.
+   * For most components this should return <code>false</code>, but some
+   * components such as {@link JViewPort} will want to return
+   * <code>true</code>.
+   *
+   * @return Whether this component is a validation root
+   */
+  public boolean isValidateRoot()
+  {
+    return false;
+  }
+
+  /**
+   * <p>Paint the component. This is a delicate process, and should only be
+   * called from the repaint thread, under control of the {@link
+   * RepaintManager}. Client code should usually call {@link #repaint} to
+   * trigger painting.</p>
+   *
+   * <p>This method will acquire a double buffer from the {@link
+   * RepaintManager} if the component's {@link #doubleBuffered} property is
+   * <code>true</code> and the <code>paint</code> call is the
+   * <em>first</em> recursive <code>paint</code> call inside swing.</p>
+   *
+   * <p>The method will also modify the provided {@link Graphics} context
+   * via the {@link #getComponentGraphics} method. If you want to customize
+   * the graphics object used for painting, you should override that method
+   * rather than <code>paint</code>.</p>
+   *
+   * <p>The body of the <code>paint</code> call involves calling {@link
+   * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
+   * order. If you want to customize painting behavior, you should override
+   * one of these methods rather than <code>paint</code>.</p>
+   *
+   * <p>For more details on the painting sequence, see <a
+   * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
+   * article</a>.</p>
+   *
+   * @param g The graphics context to paint with
+   *
+   * @see #paintImmediately
+   */
+  public void paint(Graphics g)
+  {
+    Graphics g2 = g;
+    Image doubleBuffer = null;
+    RepaintManager rm = RepaintManager.currentManager(this);
+
+    if (isDoubleBuffered()
+        && (rm.isDoubleBufferingEnabled())
+        && (! Thread.holdsLock(paintLock)))
+      {
+        doubleBuffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
+      }
+
+    synchronized (paintLock)
+      {
+        if (doubleBuffer != null)
+          {
+            g2 = doubleBuffer.getGraphics();
+            g2.setClip(g.getClipBounds());
+          }
+	  
+        g2 = getComponentGraphics(g2);
+        paintComponent(g2);
+        paintBorder(g2);
+        paintChildren(g2);
+        
+        if (doubleBuffer != null)
+          g.drawImage(doubleBuffer, 0, 0, (ImageObserver) null);
+      }
+  }
+
+  /**
+   * Paint the component's border. This usually means calling {@link
+   * Border#paintBorder} on the {@link #border} property, if it is
+   * non-<code>null</code>. You may override this if you wish to customize
+   * border painting behavior. The border is painted after the component's
+   * body, but before the component's children.
+   *
+   * @param g The graphics context with which to paint the border
+   *
+   * @see #paint
+   * @see #paintChildren
+   * @see #paintComponent
+   */
+  protected void paintBorder(Graphics g)
+  {
+    if (getBorder() != null)
+      getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
+  }
+
+  /**
+   * Paint the component's children. This usually means calling {@link
+   * Container#paint}, which recursively calls {@link #paint} on any of the
+   * component's children, with appropriate changes to coordinate space and
+   * clipping region. You may override this if you wish to customize
+   * children painting behavior. The children are painted after the
+   * component's body and border.
+   *
+   * @param g The graphics context with which to paint the children
+   *
+   * @see #paint
+   * @see #paintBorder
+   * @see #paintComponent
+   */
+  protected void paintChildren(Graphics g)
+  {
+    super.paint(g);
+  }
+
+  /**
+   * Paint the component's body. This usually means calling {@link
+   * ComponentUI#update} on the {@link #ui} property of the component, if
+   * it is non-<code>null</code>. You may override this if you wish to
+   * customize the component's body-painting behavior. The component's body
+   * is painted first, before the border and children.
+   *
+   * @param g The graphics context with which to paint the body
+   *
+   * @see #paint
+   * @see #paintBorder
+   * @see #paintChildren
+   */
+  protected void paintComponent(Graphics g)
+  {
+    if (ui != null)
+      ui.update(g, this);
+  }
+
+  /**
+   * A variant of {@link #paintImmediately(Rectangle)} which takes
+   * integer parameters.
+   *
+   * @param x The left x coordinate of the dirty region
+   * @param y The top y coordinate of the dirty region
+   * @param w The width of the dirty region
+   * @param h The height of the dirty region
+   */
+  public void paintImmediately(int x, int y, int w, int h)
+  {
+    paintImmediately(new Rectangle(x, y, w, h));
+  }
+
+  /**
+   * Transform the provided dirty rectangle for this component into the
+   * appropriate ancestral {@link JRootPane} and call {@link #paint} on
+   * that root pane. This method is called from the {@link RepaintManager}
+   * and should always be called within the painting thread.
+   *
+   * @param r The dirty rectangle to paint
+   */
+  public void paintImmediately(Rectangle r)
+  {
+    Component root = SwingUtilities.getRoot(this);
+    if (root == null || ! root.isShowing())
+      return;
+    Graphics g = root.getGraphics();
+    if (g == null)
+      return;
+
+    Rectangle clip = SwingUtilities.convertRectangle(this, r, root);
+    g.setClip(clip);
+    root.paint(g);
+    g.dispose();
+  }
+
+  /**
+   * Return a string representation for this component, for use in
+   * debugging.
+   *
+   * @return A string describing this component.
+   */
+  protected String paramString()
+  {
+    return "JComponent";
+  }
+
+  /**
+   * A variant of {@link
+   * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
+   * provides <code>null</code> for the command name.   
+   */
+  public void registerKeyboardAction(ActionListener act,
+                                     KeyStroke stroke, 
+                                     int cond)
+  {
+    registerKeyboardAction(act, null, stroke, cond);
+  }
+
+  /* 
+   * There is some charmingly undocumented behavior sun seems to be using
+   * to simulate the old register/unregister keyboard binding API. It's not
+   * clear to me why this matters, but we shall endeavour to follow suit.
+   *
+   * Two main thing seem to be happening when you do registerKeyboardAction():
+   * 
+   *  - no actionMap() entry gets created, just an entry in inputMap()
+   *
+   *  - the inputMap() entry is a proxy class which invokes the the
+   *  binding's actionListener as a target, and which clobbers the command
+   *  name sent in the ActionEvent, providing the binding command name
+   *  instead.
+   *
+   * This much you can work out just by asking the input and action maps
+   * what they contain after making bindings, and watching the event which
+   * gets delivered to the recipient. Beyond that, it seems to be a
+   * sun-private solution so I will only immitate it as much as it matters
+   * to external observers.
+   */
+
+  private static class ActionListenerProxy
+    extends AbstractAction
+  {
+    ActionListener target;
+    String bindingCommandName;
+
+    public ActionListenerProxy(ActionListener li, 
+                               String cmd)
+    {
+      target = li;
+      bindingCommandName = cmd;
+    }
+
+    public void actionPerformed(ActionEvent e)
+    {
+      ActionEvent derivedEvent = new ActionEvent(e.getSource(),
+                                                 e.getID(),
+                                                 bindingCommandName,
+                                                 e.getModifiers());
+      target.actionPerformed(derivedEvent);
+    }
+  }
+
+  
+  /**
+   * An obsolete method to register a keyboard action on this component.
+   * You should use <code>getInputMap</code> and <code>getActionMap</code>
+   * to fetch mapping tables from keystrokes to commands, and commands to
+   * actions, respectively, and modify those mappings directly.
+   *
+   * @param anAction The action to be registered
+   * @param aCommand The command to deliver in the delivered {@link
+   * java.awt.ActionEvent}
+   * @param aKeyStroke The keystroke to register on
+   * @param aCondition One of the values {@link #UNDEFINED_CONDITION},
+   * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
+   * {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
+   * be met for the action to be fired
+   *
+   * @see #unregisterKeyboardAction
+   * @see #getConditionForKeystroke
+   * @see #resetKeyboardActiond
+   */
+  public void registerKeyboardAction(ActionListener act, 
+                                     String cmd,
+                                     KeyStroke stroke, 
+                                     int cond)
+  {
+    getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
+  }
+
+
+
+  public final void setInputMap(int condition, InputMap map)
+  {
+    enableEvents(AWTEvent.KEY_EVENT_MASK);
+    switch (condition)
+      {
+      case WHEN_FOCUSED:
+        inputMap_whenFocused = map;
+        break;
+
+      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        inputMap_whenAncestorOfFocused = map;
+        break;
+
+      case WHEN_IN_FOCUSED_WINDOW:
+        inputMap_whenInFocusedWindow = map;
+        break;
+        
+      case UNDEFINED_CONDITION:
+      default:
+        throw new IllegalArgumentException();
+      }
+  }
+
+  public final InputMap getInputMap(int condition)
+  {
+    enableEvents(AWTEvent.KEY_EVENT_MASK);
+    switch (condition)
+      {
+      case WHEN_FOCUSED:
+        if (inputMap_whenFocused == null)
+          inputMap_whenFocused = new InputMap();
+        return inputMap_whenFocused;
+
+      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        if (inputMap_whenAncestorOfFocused == null)
+          inputMap_whenAncestorOfFocused = new InputMap();
+        return inputMap_whenAncestorOfFocused;
+
+      case WHEN_IN_FOCUSED_WINDOW:
+        if (inputMap_whenInFocusedWindow == null)
+          inputMap_whenInFocusedWindow = new InputMap();
+        return inputMap_whenInFocusedWindow;
+
+      case UNDEFINED_CONDITION:
+      default:
+        return null;
+      }
+  }
+
+  public final InputMap getInputMap()
+  {
+    return getInputMap(WHEN_FOCUSED);
+  }
+
+  public final ActionMap getActionMap()
+  {
+    if (actionMap == null)
+      actionMap = new ActionMap();
+    return actionMap;
+  }
+
+  public final void setActionMap(ActionMap map)
+  {
+    actionMap = map;
+  }
+
+  /**
+   * @deprecated As of 1.3 KeyStrokes can be registered with multiple
+   * simultaneous conditions.
+   *
+   * Return the condition that determines whether a registered action
+   * occurs in response to the specified keystroke.
+   *
+   * @param aKeyStroke The keystroke to return the condition of
+   *
+   * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
+   * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
+   * #WHEN_IN_FOCUSED_WINDOW}
+   *
+   * @see #registerKeyboardAction   
+   * @see #unregisterKeyboardAction   
+   * @see #resetKeyboardActiond
+   */
+  public int getConditionForKeyStroke(KeyStroke ks)
+  {
+    if (inputMap_whenFocused != null 
+        && inputMap_whenFocused.get(ks) != null)
+      return WHEN_FOCUSED;
+    else if (inputMap_whenAncestorOfFocused != null 
+             && inputMap_whenAncestorOfFocused.get(ks) != null)
+      return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
+    else if (inputMap_whenInFocusedWindow != null 
+             && inputMap_whenInFocusedWindow.get(ks) != null)
+      return WHEN_IN_FOCUSED_WINDOW;
+    else
+      return UNDEFINED_CONDITION;
+  }
+
+  /**
+   * @deprecated Use {@link #getActionMap()}
+   *
+   * Get the ActionListener (typically an {@link Action} object) which is
+   * associated with a particular keystroke. 
+   *
+   * @param aKeyStroke The keystroke to retrieve the action of
+   *
+   * @return The action associated with the specified keystroke
+   */
+  public ActionListener getActionForKeyStroke(KeyStroke ks)
+  {
+    Object cmd = getInputMap().get(ks);
+    if (cmd != null)
+      {
+        if (cmd instanceof ActionListenerProxy)
+          return (ActionListenerProxy) cmd;
+        else if (cmd instanceof String)
+          return getActionMap().get(cmd);
+      }
+    return null;
+  }
+
+  /**
+   * A hook for subclasses which want to customize event processing.
+   */
+  protected void processComponentKeyEvent(KeyEvent e)
+  {
+  }
+
+  /**
+   * Override the default key dispatch system from Component to hook into
+   * the swing {@link InputMap} / {@link ActionMap} system.
+   *
+   * See <a
+   * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
+   * report</a> for more details, it's somewhat complex.
+   */
+  protected void processKeyEvent(KeyEvent e)
+  {
+    processComponentKeyEvent(e);
+
+    // FIXME: this needs to be elaborated significantly, to do all the
+    // focus / ancestor / window searching for the various binding modes.
+    if (! e.isConsumed() &&
+        processKeyBinding(KeyStroke.getKeyStrokeForEvent(e), 
+                          e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
+      e.consume();
+  }
+
+  protected boolean processKeyBinding(KeyStroke ks,
+                                      KeyEvent e,
+                                      int condition,
+                                      boolean pressed)
+  { 
+    if (isEnabled())
+      {
+        Action act = null;
+        InputMap map = getInputMap(condition);
+        if (map != null)
+          {
+            Object cmd = map.get(ks);
+            if (cmd != null)
+              {
+                if (cmd instanceof ActionListenerProxy)
+                  act = (Action) cmd;
+                else 
+                  act = (Action) getActionMap().get(cmd);
+              }
+          }
+        if (act != null && act.isEnabled())
+          return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
+      }
+    return false;
+  }
+  
+  /**
+   * Remove a keyboard action registry.
+   *
+   * @param stroke The keystroke to unregister
+   *
+   * @see #registerKeyboardAction
+   * @see #getConditionForKeystroke
+   * @see #resetKeyboardActiond
+   */
+  public void unregisterKeyboardAction(KeyStroke aKeyStroke)
+  {
+  }
+
+
+  /**
+   * Reset all keyboard action registries.
+   *
+   * @see #registerKeyboardAction
+   * @see #unregisterKeyboardAction
+   * @see #getConditionForKeystroke
+   */
+  public void resetKeyboardActions()
+  {
+    if (inputMap_whenFocused != null)
+      inputMap_whenFocused.clear();
+    if (inputMap_whenAncestorOfFocused != null)
+      inputMap_whenAncestorOfFocused.clear();
+    if (inputMap_whenInFocusedWindow != null)
+      inputMap_whenInFocusedWindow.clear();
+    if (actionMap != null)
+      actionMap.clear();
+  }
+
+
+  /**
+   * Mark the described region of this component as dirty in the current
+   * {@link RepaintManager}. This will queue an asynchronous repaint using
+   * the system painting thread in the near future.
+   *
+   * @param tm ignored
+   * @param x coordinate of the region to mark as dirty
+   * @param y coordinate of the region to mark as dirty
+   * @param width dimension of the region to mark as dirty
+   * @param height dimension of the region to mark as dirty
+   */
+  public void repaint(long tm, int x, int y, int width, int height)
+  {
+    Rectangle dirty = new Rectangle(x, y, width, height);
+    Rectangle vis = getVisibleRect();
+    dirty = dirty.intersection(vis);
+    RepaintManager.currentManager(this).addDirtyRegion(this, dirty.x, dirty.y,
+                                                       dirty.width,
+                                                       dirty.height);
+  }
+
+  /**
+   * Mark the described region of this component as dirty in the current
+   * {@link RepaintManager}. This will queue an asynchronous repaint using
+   * the system painting thread in the near future.
+   *
+   * @param r The rectangle to mark as dirty
+   */
+  public void repaint(Rectangle r)
+  {
+    repaint((long) 0, (int) r.getX(), (int) r.getY(), (int) r.getWidth(),
+            (int) r.getHeight());
+  }
+
+  /**
+   * Request focus on the default component of this component's {@link
+   * FocusTraversalPolicy}.
+   *
+   * @return The result of {@link #requestFocus}
+   *
+   * @deprecated Use {@link #requestFocus()} on the default component provided from
+   * the {@link FocusTraversalPolicy} instead.
+   */
+  public boolean requestDefaultFocus()
+  {
+    return false;
+  }
+
+  /**
+   * Queue a an invalidation and revalidation of this component, using 
+   * {@link RepaintManager#addInvalidComponent}.
+   */
+  public void revalidate()
+  {
+    invalidate();
+    RepaintManager.currentManager(this).addInvalidComponent(this);
+  }
+
+  /**
+   * Calls <code>scrollRectToVisible</code> on the component's parent. 
+   * Components which can service this call should override.
+   *
+   * @param r The rectangle to make visible
+   */
+  public void scrollRectToVisible(Rectangle r)
+  {
+    Component p = getParent();
+    if (p instanceof JComponent)
+      ((JComponent) p).scrollRectToVisible(r);
+  }
+
+  /**
+   * Set the value of the {@link #alignmentX} property.
+   *
+   * @param a The new value of the property
+   */
+  public void setAlignmentX(float a)
+  {
+    alignmentX = a;
+  }
+
+  /**
+   * Set the value of the {@link #alignmentY} property.
+   *
+   * @param a The new value of the property
+   */
+  public void setAlignmentY(float a)
+  {
+    alignmentY = a;
+  }
+
+  /**
+   * Set the value of the {@link #autoscrolls} property.
+   *
+   * @param a The new value of the property
+   */
+  public void setAutoscrolls(boolean a)
+  {
+    autoscrolls = a;
+  }
+
+  /**
+   * Set the value of the {@link #debugGraphicsOptions} property.
+   *
+   * @param debugOptions The new value of the property
+   */
+  public void setDebugGraphicsOptions(int debugOptions)
+  {
+    debugGraphicsOptions = debugOptions;
+  }
+
+  /**
+   * Set the value of the {@link #doubleBuffered} property.
+   *
+   * @param db The new value of the property
+   */
+  public void setDoubleBuffered(boolean db)
+  {
+    doubleBuffered = db;
+  }
+
+  /**
+   * Set the value of the {@link #enabled} property, revalidate
+   * and repaint this component.
+   *
+   * @param e The new value of the property
+   */
+  public void setEnabled(boolean e)
+  {
+    super.setEnabled(e);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #font} property, revalidate
+   * and repaint this component.
+   *
+   * @param f The new value of the property
+   */
+  public void setFont(Font f)
+  {
+    super.setFont(f);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #background} property, revalidate
+   * and repaint this component.
+   *
+   * @param bg The new value of the property
+   */
+  public void setBackground(Color bg)
+  {
+    super.setBackground(bg);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #foreground} property, revalidate
+   * and repaint this component.
+   *
+   * @param fg The new value of the property
+   */
+  public void setForeground(Color fg)
+  {
+    super.setForeground(fg);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #maximumSize} property, revalidate
+   * and repaint this component.
+   *
+   * @param max The new value of the property
+   */
+  public void setMaximumSize(Dimension max)
+  {
+    maximumSize = max;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #minimumSize} property, revalidate
+   * and repaint this component.
+   *
+   * @param min The new value of the property
+   */
+  public void setMinimumSize(Dimension min)
+  {
+    minimumSize = min;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #preferredSize} property, revalidate
+   * and repaint this component.
+   *
+   * @param pref The new value of the property
+   */
+  public void setPreferredSize(Dimension pref)
+  {
+    preferredSize = pref;
+  }
+
+  /**
+   * Set the specified component to be the next component in the 
+   * focus cycle, overriding the {@link FocusTraversalPolicy} for
+   * this component.
+   *
+   * @param aComponent The component to set as the next focusable
+   *
+   * @deprecated Use FocusTraversalPolicy instead
+   */
+  public void setNextFocusableComponent(Component aComponent)
+  {
+  }
+
+  /**
+   * Set the value of the {@link #requestFocusEnabled} property.
+   *
+   * @param e The new value of the property
+   */
+  public void setRequestFocusEnabled(boolean e)
+  {
+    requestFocusEnabled = e;
+  }
+
+  /**
+   * Set the value of the {@link #opaque} property, revalidate and repaint
+   * this component.
+   *
+   * @param isOpaque The new value of the property
+   *
+   * @see ComponentUI#update
+   */
+  public void setOpaque(boolean isOpaque)
+  {
+    opaque = isOpaque;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the visible property, and revalidate / repaint the
+   * component.
+   *
+   * @param v The new value of the property
+   */
+  public void setVisible(boolean v)
+  {
+    super.setVisible(v);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Call {@link paint}. 
+   * 
+   * @param g The graphics context to paint into
+   */
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  /**
+   * Get the value of the UIClassID property. This property should be a key
+   * in the {@link UIDefaults} table managed by {@link UIManager}, the
+   * value of which is the name of a class to load for the component's
+   * {@link ui} property.
+   *
+   * @return A "symbolic" name which will map to a class to use for the
+   * component's UI, such as <code>"ComponentUI"</code>
+   *
+   * @see #setUI
+   * @see #updateUI
+   */
+  public String getUIClassID()
+  {
+    return "ComponentUI";
+  }
+
+  /**
+   * Install a new UI delegate as the component's {@link ui} property. In
+   * the process, this will call {@link ComponentUI.uninstallUI} on any
+   * existing value for the {@link ui} property, and {@link
+   * ComponentUI.installUI} on the new UI delegate.
+   *
+   * @param newUI The new UI delegate to install
+   *
+   * @see #updateUI
+   * @see #getUIClassID
+   */
+  protected void setUI(ComponentUI newUI)
+  {
+    if (ui != null)
+      ui.uninstallUI(this);
 
-		//updateUI(); // get a proper ui
-	}
+    ComponentUI oldUI = ui;
+    ui = newUI;
 
-	// protected EventListenerList listenerList
-	public boolean contains(int x, int y)
-	{
-		//return dims.contains(x,y);
-		return super.contains(x,y);
-	}
-
-	public  void addNotify()
-	{
-		//Notification to this component that it now has a parent component.
-		super.addNotify();
-	}
-
-	Hashtable get_prop_hash()
-	{
-		if (prop_hash == null)
-			prop_hash = new Hashtable();
-		return prop_hash;
-	}
-	public Vector get_veto_list()
-	{
-		if (veto_list == null)
-			veto_list = new Vector();
-		return veto_list;
-	}
-	public Vector get_change_list()
-	{
-		if (change_list == null)
-			change_list = new Vector();
-		return change_list;
-	}
-	public Vector get_ancestor_list()
-	{
-		if (ancestor_list == null)
-			ancestor_list = new Vector();
-		return ancestor_list;
-	}
-
-	public Object getClientProperty(Object key)
-        {	return get_prop_hash().get(key);    }
-
-	public void putClientProperty(Object key, Object value)
-	{    get_prop_hash().put(key, value);   }
-
-	public void removeAncestorListener(AncestorListener listener)
-	{  get_ancestor_list().removeElement(listener);  }
-
-        public void removePropertyChangeListener(PropertyChangeListener listener)
-	{  get_change_list().removeElement(listener);   }
-
-	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)
-	{  /* FIXME */   get_change_list().removeElement(listener);   }
-
-	public void removeVetoableChangeListener(VetoableChangeListener listener)
-	{  get_veto_list().removeElement(listener);   }
-
-	public void addAncestorListener(AncestorListener listener)
-	{   get_ancestor_list().addElement(listener);  }
-
-	public void addPropertyChangeListener(PropertyChangeListener listener)
-	{  get_change_list().addElement(listener);   }
-
-	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)
-	{ /* FIXME */ get_change_list().addElement(listener);   }
-
-	public void addVetoableChangeListener(VetoableChangeListener listener)
-	{  get_veto_list().addElement(listener);    }
-
-	public void computeVisibleRect(Rectangle rect)
-	{
-		//Returns the Component's "visible rect rectangle" - the intersection of the visible rectangles for this component and all of its ancestors.
-		//super.computeVisibleRect(rect);
-	}
-
-	public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue)
-	{
-		//Reports a bound property change.
-	}
-	public void firePropertyChange(String propertyName, byte oldValue, byte newValue)
-	{
-		//    Reports a bound property change.
-	}
-	public void firePropertyChange(String propertyName, char oldValue, char newValue)
-	{
-		//Reports a bound property change.
-	}
-
-	public void firePropertyChange(String propertyName, double oldValue, double newValue)
-	{
-		//Reports a bound property change.
-	}
-
-	public void firePropertyChange(String propertyName, float oldValue, float newValue)
-	{
-		//       Reports a bound property change.
-	}
-	public void firePropertyChange(String propertyName, int oldValue, int newValue)
-	{
-		//       Reports a bound property change.
-	}
-	public void firePropertyChange(String propertyName, long oldValue, long newValue)
-	{
-		//Reports a bound property change. protected
-	}
-
-  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue)
-	{
-		//       Support for reporting bound property changes.
-	}
-	public void firePropertyChange(String propertyName, short oldValue, short newValue)
-	{
-		//       Reports a bound property change.
-	}
-
-	protected  void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
-	{
-		//       Support for reporting constrained property changes.
-	}
-
-        public AccessibleContext getAccessibleContext()
-	{
-		//       Get the AccessibleContext associated with this JComponent
-		return null;
-	}
-	
-        public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke)
-	{
-		//Return the object that will perform the action registered for a given keystroke.
-		return null;
-	}
-	public float getAlignmentX()
-	{
-		//    Overrides Container.getAlignmentX to return the vertical alignment.
-		return 0;
-	}
-
-	public float getAlignmentY()
-	{
-		//       Overrides Container.getAlignmentY to return the horizontal alignment.
-		return 0;
-	}
-	public boolean getAutoscrolls()
-	{
-		//Returns true if this component automatically scrolls its contents when dragged, (when contained in a component that supports scrolling, like JViewport
-		return false;
-	}
-
-	public void setBorder(Border border)
-	{
-		//System.out.println("set border called !, new border = " + border);
-		this.border = border;
-		revalidate();
-		repaint();
-	}
-
-	public Border getBorder()
-	{	return border;    }
-
-
-        public Rectangle getBounds(Rectangle rv)
-	{
-		if (rv == null)
-			return new Rectangle(getX(),getY(),getWidth(),getHeight());
-		else
-		{
-			rv.setBounds(getX(),getY(),getWidth(),getHeight());
-			return rv;
-		}
-	}
-
-	protected  Graphics getComponentGraphics(Graphics g)
-	{      return g;       }
-
-	public int getConditionForKeyStroke(KeyStroke aKeyStroke)
-	{
-		//Return the condition that determines whether a registered action occurs in response to the specified keystroke.
-		return 0;
-	}
-	public int getDebugGraphicsOptions()
-	{
-		return 0;
-	}
-
-	public Graphics getGraphics()
-	{	return super.getGraphics();    }
-
-
-	//    static MantaNative void DebugMe(Border b);
-
-	public Insets getInsets()
-	{
-		//	System.out.println("watch this border");
-		//	DebugMe(border);
-		//	System.out.println("border = " + border);
-
-		if (border == null)
-		{
-			//System.out.println("compares to null !");
-			return super.getInsets();
-		}
-		//	System.out.println("compare failed !");
-		return getBorder().getBorderInsets(this);
-	}
-
-	public Insets getInsets(Insets insets)
-	{
-	    Insets t = getInsets();
-
-	    if (insets == null)
-		return t;
-	    
-	    
-	    return new Insets(t.top, t.left, t.bottom, t.right);
-	}
-	public Point getLocation(Point rv)
-	{
-		//Store the x,y origin of this component into "return value" rv and return rv.
-
-		if (rv == null)
-			return new Point(getX(),
-					 getY());
-
-		rv.setLocation(getX(),
-		               getY());
-		return rv;
-	}
-
-	public Dimension getMaximumSize()
-	{
-		if (max != null)
-		{
-			//System.out.println("HAVE_MAX_SIZE =  " + max);
-			return max;
-		}
-		if (ui != null)
-		{
-		    Dimension s = ui.getMaximumSize(this);
-		    if (s != null)
-			{
-				//System.out.println("        UI-MAX = " + s + ", UI = " + ui + ", IM="+this);
-				return s;
-			}
-		}
-		Dimension p = super.getMaximumSize();
-		//System.out.println("               MAX = " + p + ", COMP="+this);
-		return p;
-	}
-
-	public Dimension getMinimumSize()
-	{
-		if (min != null)
-		{
-			//System.out.println("HAVE_MIN_SIZE =  " + min);
-			return min;
-		}
-		if (ui != null)
-		{
-			Dimension s = ui.getMinimumSize(this);
-			if (s != null)
-			{
-				//	System.out.println("        UI-MIN = " + s + ", UI = " + ui + ", IM="+this);
-				return s;
-			}
-		}
-		Dimension p = super.getMinimumSize();
-		//	System.out.println("              MIN = " + p + ", COMP="+this);
-		return p;
-	}
-
-	public Dimension getPreferredSize()
-	{
-		if (pref != null)
-		{
-			//System.out.println("HAVE_PREF_SIZE =  " + pref);
-			return pref;
-		}
-
-		if (ui != null)
-		{
-			Dimension s = ui.getPreferredSize(this);
-			if (s != null)
-			{
-				//System.out.println("        UI-PREF = " + s + ", UI = " + ui + ", IM="+this);
-				return s;
-			}
-		}
-		Dimension p = super.getPreferredSize();
-		//	System.out.println("              PREF = " + p + ", COMP="+this);
-		return p;
-	}
-
-	public Component getNextFocusableComponent()
-	{
-		//          Return the next focusable component or null if the focus manager should choose the next focusable component automatically
-		return null;
-	}
-
-
-	public KeyStroke[] getRegisteredKeyStrokes()
-	{
-		//          Return the KeyStrokes that will initiate registered actions.
-		return null;
-	}
-
-	public JRootPane getRootPane()
-	{
-		JRootPane p = SwingUtilities.getRootPane(this);
-		System.out.println("root = " + p);
-		return p;
-	}
-
-	public Dimension getSize(Dimension rv)
-	{
-		//	System.out.println("JComponent, getsize()");
-		if (rv == null)
-			return new Dimension(getWidth(),
-			                     getHeight());
-		else
-		{
-			rv.setSize(getWidth(),
-			           getHeight());
-			return rv;
-		}
-	}
-
-	public JToolTip createToolTip()
-	{
-		if (tooltip == null)
-			tooltip = new JToolTip(tool_tip_text);
-		return tooltip;
-	}
-
-	public Point getToolTipLocation(MouseEvent event)
-        {	return null;    }
-
-	public void setToolTipText(String text)
-	{	tool_tip_text = text;    }
-
-	public String getToolTipText()
-	{	return tool_tip_text;    }
-
-	public String getToolTipText(MouseEvent event)
-	{	return tool_tip_text;    }
-
-	public Container getTopLevelAncestor()
-	{
-		//      Returns the top-level ancestor of this component (either the containing Window or Applet), or null if this component has not been added to any container.
-		System.out.println("JComponent, getTopLevelAncestor()");
-		return null;
-	}
-
-	public Rectangle getVisibleRect()
-	{
-		///    Returns the Component's "visible rectangle" - the intersection of this components visible rectangle:
-		System.out.println("JComponent, getVisibleRect()");
-		return null;
-	}
-
-	public void grabFocus()
-	{
-		//      Set the focus on the receiving component.
-	}
-
-	public boolean hasFocus()
-	{
-		//      Returns true if this Component has the keyboard focus.
-		return false;
-	}
-
-	public boolean isDoubleBuffered()
-	{	return use_double_buffer;    }
-
-	public boolean isFocusCycleRoot()
-	{
-		//      Override this method and return true if your component is the root of of a component tree with its own focus cycle.
-		return false;
-	}
-
-	public boolean isFocusTraversable()
-	{
-		//      Identifies whether or not this component can receive the focus.
-		return false;
-	}
-
-	public static boolean isLightweightComponent(Component c)
-	{
-		return c.getPeer() instanceof LightweightPeer;
-	}
-
-	public boolean isManagingFocus()
-	{
-		//      Override this method and return true if your JComponent manages focus.
-		return false;
-	}
-
-        public boolean isOpaque()
-	{	return opaque;    }
-
-	public boolean isOptimizedDrawingEnabled()
-	{
-		//      Returns true if this component tiles its children,
-		return true;
-	}
-
-	public boolean isPaintingTile()
-	{
-		//      Returns true if the receiving component is currently painting a tile.
-		return false;
-	}
-
-	public boolean isRequestFocusEnabled()
-	{
-		//      Return whether the receiving component can obtain the focus by calling requestFocus
-		return false;
-	}
-
-	public boolean isValidateRoot()
-	{
-		//      If this method returns true, revalidate() calls by descendants of this component will cause the entire tree beginning with this root to be validated.
-		return false;
-	}
-
-	public void paint(Graphics g)
-	{
-		//	System.out.println("SWING_PAINT:" + this);
-
-		paintBorder(g);
-		paintComponent(g);
-		paintChildren(g);
-	}
-
-	protected  void paintBorder(Graphics g)
-	{
-		//	System.out.println("PAINT_BORDER      x XXXXXXX x x x x x x x x x x x x:" + getBorder() + ", THIS="+this);
-
-		//       Paint the component's border.
-		if (getBorder() != null)
-		{
-			//System.out.println("PAINT_BORDER      x XXXXXXX x x x x x x x x x x x x:" + getBorder() + ", THIS="+this);
-
-			getBorder().paintBorder(this,
-			                        g,
-			                        0,
-			                        0,
-			                        getWidth(),
-			                        getHeight());
-		}
-	}
-
-	protected  void paintChildren(Graphics g)
-	{
-	    //      Paint this component's children.
-	    //super.paintChildren(g);
-	}
-
-	protected  void paintComponent(Graphics g)
-	{
-		//      If the UI delegate is non-null, call its paint method.
-		if (ui != null)
-		{
-			ui.paint(g, this);
-		}
-	}
-    
-    /**
-     * Paint the specified region in this component and all of 
-     * its descendants that overlap the region, immediately.
-     */
-	public void paintImmediately(int x, int y, int w, int h)
-        {
-	
-	    //Ronald: this shoudld probably redirect to the PLAF ....
-	}
-
-	public void paintImmediately(Rectangle r)
-	{
-	    ///      Paint the specified region now.
-	    paintImmediately((int)r.getX(),
-			     (int)r.getY(),
-			     (int)r.getWidth(),
-			     (int)r.getHeight());
-	}
-	protected  String paramString()
-	{
-		//      Returns a string representation of this JComponent.
-		return "JComponent";
-	}
-	protected  void processComponentKeyEvent(KeyEvent e)
-	{
-		//     Process any key events that the component itself recognizes.
-	    //System.out.println("COMP_KEY-EVENT: " + e);
-	}
-	protected  void processFocusEvent(FocusEvent e)
-	{
-		//      Processes focus events occurring on this component by dispatching them to any registered FocusListener objects.
-	    //System.out.println("FOCUS_EVENT: " + e);
-	}
-
-	protected  void processKeyEvent(KeyEvent e)
-	{
-		//      Override processKeyEvent to process events protected
-	    //System.out.println("KEY-EVENT: " + e);
-	}
-
-        public void processMouseMotionEvent(MouseEvent e)
-	{
-	    //      Processes mouse motion events occurring on this component by dispatching them to any registered MouseMotionListener objects.
-	    //System.out.println("COMP_MOUSE-EVENT: " + e + ", MEMORY = " + Runtime.getRuntime().freeMemory());
-	}
-
-	public void registerKeyboardAction(ActionListener anAction,
-	                            KeyStroke aKeyStroke,
-	                            int aCondition)
-	{
-		registerKeyboardAction(anAction,
-		                       null,
-		                       aKeyStroke,
-		                       aCondition);
-	}
-
-	public void registerKeyboardAction(ActionListener anAction,
-	                            String aCommand,
-	                            KeyStroke aKeyStroke,
-	                            int aCondition)
-	{
-		//  Register a new keyboard action.
-	}
-
-
-	public void removeNotify()
-	{
-		//      Notification to this component that it no longer has a parent component.
-	}
-
-	public void repaint(long tm, int x, int y, int width, int height)
-	{
-		//   Adds the specified region to the dirty region list if the component is showing.
-		//System.out.println("JC: repaint");
-		super.repaint(tm, x,y,width,height);
-	}
-
-	public void repaint(Rectangle r)
-	{
-		//      Adds the specified region to the dirty region list if the component is showing.
-		repaint((long)0,
-		        (int)r.getX(),
-		        (int)r.getY(),
-		        (int)r.getWidth(),
-		        (int)r.getHeight());
-	}
-
-	public boolean requestDefaultFocus()
-	{
-		//      Request the focus for the component that should have the focus by default.
-		return false;
-	}
-
-	public void requestFocus()
-	{
-		//      Set focus on the receiving component if isRequestFocusEnabled returns true
-		super.requestFocus();
-	}
-
-	public void resetKeyboardActions()
-	{
-		//      Unregister all keyboard actions
-	}
-
-	public void reshape(int x, int y, int w, int h)
-	{
-		///      Moves and resizes this component.
-		super.reshape(x,y,w,h);
-	}
-
-	public void revalidate()
-	{
-		//     Support for deferred automatic layout.
-		if (getParent() == null)
-			invalidate();
-	}
-
-	public void scrollRectToVisible(Rectangle aRect)
-	{
-		//      Forwards the scrollRectToVisible() message to the JComponent's parent.
-	}
-
-	public void setAlignmentX(float alignmentX)
-	{
-		//      Set the the vertical alignment.
-	}
-
-	public void setAlignmentY(float alignmentY)
-	{
-		//      Set the the horizontal alignment.
-	}
-
-	public void setAutoscrolls(boolean autoscrolls)
-	{
-		//      If true this component will automatically scroll its contents when dragged, if contained in a component that supports scrolling, such as JViewport
-	}
-
-	public void setDebugGraphicsOptions(int debugOptions)
-	{
-		//      Enables or disables diagnostic information about every graphics operation performed within the component or one of its children.
-	}
-
-	public void setDoubleBuffered(boolean aFlag)
-	{
-		use_double_buffer = aFlag;
-	}
-
-	public void setEnabled(boolean enabled)
-	{
-		// Sets whether or not this component is enabled.
-		super.setEnabled(enabled);
-		repaint();
-	}
-
-	public void setFont(Font font)
-	{
-		super.setFont(font);
-		revalidate();
-		repaint();
-	}
-
-	public void setBackground(Color bg)
-	{
-		super.setBackground(bg);
-		revalidate();
-		repaint();
-	}
-	public void setForeground(Color fg)
-	{
-		super.setForeground(fg);
-		revalidate();
-		repaint();
-	}
-
-	public void setMaximumSize(Dimension maximumSize)
-	{	max = maximumSize;    }
-
-	public void setMinimumSize(Dimension minimumSize)
-	{   min = minimumSize; }
-
-	public void setPreferredSize(Dimension preferredSize)
-	{   pref = preferredSize;   }
-
-	public void setNextFocusableComponent(Component aComponent)
-	{
-		//       Specifies the next component to get the focus after this one, for example, when the tab key is pressed.
-	}
-
-	public void setOpaque(boolean isOpaque)
-	{
-		opaque = isOpaque;
-		revalidate();
-		repaint();
-	}
-
-
-	public void setRequestFocusEnabled(boolean aFlag)
-	{
-	}
-
-
-	public void setVisible(boolean aFlag)
-	{
-		//    Makes the component visible or invisible.
-
-		super.setVisible(aFlag);
-		if (getParent() != null)
-		{
-			Rectangle dims = getBounds();
-			getParent().repaint((int)dims.getX(),
-			                    (int)dims.getY(),
-			                    (int)dims.getWidth(),
-			                    (int)dims.getHeight());
-		}
-	}
-
-	public void unregisterKeyboardAction(KeyStroke aKeyStroke)
-	{
-		//          Unregister a keyboard action.
-	}
-
-
-	public void update(Graphics g)
-	{
-		paint(g);
-	}
-
-        public String getUIClassID()
-	{
-		///          Return the UIDefaults key used to look up the name of the swing.
-		return "JComponent";
-	}
-
-	protected void setUI(ComponentUI newUI)
-	{
-		if (ui != null)
-		{
-			ui.uninstallUI(this);
-		}
-
-		//          Set the look and feel delegate for this component.
-		ui = newUI;
-
-		if (ui != null)
-		{
-			ui.installUI(this);
-		}
-
-		revalidate();
-		repaint();
-	}
-
-	public void updateUI()
-	{
-		//        Resets the UI property to a value from the current look and feel.
-		System.out.println("update UI not overwritten in class: " + this);
-	}
+    if (ui != null)
+      ui.installUI(this);
 
+    firePropertyChange("UI", oldUI, newUI);
+    
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * This method should be overridden in subclasses. In JComponent, the
+   * method does nothing. In subclasses, it should a UI delegate
+   * (corresponding to the symbolic name returned from {@link
+   * getUIClassID}) from the {@link UIManager}, and calls {@link setUI}
+   * with the new delegate.
+   */
+  public void updateUI()
+  {
+    System.out.println("update UI not overwritten in class: " + this);
+  }
+
+  public static Locale getDefaultLocale()
+  {
+    return defaultLocale;
+  }
+  
+  public static void setDefaultLocale(Locale l)
+  {
+    defaultLocale = l;
+  }
 }
Index: javax/swing/JDesktopPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JDesktopPane.java,v
retrieving revision 1.3
diff -u -r1.3 JDesktopPane.java
--- javax/swing/JDesktopPane.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JDesktopPane.java	6 Sep 2004 16:35:55 -0000
@@ -37,6 +37,8 @@
 
 package javax.swing;
 
+import java.awt.Component;
+import java.beans.PropertyVetoException;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import javax.accessibility.Accessible;
@@ -44,244 +46,281 @@
 import javax.accessibility.AccessibleRole;
 import javax.swing.plaf.DesktopPaneUI;
 
+
 /**
- * JDesktopPane
- * @author	Andrew Selkirk
- * @version	1.0
+ * JDesktopPane is a container (usually for JInternalFrames) that simulates a
+ * desktop. Typically, the user will create JInternalFrames and place thme in
+ * a JDesktopPane. The user can then interact with JInternalFrames like they
+ * usually would with JFrames. The actions (minimize, maximize, close, etc)
+ * are done by using a DesktopManager that is associated with the
+ * JDesktopPane.
  */
 public class JDesktopPane extends JLayeredPane implements Accessible
 {
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 766333777224038726L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJDesktopPane
-	 */
-	protected class AccessibleJDesktopPane extends AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJDesktopPane
-		 * @param component TODO
-		 */
-		protected AccessibleJDesktopPane(JDesktopPane component) {
-			super(component);
-			// TODO
-		} // AccessibleJDesktopPane()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.DESKTOP_PANE;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJDesktopPane
-
-
-	//-------------------------------------------------------------
-	// Constants --------------------------------------------------
-	//-------------------------------------------------------------
-	
-	/**
-	 * LIVE_DRAG_MODE
-	 */
-	public static int LIVE_DRAG_MODE = 0;
-
-	/**
-	 * OUTLINE_DRAG_MODE
-	 */
-	public static int OUTLINE_DRAG_MODE = 1;
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "DesktopPaneUI";
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * selectedFrame
-	 */
-	private transient JInternalFrame selectedFrame;
-
-        /**
-         * desktopManager
-         */
-	private transient DesktopManager desktopManager;
-
-
-	/**
-	 * dragMode
-	 */
-	private int dragMode;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JDesktopPane
-	 */
-	public JDesktopPane() {
-		// TODO
-	} // JDesktopPane()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getUI
-	 * @returns DesktopPaneUI
-	 */
-	public DesktopPaneUI getUI() {
-		return (DesktopPaneUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(DesktopPaneUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * setDragMode
-	 * @param mode TODO
-	 */
-	public void setDragMode(int mode) {
-		this.dragMode = mode;
-		// TODO
-	} // setDragMode()
-
-	/**
-	 * getDragMode
-	 * @returns int
-	 */
-	public int getDragMode() {
-		return dragMode;
-	} // getDragMode()
-
-	/**
-	 * getDesktopManager
-	 * @returns DesktopManager
-	 */
-	public DesktopManager getDesktopManager() {
-		return desktopManager;
-	} // getDesktopManager()
-
-	/**
-	 * setDesktopManager
-	 * @param manager TODO
-	 */
-	public void setDesktopManager(DesktopManager manager) {
-		this.desktopManager = manager;
-		// TODO
-	} // setDesktopManager()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((DesktopPaneUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getAllFrames
-	 * @returns JInternalFrame[]
-	 */
-	public JInternalFrame[] getAllFrames() {
-		return null; // TODO
-	} // getAllFrames()
-
-	/**
-	 * getSelectedFrame
-	 * @returns JInternalFrame
-	 */
-	public JInternalFrame getSelectedFrame() {
-		return null; // TODO
-	} // getSelectedFrame()
-
-	/**
-	 * setSelectedFrame
-	 * @param frame TODO
-	 */
-	public void setSelectedFrame(JInternalFrame frame) {
-		// TODO
-	} // setSelectedFrame()
-
-	/**
-	 * getAllFramesInLayer
-	 * @param layer TODO
-	 * @returns JInternalFrame[]
-	 */
-	public JInternalFrame[] getAllFramesInLayer(int layer) {
-		return null; // TODO
-	} // getAllFramesInLayer()
-
-	/**
-	 * isOpaque
-	 * @returns boolean
-	 */
-	public boolean isOpaque() {
-		return true;
-	} // isOpaque()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJDesktopPane(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JDesktopPane
+  /**
+   * This specifies that when dragged, a JInternalFrame should be completely
+   * visible.
+   */
+  public static int LIVE_DRAG_MODE = 0;
+
+  /**
+   * This specifies that when dragged, a JInternalFrame should only be visible
+   * as an outline.
+   */
+  public static int OUTLINE_DRAG_MODE = 1;
+
+  /** The selected frame in the JDesktopPane. */
+  private transient JInternalFrame selectedFrame;
+
+  /** The JDesktopManager to use for acting on JInternalFrames. */
+  transient DesktopManager desktopManager;
+
+  /** The drag mode used by the JDesktopPane. */
+  private transient int dragMode = LIVE_DRAG_MODE;
+
+  /**
+   * AccessibleJDesktopPane
+   */
+  protected class AccessibleJDesktopPane extends AccessibleJComponent
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 6079388927946077570L;
+
+    /**
+     * Constructor AccessibleJDesktopPane
+     */
+    protected AccessibleJDesktopPane()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     *
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.DESKTOP_PANE;
+    }
+  }
+
+  /**
+   * Creates a new JDesktopPane object.
+   */
+  public JDesktopPane()
+  {
+    setLayout(null);
+    updateUI();
+  }
+
+  /**
+   * This method returns the UI used with the JDesktopPane.
+   *
+   * @return The UI used with the JDesktopPane.
+   */
+  public DesktopPaneUI getUI()
+  {
+    return (DesktopPaneUI) ui;
+  }
+
+  /**
+   * This method sets the UI used with the JDesktopPane.
+   *
+   * @param ui The UI to use with the JDesktopPane.
+   */
+  public void setUI(DesktopPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets the drag mode to use with the JDesktopPane.
+   *
+   * @param mode The drag mode to use.
+   *
+   * @throws IllegalArgumentException If the drag mode given is not
+   *         LIVE_DRAG_MODE or OUTLINE_DRAG_MODE.
+   */
+  public void setDragMode(int mode)
+  {
+    if ((mode != LIVE_DRAG_MODE) && (mode != OUTLINE_DRAG_MODE))
+      throw new IllegalArgumentException("Drag mode not valid.");
+
+    // FIXME: Unsupported mode.
+    if (mode == OUTLINE_DRAG_MODE)
+      throw new IllegalArgumentException("Outline drag modes are unsupported.");
+
+    dragMode = mode;
+  }
+
+  /**
+   * This method returns the drag mode used with the JDesktopPane.
+   *
+   * @return The drag mode used with the JDesktopPane.
+   */
+  public int getDragMode()
+  {
+    return dragMode;
+  }
+
+  /**
+   * This method returns the DesktopManager used with the JDesktopPane.
+   *
+   * @return The DesktopManager to use with the JDesktopPane.
+   */
+  public DesktopManager getDesktopManager()
+  {
+    return desktopManager;
+  }
+
+  /**
+   * This method sets the DesktopManager to use with the JDesktopPane.
+   *
+   * @param manager The DesktopManager to use with the JDesktopPane.
+   */
+  public void setDesktopManager(DesktopManager manager)
+  {
+    desktopManager = manager;
+  }
+
+  /**
+   * This method restores the UI used with the JDesktopPane to the default.
+   */
+  public void updateUI()
+  {
+    setUI((DesktopPaneUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns a String identifier that allows the UIManager to know
+   * which class will act as JDesktopPane's UI.
+   *
+   * @return A String identifier for the UI class to use.
+   */
+  public String getUIClassID()
+  {
+    return "DesktopPaneUI";
+  }
+
+  /**
+   * This method returns all JInternalFrames that are in the JDesktopPane.
+   *
+   * @return All JInternalFrames that are in the JDesktopPane.
+   */
+  public JInternalFrame[] getAllFrames()
+  {
+    return getFramesFromComponents(getComponents());
+  }
+
+  /**
+   * This method returns the currently selected frame in the JDesktopPane.
+   *
+   * @return The currently selected frame in the JDesktopPane.
+   */
+  public JInternalFrame getSelectedFrame()
+  {
+    return selectedFrame;
+  }
+
+  /**
+   * This method sets the selected frame in the JDesktopPane.
+   *
+   * @param frame The selected frame in the JDesktopPane.
+   */
+  public void setSelectedFrame(JInternalFrame frame)
+  {
+    if (selectedFrame != null)
+      {
+	try
+	  {
+	    selectedFrame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+    selectedFrame = null;
+
+    try
+      {
+	if (frame != null)
+	  frame.setSelected(true);
+
+	selectedFrame = frame;
+      }
+    catch (PropertyVetoException e)
+      {
+      }
+  }
+
+  /**
+   * This method returns all the JInternalFrames in the given layer.
+   *
+   * @param layer The layer to grab frames in.
+   *
+   * @return All JInternalFrames in the given layer.
+   */
+  public JInternalFrame[] getAllFramesInLayer(int layer)
+  {
+    return getFramesFromComponents(getComponentsInLayer(layer));
+  }
+
+  /**
+   * This method always returns true to indicate that it is not transparent.
+   *
+   * @return true.
+   */
+  public boolean isOpaque()
+  {
+    return true;
+  }
+
+  /**
+   * This method returns a String that describes the JDesktopPane.
+   *
+   * @return A String that describes the JDesktopPane.
+   */
+  protected String paramString()
+  {
+    return "JDesktopPane";
+  }
+
+  /**
+   * This method returns all the JInternalFrames in the given Component array.
+   *
+   * @param components An array to search for JInternalFrames in.
+   *
+   * @return An array of JInternalFrames found in the Component array.
+   */
+  private static JInternalFrame[] getFramesFromComponents(Component[] components)
+  {
+    int count = 0;
+
+    for (int i = 0; i < components.length; i++)
+	if (components[i] instanceof JInternalFrame)
+	  count++;
+	  
+    JInternalFrame[] value = new JInternalFrame[count];
+    for (int i = 0, j = 0; i < components.length && j != count; i++)
+      if (components[i] instanceof JInternalFrame)
+	value[j++] = (JInternalFrame) components[i];
+    return value;
+  }
+
+  /**
+   * getAccessibleContext
+   *
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJDesktopPane();
+
+    return accessibleContext;
+  }
+}
Index: javax/swing/JDialog.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JDialog.java,v
retrieving revision 1.2
diff -u -r1.2 JDialog.java
--- javax/swing/JDialog.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JDialog.java	6 Sep 2004 16:35:55 -0000
@@ -1,5 +1,5 @@
 /* JDialog.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.BorderLayout;
@@ -45,227 +44,519 @@
 import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
 import java.awt.LayoutManager;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowEvent;
+import java.awt.IllegalComponentStateException;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 
+
 /**
- * Unlike JComponent derivatives, JDialog inherits from
- * java.awt.Dialog. But also lets a look-and-feel component to its work.
+ * Unlike JComponent derivatives, JDialog inherits from java.awt.Dialog. But
+ * also lets a look-and-feel component to its work.
  *
- * @author Ronald Veldema (rveldema@cs.vu.nl)
+ * @author Ronald Veldema (rveldema_AT_cs.vu.nl)
  */
-public class JDialog extends Dialog implements Accessible
+public class JDialog extends Dialog implements Accessible, WindowConstants,
+                                               RootPaneContainer
 {
-    public final static int HIDE_ON_CLOSE        = 0;
-    public final static int DISPOSE_ON_CLOSE     = 1;
-    public final static int DO_NOTHING_ON_CLOSE  = 2;
-
-    protected  AccessibleContext accessibleContext;
-
-    private int close_action = HIDE_ON_CLOSE;    
-
-    /***************************************************
-     *
-     *
-     *  constructors
-     *
-     *
-     *************/
-
-    JDialog(Frame owner)
-    {
-	this(owner, "dialog");
-    }
-    
-    JDialog(Frame owner,
-	    String s)
-    {
-	this(owner, s, true);
-    }
-    
-  JDialog(Frame owner,
-	  String s,
-	  boolean modeld)
-    {
-	super(owner, s, modeld);
-    }
-
-  JDialog(Frame owner,
-	  //  String s,
-	  boolean modeld)
-    {
-	super(owner, "JDialog", modeld);
-    }
-  JDialog(Dialog owner)
-  {
-      this(owner, "dialog");
-  }
-    
-    JDialog(Dialog owner,
-	    String s)
-    {
-	this(owner, s, true);
-    }
-    
-  JDialog(Dialog owner,
-	  String s,
-	  boolean modeld)
-    {
-	super(owner, s, modeld);
-    }
-
-
-    /***************************************************
-     *
-     *
-     *  methods, this part is shared with JDialog, JFrame
-     *
-     *
-     *************/
+  private static final long serialVersionUID = -864070866424508218L;
 
-  
-    private boolean checking;
-    protected  JRootPane         rootPane;
+  /** DOCUMENT ME! */
+  protected AccessibleContext accessibleContext;
 
-    void setLocationRelativeTo(Component c)
-    {
-    }
+  /** The single RootPane in the Dialog. */
+  protected JRootPane rootPane;
 
+  /** Whether checking is enabled on the RootPane */
+  protected boolean rootPaneCheckingEnabled = true;
 
-    protected  void frameInit()
-    {
-      super.setLayout(new BorderLayout(1, 1));
-      getRootPane(); // will do set/create
-    }
+  /** The default action taken when closed. */
+  private int close_action = HIDE_ON_CLOSE;
   
+  /** Whether JDialogs are decorated by the Look and Feel. */
+  private static boolean decorated = false;
+
+  /**
+   * Creates a new non-modal JDialog with no title 
+   * using a shared Frame as the owner.
+   */
+  public JDialog()
+  {
+    this(SwingUtilities.getOwnerFrame(), "", false, null);
+  }
+
+  /**
+   * Creates a new non-modal JDialog with no title
+   * using the given owner.
+   *
+   * @param owner The owner of the JDialog.
+   */
+  public JDialog(Dialog owner)
+  {
+    this(owner, "", false, null);
+  }
+
+  /**
+   * Creates a new JDialog with no title using the
+   * given modal setting and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   */
+  public JDialog(Dialog owner, boolean modal)
+  {
+    this(owner, "", modal, null);
+  }
+
+  /**
+   * Creates a new non-modal JDialog using the 
+   * given title and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   */
+  public JDialog(Dialog owner, String title)
+  {
+    this(owner, title, false, null);
+  }
+
+  /**
+   * Creates a new JDialog using the given modal 
+   * settings, title, and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   */
+  public JDialog(Dialog owner, String title, boolean modal)
+  {
+    this(owner, title, modal, null);
+  }
+
+  /**
+   * Creates a new JDialog using the given modal 
+   * settings, title, owner and graphics configuration.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   * @param gc The Graphics Configuration to use.
+   */
+  public JDialog(Dialog owner, String title, boolean modal,
+                 GraphicsConfiguration gc)
+  {
+    super(owner, title, modal, gc);
+    dialogInit();
+  }
+
+  /**
+   * Creates a new non-modal JDialog with no title
+   * using the given owner.
+   *
+   * @param owner The owner of the JDialog.
+   */
+  public JDialog(Frame owner)
+  {
+    this(owner, "", false, null);
+  }
+
+  /**
+   * Creates a new JDialog with no title using the
+   * given modal setting and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   */
+  public JDialog(Frame owner, boolean modal)
+  {
+    this(owner, "", modal, null);
+  }
+
+  /**
+   * Creates a new non-modal JDialog using the 
+   * given title and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   */
+  public JDialog(Frame owner, String title)
+  {
+    this(owner, title, false, null);
+  }
+
+  /**
+   * Creates a new JDialog using the given modal 
+   * settings, title, and owner.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   */
+  public JDialog(Frame owner, String title, boolean modal)
+  {
+    this(owner, title, modal, null);
+  }
+
+  /**
+   * Creates a new JDialog using the given modal 
+   * settings, title, owner and graphics configuration.
+   *
+   * @param owner The owner of the JDialog.
+   * @param title The title of the JDialog.
+   * @param modal Whether the JDialog is modal.
+   * @param gc The Graphics Configuration to use.
+   */
+  public JDialog(Frame owner, String title, boolean modal,
+                 GraphicsConfiguration gc)
+  {
+    super((owner == null) ? SwingUtilities.getOwnerFrame() : owner, 
+          title, modal, gc);
+    dialogInit();
+  }
+
+  /**
+   * This method is called to initialize the 
+   * JDialog. It sets the layout used, the locale, 
+   * and creates the RootPane.
+   */
+  protected void dialogInit()
+  {
+    // FIXME: Do a check on GraphicsEnvironment.isHeadless()
+    setRootPaneCheckingEnabled(false);
+    setLocale(JComponent.getDefaultLocale());       
+    getRootPane(); // will do set/create  
+    setRootPaneCheckingEnabled(true);    
+    invalidate();
+
+  }
+
+  /**
+   * This method returns whether JDialogs will have their
+   * window decorations provided by the Look and Feel.
+   *
+   * @return Whether the window decorations are Look and Feel provided.
+   */
+  public static boolean isDefaultLookAndFeelDecorated()
+  {
+    return decorated;
+  }
+
+  /**
+   * This method sets whether JDialogs will have their
+   * window decorations provided by the Look and Feel.
+   *
+   * @param defaultLookAndFeelDecorated Whether the window
+   * decorations are Look and Feel provided.
+   */
+  public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated)
+  {
+    decorated = defaultLookAndFeelDecorated;
+  }
+
+  /**
+   * This method returns the preferred size of 
+   * the JDialog.
+   *
+   * @return The preferred size.
+   */
   public Dimension getPreferredSize()
   {
     Dimension d = super.getPreferredSize();
     return d;
   }
 
-    JMenuBar getJMenuBar()
-    {    return getRootPane().getJMenuBar();   }
-    
-    void setJMenuBar(JMenuBar menubar)
-    {    getRootPane().setJMenuBar(menubar); }
-    
+  /**
+   * This method returns the JMenuBar used
+   * in this JDialog.
+   *
+   * @return The JMenuBar in the JDialog.
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return getRootPane().getJMenuBar();
+  }
 
-  public  void setLayout(LayoutManager manager)
-  {    super.setLayout(manager);  }
+  /**
+   * This method sets the JMenuBar used 
+   * in this JDialog.
+   *
+   * @param menubar The JMenuBar to use.
+   */
+  public void setJMenuBar(JMenuBar menubar)
+  {
+    getRootPane().setJMenuBar(menubar);
+  }
 
-    void setLayeredPane(JLayeredPane layeredPane) 
-    {   getRootPane().setLayeredPane(layeredPane);   }
-  
-    JLayeredPane getLayeredPane()
-    {   return getRootPane().getLayeredPane();     }
-  
-    JRootPane getRootPane()
-    {
-	if (rootPane == null)
-	    setRootPane(createRootPane());
-	return rootPane;          
-    }
-
-    void setRootPane(JRootPane root)
-    {
-	if (rootPane != null)
-	    remove(rootPane);
-	    
-	rootPane = root; 
-	add(rootPane, BorderLayout.CENTER);
-    }
+  /**
+   * This method sets the LayoutManager used in the JDialog.
+   * This method will throw an Error if rootPaneChecking is 
+   * enabled.
+   *
+   * @param manager The LayoutManager to use.
+   */
+  public void setLayout(LayoutManager manager)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("rootPaneChecking is enabled - cannot set layout.");
+    super.setLayout(manager);
+  }
 
-    JRootPane createRootPane()
-    {   return new JRootPane();    }
+  /**
+   * This method sets the JLayeredPane used in the JDialog.
+   * If the given JLayeredPane is null, then this method
+   * will throw an Error.
+   *
+   * @param layeredPane The JLayeredPane to use.
+   */
+  public void setLayeredPane(JLayeredPane layeredPane)
+  {
+    if (layeredPane == null)
+      throw new IllegalComponentStateException("layeredPane cannot be null.");
+    getRootPane().setLayeredPane(layeredPane);
+  }
 
-    Container getContentPane()
-    {    return getRootPane().getContentPane();     }
+  /**
+   * This method returns the JLayeredPane used with this JDialog.
+   *
+   * @return The JLayeredPane used with this JDialog.
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    return getRootPane().getLayeredPane();
+  }
 
-    void setContentPane(Container contentPane)
-    {    getRootPane().setContentPane(contentPane);    }
-  
-    Component getGlassPane()
-    {    return getRootPane().getGlassPane();   }
-  
-    void setGlassPane(Component glassPane)
-    {   getRootPane().setGlassPane(glassPane);   }
+  /**
+   * This method returns the JRootPane used with this JDialog.
+   *
+   * @return The JRootPane used with this JDialog.
+   */
+  public JRootPane getRootPane()
+  {
+    if (rootPane == null)
+      setRootPane(createRootPane());
+    return rootPane;
+  }
 
-    
-    protected  void addImpl(Component comp, Object constraints, int index)
-    {	super.addImpl(comp, constraints, index);    }
+  /**
+   * This method sets the JRootPane used with this JDialog.
+   *
+   * @param root The JRootPane to use.
+   */
+  protected void setRootPane(JRootPane root)
+  {
+    if (rootPane != null)
+      remove(rootPane);
 
+    rootPane = root;
+    rootPane.show();
+    add(rootPane);
+  }
 
-    public void remove(Component comp)
-    {   getContentPane().remove(comp);  }
-  
-    protected  boolean isRootPaneCheckingEnabled()
-    {    return checking;        }
+  /**
+   * This method creates a new JRootPane.
+   *
+   * @return A new JRootPane.
+   */
+  protected JRootPane createRootPane()
+  {
+    return new JRootPane();
+  }
 
+  /**
+   * This method returns the ContentPane
+   * in the JRootPane.
+   *
+   * @return The ContentPane in the JRootPane.
+   */
+  public Container getContentPane()
+  {
+    return getRootPane().getContentPane();
+  }
 
-    protected  void setRootPaneCheckingEnabled(boolean enabled)
-    { checking = enabled;  }
+  /**
+   * This method sets the ContentPane to use with this
+   * JDialog. If the ContentPane given is null, this method
+   * will throw an exception.
+   *
+   * @param contentPane The ContentPane to use with the JDialog.
+   */
+  public void setContentPane(Container contentPane)
+  {
+    if (contentPane == null)
+      throw new IllegalComponentStateException("contentPane cannot be null.");
+    getRootPane().setContentPane(contentPane);
+  }
 
+  /**
+   * This method returns the GlassPane for this JDialog.
+   *
+   * @return The GlassPane for this JDialog.
+   */
+  public Component getGlassPane()
+  {
+    return getRootPane().getGlassPane();
+  }
 
-    public void update(Graphics g)
-    {   paint(g);  }
+  /**
+   * This method sets the GlassPane for this JDialog.
+   *
+   * @param glassPane The GlassPane for this JDialog.
+   */
+  public void setGlassPane(Component glassPane)
+  {
+    getRootPane().setGlassPane(glassPane);
+  }
 
-    protected  void processKeyEvent(KeyEvent e)
-    {	super.processKeyEvent(e);    }
+  /**
+   * This method is called when a component is added to the 
+   * the JDialog. Calling this method with rootPaneCheckingEnabled
+   * will cause an Error to be thrown.
+   *
+   * @param comp The component to add.
+   * @param constraints The constraints.
+   * @param index The position of the component.
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("rootPaneChecking is enabled - adding components disallowed.");
+    super.addImpl(comp, constraints, index);
+  }
 
-    /////////////////////////////////////////////////////////////////////////////////
-  
+  /**
+   * This method removes a component from the JDialog.
+   *
+   * @param comp The component to remove.
+   */
+  public void remove(Component comp)
+  {
+    // The path changes if the component == root.
+    if (comp == rootPane)
+      super.remove(rootPane);
+    else 
+      getContentPane().remove(comp);
+  }
 
-    protected  void processWindowEvent(WindowEvent e)
-    {
-	//	System.out.println("PROCESS_WIN_EV-1: " + e);
-	super.processWindowEvent(e); 
-	//	System.out.println("PROCESS_WIN_EV-2: " + e);
-	switch (e.getID())
+  /**
+   * This method returns whether rootPane checking is enabled.
+   *
+   * @return Whether rootPane checking is enabled.
+   */
+  protected boolean isRootPaneCheckingEnabled()
+  {
+    return rootPaneCheckingEnabled;
+  }
+
+  /**
+   * This method sets whether rootPane checking is enabled.
+   *
+   * @param enabled Whether rootPane checking is enabled.
+   */
+  protected void setRootPaneCheckingEnabled(boolean enabled)
+  {
+    rootPaneCheckingEnabled = enabled;
+  }
+
+  /**
+   * This method simply calls paint and returns.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+  
+  
+  /**
+   * This method handles window events. This allows the JDialog
+   * to honour its default close operation.
+   *
+   * @param e The WindowEvent.
+   */
+  protected void processWindowEvent(WindowEvent e)
+  {
+    //	System.out.println("PROCESS_WIN_EV-1: " + e);
+    super.processWindowEvent(e);
+    //	System.out.println("PROCESS_WIN_EV-2: " + e);
+    switch (e.getID())
+      {
+      case WindowEvent.WINDOW_CLOSING:
+        {
+	  switch (getDefaultCloseOperation())
 	    {
-	    case WindowEvent.WINDOW_CLOSING:
-		{
-		    switch(close_action)
-			{
-			case DISPOSE_ON_CLOSE:
-			    {
-				System.out.println("user requested dispose on close");
-				dispose();
-				break;
-			    }
-			case HIDE_ON_CLOSE:
-			    {
-				setVisible(false);
-				break;
-			    }
-			case DO_NOTHING_ON_CLOSE:
-			    break;
-			}
-		    break;
-		}
-		
-	    case WindowEvent.WINDOW_CLOSED:
-	    case WindowEvent.WINDOW_OPENED:
-	    case WindowEvent.WINDOW_ICONIFIED:
-	    case WindowEvent.WINDOW_DEICONIFIED:
-	    case WindowEvent.WINDOW_ACTIVATED:
-	    case WindowEvent.WINDOW_DEACTIVATED:
+	    case DISPOSE_ON_CLOSE:
+	      {
+		dispose();
+		break;
+	      }
+	    case HIDE_ON_CLOSE:
+	      {
+		setVisible(false);
 		break;
+	      }
+	    case DO_NOTHING_ON_CLOSE:
+	      break;
 	    }
-    }   
- 
+	  break;
+        }
+      case WindowEvent.WINDOW_CLOSED:
+      case WindowEvent.WINDOW_OPENED:
+      case WindowEvent.WINDOW_ICONIFIED:
+      case WindowEvent.WINDOW_DEICONIFIED:
+      case WindowEvent.WINDOW_ACTIVATED:
+      case WindowEvent.WINDOW_DEACTIVATED:
+	break;
+      }
+  }
+
+  /**
+   * This method sets the action to take
+   * when the JDialog is closed.
+   *
+   * @param operation The action to take.
+   */
+  public void setDefaultCloseOperation(int operation)
+  {
+    if (operation == DO_NOTHING_ON_CLOSE ||
+    	operation == HIDE_ON_CLOSE ||
+	operation == DISPOSE_ON_CLOSE)
+      close_action = operation;
+    else
+      throw new IllegalArgumentException("Default close operation must be one of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, or DISPOSE_ON_CLOSE");
+  }
 
-    void setDefaultCloseOperation(int operation)
-    {  close_action = operation;   }
+  /**
+   * This method returns the action taken when
+   * the JDialog is closed.
+   *
+   * @return The action to take.
+   */
+  public int getDefaultCloseOperation()
+  {
+    return close_action;
+  }
 
-    protected  String paramString()
-    {   return "JDialog";     }
+  /**
+   * This method returns a String describing the JDialog.
+   *
+   * @return A String describing the JDialog.
+   */
+  protected String paramString()
+  {
+    return "JDialog";
+  }
 
-    public AccessibleContext getAccessibleContext()
-    {
-	return null;
-    }  
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
 }
Index: javax/swing/JEditorPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JEditorPane.java,v
retrieving revision 1.2
diff -u -r1.2 JEditorPane.java
--- javax/swing/JEditorPane.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JEditorPane.java	6 Sep 2004 16:35:55 -0000
@@ -1,5 +1,5 @@
-/* JEditorPane.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JEditorPane.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,189 +35,284 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Dimension;
 import java.awt.event.KeyEvent;
 import java.io.InputStream;
+import java.io.IOException;
 import java.net.URL;
+
 import javax.accessibility.AccessibleContext;
-import javax.swing.text.EditorKit;
-import javax.swing.text.JTextComponent;
-import javax.swing.text.PlainEditorKit;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkListener;
+import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.EditorKit;
+import javax.swing.text.JTextComponent;
+
 
 public class JEditorPane extends JTextComponent
 {
-    URL page_url;
-    EditorKit kit;
-    String ctype = "text/plain";
-    boolean focus_root;
-    boolean manages_focus;
-
-
-    public JEditorPane()
-    {
-    }
-
-    public JEditorPane(String url)
-    {
-	this();
-	setPage(url);
-    }
-    
-    public JEditorPane(String type, String text)
-    {
-	ctype = text;
-	setText(text);
-    }
-    
-    public JEditorPane(URL url)
-    {
-	setPage(url);
-    }
-
-    void addHyperlinkListener(HyperlinkListener listener)
-    {  }
-    
-    protected  EditorKit createDefaultEditorKit()
-    {	return new PlainEditorKit();    }
-    
-    static EditorKit createEditorKitForContentType(String type)
-    {	return new PlainEditorKit();     }
-    
-  void fireHyperlinkUpdate(HyperlinkEvent e)
+  private static final long serialVersionUID = 3140472492599046285L;
+  
+  URL page_url;
+  EditorKit kit;
+  String ctype = "text/plain";
+  boolean focus_root;
+  boolean manages_focus;
+
+  public JEditorPane()
+  {
+  }
+
+  public JEditorPane(String url) throws IOException
+  {
+    setPage(url);
+  }
+
+  public JEditorPane(String type, String text)
   {
+    ctype = text;
+    setText(text);
+  }
+
+  public JEditorPane(URL url) throws IOException
+  {
+    setPage(url);
+  }
+
+  protected EditorKit createDefaultEditorKit()
+  {
+    return new DefaultEditorKit();
+  }
+
+  public static EditorKit createEditorKitForContentType(String type)
+  {
+    return new DefaultEditorKit();
+  }
+
+  /**
+   * Sends a given <code>HyperlinkEvent</code> to all registered listeners.
+   *
+   * @param event the event to send
+   */
+  public void fireHyperlinkUpdate(HyperlinkEvent event)
+  {
+    HyperlinkListener[] listeners = getHyperlinkListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+       listeners[index].hyperlinkUpdate(event);
   }
 
   public AccessibleContext getAccessibleContext()
-  {      return null;  }
+  {
+    return null;
+  }
 
-  String getContentType()
-    {  return ctype;   }
+  public String getContentType()
+  {
+    return ctype;
+  }
 
-  EditorKit getEditorKit()
-    {  return kit;    }
-    
-  static String getEditorKitClassNameForContentType(String type)
-    { return "text/plain";  }
-  
-  EditorKit getEditorKitForContentType(String type)
-    { return kit;  }
-    
-    public Dimension getPreferredSize()
-    {
-	//Returns the preferred size for the JEditorPane.  
-	return super.getPreferredSize();
-    }
+  public EditorKit getEditorKit()
+  {
+    return kit;
+  }
+
+  public static String getEditorKitClassNameForContentType(String type)
+  {
+    return "text/plain";
+  }
+
+  public EditorKit getEditorKitForContentType(String type)
+  {
+    return kit;
+  }
+
+  /**
+   * Returns the preferred size for the JEditorPane.  
+   */
+  public Dimension getPreferredSize()
+  {
+    return super.getPreferredSize();
+  }
 
   public boolean getScrollableTracksViewportHeight()
-    {  return false;  }
+  {
+    return false;
+  }
+
   public boolean getScrollableTracksViewportWidth()
-    {  return false;  }
+  {
+    return false;
+  }
+
+  public URL getPage()
+  {
+    return page_url;
+  }
 
-  URL getPage()
-    { return page_url;  }
+  protected InputStream getStream(URL page)
+  {
+    try
+      {
+	return page.openStream();
+      }
+    catch (Exception e)
+      {
+	System.out.println("Hhmmm, failed to open stream: " + e);
+      }
+    return null;
+  }
 
-  protected  InputStream getStream(URL page)
-    {	
-	try {
-	    return page.openStream();    
-	} catch (Exception e) {
-	    System.out.println("Hhmmm, failed to open stream: " + e);
-	}	
-	return null;
-    }
-
-    public String getText()
-    { return super.getText();    }
-    
-    public String getUIClassID()
-    {    return "JEditorPane";  }
-
-    public boolean isFocusCycleRoot()
-    { return focus_root;    }
-
-    public boolean isManagingFocus()
-    { return manages_focus;  }
-
-  protected  String paramString()
-    { return "JEditorPane";  }
-    
-  protected  void processComponentKeyEvent(KeyEvent e)
-    {
-	//Overridden to handle processing of tab/shift tab. 
-    }
-    
+  public String getText()
+  {
+    return super.getText();
+  }
+
+  public String getUIClassID()
+  {
+    return "EditorPaneUI";
+  }
+
+  public boolean isFocusCycleRoot()
+  {
+    return focus_root;
+  }
+
+  public boolean isManagingFocus()
+  {
+    return manages_focus;
+  }
+
+  protected String paramString()
+  {
+    return "JEditorPane";
+  }
+
+  /**
+   * Overridden to handle processing of tab/shift tab. 
+   */
+  protected void processComponentKeyEvent(KeyEvent e)
+  {
+  }
+
+  /**
+   * Make sure that TAB and Shift-TAB events get consumed,
+   * so that awt doesn't attempt focus traversal.  
+   */
   protected void processKeyEvent(KeyEvent e)
-    {
-	//Make sure that TAB and Shift-TAB events get consumed, so that awt doesn't attempt focus traversal.  
-    }
-    
-    void read(InputStream in, Object desc)
-    {
-	//This method initializes from a stream. 
-    }
-    
-    static void registerEditorKitForContentType(String type, String classname)
-    {
-	//Establishes the default bindings of type to classname. 
-    }
-    
-    static void registerEditorKitForContentType(String type, String classname, ClassLoader loader)
-    {
-	//Establishes the default bindings of type to classname.  
-    }
-    
-    void removeHyperlinkListener(HyperlinkListener listener)
-    {
-	//Removes a hyperlink listener.  
-    }
-    
-    void replaceSelection(String content)
-    {
-	//Replaces the currently selected content with new content represented by the given string. 
-    }
-    
-    protected  void scrollToReference(String reference)
-    {
-	//Scrolls the view to the given reference location (that is, the value returned by the UL.getRef method for the URL being displayed).  
-    }
-    
-    void setContentType(String type)
-    {
-	ctype = type;
-	invalidate();
-	repaint();
-    }
-    
-    void setEditorKit(EditorKit kit)
-    {
-	this.kit = kit;
-	invalidate();
-	repaint();
-    }
-    
-    void setEditorKitForContentType(String type, EditorKit k)
-    {
-	ctype = type;
-	setEditorKit(k);
-    }
-  
-  void setPage(String url)
-    {
-	//  Sets the current URL being displayed.  
-    }
-    
-    void setPage(URL page)
-    {
-	//    Sets the current URL being displayed.  
-    }
-    
-    public void setText(String t)
-    {	
-	super.setText(t);
-    }
-} // class JEditorPane
+  {
+  }
+
+  /**
+   * This method initializes from a stream. 
+   */
+  public void read(InputStream in, Object desc)
+  {
+  }
+
+  /**
+   * Establishes the default bindings of type to classname. 
+   */
+  public static void registerEditorKitForContentType(String type,
+                                                     String classname)
+  {
+  }
+
+  /**
+   * Establishes the default bindings of type to classname.  
+   */
+  public static void registerEditorKitForContentType(String type,
+                                                     String classname,
+                                                     ClassLoader loader)
+  {
+  }
+
+  /**
+   * Replaces the currently selected content with new content represented
+   * by the given string.
+   */
+  public void replaceSelection(String content)
+  {
+  }
+
+  /**
+   * Scrolls the view to the given reference location (that is, the value
+   * returned by the UL.getRef method for the URL being displayed).
+   */
+  public void scrollToReference(String reference)
+  {
+  }
+
+  public void setContentType(String type)
+  {
+    ctype = type;
+    invalidate();
+    repaint();
+  }
+
+  public void setEditorKit(EditorKit kit)
+  {
+    this.kit = kit;
+    invalidate();
+    repaint();
+  }
+
+  public void setEditorKitForContentType(String type, EditorKit k)
+  {
+    ctype = type;
+    setEditorKit(k);
+  }
+
+  /**
+   * Sets the current URL being displayed.  
+   */
+  public void setPage(String url) throws IOException
+  {
+  }
+
+  /**
+   * Sets the current URL being displayed.  
+   */
+  public void setPage(URL page) throws IOException
+  {
+  }
+
+  public void setText(String t)
+  {
+    super.setText(t);
+  }
+
+  /**
+   * Add a <code>HyperlinkListener</code> object to this editor pane.
+   *
+   * @param listener the listener to add
+   */
+  public void addHyperlinkListener(HyperlinkListener listener)
+  {
+    listenerList.add(HyperlinkListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>HyperlinkListener</code> object to this editor pane.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeHyperlinkListener(HyperlinkListener listener)
+  {
+    listenerList.remove(HyperlinkListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>HyperlinkListener</code> objects.
+   *
+   * @return array of listeners
+   *
+   * @since 1.4
+   */
+  public HyperlinkListener[] getHyperlinkListeners()
+  {
+    return (HyperlinkListener[]) getListeners(HyperlinkListener.class);
+  }
+}
Index: javax/swing/JFileChooser.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JFileChooser.java,v
retrieving revision 1.2
diff -u -r1.2 JFileChooser.java
--- javax/swing/JFileChooser.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JFileChooser.java	6 Sep 2004 16:35:55 -0000
@@ -59,53 +59,32 @@
  */
 public class JFileChooser extends JComponent implements Accessible {
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJFileChooser
-	 */
-	protected class AccessibleJFileChooser extends AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJFileChooser
-		 * @param component TODO
-		 */
-		protected AccessibleJFileChooser(JFileChooser component) {
-			super(component);
-			// TODO
-		} // AccessibleJFileChooser()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.FILE_CHOOSER;
-		} // getAccessibleRole()
+  private static final long serialVersionUID = 3162921138695327837L;
 
-
-	} // AccessibleJFileChooser
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+  /**
+   * AccessibleJFileChooser
+   */
+  protected class AccessibleJFileChooser extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = 8205148454060169244L;
+
+    /**
+     * Constructor AccessibleJFileChooser
+     * @param component TODO
+     */
+    protected AccessibleJFileChooser()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.FILE_CHOOSER;
+    }
+  }
 
 	/**
 	 * uiClassID
@@ -906,17 +885,24 @@
 	 * addActionListener
 	 * @param listener TODO
 	 */
-	public void addActionListener(ActionListener listener) {
-		// TODO
-	} // addActionListener()
+	public void addActionListener(ActionListener listener)
+	{
+		listenerList.add (ActionListener.class, listener);
+	}
 
 	/**
 	 * removeActionListener
 	 * @param listener TODO
 	 */
-	public void removeActionListener(ActionListener listener) {
-		// TODO
-	} // removeActionListener()
+	public void removeActionListener(ActionListener listener)
+	{
+		listenerList.remove (ActionListener.class, listener);
+	}
+
+	public ActionListener[] getActionListeners()
+	{
+		return (ActionListener[]) listenerList.getListeners (ActionListener.class);
+	}
 
 	/**
 	 * fireActionPerformed
@@ -958,16 +944,15 @@
 		return null; // TODO
 	} // paramString()
 
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJFileChooser(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JFileChooser
+  /**
+   * getAccessibleContext
+   * @returns AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJFileChooser();
+
+    return accessibleContext;
+  }
+}
Index: javax/swing/JFormattedTextField.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JFormattedTextField.java,v
retrieving revision 1.2
diff -u -r1.2 JFormattedTextField.java
--- javax/swing/JFormattedTextField.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JFormattedTextField.java	6 Sep 2004 16:35:55 -0000
@@ -1,5 +1,5 @@
 /* JFormattedTextField.java --
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -52,14 +52,19 @@
  */
 public class JFormattedTextField extends JTextField
 {
+  private static final long serialVersionUID = 5464657870110180632L;
+
   public abstract static class AbstractFormatter implements Serializable
   {
+    private static final long serialVersionUID = -5193212041738979680L;
+    
     public AbstractFormatter ()
     {
       //Do nothing here.
     }
 
     protected Object clone ()
+      throws CloneNotSupportedException
     {
       throw new InternalError ("not implemented");
     }
@@ -99,14 +104,16 @@
       throw new InternalError ("not implemented");
     }
 
-    protected void setEditValid ()
+    protected void setEditValid (boolean valid)
     {
       throw new InternalError ("not implemented");
     }
 
-    public abstract Object stringToValue (String text);
+    public abstract Object stringToValue (String text)
+      throws ParseException;
 
-    public abstract String valueToString (Object value);
+    public abstract String valueToString (Object value)
+      throws ParseException;
   }
   
   public abstract static class AbstractFormatterFactory
@@ -124,9 +131,11 @@
   public static final int REVERT = 2;
   public static final int PERSIST = 3;
 
+  private Object value;
+  
   public JFormattedTextField ()
   {
-    throw new InternalError ("not implemented");
+    this((AbstractFormatterFactory) null);
   }
 
   public JFormattedTextField (Format format)
@@ -141,7 +150,7 @@
 
   public JFormattedTextField (AbstractFormatterFactory factory)
   {
-    throw new InternalError ("not implemented");
+    this(factory, null);
   }
 
   public JFormattedTextField (AbstractFormatterFactory factory, Object value)
@@ -151,10 +160,11 @@
 
   public JFormattedTextField (Object value)
   {
-    throw new InternalError ("not implemented");
+    this.value = value;
   }
 
   public void commitEdit ()
+    throws ParseException
   {
     throw new InternalError ("not implemented");
   }
@@ -181,12 +191,12 @@
 
   public String getUIClassID ()
   {
-    throw new InternalError ("not implemented");
+    return "FormattedTextFieldUI";
   }
 
   public Object getValue ()
   {
-    throw new InternalError ("not implemented");
+    return value;
   }
 
   protected void invalidEdit ()
@@ -204,9 +214,15 @@
     throw new InternalError ("not implemented");
   }
 
-  public void setDocument (Document document)
+  public void setDocument(Document newdoc)
   {
-    throw new InternalError ("not implemented");
+    Document document = getDocument();
+
+    if (document == newdoc)
+      return;
+    
+    setDocument(newdoc);
+    firePropertyChange("document", document, newdoc);
   }
 
   public void setLostFocusBehavior (int behavior)
@@ -224,8 +240,8 @@
     throw new InternalError ("not implemented");
   }
 
-  public void setValue (Object value)
+  public void setValue (Object newValue)
   {
-    throw new InternalError ("not implemented");
+    value = newValue;
   }
 }
Index: javax/swing/JFrame.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JFrame.java,v
retrieving revision 1.3
diff -u -r1.3 JFrame.java
--- javax/swing/JFrame.java	22 Nov 2003 00:03:35 -0000	1.3
+++ javax/swing/JFrame.java	6 Sep 2004 16:35:55 -0000
@@ -1,5 +1,5 @@
 /* JFrame.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,16 +38,17 @@
 
 package javax.swing;
 
+import java.awt.AWTEvent;
 import java.awt.BorderLayout;
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
 import java.awt.LayoutManager;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowEvent;
+
 import javax.accessibility.AccessibleContext;
 
 /**
@@ -56,17 +57,25 @@
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
-public class JFrame extends Frame
+public class JFrame extends Frame implements WindowConstants, RootPaneContainer
 {
-    public final static int HIDE_ON_CLOSE        = 0;
-    public final static int EXIT_ON_CLOSE        = 1;
-    public final static int DISPOSE_ON_CLOSE     = 2;
-    public final static int DO_NOTHING_ON_CLOSE  = 3;
+  private static final long serialVersionUID = -3362141868504252139L;
+  
+  protected  AccessibleContext accessibleContext;
+  
+  private int close_action = HIDE_ON_CLOSE;    
+  
+  private static boolean defaultLookAndFeelDecorated = false;    
 
-    protected  AccessibleContext accessibleContext;
+  public static void setDefaultLookAndFeelDecorated(boolean d)
+  {
+    defaultLookAndFeelDecorated = d;
+  }
 
-    private int close_action = EXIT_ON_CLOSE;    
-    
+  public static boolean isDefaultLookAndFeelDecorated()
+  {
+    return defaultLookAndFeelDecorated;
+  }
 
     /***************************************************
      *
@@ -105,6 +114,7 @@
     protected  void frameInit()
     {
       super.setLayout(new BorderLayout(1, 1));
+      enableEvents(AWTEvent.WINDOW_EVENT_MASK);
       getRootPane(); // will do set/create
     }
   
@@ -114,30 +124,30 @@
     return d;
   }
 
-    JMenuBar getJMenuBar()
+  public JMenuBar getJMenuBar()
     {    return getRootPane().getJMenuBar();   }
     
-    void setJMenuBar(JMenuBar menubar)
+  public void setJMenuBar(JMenuBar menubar)
     {    getRootPane().setJMenuBar(menubar); }
     
 
   public  void setLayout(LayoutManager manager)
   {    super.setLayout(manager);  }
 
-    void setLayeredPane(JLayeredPane layeredPane) 
+  public void setLayeredPane(JLayeredPane layeredPane) 
     {   getRootPane().setLayeredPane(layeredPane);   }
   
-    JLayeredPane getLayeredPane()
+  public JLayeredPane getLayeredPane()
     {   return getRootPane().getLayeredPane();     }
   
-    JRootPane getRootPane()
+  public JRootPane getRootPane()
     {
 	if (rootPane == null)
 	    setRootPane(createRootPane());
 	return rootPane;          
     }
 
-    void setRootPane(JRootPane root)
+  public void setRootPane(JRootPane root)
     {
 	if (rootPane != null)
 	    remove(rootPane);
@@ -146,19 +156,19 @@
 	add(rootPane, BorderLayout.CENTER);
     }
 
-    JRootPane createRootPane()
+  public JRootPane createRootPane()
     {   return new JRootPane();    }
 
-    public Container getContentPane()
+  public Container getContentPane()
     {    return getRootPane().getContentPane();     }
 
-    void setContentPane(Container contentPane)
+  public void setContentPane(Container contentPane)
     {    getRootPane().setContentPane(contentPane);    }
   
-    Component getGlassPane()
+  public Component getGlassPane()
     {    return getRootPane().getGlassPane();   }
   
-    void setGlassPane(Component glassPane)
+  public void setGlassPane(Component glassPane)
     {   getRootPane().setGlassPane(glassPane);   }
 
     
@@ -190,7 +200,7 @@
     return accessibleContext;
   }
   
-    int getDefaultCloseOperation()
+    public int getDefaultCloseOperation()
     {    return close_action;   }
 
     
@@ -201,9 +211,7 @@
 
     protected  void processWindowEvent(WindowEvent e)
     {
-	//	System.out.println("PROCESS_WIN_EV-1: " + e);
 	super.processWindowEvent(e); 
-	//	System.out.println("PROCESS_WIN_EV-2: " + e);
 	switch (e.getID())
 	    {
 	    case WindowEvent.WINDOW_CLOSING:
@@ -212,13 +220,11 @@
 			{
 			case EXIT_ON_CLOSE:
 			    {
-				System.out.println("user requested exit on close");
-				System.exit(1);
+				System.exit(0);
 				break;
 			    }
 			case DISPOSE_ON_CLOSE:
 			    {
-				System.out.println("user requested dispose on close");
 				dispose();
 				break;
 			    }
@@ -243,8 +249,30 @@
 	    }
     }   
  
-
-    void setDefaultCloseOperation(int operation)
-    {  close_action = operation;   }
+    /**
+     * Defines what happens when this frame is closed. Can be one off
+     * <code>EXIT_ON_CLOSE</code>,
+     * <code>DISPOSE_ON_CLOSE</code>,
+     * <code>HIDE_ON_CLOSE</code> or
+     * <code>DO_NOTHING_ON_CLOSE</code>.
+     * The default is <code>HIDE_ON_CLOSE</code>.
+     * When <code>EXIT_ON_CLOSE</code> is specified this method calls
+     * <code>SecurityManager.checkExit(0)</code> which might throw a
+     * <code>SecurityException</code>. When the specified operation is
+     * not one of the above a <code>IllegalArgumentException</code> is
+     * thrown.
+     */
+    public void setDefaultCloseOperation(int operation)
+    {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm != null && operation == EXIT_ON_CLOSE)
+	sm.checkExit(0);
+
+      if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE
+	  && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE)
+	throw new IllegalArgumentException("operation = " + operation);
+	  
+      close_action = operation;
+    }
 
 }
Index: javax/swing/JInternalFrame.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JInternalFrame.java,v
retrieving revision 1.2
diff -u -r1.2 JInternalFrame.java
--- javax/swing/JInternalFrame.java	19 Jun 2003 16:30:09 -0000	1.2
+++ javax/swing/JInternalFrame.java	6 Sep 2004 16:35:56 -0000
@@ -1,5 +1,5 @@
 /* JInternalFrame.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,27 +35,1673 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.KeyboardFocusManager;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.beans.PropertyVetoException;
 import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.InternalFrameUI;
+
 
-public class JInternalFrame extends JComponent
-/*implements Accessible, WindowConstants, RootPaneContainer*/
+/**
+ * This class implements a Swing widget that looks and acts like a native
+ * frame. The frame can be dragged, resized, closed, etc. Typically,
+ * JInternalFrames are placed in JDesktopPanes. The actions that the
+ * JInternalFrame performs (maximizing, minimizing, etc.) are performed by a
+ * DesktopManager. As with regular frames, components are added by calling
+ * frame.getContentPane().add.
+ */
+public class JInternalFrame extends JComponent implements Accessible,
+                                                          WindowConstants,
+                                                          RootPaneContainer
 {
+  /** DOCUMENT ME! */
   private static final long serialVersionUID = -5425177187760785402L;
 
-  public static final String CONTENT_PANE_PROPERTY = "contentPane";
-  public static final String MENU_BAR_PROPERTY = "JMenuBar";
-  public static final String TITLE_PROPERTY = "title";
-  public static final String LAYERED_PANE_PROPERTY = "layeredPane";
-  public static final String ROOT_PANE_PROPERTY = "rootPane";
-  public static final String GLASS_PANE_PROPERTY = "glassPane";
-  public static final String FRAME_ICON_PROPERTY = "frameIcon";
-  public static final String IS_SELECTED_PROPERTY = "selected";
-  public static final String IS_CLOSED_PROPERTY = "closed";
-  public static final String IS_MAXIMUM_PROPERTY = "maximum";
-  public static final String IS_ICON_PROPERTY = "icon";
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJInternalFrame extends AccessibleJComponent
+    implements AccessibleValue
+  {
+    /**
+     * Creates a new AccessibleJInternalFrame object.
+     */
+    protected AccessibleJInternalFrame()
+    {
+      super();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getAccessibleName()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean setCurrentAccessibleValue(Number n)
+    {
+      return false;
+    }
+  }
+
+  /**
+   * This class represents the JInternalFrame while it is iconified.
+   */
+  public static class JDesktopIcon extends JComponent implements Accessible
+  {
+    /**
+     * DOCUMENT ME!
+     */
+    protected class AccessibleJDesktopIcon extends AccessibleJComponent
+      implements AccessibleValue
+    {
+      /**
+       * Creates a new AccessibleJDesktopIcon object.
+       */
+      protected AccessibleJDesktopIcon()
+      {
+	super();
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public AccessibleValue getAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getCurrentAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getMaximumAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getMinimumAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @param n DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public boolean setCurrentAccessibleValue(Number n)
+      {
+	return false;
+      }
+    }
+
+    /** The JInternalFrame this DesktopIcon represents. */
+    JInternalFrame frame;
+
+    /**
+     * Creates a new JDesktopIcon object for representing the given frame.
+     *
+     * @param f The JInternalFrame to represent.
+     */
+    public JDesktopIcon(JInternalFrame f)
+    {
+      frame = f;
+      updateUI();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleContext getAccessibleContext()
+    {
+      if (accessibleContext == null)
+	accessibleContext = new AccessibleJDesktopIcon();
+      return accessibleContext;
+    }
+
+    /**
+     * This method returns the JDesktopPane this JDesktopIcon is in.
+     *
+     * @return The JDesktopPane this JDesktopIcon is in.
+     */
+    public JDesktopPane getDesktopPane()
+    {
+      JDesktopPane p = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                        this);
+      return p;
+    }
+
+    /**
+     * This method returns the JInternalFrame this JDesktopIcon represents.
+     *
+     * @return The JInternalFrame this JDesktopIcon represents.
+     */
+    public JInternalFrame getInternalFrame()
+    {
+      return frame;
+    }
+
+    /**
+     * This method returns the UI that is responsible for the JDesktopIcon.
+     *
+     * @return The UI that is responsible for the JDesktopIcon.
+     */
+    public DesktopIconUI getUI()
+    {
+      return (DesktopIconUI) ui;
+    }
+
+    /**
+     * This method returns the String identifier that is used to determine
+     * which class is used for JDesktopIcon's UI.
+     *
+     * @return A String identifier for the UI class.
+     */
+    public String getUIClassID()
+    {
+      return "DesktopIconUI";
+    }
+
+    /**
+     * This method sets the JInternalFrame that this JDesktopIcon represents.
+     *
+     * @param f The JInternalFrame that this JDesktopIcon represents.
+     */
+    public void setInternalFrame(JInternalFrame f)
+    {
+      frame = f;
+    }
+
+    /**
+     * This method sets the UI used for this JDesktopIcon.
+     *
+     * @param ui The UI to use.
+     */
+    public void setUI(DesktopIconUI ui)
+    {
+      super.setUI(ui);
+    }
+
+    /**
+     * This method restores the UI property to the defaults.
+     */
+    public void updateUI()
+    {
+      setUI((DesktopIconUI) UIManager.getUI(this));
+    }
+  }
+
+  /**
+   * The property fired in a PropertyChangeEvent when the contentPane property
+   * changes.
+   */
+  public static String CONTENT_PANE_PROPERTY = "contentPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the frameIcon property
+   * changes.
+   */
+  public static String FRAME_ICON_PROPERTY = "frameIcon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the glassPane property
+   * changes.
+   */
+  public static String GLASS_PANE_PROPERTY = "glassPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the closed property
+   * changes.
+   */
+  public static String IS_CLOSED_PROPERTY = "closed";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the icon property
+   * changes.
+   */
+  public static String IS_ICON_PROPERTY = "icon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the maximum property
+   * changes.
+   */
+  public static String IS_MAXIMUM_PROPERTY = "maximum";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the selected property
+   * changes.
+   */
+  public static String IS_SELECTED_PROPERTY = "selected";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the layeredPane property
+   * changes.
+   */
+  public static String LAYERED_PANE_PROPERTY = "layeredPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the jMenuBar property
+   * changes.
+   */
+  public static String MENU_BAR_PROPERTY = "jMenuBar";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the rootPane property
+   * changes.
+   */
+  public static String ROOT_PANE_PROPERTY = "rootPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the title property
+   * changes.
+   */
+  public static String TITLE_PROPERTY = "title";
+
+  /** Whether the JInternalFrame is closable. */
+  protected boolean closable;
+
+  /** Whether the JInternalFrame can be iconified. */
+  protected boolean iconable;
+
+  /** Whether the JInternalFrame is closed. */
+  protected boolean isClosed;
+
+  /** Whether the JInternalFrame has been iconified. */
+  protected boolean isIcon;
+
+  /** Whether the JInternalFrame has been maximized. */
+  protected boolean isMaximum;
+
+  /** Whether the JInternalFrame is the active frame. */
+  protected boolean isSelected;
+
+  /** Whether the JInternalFrame can be maximized. */
+  protected boolean maximizable;
+
+  /** Whether the JInternalFrame has rootPaneChecking enabled. */
+  protected boolean rootPaneCheckingEnabled = true;
+
+  /** Whether the JInternalFrame is resizable. */
+  protected boolean resizable;
+
+  /**
+   * The JDesktopIcon that represents the JInternalFrame while it is
+   * iconified.
+   */
+  protected JDesktopIcon desktopIcon;
+
+  /** The icon used in the JMenuBar in the TitlePane. */
+  protected Icon frameIcon;
+
+  /** The rootPane of the JInternalFrame. */
+  protected JRootPane rootPane;
+
+  /** The title on the TitlePane of the JInternalFrame. */
+  protected String title;
+
+  /** The bounds of the JInternalFrame before it was maximized. */
+  private transient Rectangle storedBounds;
+
+  /** The Component that receives focus by default. */
+  private transient Component defaultFocus;
+
+  /** The default close action taken, */
+  private transient int defaultCloseOperation = DISPOSE_ON_CLOSE;
+
+  /** Whether the JInternalFrame has become visible for the very first time. */
+  private transient boolean isFirstTimeVisible = true;
+
+  /**
+   * Whether the JInternalFrame is in the transition from being a maximized
+   * frame back to a regular sized frame.
+   */
+  private transient boolean maxTransition = false;
+
+  /** DOCUMENT ME! */
+  private transient boolean wasIcon = false;
+
+  /**
+   * Creates a new JInternalFrame object that has no title, and is
+   * non-resizable, non-maximizable, non-iconifiable, and non-closable.
+   */
+  public JInternalFrame()
+  {
+    this(null, false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and is
+   * non-resizable, non-maximizable, non-iconifiable, and non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   */
+  public JInternalFrame(String title)
+  {
+    this(title, false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and resizable
+   * properties. The JInternalFrame is non-maximizable, non-iconifiable, and
+   * non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   */
+  public JInternalFrame(String title, boolean resizable)
+  {
+    this(title, resizable, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable, and
+   * closable properties. The JInternalFrame is non-maximizable and
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable)
+  {
+    this(title, resizable, closable, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable and maximizable properties. The JInternalFrame is
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable)
+  {
+    this(title, resizable, closable, maximizable, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable, maximizable and iconifiable properties.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   * @param iconifiable Whether the JInternalFrame is iconifiable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable, boolean iconifiable)
+  {
+    this.title = title;
+    this.resizable = resizable;
+    this.closable = closable;
+    this.maximizable = maximizable;
+    this.iconable = iconifiable;
+    storedBounds = new Rectangle();
+
+    setRootPaneCheckingEnabled(false);
+    setRootPane(createRootPane());
+
+    updateUI();
+    setRootPaneCheckingEnabled(true);
+  }
+
+  /**
+   * This method adds Components to this Container. For JInternalFrames,
+   * instead of calling add directly on the JInternalFrame, it should be
+   * called with JInternalFrame.getContentPane().add. If root pane checking
+   * is enabled, calling this method will cause an exception to be thrown.
+   *
+   * @param comp The Component to add.
+   * @param constraints The constraints on the Component added.
+   * @param index The position to place the Component.
+   *
+   * @throws Error DOCUMENT ME!
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("Do not use add() on JInternalPane directly. Use getContentPane().add() instead");
+
+    super.addImpl(comp, constraints, index);
+  }
+
+  /**
+   * This method adds an InternalFrameListener to this JInternalFrame.
+   *
+   * @param l The listener to add.
+   */
+  public void addInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.add(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method is used to create a root pane for the JInternalFrame. This
+   * method is called by the constructors.
+   *
+   * @return A root pane for the JInternalFrame to use.
+   */
+  protected JRootPane createRootPane()
+  {
+    return new JRootPane();
+  }
+
+  /**
+   * This method makes this JInternalFrame invisible, unselected and closed.
+   * If this JInternalFrame is not closed already, it will fire an
+   * INTERNAL_FRAME_CLoSED event. This method is similar to setClosed but it
+   * doesn't give vetoable listeners a chance to veto and it will not fire an
+   * INTERNAL_FRAME_CLOSING event.
+   */
+  public void dispose()
+  {
+    hide();
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      pane.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing if they don't want to be unselected.
+	  }
+      }
+    isClosed = true;
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
+    removeNotify();
+  }
+
+  /**
+   * This method is used for closing this JInternalFrame. It fires an
+   * INTERNAL_FRAME_CLOSING event and then performs the action specified by
+   * the default close operation.
+   */
+  public void doDefaultCloseAction()
+  {
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+    switch (getDefaultCloseOperation())
+      {
+      case HIDE_ON_CLOSE:
+	hide();
+	break;
+      case DISPOSE_ON_CLOSE:
+	dispose();
+	break;
+      }
+  }
+
+  /**
+   * This method fires an InternalFrameEvent to the listeners.
+   *
+   * @param id The type of event being fired. See InternalFrameEvent.
+   */
+  protected void fireInternalFrameEvent(int id)
+  {
+    Object[] ifListeners = listenerList.getListenerList();
+    InternalFrameEvent evt = new InternalFrameEvent(this, id);
+    switch (id)
+      {
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameClosing(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameActivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameClosed(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeactivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeiconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameIconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_OPENED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameOpened(evt);
+	  }
+	break;
+      }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJInternalFrame();
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the Content Pane for this JInternalFrame.
+   *
+   * @return The Content Pane for this JInternalFrame.
+   */
+  public Container getContentPane()
+  {
+    return getRootPane().getContentPane();
+  }
+
+  /**
+   * This method returns the default action taken when this JInternalFrame is
+   * closed.
+   *
+   * @return The default action taken when this JInternalFrame is closed.
+   */
+  public int getDefaultCloseOperation()
+  {
+    return defaultCloseOperation;
+  }
+
+  /**
+   * This method returns the JDesktopIcon that represents this JInternalFrame
+   * while it is iconified.
+   *
+   * @return The JDesktopIcon that represents this JInternalFrame while it is
+   *         iconified.
+   */
+  public JDesktopIcon getDesktopIcon()
+  {
+    if (desktopIcon == null)
+      desktopIcon = new JDesktopIcon(this);
+    return desktopIcon;
+  }
+
+  /**
+   * This method searches this JInternalFrame ancestors for an instance of
+   * JDesktopPane. If one is found, it is returned. If none is found, then it
+   * will search the JDesktopIcon for a JDesktopPane.
+   *
+   * @return The JDesktopPane that this JInternalFrame belongs to.
+   */
+  public JDesktopPane getDesktopPane()
+  {
+    JDesktopPane value = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                          this);
+    if (value == null && desktopIcon != null)
+      value = desktopIcon.getDesktopPane();
+    return value;
+  }
+
+  /**
+   * This method returns null because this must always be the root of a focus
+   * traversal.
+   *
+   * @return null.
+   */
+  public Container getFocusCycleRootAncestor()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method returns the child Component that will receive focus if this
+   * JInternalFrame is selected.
+   *
+   * @return The child Component that will receive focus.
+   */
+  public Component getFocusOwner()
+  {
+    if (isSelected())
+      {
+	Component focus = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+	if (SwingUtilities.isDescendingFrom(focus, this))
+	  {
+	    defaultFocus = focus;
+	    return focus;
+	  }
+      }
+    return null;
+  }
+
+  /**
+   * This method returns the Frame Icon (the icon used in the JInternalFrame
+   * TitlePane and iconified frame).
+   *
+   * @return The Frame Icon.
+   */
+  public Icon getFrameIcon()
+  {
+    return frameIcon;
+  }
+
+  /**
+   * This method returns the Glass Pane used with this JInternalFrame.
+   *
+   * @return The Glass Pane used with this JInternalFrame.
+   */
+  public Component getGlassPane()
+  {
+    return getRootPane().getGlassPane();
+  }
+
+  /**
+   * This method returns an array of InternalFrameListeners that are listening
+   * to this JInternalFrame.
+   *
+   * @return An array of InternalFrameListeners that are listening to this
+   *         JInternalFrame.
+   */
+  public InternalFrameListener[] getInternalFrameListeners()
+  {
+    return (InternalFrameListener[]) listenerList.getListeners(InternalFrameListener.class);
+  }
+
+  /**
+   * This method returns the JMenuBar for this JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return getRootPane().getJMenuBar();
+  }
+
+  /**
+   * This method returns the layer that this JInternalFrame resides in.
+   *
+   * @return The layer that this JInternalFrame resides in.
+   */
+  public int getLayer()
+  {
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      return pane.getLayer(this).intValue();
+    return -1;
+  }
+
+  /**
+   * This method returns the LayeredPane for this JInternalFrame.
+   *
+   * @return The LayeredPane for this JInternalFrame.
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    return getRootPane().getLayeredPane();
+  }
+
+  /**
+   * This method is deprecated. This method returns the JMenuBar for this
+   * JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   */
+  public JMenuBar getMenuBar()
+  {
+    return getJMenuBar();
+  }
+
+  /**
+   * This method returns the child Component that will receive focus when the
+   * JInternalFrame is selected. If the JInternalFrame is selected, this
+   * method returns getFocusOwner(). Otherwise, it will return the child
+   * Component that most recently requested focus. If that is null, then the
+   * initial focus Component is returned. If that is null, then the default
+   * focus component is returned.
+   *
+   * @return The most recent focus owner.
+   */
+  public Component getMostRecentFocusOwner()
+  {
+    if (isSelected())
+      return getFocusOwner();
+    else
+      return defaultFocus;
+  }
+
+  /**
+   * This method returns the bounds of the JInternalFrame if it is not
+   * maximized. If it is maximized, it returns the bounds of the
+   * JInternalFrame before it was maximized (the bounds that it will be
+   * restored to).
+   *
+   * @return A Rectangle that contains this JInternalFrame's normal bounds (or
+   *         just its bounds if it is not maximized).
+   */
+  public Rectangle getNormalBounds()
+  {
+    if (! isMaximum() && ! maxTransition)
+      return getBounds();
+    else
+      return storedBounds;
+  }
+
+  /**
+   * This method returns the Root Pane for this JInternalFrame.
+   *
+   * @return The Root Pane for this JInternalFrame.
+   */
+  public JRootPane getRootPane()
+  {
+    return rootPane;
+  }
+
+  /**
+   * This method sets the title of the JInternalFrame.
+   *
+   * @return The String displayed in the TitlePane of this JInternalFrame.
+   */
+  public String getTitle()
+  {
+    return title;
+  }
+
+  /**
+   * This method returns the UI used to represent the JInternalFrame.
+   *
+   * @return The UI used to represent the JInternalFrame.
+   */
+  public InternalFrameUI getUI()
+  {
+    return (InternalFrameUI) ui;
+  }
+
+  /**
+   * This method returns a String identifier that is used to determine which
+   * class acts as the JInternalFrame's UI.
+   *
+   * @return A String identifier to determine a UI class.
+   */
+  public String getUIClassID()
+  {
+    return "InternalFrameUI";
+  }
+
+  /**
+   * This method returns null.
+   *
+   * @return null.
+   */
+  public String getWarningString()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method deselects this JInternalFrame and hides it.
+   */
+  public void hide()
+  {
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      pane.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+    super.hide();
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is closable.
+   *
+   * @return Whether this JInternalFrame is closable.
+   */
+  public boolean isClosable()
+  {
+    return closable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame has been closed.
+   *
+   * @return Whether this JInternalFrame is closed.
+   */
+  public boolean isClosed()
+  {
+    return isClosed;
+  }
+
+  /**
+   * This must always return true.
+   *
+   * @return True
+   */
+  public boolean isFocusCycleRoot()
+  {
+    return true;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently iconified.
+   *
+   * @return Whether this JInternalFrame is currently iconified.
+   */
+  public boolean isIcon()
+  {
+    return isIcon;
+  }
+
+  /**
+   * This method returns whether the JInternalFrame can be iconified.
+   *
+   * @return Whether the JInternalFrame can be iconified.
+   */
+  public boolean isIconifiable()
+  {
+    return iconable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame can be maximized.
+   *
+   * @return Whether this JInternalFrame can be maximized.
+   */
+  public boolean isMaximizable()
+  {
+    return maximizable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently maximized.
+   *
+   * @return Whether this JInternalFrame is maximized.
+   */
+  public boolean isMaximum()
+  {
+    return isMaximum;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is resizable.
+   *
+   * @return Whether this JInternalFrame is resizable.
+   */
+  public boolean isResizable()
+  {
+    return resizable;
+  }
+
+  /**
+   * This method returns whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @return Whether root pane checking is enabled.
+   */
+  protected boolean isRootPaneCheckingEnabled()
+  {
+    return rootPaneCheckingEnabled;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is selected.
+   *
+   * @return Whether this JInternalFrame is selected.
+   */
+  public boolean isSelected()
+  {
+    return isSelected;
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the back if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToBack()
+  {
+    if (getParent() instanceof JLayeredPane)
+      ((JLayeredPane) getParent()).moveToBack(this);
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the front if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToFront()
+  {
+    if (getParent() instanceof JLayeredPane)
+      ((JLayeredPane) getParent()).moveToFront(this);
+  }
+
+  /**
+   * This method causes the children of this JInternalFrame to be laid out.
+   * Before it begins, if this JInternalFrame is an icon, then it will be
+   * deiconified. If it is maximized, then it will be restored. If either
+   * operation fails, then this method will return.
+   */
+  public void pack()
+  {
+    try
+      {
+	if (isIcon())
+	  setIcon(false);
+	else if (isMaximum())
+	  setMaximum(false);
+      }
+    catch (PropertyVetoException e)
+      {
+	// Do nothing if they don't want to be restored first.
+      }
+    doLayout();
+  }
+
+  /**
+   * This method is overridden to allow for speedier painting while this
+   * JInternalFramme is being dragged.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintComponent(Graphics g)
+  {
+    super.paintComponent(g);
+  }
+
+  /**
+   * This method returns a String describing this JInternalFrame.
+   *
+   * @return A String describing this JInternalFrame.
+   */
+  protected String paramString()
+  {
+    return "JInternalFrame";
+  }
+
+  /**
+   * This method removes the given Component from the Container.
+   *
+   * @param comp The Component to remove.
+   */
+  public void remove(Component comp)
+  {
+    super.remove(comp);
+  }
+
+  /**
+   * This method removes an InternalFrameListener from this JInternalFrame.
+   *
+   * @param l The listener to remove.
+   */
+  public void removeInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.remove(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method resizes and positions this JInternalFrame. It also forces a
+   * relayout of the Container.
+   *
+   * @param x The x position of this JInternalFrame.
+   * @param y The y position of this JInternalFrame.
+   * @param width The width of this JInternalFrame.
+   * @param height The height of this JInternalFrame.
+   */
+  public void reshape(int x, int y, int width, int height)
+  {
+    super.reshape(x, y, width, height);
+    invalidate();
+    doLayout();
+  }
+
+  /**
+   * This method gives focus to the last child Component that had focus. This
+   * is used by the UI when this JInternalFrame is activated.
+   */
+  public void restoreSubcomponentFocus()
+  {
+    Component c = getMostRecentFocusOwner();
+    if (c != null)
+      c.requestFocus();
+  }
+
+  /**
+   * This method sets whether this JInternalFrame can be closed.
+   *
+   * @param b Whether this JInternalFrame can be closed.
+   */
+  public void setClosable(boolean b)
+  {
+    closable = b;
+  }
+
+  /**
+   * This method closes the JInternalFrame if the given boolean is true. If it
+   * is false, then the result of this method is unspecified. If the
+   * JInternalFrame is closed, this method does nothing. This method will
+   * first fire an INTERNAL_FRAME_CLOSING event and give a chance for veto
+   * listeners to cancel the close. If no listener vetoes the change, the
+   * closed property is set to true and the JInternalFrame is hidden and
+   * unselected. The method will finish by firing an INTERNAL_FRAME_CLOSED
+   * event.
+   *
+   * @param b Whether the JInternalFrame will be closed.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setClosed(boolean b) throws PropertyVetoException
+  {
+    if (b && ! isClosed())
+      {
+	fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+	fireVetoableChange(IS_CLOSED_PROPERTY, false, true);
+
+	isClosed = b;
+
+	firePropertyChange(IS_CLOSED_PROPERTY, false, true);
+	fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
+      }
+  }
+
+  /**
+   * This method sets the Container to be used as a Content Pane for this
+   * JInternalFrame.
+   *
+   * @param c The Container to use as a Content Pane.
+   */
+  public void setContentPane(Container c)
+  {
+    if (c != getContentPane())
+      {
+	Container old = getContentPane();
+	getRootPane().setContentPane(c);
+	firePropertyChange(CONTENT_PANE_PROPERTY, old, c);
+      }
+  }
+
+  /**
+   * 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.
+   *
+   * @throws Error If the given operation is not one of the allowed modes.
+   */
+  public void setDefaultCloseOperation(int operation)
+  {
+    if (operation != DO_NOTHING_ON_CLOSE || operation != HIDE_ON_CLOSE
+        || operation != DISPOSE_ON_CLOSE)
+      throw new Error("Close operation must be one of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, or DISPOSE_ON_CLOSE");
+    defaultCloseOperation = operation;
+  }
+
+  /**
+   * This method sets the JDesktopIcon that represents this JInternalFrame
+   * while it is iconified.
+   *
+   * @param d The JDesktopIcon that represents this JInternalFrame while it is
+   *        iconified.
+   */
+  public void setDesktopIcon(JDesktopIcon d)
+  {
+    d.setInternalFrame(this);
+    desktopIcon = d;
+  }
+
+  /**
+   * This method does nothing because this must be the root of a focus
+   * traversal cycle.
+   *
+   * @param focusCycleRoot Not used.
+   */
+  public final void setFocusCycleRoot(boolean focusCycleRoot)
+  {
+    // Do nothing
+  }
+
+  /**
+   * This method sets the Icon to be used in two places. The first is icon
+   * that is painted at the top left corner of the JInternalFrame when it is
+   * not iconified (clicking on that icon will activate the TitlePane
+   * JMenuBar). When the JInternalFrame is iconified, it will be the icon
+   * displayed in the JDesktopIcon. If no icon is set, the JInternalFrame
+   * will use a Look and Feel default.
+   *
+   * @param icon The Icon used in the TitlePane JMenuBar and iconified frames.
+   */
+  public void setFrameIcon(Icon icon)
+  {
+    if (icon != frameIcon)
+      {
+	Icon old = frameIcon;
+	frameIcon = icon;
+	firePropertyChange(FRAME_ICON_PROPERTY, old, frameIcon);
+      }
+  }
+
+  /**
+   * This method sets the Glass Pane used with this JInternalFrame.
+   *
+   * @param glass The Glass Pane to use with this JInternalFrame.
+   */
+  public void setGlassPane(Component glass)
+  {
+    if (glass != getGlassPane())
+      {
+	Component old = getGlassPane();
+	getRootPane().setGlassPane(glass);
+	firePropertyChange(GLASS_PANE_PROPERTY, old, glass);
+      }
+  }
+
+  /**
+   * This method iconifies or deiconifies this JInternalFrame given the
+   * boolean argument. If the JInternalFrame becomes iconified, it will fire
+   * an INTERNAL_FRAME_ICONIFIED event. If the JInternalFrame becomes
+   * deiconified, it will fire anINTERNAL_FRAME_DEICONIFIED event.
+   *
+   * @param b Whether this JInternalFrame is to be iconified or deiconified.
+   *
+   * @throws PropertyVetoException DOCUMENT ME!
+   */
+  public void setIcon(boolean b) throws PropertyVetoException
+  {
+    if (b != isIcon())
+      {
+	fireVetoableChange(IS_ICON_PROPERTY, b, isIcon);
+
+	isIcon = b;
+
+	firePropertyChange(IS_ICON_PROPERTY, ! isIcon, isIcon);
+	if (b)
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
+	else
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be iconified. (This means
+   * that the JInternalFrame can be turned into an icon if minimized).
+   *
+   * @param b Whether the JInternalFrame can be iconified.
+   */
+  public void setIconifiable(boolean b)
+  {
+    iconable = b;
+  }
+
+  /**
+   * This method sets the JMenuBar to be used with this JInternalFrame.
+   *
+   * @param b The JMenuBar to be used with this JInternalFrame.
+   */
+  public void setJMenuBar(JMenuBar b)
+  {
+    getRootPane().setJMenuBar(b);
+  }
+
+  /**
+   * A helper method that set the layer that this JInternalFrame resides in.
+   * Using this version of the method means that the user should not set it
+   * to values that are already defined in JLayeredPane. If predefined values
+   * are to be used, the user should use the setLayer(Integer) version.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(int layer)
+  {
+    setLayer(new Integer(layer));
+  }
+
+  /**
+   * A helper method that sets the layer that this JInternalFrame resides in.
+   * Calling this version of the method should use layer values that are
+   * already defined in JLayeredPane.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(Integer layer)
+  {
+    JDesktopPane p = getDesktopPane();
+    if (p != null)
+      {
+	int pos = p.getPosition(this);
+	p.setLayer(this, layer.intValue(), pos);
+      }
+  }
+
+  /**
+   * This method sets the JLayeredPane to use with this JInternalFrame.
+   *
+   * @param layered The JLayeredPane to use as a layeredPane.
+   */
+  public void setLayeredPane(JLayeredPane layered)
+  {
+    if (layered != getLayeredPane())
+      {
+	JLayeredPane old = getLayeredPane();
+	getRootPane().setLayeredPane(layered);
+	firePropertyChange(LAYERED_PANE_PROPERTY, old, layered);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be maximized.
+   *
+   * @param b Whether this JInternalFrame can be maximized.
+   */
+  public void setMaximizable(boolean b)
+  {
+    maximizable = b;
+  }
+
+  /**
+   * This method sets the Layout Manager used in the JInternalFrame. SetLayout
+   * should not be called on the JInternalFrame directly. Instead, it should
+   * be called with JInternalFrame.getContentPane().setLayout. Calls to this
+   * method with root pane checking enabled will cause exceptions to be
+   * thrown.
+   *
+   * @param manager The Layout Manager to be used with the JInternalFrame.
+   *
+   * @throws Error If rootPaneChecking is enabled.
+   */
+  public void setLayout(LayoutManager manager)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("Cannot set layout. Use getContentPane().setLayout() instead.");
+    super.setLayout(manager);
+  }
+
+  /**
+   * This method sets the JInternalFrame to maximized (if the given argument
+   * is true) or restores the JInternalFrame to its normal bounds otherwise.
+   *
+   * @param b Whether this JInteralFrame will be maximized or restored.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setMaximum(boolean b) throws PropertyVetoException
+  {
+    if (b != isMaximum())
+      {
+	fireVetoableChange(IS_MAXIMUM_PROPERTY, b, isMaximum);
+	isMaximum = b;
+	if (b)
+	  setNormalBounds(getBounds());
+	maxTransition = ! b;
+	firePropertyChange(IS_MAXIMUM_PROPERTY, ! isMaximum, isMaximum);
+	maxTransition = false;
+      }
+  }
+
+  /**
+   * This method is deprecated. This method sets the JMenuBar used with this
+   * JInternalFrame.
+   *
+   * @param m The JMenuBar to use with this JInternalFrame.
+   */
+  public void setMenuBar(JMenuBar m)
+  {
+    setJMenuBar(m);
+  }
+
+  /**
+   * This method sets the bounds that this JInternalFrame will be restored to.
+   *
+   * @param r The bounds that this JInternalFrame will be restored to.
+   */
+  public void setNormalBounds(Rectangle r)
+  {
+    storedBounds.setBounds(r.x, r.y, r.width, r.height);
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be resized by a user
+   * action (like dragging at the frame borders).
+   *
+   * @param b Whether this JInternalFramer can be resized.
+   */
+  public void setResizable(boolean b)
+  {
+    resizable = b;
+  }
+
+  /**
+   * This method sets the Root Pane for this JInternalFrame.
+   *
+   * @param root The Root Pane for this JInternalFrame.
+   */
+  protected void setRootPane(JRootPane root)
+  {
+    if (rootPane != null)
+      remove(rootPane);
+
+    rootPane = root;
+    add(root);
+  }
+
+  /**
+   * This method sets whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @param enabled Whether root pane checking is enabled.
+   */
+  protected void setRootPaneCheckingEnabled(boolean enabled)
+  {
+    rootPaneCheckingEnabled = enabled;
+  }
+
+  /**
+   * This method sets whether this JInternalFrame is the selected frame in the
+   * JDesktopPane (or other container). When selected, a JInternalFrame will
+   * have focus and paint its TitlePane differently (usually a different
+   * colour). If this method selects the frame, this JInternalFrame will fire
+   * an INTERNAL_FRAME_ACTIVATED event. If it deselects this frame, it will
+   * fire an INTERNAL_FRAME_DEACTIVATED event.
+   *
+   * @param selected Whether this JInternalFrame will become selected or
+   *        deselected.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setSelected(boolean selected) throws PropertyVetoException
+  {
+    if (selected != isSelected())
+      {
+	fireVetoableChange(IS_SELECTED_PROPERTY, selected, isSelected);
+
+	if (! selected)
+	  defaultFocus = getMostRecentFocusOwner();
+
+	isSelected = selected;
+
+	if (selected)
+	  restoreSubcomponentFocus();
+
+	firePropertyChange(IS_SELECTED_PROPERTY, ! isSelected, isSelected);
+
+	if (isSelected)
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
+	else
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
+      }
+  }
+
+  /**
+   * This method sets the title displayed in the TitlePane of this
+   * JInternalFrame.
+   *
+   * @param title The title displayed.
+   */
+  public void setTitle(String title)
+  {
+    if (title == null && this.title == null)
+      return;
+    if (title == null || this.title == null || ! this.title.equals(title))
+      {
+	String old = title;
+	this.title = title;
+	firePropertyChange(TITLE_PROPERTY, old, this.title);
+      }
+  }
+
+  /**
+   * This method displays the JInternalFrame. If it is not visible, this
+   * method will bring this JInternalFrame to the front, make it visible and
+   * select it. If this is the first time this JInternalFrame is made
+   * visible, an INTERNAL_FRAME_OPENED event will be fired.
+   */
+  public void show()
+  {
+    if (! isVisible())
+      {
+	moveToFront();
+	super.show();
+
+	JDesktopPane pane = getDesktopPane();
+	if (pane != null)
+	  pane.setSelectedFrame(this);
+	else
+	  {
+	    try
+	      {
+		setSelected(true);
+	      }
+	    catch (PropertyVetoException e)
+	      {
+		// Do nothing. if they don't want to be selected.
+	      }
+	  }
+	if (isFirstTimeVisible)
+	  {
+	    isFirstTimeVisible = false;
+	    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
+	  }
+      }
+  }
+
+  /**
+   * This method is used to set the UI responsible for the JInternalFrame.
+   *
+   * @param ui The UI responsible for the JInternalFrame.
+   */
+  public void setUI(InternalFrameUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brough to back in the
+   * z-order.
+   */
+  public void toBack()
+  {
+    moveToBack();
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brought to front in the
+   * z-order.
+   */
+  public void toFront()
+  {
+    moveToFront();
+  }
+
+  /**
+   * This method resets the UI to the Look and Feel defaults.
+   */
+  public void updateUI()
+  {
+    setUI((InternalFrameUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This helper method allows JInternalFrames to signal that they were
+   * iconned for the first time.
+   *
+   * @param b Whether the JInternalFrame was iconned.
+   * @param ID The identifier of the property change event to fire if the
+   *        JInternalFrame is iconned for the first time.
+   */
+  void setWasIcon(boolean b, String ID)
+  {
+    if (b && ! wasIcon)
+      {
+	wasIcon = b;
+	firePropertyChange(ID, ! b, b);
+      }
+  }
+
+  /**
+   * This helper method returns whether the JInternalFrame has been iconned
+   * once already.
+   *
+   * @return Whether the JInternalFrame has been iconned once already.
+   */
+  boolean getWasIcon()
+  {
+    return wasIcon;
+  }
+
+  /**
+   * This method is a convenience method to fire vetoable property changes.
+   *
+   * @param name The identifier of the property change.
+   * @param oldValue The old value.
+   * @param newValue The new value.
+   *
+   * @throws PropertyVetoException Fired if a vetoable change listener vetoes
+   *         the change.
+   */
+  private void fireVetoableChange(String name, boolean oldValue,
+                                  boolean newValue)
+                           throws PropertyVetoException
+  {
+    super.fireVetoableChange(name, new Boolean(oldValue), new Boolean(newValue));
+  }
 } // class JInternalFrame
Index: javax/swing/JLabel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JLabel.java,v
retrieving revision 1.2
diff -u -r1.2 JLabel.java
--- javax/swing/JLabel.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JLabel.java	6 Sep 2004 16:35:56 -0000
@@ -1,5 +1,5 @@
-/* JLabel.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JLabel.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,203 +35,662 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Component;
+import java.awt.Font;
 import java.awt.Image;
+import java.awt.event.KeyEvent;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
+import javax.swing.Icon;
 import javax.swing.plaf.LabelUI;
 
+
+/**
+ * <p>
+ * A swing widget that displays a text message and/or an icon.
+ * </p>
+ */
 public class JLabel extends JComponent implements Accessible, SwingConstants
 {
-    String text;
-    Icon icon;
-    int gap;
-    int align;
-
-    int hor_align;
-    int hor_text_pos;
-
-    int vert_align;
-    int vert_text_pos;
-
-    public JLabel()
-    {
-	this("", null, 0);
-    }
-
-    public JLabel(Icon image)
-    {
-	this("", image, 0);
-    }
-
-    public JLabel(Icon image, int horizontalAlignment)
-    {
-	this("", image, horizontalAlignment);
-    }
-
-    public JLabel(String text)
-    {
-	this(text, null, 0);
-    }
-
-    public JLabel(String text, int horizontalAlignment)
-    {
-	this(text, null, horizontalAlignment);
-    }
-
-    public JLabel(String text, Icon icon, int horizontalAlignment)
-    {
-	// do the work.....
-	this.text = text;
-	setIcon(icon);
-	this.align     = horizontalAlignment;
-
-	updateUI(); // get a proper ui
-    } 
-
-
-    protected  int checkHorizontalKey(int key, String message)
-    {
-	//    Verify that key is a legal value for the horizontalAlignment properties. 
-	return 0;
-    }
-    protected  int checkVerticalKey(int key, String message)
-    {
-	//      Verify that key is a legal value for the verticalAlignment or verticalTextPosition properties.  
-	return 0;
-    }
-    public AccessibleContext getAccessibleContext()
-    {
-	//          Get the AccessibleContext of this object 
-	return null;
-    }
-    public Icon getDisabledIcon()
-    {
-	//          Returns the value of the disabledIcon property if it's been set, If it hasn't been set and the value of the icon property is an ImageIcon, we compute a "grayed out" version of the icon and update the disabledIcon property with that.  
-	return null;
-    }
-    public int getDisplayedMnemonic()
-    {
-	//          Return the keycode that indicates a mnemonic key.   
-	return 0;
-    }
-    public int getHorizontalAlignment()
-    {
-	//          Returns the alignment of the label's contents along the X axis.   
-	return hor_align;
-    }
-    public int getHorizontalTextPosition()
-    {
-	//          Returns the horizontal position of the label's text, relative to its image.    
-	return hor_text_pos;
-    }
-
-    public Icon getIcon()
-    {	return icon;    }
-
-    public int getIconTextGap()
-    {
-	//          Returns the amount of space between the text and the icon displayed in this label.   
-	return 0;
-    }
-    public Component getLabelFor()
-    {
-	//          Get the component this is labelling.  
-	return null;
-    }
-    public String getText()
-    {	return text;    }
-
-    public String getUIClassID()
-    {	return "JLabel";    }
-
-    public int getVerticalAlignment()
-    {
-	//          Returns the alignment of the label's contents along the Y axis. 
-	return vert_align;
-    }
-    public int getVerticalTextPosition()
-    {
-	//          Returns the vertical position of the label's text, relative to its image. 
-	return vert_text_pos;
-    }
-
-    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
-    {
-	//          This is overriden to return false if the current Icon's Image is not equal to the passed in Image img. 
-	return (img == icon);
-    }
-    protected  String paramString()
-    {
-	//          Returns a string representation of this JLabel.  
-	return "JLabel";
-    }
-    public void setDisabledIcon(Icon disabledIcon)
-    {
-	//          Set the icon to be displayed if this JLabel is "disabled" (JLabel.setEnabled(false)).  
-    }
-    public void setDisplayedMnemonic(char aChar)
-    {
-	//          Specifies the displayedMnemonic as a char value.  
-    }
-    public void setDisplayedMnemonic(int key)
-    {
-	//          Specify a keycode that indicates a mnemonic key.  
-    }
-    public void setHorizontalAlignment(int alignment)
-    {
-	//          Sets the alignment of the label's contents along the X axis.  
-	hor_align = alignment;
-    }
-    public void setHorizontalTextPosition(int textPosition)
-    {
-	//          Sets the horizontal position of the label's text, relative to its image.  
-	hor_text_pos = textPosition;
-    }
-    public void setIcon(Icon icon)
-    {
-	this.icon = icon;
-	if (icon != null)
-	    {
-                  // XXX FIXME - icons do not know their parent
-//  		icon.setParent(this);
-	    }
-	revalidate();
-	repaint();
-    }
-
-    public void setIconTextGap(int iconTextGap)
-    {
-	gap = iconTextGap;
-    }
-  
-    public void setLabelFor(Component c)
-    {
-	//          Set the component this is labelling.  
-    }
-    public void setText(String text)
-    {
-	this.text = text;
-	revalidate();
-	repaint();
-    }
-  
-    public void setVerticalAlignment(int alignment)
-    {
-	//          Sets the alignment of the label's contents along the Y axis.  
-	vert_align = alignment;
-    }
-    public void setVerticalTextPosition(int textPosition)
-    {
-	//          Sets the vertical position of the label's text, relative to its image.  
-	vert_text_pos = textPosition;
-    }
-    public void updateUI()
-    {	
-	LabelUI b = (LabelUI)UIManager.getUI(this);
-	setUI(b);
-    }
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 5496508283662221534L;
+
+  /**
+   * The Component the label will give focus to when its mnemonic is
+   * activated.
+   */
+  protected Component labelFor;
+
+  /** The label's text. */
+  private transient String text;
+
+  /** Where the label will be positioned horizontally. */
+  private transient int horizontalAlignment = LEADING;
+
+  /** Where the label text will be placed horizontally relative to the icon. */
+  private transient int horizontalTextPosition = TRAILING;
+
+  /** Where the label will be positioned vertically. */
+  private transient int verticalAlignment = CENTER;
+
+  /** Where the label text will be place vertically relative to the icon. */
+  private transient int verticalTextPosition = CENTER;
+
+  /** The icon painted when the label is enabled. */
+  private transient Icon icon;
+
+  /** The icon painted when the label is disabled. */
+  private transient Icon disabledIcon;
+
+  /** The label's mnemnonic key. */
+  private transient int displayedMnemonic = KeyEvent.VK_UNDEFINED;
+
+  /** The index of the menemonic character in the text. */
+  private transient int displayedMnemonicIndex = -1;
+
+  /** The gap between the icon and the text. */
+  private transient int iconTextGap = 4;
+
+  /**
+   * Fired in a PropertyChangeEvent when the "disabledIcon" property changes.
+   */
+  public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "displayedMnemonic" property
+   * changes.
+   */
+  public static final String DISPLAYED_MNEMONIC_CHANGED_PROPERTY = "displayedMnemonic";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "displayedMnemonicIndex" property
+   * changes.
+   */
+  public static final String DISPLAYED_MNEMONIC_INDEX_CHANGED_PROPERTY = "displayedMnemonicIndex";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "horizontalAlignment" property
+   * changes.
+   */
+  public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY = "horizontalAlignment";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "horizontalTextPosition" property
+   * changes.
+   */
+  public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY = "horizontalTextPosition";
+
+  /** Fired in a PropertyChangeEvent when the "icon" property changes. */
+  public static final String ICON_CHANGED_PROPERTY = "icon";
+
+  /** Fired in a PropertyChangeEvent when the "iconTextGap" property changes. */
+  public static final String ICON_TEXT_GAP_CHANGED_PROPERTY = "iconTextGap";
+
+  /** Fired in a PropertyChangeEvent when the "labelFor" property changes. */
+  public static final String LABEL_FOR_CHANGED_PROPERTY = "labelFor";
+
+  /** Fired in a PropertyChangeEvent when the "text" property changes. */
+  public static final String TEXT_CHANGED_PROPERTY = "text";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "verticalAlignment" property
+   * changes.
+   */
+  public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY = "verticalAlignment";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "verticalTextPosition" property
+   * changes.
+   */
+  public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY = "verticalTextPosition";
+
+  /**
+   * Creates a new horizontally and vertically centered JLabel object with no
+   * text and no icon.
+   */
+  public JLabel()
+  {
+    this(null, null, CENTER);
+  }
+
+  /**
+   * Creates a new horizontally and vertically centered JLabel object with no
+   * text and the given icon.
+   *
+   * @param image The icon to use with the label.
+   */
+  public JLabel(Icon image)
+  {
+    this(null, image, CENTER);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with no text and the
+   * given icon and horizontal alignment. By default, the text is TRAILING
+   * the image.
+   *
+   * @param image The icon to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(Icon image, int horizontalAlignment)
+  {
+    this(null, image, horizontalAlignment);
+  }
+
+  /**
+   * Creates a new horizontally and vertically centered JLabel object with no
+   * icon and the given text.
+   *
+   * @param text The text to use with the label.
+   */
+  public JLabel(String text)
+  {
+    this(text, null, CENTER);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with no icon and the
+   * given text and horizontal alignment.
+   *
+   * @param text The text to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(String text, int horizontalAlignment)
+  {
+    this(text, null, horizontalAlignment);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with the given text,
+   * icon, and horizontal alignment.
+   *
+   * @param text The text to use with the label.
+   * @param icon The icon to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(String text, Icon icon, int horizontalAlignment)
+  {
+    this.text = text;
+    this.icon = icon;
+    this.horizontalAlignment = horizontalAlignment;
+    updateUI();
+  }
+
+  /**
+   * This method returns the label's UI delegate.
+   *
+   * @return The label's UI delegate.
+   */
+  public LabelUI getUI()
+  {
+    return (LabelUI) ui;
+  }
+
+  /**
+   * This method sets the label's UI delegate.
+   *
+   * @param ui The label's UI delegate.
+   */
+  public void setUI(LabelUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method resets the label's UI delegate to the default UI for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((LabelUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for this label.
+   *
+   * @return The UIClass identifier. "LabelUI"
+   */
+  public String getUIClassID()
+  {
+    return "LabelUI";
+  }
+
+  /**
+   * This method is used primarily for debugging purposes and returns a string
+   * that can be used to represent this label.
+   *
+   * @return A string to represent this label.
+   */
+  protected String paramString()
+  {
+    return "JLabel";
+  }
+
+  /**
+   * This method returns the label text.
+   *
+   * @return The label text.
+   */
+  public String getText()
+  {
+    return text;
+  }
+
+  /**
+   * This method changes the "text" property. The given text will be painted
+   * in the label.
+   *
+   * @param newText The label's text.
+   */
+  public void setText(String newText)
+  {
+    if (text != newText)
+      {
+	String oldText = text;
+	text = newText;
+	firePropertyChange(TEXT_CHANGED_PROPERTY, oldText, newText);
+
+	if (text != null && text.length() <= displayedMnemonicIndex)
+	  setDisplayedMnemonicIndex(text.length() - 1);
+      }
+  }
+
+  /**
+   * This method returns the active icon. The active icon is painted when the
+   * label is enabled.
+   *
+   * @return The active icon.
+   */
+  public Icon getIcon()
+  {
+    return icon;
+  }
+
+  /**
+   * This method changes the "icon" property. This icon (the active icon) will
+   * be the one displayed when the label is enabled.
+   *
+   * @param newIcon The active icon.
+   */
+  public void setIcon(Icon newIcon)
+  {
+    if (icon != newIcon)
+      {
+	Icon oldIcon = icon;
+	icon = newIcon;
+	firePropertyChange(ICON_CHANGED_PROPERTY, oldIcon, newIcon);
+      }
+  }
+
+  /**
+   * This method returns the disabled icon. The disabled icon is painted when
+   * the label is disabled. If the disabled icon is null and the active icon
+   * is an ImageIcon, this method returns a grayed version of the icon. The
+   * grayed  version of the icon becomes the disabledIcon.
+   *
+   * @return The disabled icon.
+   */
+  public Icon getDisabledIcon()
+  {
+    if (disabledIcon == null && icon instanceof ImageIcon)
+      disabledIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) icon)
+                                                                  .getImage()));
+
+    return disabledIcon;
+  }
+
+  /**
+   * This method changes the "disabledIcon" property. This icon (the disabled
+   * icon) will be the one displayed when the label is disabled.
+   *
+   * @param newIcon The disabled icon.
+   */
+  public void setDisabledIcon(Icon newIcon)
+  {
+    if (disabledIcon != newIcon)
+      {
+	Icon oldIcon = disabledIcon;
+	disabledIcon = newIcon;
+	firePropertyChange(DISABLED_ICON_CHANGED_PROPERTY, oldIcon, newIcon);
+      }
+  }
+
+  /**
+   * This method sets the keycode that will be the label's mnemonic. If the
+   * label is used as a label for another component, the label will give
+   * focus to that component when the mnemonic is activated.
+   *
+   * @param mnemonic The keycode to use for the mnemonic.
+   */
+  public void setDisplayedMnemonic(int mnemonic)
+  {
+    if (displayedMnemonic != mnemonic)
+      {
+	firePropertyChange(DISPLAYED_MNEMONIC_CHANGED_PROPERTY,
+	                   displayedMnemonic, mnemonic);
+	displayedMnemonic = mnemonic;
+
+	if (text != null)
+	  setDisplayedMnemonicIndex(text.indexOf(mnemonic));
+      }
+  }
+
+  /**
+   * This method sets the character that will be the mnemonic used. If the
+   * label is used as a label for another component, the label will give
+   * focus to that component when the mnemonic is activated.
+   *
+   * @param mnemonic The character to use for the mnemonic.
+   */
+  public void setDisplayedMnemonic(char mnemonic)
+  {
+    setDisplayedMnemonic((int) mnemonic);
+  }
+
+  /**
+   * This method returns the keycode that is used for the label's mnemonic.
+   *
+   * @return The keycode that is used for the label's mnemonic.
+   */
+  public int getDisplayedMnemonic()
+  {
+    return (int) displayedMnemonic;
+  }
+
+  /**
+   * This method sets which character in the text will be  the underlined
+   * character. If the given index is -1, then this indicates  that there is
+   * no mnemonic. If the index is less than -1 or if the index is equal to
+   * the length, this method will throw an IllegalArgumentException.
+   *
+   * @param newIndex The index of the character to underline.
+   *
+   * @throws IllegalArgumentException If index less than -1 or index equals
+   *         length.
+   */
+  public void setDisplayedMnemonicIndex(int newIndex)
+                                 throws IllegalArgumentException
+  {
+    if (newIndex < -1 || (text != null && newIndex >= text.length()))
+      throw new IllegalArgumentException();
+
+    if (text == null || text.charAt(newIndex) != displayedMnemonic)
+      newIndex = -1;
+
+    if (newIndex != displayedMnemonicIndex)
+      {
+	firePropertyChange(DISPLAYED_MNEMONIC_INDEX_CHANGED_PROPERTY,
+	                   displayedMnemonicIndex, newIndex);
+	displayedMnemonicIndex = newIndex;
+      }
+  }
+
+  /**
+   * This method returns which character in the text will be  the underlined
+   * character.
+   *
+   * @return The index of the character that will be underlined.
+   */
+  public int getDisplayedMnemonicIndex()
+  {
+    return displayedMnemonicIndex;
+  }
+
+  /**
+   * This method ensures that the key is valid as a horizontal alignment.
+   * Valid keys are: LEFT, CENTER, RIGHT, LEADING, TRAILING
+   *
+   * @param key The key to check.
+   * @param message The message of the exception to be thrown if the key is
+   *        invalid.
+   *
+   * @return The key if it's valid.
+   *
+   * @throws IllegalArgumentException If the key is invalid.
+   */
+  protected int checkHorizontalKey(int key, String message)
+  {
+    if (key != LEFT && key != CENTER && key != RIGHT && key != LEADING
+        && key != TRAILING)
+      throw new IllegalArgumentException(message);
+    else
+      return key;
+  }
+
+  /**
+   * This method ensures that the key is valid as a  vertical alignment. Valid
+   * keys are: TOP, CENTER, and BOTTOM.
+   *
+   * @param key The key to check.
+   * @param message The message of the exception to be thrown if the key is
+   *        invalid.
+   *
+   * @return The key if it's valid.
+   *
+   * @throws IllegalArgumentException If the key is invalid.
+   */
+  protected int checkVerticalKey(int key, String message)
+  {
+    if (key != TOP && key != BOTTOM && key != CENTER)
+      throw new IllegalArgumentException(message);
+    else
+      return key;
+  }
+
+  /**
+   * This method returns the gap between the icon and the text.
+   *
+   * @return The gap between the icon and the text.
+   */
+  public int getIconTextGap()
+  {
+    return iconTextGap;
+  }
+
+  /**
+   * This method changes the "iconTextGap" property. The iconTextGap
+   * determines how much space there is between the icon and the text.
+   *
+   * @param newGap The gap between the icon and the text.
+   */
+  public void setIconTextGap(int newGap)
+  {
+    if (iconTextGap != newGap)
+      {
+	firePropertyChange(ICON_TEXT_GAP_CHANGED_PROPERTY, iconTextGap, newGap);
+	iconTextGap = newGap;
+      }
+  }
+
+  /**
+   * This method returns the vertical alignment of the label.
+   *
+   * @return The vertical alignment of the label.
+   */
+  public int getVerticalAlignment()
+  {
+    return verticalAlignment;
+  }
+
+  /**
+   * This method changes the "verticalAlignment" property of the label. The
+   * vertical alignment determines how where the label will be placed
+   * vertically. If the alignment is not valid, it will default to the
+   * center.
+   *
+   * @param alignment The vertical alignment of the label.
+   */
+  public void setVerticalAlignment(int alignment)
+  {
+    if (alignment != verticalAlignment)
+      {
+	int oldAlignment = verticalAlignment;
+	verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
+	firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, oldAlignment,
+	                   verticalAlignment);
+      }
+  }
+
+  /**
+   * This method returns the horziontal alignment of the label.
+   *
+   * @return The horizontal alignment of the label.
+   */
+  public int getHorizontalAlignment()
+  {
+    return horizontalAlignment;
+  }
+
+  /**
+   * This method changes the "horizontalAlignment" property. The horizontal
+   * alignment determines where the label will be placed horizontally.
+   *
+   * @param alignment The horizontal alignment of the label.
+   */
+  public void setHorizontalAlignment(int alignment)
+  {
+    int oldAlignment = horizontalAlignment;
+    horizontalAlignment = checkHorizontalKey(alignment, "horizontalAlignment");
+    firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, oldAlignment,
+                       horizontalAlignment);
+  }
+
+  /**
+   * This method returns the vertical text position of the label.
+   *
+   * @return The vertical text position of the label.
+   */
+  public int getVerticalTextPosition()
+  {
+    return verticalTextPosition;
+  }
+
+  /**
+   * This method changes the "verticalTextPosition" property of the label. The
+   * vertical text position determines where the text will be placed
+   * vertically relative to the icon.
+   *
+   * @param textPosition The vertical text position.
+   */
+  public void setVerticalTextPosition(int textPosition)
+  {
+    if (textPosition != verticalTextPosition)
+      {
+	int oldPos = verticalTextPosition;
+	verticalTextPosition = checkVerticalKey(textPosition,
+	                                        "verticalTextPosition");
+	firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, oldPos,
+	                   verticalTextPosition);
+      }
+  }
+
+  /**
+   * This method returns the horizontal text position of the label.
+   *
+   * @return The horizontal text position.
+   */
+  public int getHorizontalTextPosition()
+  {
+    return horizontalTextPosition;
+  }
+
+  /**
+   * This method changes the "horizontalTextPosition" property of the label.
+   * The horizontal text position determines where the text will be placed
+   * horizontally relative to the icon.
+   *
+   * @param textPosition The horizontal text position.
+   */
+  public void setHorizontalTextPosition(int textPosition)
+  {
+    if (textPosition != horizontalTextPosition)
+      {
+	int oldPos = horizontalTextPosition;
+	horizontalTextPosition = checkHorizontalKey(textPosition,
+	                                            "horizontalTextPosition");
+	firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, oldPos,
+	                   horizontalTextPosition);
+      }
+  }
+
+  /**
+   * This method simply returns false if the current icon image (current  icon
+   * will depend on whether the label is enabled) is not equal to the passed
+   * in image.
+   *
+   * @param img The image to check.
+   * @param infoflags The bitwise inclusive OR of ABORT, ALLBITS, ERROR,
+   *        FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, and WIDTH
+   * @param x The x position
+   * @param y The y position
+   * @param w The width
+   * @param h The height
+   *
+   * @return Whether the current icon image is equal to the image given.
+   */
+  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
+                             int h)
+  {
+    Icon currIcon = isEnabled() ? icon : disabledIcon;
+
+    // XXX: Is this the correct way to check for image equality?
+    if (currIcon != null && currIcon instanceof ImageIcon)
+      return (((ImageIcon) currIcon).getImage() == img);
+
+    return false;
+  }
+
+  /**
+   * This method returns the component that the label gives focus to  when the
+   * mnemonic is activated.
+   *
+   * @return The component that gets focus when the label's mnemonic is
+   *         activated.
+   */
+  public Component getLabelFor()
+  {
+    return labelFor;
+  }
+
+  /**
+   * This method changes the "labelFor" property. The component that the label
+   * is acting as a label for will request focus when the label's  mnemonic
+   * is activated.
+   *
+   * @param c The component that gets focus when the label's mnemonic is
+   *        activated.
+   */
+  public void setLabelFor(Component c)
+  {
+    if (c != labelFor)
+      {
+	firePropertyChange(LABEL_FOR_CHANGED_PROPERTY, labelFor, c);
+	labelFor = c;
+      }
+  }
+
+  /**
+   * This method overrides setFont so that we can call for a repaint after the
+   * font is changed.
+   *
+   * @param f The font for this label.
+   */
+  public void setFont(Font f)
+  {
+    super.setFont(f);
+    repaint();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
 }
Index: javax/swing/JLayeredPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JLayeredPane.java,v
retrieving revision 1.6
diff -u -r1.6 JLayeredPane.java
--- javax/swing/JLayeredPane.java	9 Jan 2004 22:52:18 -0000	1.6
+++ javax/swing/JLayeredPane.java	6 Sep 2004 16:35:56 -0000
@@ -82,17 +82,18 @@
  * <dd>An offset into a layer's "logical drawing order". Layer position 0
  * is drawn last. Layer position -1 is a synonym for the first layer
  * position (the logical "bottom").</dd>
+ * </dl>
  *
  * <p><b>Note:</b> the layer numbering order is the <em>reverse</em> of the
  * component indexing and position order</p>
  *
  * @author Graydon Hoare <graydon@redhat.com>
  */
-
 public class JLayeredPane extends JComponent implements Accessible
 {
-
-  public static String LAYER_PROPERTY = "LAYER_PROPERTY";
+  private static final long serialVersionUID = 5534920399324590459L;
+  
+  public static final String LAYER_PROPERTY = "layeredContainerLayer";
 
   public static Integer FRAME_CONTENT_LAYER = new Integer (-30000);
 
@@ -105,7 +106,7 @@
   TreeMap layers;               // Layer Number (Integer) -> Layer Size (Integer)
   Hashtable componentToLayer;   // Component -> Layer Number (Integer)
 
-  JLayeredPane()
+  public JLayeredPane()
   {
     layers = new TreeMap ();
     componentToLayer = new Hashtable ();
@@ -152,7 +153,7 @@
         Map.Entry pair = (Map.Entry) i.next();
         Integer layerNum = (Integer) pair.getKey ();
         Integer layerSz = (Integer) pair.getValue ();
-        if (layerNum == layer)
+        if (layerNum.intValue() == layer.intValue())
           {
             ret[0] = ret[1] - layerSz.intValue ();
             return ret;
@@ -313,7 +314,7 @@
     int bot = range[1];
     if (position == -1)
 	    position = (bot - top) - 1;
-    int targ = top + position;
+    int targ = Math.min(top + position, bot-1);
     int curr = -1;
 
     Component[] comps = getComponents();
@@ -330,7 +331,7 @@
 	    throw new IllegalArgumentException ();
 
     super.swapComponents (curr, targ);
-    validate();
+    revalidate();
     repaint();
   }
     
@@ -493,6 +494,8 @@
     decrLayer (layer);
     componentToLayer.remove (c);
     super.remove (index);
+    revalidate();
+    repaint();
   }
 
   /**
@@ -536,9 +539,10 @@
                        int layer,
                        int position)
   {
-    componentToLayer.put (c, getObjectForLayer (layer));
+    remove(c);
+    add(c, getObjectForLayer (layer));
     setPosition(c, position);
-    validate();
+    revalidate();
     repaint();
   }
 
@@ -563,13 +567,13 @@
     else
 	    layer = DEFAULT_LAYER;
 
-    int newIdx = insertIndexForLayer(layer.intValue (), -1);
+    int newIdx = insertIndexForLayer(layer.intValue (), index);
 
     componentToLayer.put (comp, layer);
     incrLayer (layer);
 	
     super.addImpl(comp, null, newIdx);	
-    validate();
+    revalidate();
     repaint();
   }     
 }
Index: javax/swing/JList.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JList.java,v
retrieving revision 1.2
diff -u -r1.2 JList.java
--- javax/swing/JList.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JList.java	6 Sep 2004 16:35:56 -0000
@@ -1,4 +1,4 @@
-/* JList.java -- 
+/* JList.java --
    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -35,204 +35,1164 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
 import java.awt.Dimension;
+import java.awt.Point;
 import java.awt.Rectangle;
 import java.util.Vector;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.swing.event.ListDataEvent;
 import javax.swing.event.ListDataListener;
+import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import javax.swing.plaf.ListUI;
 
-public class JList extends JComponent implements Accessible, Scrollable
-{
-    Color select_back, select_fore;
-    ListCellRenderer render;
-    int visibles = 8;
-    
-    ListModel          model;
-    ListSelectionModel sel_model;
-
-    public JList()
-    {	
-	init();
-    }
-
-    public JList(Object[] listData)
-    {
-	init();
-	setListData(listData);
-    }
-
-
-    public JList(Vector listData)
-    {
-	init();
-	setListData(listData);
-    }
-
-
-    public JList(ListModel listData)
-    {
-	init();
-	setModel(listData);
-    }
-    void init()
-    {
-	render = new DefaultCellRenderer();
-	
-	sel_model = new DefaultListSelectionModel();
-	setModel(new DefaultListModel());
 
-	select_back = new Color(0,0,255);
-	select_fore = new Color(255,255,255);
-
-	updateUI();
-    }
-
-    
-    public int getVisibleRowCount()
-    { return visibles; }
-    public void setVisibleRowCount(int visibleRowCount)
-    {
-	visibles =  visibleRowCount;
-	invalidate();
-	repaint();
-    }
-
-    void addListSelectionListener(ListSelectionListener listener)
-    { sel_model.addListSelectionListener(listener);    }
-    void removeListSelectionListener(ListSelectionListener listener)
-    { sel_model.removeListSelectionListener(listener);    }
-
-    void setSelectionMode(int a)
-    {  sel_model.setSelectionMode(a);   }
-    void setSelectedIndex(int a)
-    {  sel_model.setSelectionInterval(a,a); }
-    int getSelectedIndex()
-    {	return sel_model.getMinSelectionIndex();    }
-    Object getSelectedValue()
-    {  
-	int index = getSelectedIndex();
-	if (index == -1)
-	    return null;
-	return getModel().getElementAt(index);
-    }
-
-    Color getSelectionBackground()
-    { return select_back;    }    
-    Color getSelectionForeground()
-    { return select_fore;    }
+/**
+ * <p>This class is a facade over three separate objects: {@link
+ * javax.swing.ListModel}, {@link javax.swing.ListSelectionModel} and
+ * {@link javax.swing.plaf.ListUI}. The facade represents a unified "list"
+ * concept, with independently replacable (possibly client-provided) models
+ * for its contents and its current selection. In addition, each element in
+ * the list is rendered via a strategy class {@link
+ * javax.swing.ListCellRenderer}.</p>
+ *
+ * <p>Lists have many properties, some of which are stored in this class
+ * while others are delegated to the list's model or selection. The
+ * following properties are available:</p>
+ *
+ * <table>
+ * <tr><th>Property                       </th><th>Stored in</th><th>Bound?</th></tr>
+ * <tr><td>accessibleContext              </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>anchorSelectionIndex           </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>cellRenderer                   </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>dragEnabled                    </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>firstVisibleIndex              </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>fixedCellHeight                </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>fixedCellWidth                 </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>lastVisibleIndex               </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>layoutOrientation              </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>leadSelectionIndex             </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>maxSelectionIndex              </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>minSelectionIndex              </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>model                          </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>opaque                         </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>preferredScrollableViewportSize</td><td>list     </td><td>no    </td></tr>
+ * <tr><td>prototypeCellValue             </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>scrollableTracksViewportHeight </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>scrollableTracksViewportWidth  </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>selectedIndex                  </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectedIndices                </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectedValue                  </td><td>model    </td><td>no    </td></tr>
+ * <tr><td>selectedValues                 </td><td>model    </td><td>no    </td></tr>
+ * <tr><td>selectionBackground            </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>selectionEmpty                 </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectionForeground            </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>selectionMode                  </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectionModel                 </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>UI                             </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>UIClassID                      </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>valueIsAdjusting               </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>visibleRowCount                </td><td>list     </td><td>no    </td></tr>
+ * </table> 
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
 
+public class JList extends JComponent implements Accessible, Scrollable
+{
+  private static final long serialVersionUID = 4406629526391098046L;
 
-    public void setListData(final Object[] listData)
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in a single vertical column. This is the default. 
+   */
+  public static final int VERTICAL = 0;
+
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in multiple columns "newspaper style", filling
+   * vertically first, then horizontally. 
+   */
+  public static final int VERTICAL_WRAP = 1;
+  
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in multiple columns "newspaper style",
+   * filling horizontally first, then vertically. 
+   */
+  public static final int HORIZONTAL_WRAP = 2;
+
+  /** Fired in a PropertyChangeEvent when the "cellRenderer" property changes. */
+  public static final String CELL_RENDERER_PROPERTY_CHANGED = "cellRenderer";
+
+  /** Fired in a PropertyChangeEvent when the "fixedCellHeight" property changes. */
+  public static final String FIXED_CELL_HEIGHT_PROPERTY_CHANGED = "fixedCellHeight";
+
+  /** Fired in a PropertyChangeEvent when the "fixedCellWidth" property changes. */
+  public static final String FIXED_CELL_WIDTH_PROPERTY_CHANGED = "fixedCellWidth";
+
+  /** Fired in a PropertyChangeEvent when the "layoutOrientation" property changes. */
+  public static final String LAYOUT_ORIENTATION_PROPERTY_CHANGED = "layoutOrientation";
+
+  /** Fired in a PropertyChangeEvent when the "model" property changes. */
+  public static final String MODEL_PROPERTY_CHANGED = "model";
+
+  /** Fired in a PropertyChangeEvent when the "prototypeCellValue" property changes. */
+  public static final String PROTOTYPE_CELL_VALUE_PROPERTY_CHANGED = "prototypeCellValue";
+
+  /** Fired in a PropertyChangeEvent when the "selectionBackground" property changes. */
+  public static final String SELECTION_BACKGROUND_PROPERTY_CHANGED = "selectionBackground";
+
+  /** Fired in a PropertyChangeEvent when the "selectionForeground" property changes. */
+  public static final String SELECTION_FOREGROUND_PROPERTY_CHANGED = "selectionForeground";
+
+  /** Fired in a PropertyChangeEvent when the "selectionModel" property changes. */
+  public static final String SELECTION_MODEL_PROPERTY_CHANGED = "selectionModel";
+
+
+  /**
+   * This property indicates whether "drag and drop" functions are enabled
+   * on the list.
+   */
+  boolean dragEnabled;
+
+  /** This property provides a strategy for rendering cells in the list. */
+  ListCellRenderer cellRenderer;
+
+  /**
+   * This property indicates an fixed width to assign to all cells in the
+   * list. If its value is <code>-1</code>, no width has been
+   * assigned. This value can be set explicitly, or implicitly by setting
+   * the {@link #prototypeCellValue} property.
+   */
+  int fixedCellWidth;
+  
+  /**
+   * This property indicates an fixed height to assign to all cells in the
+   * list. If its value is <code>-1</code>, no height has been
+   * assigned. This value can be set explicitly, or implicitly by setting
+   * the {@link #prototypeCellValue} property.
+   */
+  int fixedCellHeight;
+
+  /** 
+   * This property holds the current layout orientation of the list, which
+   * is one of the integer constants {@link #VERTICAL}, {@link
+   * #VERTICAL_WRAP}, or {@link #HORIZONTAL_WRAP}. 
+   */
+
+  int layoutOrientation;
+  
+  /** This property holds the data elements displayed by the list. */
+  ListModel model;
+
+  /**
+   * <p>This property holds a reference to a "prototype" data value --
+   * typically a String -- which is used to calculate the {@link
+   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
+   * {@link #cellRenderer} property to acquire a component to render the
+   * prototype.</p>
+   *
+   * <p>It is important that you <em>not</em> set this value to a
+   * component. It has to be a <em>data value</em> such as the objects you
+   * would find in the list's model. Setting it to a component will have
+   * undefined (and undesirable) affects. </p>
+   */
+  Object prototypeCellValue;
+
+  /** 
+   * This property specifies a foreground color for the selected cells in
+   * the list. When {@link ListCellRenderer.getListCellRendererComponent}
+   * is called with a selected cell object, the component returned will
+   * have its "foreground" set to this color.
+   */
+  Color selectionBackground;
+
+  /** 
+   * This property specifies a background color for the selected cells in
+   * the list. When {@link ListCellRenderer.getListCellRendererComponent}
+   * is called with a selected cell object, the component returned will
+   * have its "background" property set to this color.
+   */
+  Color selectionForeground;
+
+  /** 
+   * This property holds a description of which data elements in the {@link
+   * #model} property should be considered "selected", when displaying and
+   * interacting with the list.
+   */
+  ListSelectionModel selectionModel;
+
+
+  /**
+   * This property indicates that the list's selection is currently
+   * "adjusting" -- perhaps due to a user actively dragging the mouse over
+   * multiple list elements -- and is therefore likely to change again in
+   * the near future. A {@link ListSelectionListener} might choose to delay
+   * updating its view of the list's selection until this property is
+   * false, meaning that the adjustment has completed.
+   */
+  boolean valueIsAdjusting;
+
+  /** 
+   * This property indicates a <em>preference</em> for the number of rows
+   * displayed in the list, and will scale the
+   * {@link #preferredScrollableViewportSize} property accordingly. The actual
+   * number of displayed rows, when the list is placed in a real {@link
+   * Viewport} or other component, may be greater or less than this number.
+   */
+  int visibleRowCount;
+
+
+
+  /**
+   * Fire a {@link ListSelectionEvent} to all the registered ListSelectionListeners.
+   */
+  void fireSelectionValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) 
+  {
+    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting);
+    ListSelectionListener listeners[] = getListSelectionListeners();
+    for (int i = 0; i < listeners.length; ++i)
+      {
+        listeners[i].valueChanged(evt);
+      }
+  }
+
+
+  /**
+   * This private listener propagates {@link ListSelectionEvent} events
+   * from the list's "selectionModel" property to the list's {@link
+   * ListSelectionListener} listeners. It also listens to {@link
+   * ListDataEvent} events from the list's {@link #model} property. If this
+   * class receives either type of event, it triggers repainting of the
+   * list.
+   */
+  private class ListListener 
+    implements ListSelectionListener, ListDataListener
+  {
+    // ListDataListener events
+    public void contentsChanged(ListDataEvent event)
     {
-	class AL extends AbstractListModel
-	{
-	    public int getSize()              { return listData.length; }
-	    public Object getElementAt(int i) { return listData[i];     }
-	};
-	
-	setModel (new AL());
+      JList.this.revalidate();
+      JList.this.repaint();
     }
-    
-    public void setListData(final Vector listData)
+    public void intervalAdded(ListDataEvent event)
     {
-	class AL extends AbstractListModel 
-	{
-	    public int getSize()              { return listData.size(); }
-	    public Object getElementAt(int i) { return listData.elementAt(i); }
-	};
-	
-        setModel (new AL());
+      JList.this.revalidate();
+      JList.this.repaint();
     }
-    
-    
-    public ListCellRenderer getCellRenderer()
-    {    return  render; }
-    public void setCellRenderer(ListCellRenderer cellRenderer)
+    public void intervalRemoved(ListDataEvent event)
     {
-	render = cellRenderer;
-	invalidate();
-	repaint();
+      JList.this.revalidate();
+      JList.this.repaint();
     }
-    
-    public void setModel(ListModel model)
+    // ListSelectionListener events
+    public void valueChanged(ListSelectionEvent event)
     {
-	ListDataListener l = new ListDataListener()
-	    {
-		public void intervalAdded(ListDataEvent e) {
-		    repaint();
-		}
-		public void intervalRemoved(ListDataEvent e) {
-		    repaint();
-		}
-		public void contentsChanged(ListDataEvent e) {
-		    repaint();
-		}
-	    };
-	
-	this.model = model;  
-	model.addListDataListener(l);	
+      JList.this.fireSelectionValueChanged(event.getFirstIndex(),
+                                           event.getLastIndex(),
+                                           event.getValueIsAdjusting());
+      JList.this.repaint();
     }
+  };
 
-    public ListModel getModel() 
-    {  return model;        }
-    
-    
-    public ListUI getUI()
-    {  return (ListUI) ui;    }
-    public void setUI(ListUI ui)
-    {   super.setUI(ui);      }
-
-    public void updateUI()
-    {
-        setUI((ListUI)UIManager.getUI(this));
-    }
-
-    public String getUIClassID()
-    {
-	return "JList";
-    }
-
-
-    public AccessibleContext getAccessibleContext()
-    {
-      return null;
-    }
-
-    public Dimension getPreferredScrollableViewportSize()
-    {
+  /** 
+   * Shared ListListener instance, subscribed to both the current {@link
+   * #model} and {@link #selectionModel} properties of the list.
+   */
+  ListListener listListener;
+
+
+  /**
+   * Creates a new JList object.
+   */
+  public JList()
+  {
+    init();
+  }
+
+  /**
+   * Creates a new JList object.
+   *
+   * @param listData Initial data to populate the list with
+   */
+  public JList(Object[] listData)
+  {
+    init();
+    setListData(listData);
+  }
+
+  /**
+   * Creates a new JList object.
+   *
+   * @param listData Initial data to populate the list with
+   */
+  public JList(Vector listData)
+  {
+    init();
+    setListData(listData);
+  }
+
+  /**
+   * Creates a new JList object.
+   *
+   * @param listData Initial data to populate the list with
+   */
+  public JList(ListModel listData)
+  {
+    init();
+    setModel(listData);
+  }
+
+  void init()
+  {
+    dragEnabled = false;
+    fixedCellHeight = -1;
+    fixedCellWidth = -1;
+    layoutOrientation = VERTICAL;
+    opaque = true;
+    valueIsAdjusting = false;
+    visibleRowCount = 8;
+
+    cellRenderer = new DefaultListCellRenderer();
+    listListener = new ListListener();
+
+    setModel(new DefaultListModel());
+    setSelectionModel(new DefaultListSelectionModel());
+
+    updateUI();
+  }
+
+  /**
+   * Gets the value of the {@link #fixedCellHeight} property. This property
+   * may be <code>-1</code> to indicate that no cell height has been
+   * set. This property is also set implicitly when the
+   * {@link #prototypeCellValue} property is set.
+   *
+   * @return The current value of the property 
+   * 
+   * @see #fixedCellHeight
+   * @see #setFixedCellHeight
+   * @see #setPrototypeCellValue
+   */
+  public int getFixedCellHeight()
+  {
+    return fixedCellHeight;
+  }
+
+  /**
+   * Sets the value of the {@link #fixedCellHeight} property. This property
+   * may be <code>-1</code> to indicate that no cell height has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set, but setting it explicitly
+   * overrides the height computed from {@link #prototypeCellValue}.
+   *
+   * @see #getFixedCellHeight
+   * @see #getPrototypeCellValue
+   */
+  public void setFixedCellHeight(int h)
+  {
+    int old = fixedCellHeight;
+    fixedCellHeight = h;
+    firePropertyChange(FIXED_CELL_WIDTH_PROPERTY_CHANGED, old, h);
+  }
+
+
+  /**
+   * Gets the value of the {@link #fixedCellWidth} property. This property
+   * may be <code>-1</code> to indicate that no cell width has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set.
+   *
+   * @return The current value of the property 
+   * 
+   * @see #setFixedCellWidth
+   * @see #setPrototypeCellValue
+   */
+  public int getFixedCellWidth()
+  {
+    return fixedCellWidth;
+  }
+
+  /**
+   * Sets the value of the {@link #fixedCellWidth} property. This property
+   * may be <code>-1</code> to indicate that no cell width has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set, but setting it explicitly
+   * overrides the width computed from {@link #prototypeCellValue}.
+   *
+   * @see #getFixedCellWidth
+   * @see #getPrototypeCellValue
+   */
+  public void setFixedCellWidth(int h)
+  {
+    int old = fixedCellHeight;
+    fixedCellHeight = h;
+    firePropertyChange(FIXED_CELL_HEIGHT_PROPERTY_CHANGED, old, h);
+  }
+
+
+  /** 
+   * Gets the value of the {@link #visibleRowCount} property. 
+   *
+   * @return the current value of the property.
+   */
+
+  public int getVisibleRowCount()
+  {
+    return visibleRowCount;
+  }
+
+  /**
+   * Sets the value of the {@link #visibleRowCount} property. 
+   *
+   * @param visibleRowCount The new property value
+   */
+  public void setVisibleRowCount(int vc)
+  {
+    visibleRowCount = vc;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Adds a {@link ListSelectionListener} to the listener list for this
+   * list. The listener will be called back with a {@link
+   * ListSelectionEvent} any time the list's {@link #selectionModel}
+   * property changes. The source of such events will be the JList,
+   * not the selection model.
+   *
+   * @param listener The new listener to add
+   */
+  public void addListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.add (ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Removes a {@link ListSelectionListener} from the listener list for
+   * this list. The listener will no longer be called when the list's
+   * {@link #selectionModel} changes.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.remove(ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Returns an array of all ListSelectionListeners subscribed to this
+   * list. 
+   *
+   * @return The current subscribed listeners
+   *
+   * @since 1.4
+   */
+  public ListSelectionListener[] getListSelectionListeners()
+  {
+    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
+  }
+
+  /**
+   * Sets the list's "selectionMode" property, which simply mirrors the
+   * same property on the list's {@link #selectionModel} property. This
+   * property should be one of the integer constants
+   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>,
+   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from the {@link
+   * ListSelectionModel} interface.
+   *
+   * @param a The new selection mode
+   */
+  public void setSelectionMode(int a)
+  {
+    selectionModel.setSelectionMode(a);
+  }
+
+  /**
+   * Adds the interval <code>[a,a]</code> to the set of selections managed
+   * by this list's {@link #selectionModel} property. Depending on the
+   * selection mode, this may cause existing selections to become invalid,
+   * or may simply expand the set of selections. 
+   *
+   * @param a A number in the half-open range <code>[0, x)</code> where
+   * <code>x = getModel.getSize()</code>, indicating the index of an
+   * element in the list to select.
+   *
+   * @see #setSelectionMode
+   * @see #selectionModel
+   */
+  public void setSelectedIndex(int a)
+  {
+    selectionModel.setSelectionInterval(a, a);
+  }
+
+  /**
+   * For each element <code>a[i]</code> of the provided array
+   * <code>a</code>, calls {@link #setSelectedIndex} on <code>a[i]</code>.
+   *
+   * @see #setSelectionMode
+   * @see #selectionModel
+   */
+  public void setSelectedIndices(int [] a)
+  {
+    for (int i = 0; i < a.length; ++i)
+      setSelectedIndex(a[i]);
+  }
+
+  /**
+   * Returns the minimum index of an element in the list which is currently
+   * selected.
+   *
+   * @return A number in the half-open range <code>[0, x)</code> where
+   * <code>x = getModel.getSize()</code>, indicating the minimum index of
+   * an element in the list for which the element is selected, or
+   * <code>-1</code> if no elements are selected
+   */
+  public int getSelectedIndex()
+  {
+    return selectionModel.getMinSelectionIndex();
+  }
+
+  /**
+   * Returns <code>true</code> if the model's selection is empty, otherwise
+   * <code>false</code>. 
+   *
+   * @return The return value of {@link ListSelectionModel#isSelectionEmpty}
+   */
+  public boolean isSelectionEmpty()
+  {
+    return selectionModel.isSelectionEmpty();
+  }
+
+  /**
+   * Returns the list index of the upper left or upper right corner of the
+   * {@link #visibleRect} property, depending on the {@link
+   * #componentOrientation} property.
+   *
+   * @return The index of the first visible list cell, or <code>-1</code>
+   * if none is visible.
+   */
+  public int getFirstVisibleIndex()
+  {
+    ComponentOrientation or = getComponentOrientation();
+    Rectangle r = getVisibleRect();
+    if (or == ComponentOrientation.RIGHT_TO_LEFT)
+      r.translate((int) r.getWidth(), 0);
+    return getUI().locationToIndex(this, r.getLocation());      
+  }
+
+
+  /**
+   * Returns index of the cell to which specified location is closest to
+   * @param location for which to look for in the list
+   * 
+   * @return index of the cell to which specified location is closest to.
+   */
+   public int locationToIndex(Point location) {
+     return getUI().locationToIndex(this, location);      
+   }
+
+  /**
+   * Returns location of the cell located at the specified index in the list.
+   * @param index of the cell for which location will be determined
+   * 
+   * @return location of the cell located at the specified index in the list.
+   */
+   public Point indexToLocation(int index){
+   	//FIXME: Need to implement.
 	return null;
-    }
-
-    public int getScrollableUnitIncrement(Rectangle visibleRect,
-					  int orientation,
-					  int direction)
-    {
-	return 1;
-    }
-
-    public int getScrollableBlockIncrement(Rectangle visibleRect,
-					   int orientation,
-					   int direction)
-    {
-	return 1;
-    }
+   }
 
-    public boolean getScrollableTracksViewportWidth()
-    {
-	return false;
-    }
+  /**
+   * Returns the list index of the lower right or lower left corner of the
+   * {@link #visibleRect} property, depending on the {@link
+   * #componentOrientation} property.
+   *
+   * @return The index of the first visible list cell, or <code>-1</code>
+   * if none is visible.
+   */
+  public int getLastVisibleIndex()
+  {
+    ComponentOrientation or = getComponentOrientation();
+    Rectangle r = getVisibleRect();
+    r.translate(0, (int) r.getHeight());
+    if (or == ComponentOrientation.LEFT_TO_RIGHT)
+      r.translate((int) r.getWidth(), 0);
+    return getUI().locationToIndex(this, r.getLocation());      
+  }
+
+  /**
+   * Returns the indices of values in the {@link #model} property which are
+   * selected.
+   *
+   * @return An array of model indices, each of which is selected according
+   * to the {@link #selection} property
+   */
+  public int[] getSelectedIndices()
+  {
+    int lo, hi, n, i, j;
+    if (selectionModel.isSelectionEmpty())
+      return new int[0];
+    lo = selectionModel.getMinSelectionIndex();
+    hi = selectionModel.getMaxSelectionIndex();
+    n = 0;
+    for (i = lo; i < hi; ++i)
+      if (selectionModel.isSelectedIndex(i))
+        n++;
+    int [] v = new int[n];
+    j = 0;
+    for (i = lo; i < hi; ++i)
+      if (selectionModel.isSelectedIndex(i))
+        v[j++] = i;
+    return v;
+  }
+
+  /**
+   * Indicates whether the list element at a given index value is
+   * currently selected.
+   *
+   * @param a The index to check 
+   * @return <code>true</code> if <code>a</code> is the index of a selected
+   * list element
+   */
+  public boolean isSelectedIndex(int a)
+  {
+    return selectionModel.isSelectedIndex(a);
+  }
+
+  /**
+   * Returns the first value in the list's {@link #model} property which is
+   * selected, according to the list's {@link #selectionModel} property.
+   * This is equivalent to calling
+   * <code>getModel()getElementAt(getSelectedIndex())</code>, with a check
+   * for the special index value of <code>-1</code> which returns null
+   * <code>null</code>.
+   *
+   * @return The first selected element, or <code>null</code> if no element
+   * is selected.
+   *
+   * @see getSelectedValues
+   */
+  public Object getSelectedValue()
+  {
+    int index = getSelectedIndex();
+    if (index == -1)
+      return null;
+    return getModel().getElementAt(index);
+  }
 
-    public boolean getScrollableTracksViewportHeight()
-    {
-	return false;
-    }
-    
+  /**
+   * Returns all the values in the list's {@link #model} property which
+   * are selected, according to the list's {@link #selectionModel} property.
+   *
+   * @return An array containing all the selected values
+   *
+   * @see getSelectedValue
+   */
+  public Object[] getSelectedValues()
+  {
+    int [] idx = getSelectedIndices();
+    Object [] v = new Object[idx.length];
+    for (int i = 0; i < idx.length; ++i)
+      v[i] = getModel().getElementAt(i);
+    return v;
+  }
+
+  /**
+   * Gets the value of the {@link #selectionBackground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionBackground()
+  {
+    return selectionBackground;
+  }
+
+  /**
+   * Sets the value of the {@link #selectionBackground} property.
+   *
+   * @param c The new value of the property
+   */
+  public void setSelectionBackground(Color c)
+  {
+    Color old = selectionBackground;
+    selectionBackground = c;
+    firePropertyChange(SELECTION_BACKGROUND_PROPERTY_CHANGED, old, c);
+    repaint();
+  }
+
+  /**
+   * Gets the value of the {@link #selectionForeground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionForeground()
+  {
+    return selectionForeground;
+  }
+  
+  /**
+   * Sets the value of the {@link #selectionForeground} property.
+   *
+   * @param c The new value of the property
+   */
+  public void setSelectionForeground(Color c)
+  {
+    Color old = selectionForeground;
+    selectionForeground = c;
+    firePropertyChange(SELECTION_FOREGROUND_PROPERTY_CHANGED, old, c);
+  }
+
+  /**
+   * Sets the selection to cover only the specified value, if it
+   * exists in the model. 
+   *
+   * @param obj The object to select
+   * @param scroll Whether to scroll the list to make the newly selected
+   * value visible
+   *
+   * @see #ensureIndexIsVisible
+   */
+
+  public void setSelectedValue(Object obj, boolean scroll)
+  {
+    for (int i = 0; i < model.getSize(); ++i)
+      {
+        if (model.getElementAt(i).equals(obj))
+          {
+            setSelectedIndex(i);
+            if (scroll)
+              ensureIndexIsVisible(i);
+            break;
+          }
+      }
+  }
+
+  /**
+   * Scrolls this list to make the specified cell visible. This
+   * only works if the list is contained within a viewport.
+   *
+   * @param i The list index to make visible
+   *
+   * @see JComponent#scrollRectToVisible
+   */
+  public void ensureIndexIsVisible(int i)
+  {
+    scrollRectToVisible(getUI().getCellBounds(this, i, i));
+  }
+
+  /**
+   * Sets the {@link #model} property of the list to a new anonymous
+   * {@link AbstractListModel} subclass which accesses the provided Object
+   * array directly.
+   *
+   * @param listData The object array to build a new list model on
+   * @see #setModel
+   */
+  public void setListData(final Object[] listData)
+  {
+    setModel(new AbstractListModel()
+        {
+          public int getSize()
+          {
+            return listData.length;
+          }
+
+          public Object getElementAt(int i)
+          {
+            return listData[i];
+          }
+        });
+  }
+
+  /**
+   * Sets the {@link #model} property of the list to a new anonymous {@link
+   * AbstractListModel} subclass which accesses the provided vector
+   * directly.
+   *
+   * @param listData The object array to build a new list model on
+   * @see #setModel
+   */
+  public void setListData(final Vector listData)
+  {
+    setModel(new AbstractListModel()
+        {
+          public int getSize()
+          {
+            return listData.size();
+          }
+
+          public Object getElementAt(int i)
+          {
+            return listData.elementAt(i);
+          }
+        });
+  }
+
+  /**
+   * Gets the value of the {@link #cellRenderer} property. 
+   *
+   * @return The current value of the property
+   */
+  public ListCellRenderer getCellRenderer()
+  {
+    return cellRenderer;
+  }
+
+  /**
+   * Sets the value of the {@link #celLRenderer} property.
+   *
+   * @param cellRenderer The new property value
+   */
+  public void setCellRenderer(ListCellRenderer cr)
+  {
+    ListCellRenderer old = cellRenderer;
+    cellRenderer = cr;
+    firePropertyChange(CELL_RENDERER_PROPERTY_CHANGED, old, cr);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Gets the value of the {@link #model} property. 
+   *
+   * @return The current value of the property
+   */
+  public ListModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * Sets the value of the {@link #model} property. The list's {@link
+   * #listListener} is unsubscribed from the existing model, if it exists,
+   * and re-subscribed to the new model.
+   *
+   * @param model The new property value
+   */
+  public void setModel(ListModel m)
+  {
+    ListModel old = model;
+    if (old != null)
+      old.removeListDataListener(listListener);
+    model = m;
+    if (model != null)
+      model.addListDataListener(listListener);
+    firePropertyChange(MODEL_PROPERTY_CHANGED, old, m);
+    revalidate();
+    repaint();
+  }
+
+
+  public ListSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Sets the value of the {@link #selectionModel} property. The list's
+   * {@link #listListener} is unsubscribed from the existing selection
+   * model, if it exists, and re-subscribed to the new selection model.
+   *
+   * @param l The new property value
+   */
+  public void setSelectionModel(ListSelectionModel l)
+  {
+    ListSelectionModel old = selectionModel;
+    if (old != null)
+      old.removeListSelectionListener(listListener);
+    selectionModel = l;
+    if (selectionModel != null)
+      selectionModel.addListSelectionListener(listListener);
+    firePropertyChange(SELECTION_MODEL_PROPERTY_CHANGED, old, l);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Gets the value of the UI property.
+   *
+   * @return The current property value
+   */
+  public ListUI getUI()
+  {
+    return (ListUI) ui;
+  }
+
+  /**
+   * Sets the value of the UI property.
+   *
+   * @param ui The new property value
+   */
+  public void setUI(ListUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Calls {@link #setUI} with the {@link ListUI} subclass
+   * returned from calling {@link UIManager#getUI}.
+   */
+  public void updateUI()
+  {
+    setUI((ListUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Return the class identifier for the list's UI property.  This should
+   * be the constant string <code>"ListUI"</code>, and map to an
+   * appropriate UI class in the {@link UIManager}.
+   *
+   * @return The class identifier
+   */
+  public String getUIClassID()
+  {
+    return "ListUI";
+  }
+
+
+  /**
+   * Returns the current value of the {@link #prototypeCellValue}
+   * property. This property holds a reference to a "prototype" data value
+   * -- typically a String -- which is used to calculate the {@link
+   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
+   * {@link #cellRenderer} property to acquire a component to render the
+   * prototype.
+   *
+   * @return The current prototype cell value
+   * @see #setPrototypeCellValue
+   */
+  public Object getPrototypeCellValue()
+  {
+    return prototypeCellValue;
+  }
+
+  /**
+   * <p>Set the {@link #prototypeCellValue} property. This property holds a
+   * reference to a "prototype" data value -- typically a String -- which
+   * is used to calculate the {@link #fixedCellWidth} and {@link
+   * #fixedCellHeight} properties, using the {@link #cellRenderer} property
+   * to acquire a component to render the prototype.</p>
+   *
+   * <p>It is important that you <em>not</em> set this value to a
+   * component. It has to be a <em>data value</em> such as the objects you
+   * would find in the list's model. Setting it to a component will have
+   * undefined (and undesirable) affects. </p>
+   *
+   * @param obj The new prototype cell value
+   * @see #getPrototypeCellValue
+   */
+  public void setPrototypeCellValue(Object obj)
+  {
+    Object old = prototypeCellValue;
+    Component comp = getCellRenderer()
+      .getListCellRendererComponent(this, obj, 0, false, false); 
+    Dimension d = comp.getPreferredSize();
+    fixedCellWidth = d.width;
+    fixedCellHeight = d.height;
+    prototypeCellValue = obj;
+    firePropertyChange(PROTOTYPE_CELL_VALUE_PROPERTY_CHANGED, old, obj);
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+  /**
+   * Returns a size indicating how much space this list would like to
+   * consume, when contained in a scrollable viewport. This is part of the
+   * {@link Scrollable} interface, which interacts with {@link
+   * ScrollPaneLayout} and {@link Viewport} to define scrollable objects.
+   *
+   * @return The preferred size
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    int vis = getVisibleRowCount();
+    int nrows = getModel() == null ? 0 : getModel().getSize();
+    // FIXME: this is a somewhat arbitrary default, but.. ?
+    Dimension single = new Dimension(10, 10);;
+    Rectangle bounds = null;
+
+    if (vis > nrows)
+      {
+        if (fixedCellWidth != -1 && 
+            fixedCellHeight != -1)
+          {
+            single = new Dimension(fixedCellWidth, fixedCellHeight);
+          }
+        else if (nrows != 0 && getUI() != null)
+          {
+            Rectangle tmp = getUI().getCellBounds(this, 0, 0);
+            if (tmp != null)
+              single = tmp.getSize();
+          }
+      }
+    else if (getUI() != null)
+      {
+        return getUI().getCellBounds(this, 0, vis - 1).getSize();
+      }
+
+    return new Dimension(single.width, single.height * vis);
+  }
+
+  /**
+   * <p>Return the number of pixels the list must scroll in order to move a
+   * "unit" of the list into the provided visible rectangle. When the
+   * provided direction is positive, the call describes a "downwards"
+   * scroll, which will be exposing a cell at a <em>greater</em> index in
+   * the list than those elements currently showing. Then the provided
+   * direction is negative, the call describes an "upwards" scroll, which
+   * will be exposing a cell at a <em>lesser</em> index in the list than
+   * those elements currently showing.</p>
+   *
+   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
+   * comments refer to "rightwards" for positive direction, and "leftwards"
+   * for negative.</p>
+   * 
+   *
+   * @param visibleRect The rectangle to scroll an element into
+   * @param orientation One of the numeric consants <code>VERTICAL</code>
+   * or <code>HORIZONTAL</code>
+   * @param direction An integer indicating the scroll direction: positive means
+   * forwards (down, right), negative means backwards (up, left)
+   *
+   * @return The scrollable unit increment, in pixels
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect,
+                                        int orientation, int direction)
+  {
+    ListUI lui = this.getUI();
+    if (orientation == SwingConstants.VERTICAL)
+      {
+        if (direction > 0)
+          {
+            // Scrolling down
+            Point bottomLeft = new Point(visibleRect.x,
+                                         visibleRect.y + visibleRect.height);
+            int curIdx = lui.locationToIndex(this, bottomLeft);
+            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
+            if (curBounds.y + curBounds.height == bottomLeft.y)
+              {
+                // we are at the exact bottom of the current cell, so we 
+                // are being asked to scroll to the end of the next one
+                if (curIdx + 1 < model.getSize())
+                  {
+                    // there *is* a next item in the list
+                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx + 1, curIdx + 1);
+                    return nxtBounds.height;
+                  }
+                else
+                  {
+                    // no next item, no advance possible
+                    return 0;
+                  }
+              }
+            else
+              {
+                // we are part way through an existing cell, so we are being
+                // asked to scroll to the bottom of it
+                return (curBounds.y + curBounds.height) - bottomLeft.y;
+              }		      
+          }
+        else
+          {
+            // scrolling up
+            Point topLeft = new Point(visibleRect.x, visibleRect.y);
+            int curIdx = lui.locationToIndex(this, topLeft);
+            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
+            if (curBounds.y == topLeft.y)
+              {
+                // we are at the exact top of the current cell, so we 
+                // are being asked to scroll to the top of the previous one
+                if (curIdx > 0)
+                  {
+                    // there *is* a previous item in the list
+                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx - 1, curIdx - 1);
+                    return -nxtBounds.height;
+                  }
+                else
+                  {
+                    // no previous item, no advance possible
+                    return 0;
+                  }
+              }
+            else
+              {
+                // we are part way through an existing cell, so we are being
+                // asked to scroll to the top of it
+                return curBounds.y - topLeft.y;
+              }		      
+          }
+      }
+
+    // FIXME: handle horizontal scrolling (also wrapping?)
+    return 1;
+  }
+
+  /**
+   * <p>Return the number of pixels the list must scroll in order to move a
+   * "block" of the list into the provided visible rectangle. When the
+   * provided direction is positive, the call describes a "downwards"
+   * scroll, which will be exposing a cell at a <em>greater</em> index in
+   * the list than those elements currently showing. Then the provided
+   * direction is negative, the call describes an "upwards" scroll, which
+   * will be exposing a cell at a <em>lesser</em> index in the list than
+   * those elements currently showing.</p>
+   *
+   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
+   * comments refer to "rightwards" for positive direction, and "leftwards"
+   * for negative.</p>
+   * 
+   *
+   * @param visibleRect The rectangle to scroll an element into
+   * @param orientation One of the numeric consants <code>VERTICAL</code>
+   * or <code>HORIZONTAL</code>
+   * @param direction An integer indicating the scroll direction: positive means
+   * forwards (down, right), negative means backwards (up, left)
+   *
+   * @return The scrollable unit increment, in pixels
+   */
+  public int getScrollableBlockIncrement(Rectangle visibleRect,
+                                         int orientation, int direction)
+  {
+      if (orientation == VERTICAL)
+	  return visibleRect.height * direction;
+      else
+	  return visibleRect.width * direction;
+  }
+
+  /**
+   * Gets the value of the {@link #scrollableTracksViewportWidth} property.
+   *
+   * @return <code>true</code> if the viewport is larger (horizontally)
+   * than the list and the list should be expanded to fit the viewport;
+   * <code>false</code> if the viewport is smaller than the list and the
+   * list should scroll (horizontally) within the viewport
+   */
+  public boolean getScrollableTracksViewportWidth()
+  {
+    return false;
+  }
+
+  /**
+   * Gets the value of the {@link #scrollableTracksViewportWidth} property.
+   *
+   * @return <code>true</code> if the viewport is larger (vertically)
+   * than the list and the list should be expanded to fit the viewport;
+   * <code>false</code> if the viewport is smaller than the list and the
+   * list should scroll (vertically) within the viewport
+   */
+  public boolean getScrollableTracksViewportHeight()
+  {
+    return false;
+  }
 }
Index: javax/swing/JMenu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenu.java,v
retrieving revision 1.3
diff -u -r1.3 JMenu.java
--- javax/swing/JMenu.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JMenu.java	6 Sep 2004 16:35:57 -0000
@@ -1,5 +1,5 @@
 /* JMenu.java --
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,731 +39,853 @@
 
 import java.awt.Component;
 import java.awt.Point;
+import java.awt.Window;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.util.EventListener;
 import java.util.Hashtable;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleSelection;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
-import javax.swing.event.ChangeListener;
+import javax.swing.plaf.MenuItemUI;
+
 
 /**
- * JMenu
- * @author	Andrew Selkirk
- * @version	1.0
+ * <p>
+ * This class represents a menu that can be added to a menu bar or
+ * can be a submenu in some other menu. When JMenu is selected it
+ * displays JPopupMenu containing its menu items.
+ * </p>
+ *
+ * <p>
+ * JMenu's fires MenuEvents when this menu's selection changes. If this menu
+ * is selected, then fireMenuSelectedEvent() is invoked. In case when menu is
+ * deselected or cancelled, then fireMenuDeselectedEvent() or 
+ * fireMenuCancelledEvent() is invoked, respectivelly.
+ * </p>
+ *
  */
-public class JMenu
-  extends JMenuItem
-  implements Accessible, MenuElement
+public class JMenu extends JMenuItem implements Accessible, MenuElement
 {
   static final long serialVersionUID = 4227225638931828014L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJMenu
-	 */
-	protected class AccessibleJMenu extends AccessibleJMenuItem 
-			implements AccessibleSelection {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJMenu
-		 * @param component TODO
-		 */
-		protected AccessibleJMenu(JMenu component) {
-			super(component);
-			// TODO
-		} // AccessibleJMenu()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleChildrenCount
-		 * @returns int
-		 */
-		public int getAccessibleChildrenCount() {
-			return 0; // TODO
-		} // getAccessibleChildrenCount()
-
-		/**
-		 * getAccessibleChild
-		 * @param value0 TODO
-		 * @returns Accessible
-		 */
-		public Accessible getAccessibleChild(int value0) {
-			return null; // TODO
-		} // getAccessibleChild()
-
-		/**
-		 * getAccessibleSelection
-		 * @returns AccessibleSelection
-		 */
-		public AccessibleSelection getAccessibleSelection() {
-			return null; // TODO
-		} // getAccessibleSelection()
-
-		/**
-		 * getAccessibleSelection
-		 * @param value0 TODO
-		 * @returns Accessible
-		 */
-		public Accessible getAccessibleSelection(int value0) {
-			return null; // TODO
-		} // getAccessibleSelection()
-
-		/**
-		 * isAccessibleChildSelected
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean isAccessibleChildSelected(int value0) {
-			return false; // TODO
-		} // isAccessibleChildSelected()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.MENU;
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleSelectionCount
-		 * @returns int
-		 */
-		public int getAccessibleSelectionCount() {
-			return 0; // TODO
-		} // getAccessibleSelectionCount()
-
-		/**
-		 * addAccessibleSelection
-		 * @param value0 TODO
-		 */
-		public void addAccessibleSelection(int value0) {
-			// TODO
-		} // addAccessibleSelection()
-
-		/**
-		 * removeAccessibleSelection
-		 * @param value0 TODO
-		 */
-		public void removeAccessibleSelection(int value0) {
-			// TODO
-		} // removeAccessibleSelection()
-
-		/**
-		 * clearAccessibleSelection
-		 */
-		public void clearAccessibleSelection() {
-			// TODO
-		} // clearAccessibleSelection()
-
-		/**
-		 * selectAllAccessibleSelection
-		 */
-		public void selectAllAccessibleSelection() {
-			// TODO
-		} // selectAllAccessibleSelection()
-
-
-	} // AccessibleJMenu
-
-	/**
-	 * WinListener
-	 */
-	protected class WinListener extends WindowAdapter implements Serializable {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * popupMenu
-		 */
-		JPopupMenu popupMenu;
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor WinListener
-		 * @param value0 TODO
-		 * @param value1 TODO
-		 */
-		public WinListener(JMenu value0, JPopupMenu value1) {
-			// TODO
-		} // WinListener()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * windowClosing
-		 * @param value0 TODO
-		 */
-		public void windowClosing(WindowEvent value0) {
-			// TODO
-		} // windowClosing()
-
-
-	} // WinListener
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "MenuUI";
-
-	/**
-	 * popupMenu
-	 */
-	private JPopupMenu popupMenu;
-
-	/**
-	 * menuChangeListener
-	 */
-	private ChangeListener menuChangeListener;
-
-	/**
-	 * menuEvent
-	 */
-	private MenuEvent menuEvent;
-
-	/**
-	 * listenerRegistry
-	 */
-	private static Hashtable listenerRegistry = null; // TODO
-
-	/**
-	 * delay
-	 */
-	private int delay;
-
-	/**
-	 * TRACE
-	 */
-	private static final boolean TRACE = false; // TODO
-
-	/**
-	 * VERBOSE
-	 */
-	private static final boolean VERBOSE = false; // TODO
-
-	/**
-	 * DEBUG
-	 */
-	private static final boolean DEBUG = false; // TODO
-
-	/**
-	 * popupListener
-	 */
-	protected JMenu.WinListener popupListener;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JMenu
-	 */
-	public JMenu() {
-		// TODO
-	} // JMenu()
-
-	/**
-	 * Constructor JMenu
-	 * @param text TODO
-	 */
-	public JMenu(String text) {
-		// TODO
-	} // JMenu()
-
-	/**
-	 * Constructor JMenu
-	 * @param action TODO
-	 */
-	public JMenu(Action action) {
-		// TODO
-	} // JMenu()
-
-	/**
-	 * Constructor JMenu
-	 * @param text TODO
-	 * @param tearoff TODO
-	 */
-	public JMenu(String text, boolean tearoff) {
-		// TODO
-	} // JMenu()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * add
-	 * @param value0 TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(JMenuItem item) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param component TODO
-	 * @returns Component
-	 */
-	public Component add(Component component) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param component TODO
-	 * @param index TODO
-	 * @returns Component
-	 */
-	public Component add(Component component, int index) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param text TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(String text) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param action TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(Action action) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * remove
-	 * @param item TODO
-	 */
-	public void remove(JMenuItem item) {
-		// TODO
-	} // remove()
-
-	/**
-	 * remove
-	 * @param index TODO
-	 */
-	public void remove(int index) {
-		// TODO
-	} // remove()
-
-	/**
-	 * remove
-	 * @param component TODO
-	 */
-	public void remove(Component component) {
-		// TODO
-	} // remove()
-
-	/**
-	 * removeAll
-	 */
-	public void removeAll() {
-		// TODO
-	} // removeAll()
-
-	/**
-	 * insert
-	 * @param text TODO
-	 * @param index TODO
-	 */
-	public void insert(String text, int index) {
-		// TODO
-	} // insert()
-
-	/**
-	 * insert
-	 * @param item TODO
-	 * @param index TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem insert(JMenuItem item, int index) {
-		return null; // TODO
-	} // insert()
-
-	/**
-	 * insert
-	 * @param action TODO
-	 * @param index TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem insert(Action action, int index) {
-		return null; // TODO
-	} // insert()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		//setUI((MenuUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * setModel
-	 * @param model TODO
-	 */
-	public void setModel(ButtonModel model) {
-		// TODO
-	} // setModel()
-
-	/**
-	 * isSelected
-	 * @returns boolean
-	 */
-	public boolean isSelected() {
-		return false; // TODO
-	} // isSelected()
-
-	/**
-	 * setSelected
-	 * @param selected TODO
-	 */
-	public void setSelected(boolean selected) {
-		// TODO
-	} // setSelected()
-
-	/**
-	 * isPopupMenuVisible
-	 * @returns boolean
-	 */
-	public boolean isPopupMenuVisible() {
-		return false; // TODO
-	} // isPopupMenuVisible()
-
-	/**
-	 * setPopupMenuVisible
-	 * @param popup TODO
-	 */
-	public void setPopupMenuVisible(boolean popup) {
-		// TODO
-	} // setPopupMenuVisible()
-
-	/**
-	 * getPopupMenuOrigin
-	 * @returns Point
-	 */
-	protected Point getPopupMenuOrigin() {
-		return null; // TODO
-	} // getPopupMenuOrigin()
-
-	/**
-	 * getDelay
-	 * @returns int
-	 */
-	public int getDelay() {
-		return 0; // TODO
-	} // getDelay()
-
-	/**
-	 * setDelay
-	 * @param value0 TODO
-	 */
-	public void setDelay(int delay) {
-		// TODO
-	} // setDelay()
-
-	/**
-	 * setMenuLocation
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	public void setMenuLocation(int x, int y) {
-		// TODO
-	} // setMenuLocation()
-
-	/**
-	 * createActionComponent
-	 * @param action TODO
-	 * @returns JMenuItem
-	 */
-	protected JMenuItem createActionComponent(Action action) {
-		return null; // TODO
-	} // createActionComponent()
-
-	/**
-	 * createActionChangeListener
-	 * @param item TODO
-	 * @returns PropertyChangeListener
-	 */
-	protected PropertyChangeListener createActionChangeListener(JMenuItem item) {
-		return null; // TODO
-	} // createActionChangeListener()
-
-	/**
-	 * addSeparator
-	 */
-	public void addSeparator() {
-		// TODO
-	} // addSeparator()
-
-	/**
-	 * insertSeparator
-	 * @param index TODO
-	 */
-	public void insertSeparator(int index) {
-		// TODO
-	} // insertSeparator()
-
-	/**
-	 * getItem
-	 * @param index TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem getItem(int index) {
-		return null; // TODO
-	} // getItem()
-
-	/**
-	 * getItemCount
-	 * @returns int
-	 */
-	public int getItemCount() {
-		return 0; // TODO
-	} // getItemCount()
-
-	/**
-	 * isTearOff
-	 * @returns boolean
-	 */
-	public boolean isTearOff() {
-		return false; // TODO
-	} // isTearOff()
-
-	/**
-	 * getMenuComponentCount
-	 * @returns int
-	 */
-	public int getMenuComponentCount() {
-		return 0; // TODO
-	} // getMenuComponentCount()
-
-	/**
-	 * getMenuComponent
-	 * @param index TODO
-	 * @returns Component
-	 */
-	public Component getMenuComponent(int index) {
-		return null; // TODO
-	} // getMenuComponent()
-
-	/**
-	 * getMenuComponents
-	 * @returns Component[]
-	 */
-	public Component[] getMenuComponents() {
-		return null; // TODO
-	} // getMenuComponents()
-
-	/**
-	 * isTopLevelMenu
-	 * @returns boolean
-	 */
-	public boolean isTopLevelMenu() {
-		return false; // TODO
-	} // isTopLevelMenu()
-
-	/**
-	 * isMenuComponent
-	 * @param component TODO
-	 * @returns boolean
-	 */
-	public boolean isMenuComponent(Component component) {
-		return false; // TODO
-	} // isMenuComponent()
-
-	/**
-	 * getPopupMenu
-	 * @returns JPopupMenu
-	 */
-	public JPopupMenu getPopupMenu() {
-		return null; // TODO
-	} // getPopupMenu()
-
-	/**
-	 * addMenuListener
-	 * @param listener TODO
-	 */
-	public void addMenuListener(MenuListener listener) {
-		// TODO
-	} // addMenuListener()
-
-	/**
-	 * removeMenuListener
-	 * @param listener TODO
-	 */
-	public void removeMenuListener(MenuListener listener) {
-		// TODO
-	} // removeMenuListener()
-
-	/**
-	 * fireMenuSelected
-	 */
-	protected void fireMenuSelected() {
-		// TODO
-	} // fireMenuSelected()
-
-	/**
-	 * fireMenuDeselected
-	 */
-	protected void fireMenuDeselected() {
-		// TODO
-	} // fireMenuDeselected()
-
-	/**
-	 * fireMenuCanceled
-	 */
-	protected void fireMenuCanceled() {
-		// TODO
-	} // fireMenuCanceled()
-
-	/**
-	 * createMenuChangeListener
-	 * @returns ChangeListener
-	 */
-	private ChangeListener createMenuChangeListener() {
-		return null; // TODO
-	} // createMenuChangeListener()
-
-	/**
-	 * createWinListener
-	 * @param popup TODO
-	 * @returns JMenu.WinListener
-	 */
-	protected JMenu.WinListener createWinListener(JPopupMenu popup) {
-		return null; // TODO
-	} // createWinListener()
-
-	/**
-	 * menuSelectionChanged
-	 * @param value0 TODO
-	 */
-	public void menuSelectionChanged(boolean changed) {
-		// TODO
-	} // menuSelectionChanged()
-
-	/**
-	 * getSubElements
-	 * @returns MenuElement[]
-	 */
-	public MenuElement[] getSubElements() {
-		return null; // TODO
-	} // getSubElements()
-
-	/**
-	 * getComponent
-	 * @returns Component
-	 */
-	public Component getComponent() {
-		return null; // TODO
-	} // getComponent()
-
-	/**
-	 * setAccelerator
-	 * @param keystroke TODO
-	 */
-	public void setAccelerator(KeyStroke keystroke) {
-		// TODO
-	} // setAccelerator()
-
-	/**
-	 * processKeyEvent
-	 * @param event TODO
-	 */
-	protected void processKeyEvent(KeyEvent event) {
-		// TODO
-	} // processKeyEvent()
-
-	/**
-	 * doClick
-	 * @param time TODO
-	 */
-	public void doClick(int time) {
-		// TODO
-	} // doClick()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJMenu(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
+  /** name for the UI delegate for this menu. */
+  private static final String uiClassID = "MenuUI";
 
+  /** A Popup menu associated with this menu, which pops up when menu is selected */
+  private JPopupMenu popupMenu = new JPopupMenu();
 
-} // JMenu
+  /** Whenever menu is selected or deselected the MenuEvent is fired to
+     menu's registered listeners. */
+  private MenuEvent menuEvent = new MenuEvent(this);
+
+  /*Amount of time, in milliseconds, that should pass before popupMenu
+    associated with this menu appears or disappers */
+  private int delay;
+
+  /* PopupListener */
+  protected WinListener popupListener;
+
+  /** Location at which popup menu associated with this menu will be
+     displayed */
+  private Point menuLocation;
+
+  /**
+   * Creates a new JMenu object.
+   */
+  public JMenu()
+  {
+    super();
+  }
+
+  /**
+   * Creates a new JMenu with the spicified label
+   *
+   * @param text label for this menu
+   */
+  public JMenu(String text)
+  {
+    super(text);
+  }
+
+  /**
+   * Creates a new JMenu object
+   *
+   * @param action Action that  is used to create menu item tha will be
+   * added to the menu.
+   */
+  public JMenu(Action action)
+  {
+    super(action);
+    createActionChangeListener(this);
+  }
+
+  /**
+   * Creates a new JMenu with specified label and an option
+   * for this menu to be tear-off menu
+   *
+   * @param text label for this menu
+   * @param tearoff true if this menu should be tear-off and false otherwise
+   */
+  public JMenu(String text, boolean tearoff)
+  {
+    throw new Error("not implemented");
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * Adds specified menu item to this menu
+   *
+   * @param item Menu item to add to this menu
+   *
+   * @return Menu item that was added
+   */
+  public JMenuItem add(JMenuItem item)
+  {
+    return popupMenu.add(item);
+  }
+
+  /**
+   * Adds specified component to this menu.
+   *
+   * @param component Component to add to this menu
+   *
+   * @return Component that was added
+   */
+  public Component add(Component component)
+  {
+    return popupMenu.add(component);
+  }
+
+  /**
+   * Adds specified component to this menu at the given index
+   *
+   * @param component Component to add
+   * @param index Position of this menu item in the menu
+   *
+   * @return Component that was added
+   */
+  public Component add(Component component, int index)
+  {
+    return popupMenu.add(component, index);
+  }
+
+  /**
+   * Adds JMenuItem constructed with the specified label to this menu
+   *
+   * @param text label for the menu item that will be added
+   *
+   * @return Menu Item that was added to this menu
+   */
+  public JMenuItem add(String text)
+  {
+    return popupMenu.add(text);
+  }
+
+  /**
+   * Adds JMenuItem constructed using properties from specified action.
+   *
+   * @param action action to construct the menu item with
+   *
+   * @return Menu Item that was added to this menu
+   */
+  public JMenuItem add(Action action)
+  {
+    return popupMenu.add(action);
+  }
+
+  /**
+   * Removes given menu item from this menu. Nothing happens if
+   * this menu doesn't contain specified menu item.
+   *
+   * @param item Menu Item which needs to be removed
+   */
+  public void remove(JMenuItem item)
+  {
+    popupMenu.remove(item);
+  }
+
+  /**
+   * Removes component at the specified index from this menu
+   *
+   * @param index Position of the component that needs to be removed in the menu
+   */
+  public void remove(int index)
+  {
+    popupMenu.remove(index);
+  }
+
+  /**
+   * Removes given component from this menu.
+   *
+   * @param component Component to remove
+   */
+  public void remove(Component component)
+  {
+    int index = popupMenu.getComponentIndex(component);
+    popupMenu.remove(index);
+  }
+
+  /**
+   * Removes all menu items from the menu
+   */
+  public void removeAll()
+  {
+    popupMenu.removeAll();
+  }
+
+  /**
+   * Creates JMenuItem with the specified text and inserts it in the
+   * at the specified index
+   *
+   * @param text label for the new menu item
+   * @param index index at which to insert newly created menu item.
+   */
+  public void insert(String text, int index)
+  {
+    this.insert(new JMenuItem(text), index);
+  }
+
+  /**
+   * Creates JMenuItem with the specified text and inserts it in the
+   * at the specified index. IllegalArgumentException is thrown
+   * if index is less than 0
+   *
+   * @param item menu item to insert
+   * @param index index at which to insert menu item.
+   * @return Menu item that was added to the menu
+   */
+  public JMenuItem insert(JMenuItem item, int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than zero");
+
+    popupMenu.insert(item, index);
+
+    return item;
+  }
+
+  /**
+   * Creates JMenuItem with the associated action and inserts it to the menu
+   * at the specified index. IllegalArgumentException is thrown
+   * if index is less than 0
+   *
+   * @param action Action for the new menu item
+   * @param index index at which to insert newly created menu item.
+   * @return Menu item that was added to the menu
+   */
+  public JMenuItem insert(Action action, int index)
+  {
+    JMenuItem item = new JMenuItem(action);
+    this.insert(item, index);
+
+    return item;
+  }
+
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    super.setUI((MenuItemUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menu.
+   *
+   * @return The Look and Feel classID. "MenuUI"
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * Sets model for this menu.
+   *
+   * @param model model to set
+   */
+  public void setModel(ButtonModel model)
+  {
+    super.setModel(model);
+  }
+
+  /**
+   * Returns true if the menu is selected and false otherwise
+   *
+   * @return true if the menu is selected and false otherwise
+   */
+  public boolean isSelected()
+  {
+    return super.isArmed();
+  }
+
+  /**
+   * Changes this menu selected state if selected is true and false otherwise
+   * This method fires menuEvents to menu's registered listeners.
+   *
+   * @param selected true if the menu should be selected and false otherwise
+   */
+  public void setSelected(boolean selected)
+  {
+    // if this menu selection is true, then activate this menu and 
+    // display popup associated with this menu	
+    if (selected)
+      {
+    super.setArmed(true);
+	super.setSelected(true);
+
+	// FIXME: The popup menu should be shown on the screen after certain
+	// number of seconds pass. The 'delay' property of this menu indicates
+	// this amount of seconds. 'delay' property is 0 by default.
+	if (this.isShowing())
+	  {
+    fireMenuSelected();
+
+	    int x = 0;
+	    int y = 0;
+
+	    if (menuLocation == null)
+	      {
+		// Calculate correct position of the popup. Note that location of the popup 
+		// passed to show() should be relative to the popup's invoker
+		if (isTopLevelMenu())
+		  y = this.getHeight();
+		else
+		  x = this.getWidth();
+
+		getPopupMenu().show(this, x, y);
+	      }
+	    else
+	      getPopupMenu().show(this, menuLocation.x, menuLocation.y);
+	  }
+      }
+
+    else
+      {
+	super.setSelected(false);
+	super.setArmed(false);
+	fireMenuDeselected();
+	popupMenu.setVisible(false);
+      }
+  }
+
+  /**
+   * Checks if PopupMenu associated with this menu is visible
+   *
+   * @return true if the popup associated with this menu is currently visible on the screen and
+   * false otherwise.
+   */
+  public boolean isPopupMenuVisible()
+  {
+    return popupMenu.isVisible();
+  }
+
+  /**
+   * Sets popup menu visibility
+   *
+   * @param popup true if popup should be visible and false otherwise
+   */
+  public void setPopupMenuVisible(boolean popup)
+  {
+    if (getModel().isEnabled())
+      popupMenu.setVisible(popup);
+  }
+
+  /**
+   * Returns origin point of the popup menu
+   *
+   * @return Point containing
+   */
+  protected Point getPopupMenuOrigin()
+  {
+    // if menu in the menu bar
+    if (isTopLevelMenu())
+      return new Point(0, this.getHeight());
+
+    // if submenu            
+    return new Point(this.getWidth(), 0);
+  }
+
+  /**
+   * Returns delay property.
+   *
+   * @return delay property, indicating number of milliseconds before
+   * popup menu associated with the menu appears or disappears after
+   * menu was selected or deselected respectively
+   */
+  public int getDelay()
+  {
+    return delay;
+  }
+
+  /**
+   * Sets delay property for this menu. If given time for the delay
+   * property is negative, then IllegalArgumentException is thrown
+   *
+   * @param delay number of milliseconds before
+   * popup menu associated with the menu appears or disappears after
+   * menu was selected or deselected respectively
+   */
+  public void setDelay(int delay)
+  {
+    if (delay < 0)
+      throw new IllegalArgumentException("delay less than 0");
+    this.delay = delay;
+  }
+
+  /**
+   * Sets location at which popup menu should be displayed
+   * The location given is relative to this menu item
+   *
+   * @param x x-coordinate of the menu location
+   * @param y y-coordinate of the menu location
+   */
+  public void setMenuLocation(int x, int y)
+  {
+    menuLocation = new Point(x, y);
+  }
+
+  /**
+   * Creates and returns JMenuItem associated with the given action
+   *
+   * @param action Action to use for creation of JMenuItem
+   *
+   * @return JMenuItem that was creted with given action
+   */
+  protected JMenuItem createActionComponent(Action action)
+  {
+    return new JMenuItem(action);
+  }
+
+  /**
+   * Creates ActionChangeListener to listen for PropertyChangeEvents occuring
+   * in the action that is associated with this menu
+   *
+   * @param item menu that contains action to listen to
+   *
+   * @return The PropertyChangeListener
+   */
+  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
+  {
+    return new ActionChangedListener(item);
+  }
+
+  /**
+   * Adds separator to the end of the menu items in the menu.
+   */
+  public void addSeparator()
+  {
+    getPopupMenu().addSeparator();
+  }
+
+  /**
+   * Inserts separator in the menu at the specified index.
+   *
+   * @param index Index at which separator should be inserted
+   */
+  public void insertSeparator(int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than 0");
+
+    getPopupMenu().insert(new JPopupMenu.Separator(), index);
+  }
+
+  /**
+   * Returns menu item located at the specified index in the menu
+   *
+   * @param index Index at which to look for the menu item
+   *
+   * @return menu item located at the specified index in the menu
+   */
+  public JMenuItem getItem(int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than 0");
+
+    Component c = popupMenu.getComponentAtIndex(index);
+
+    if (c instanceof JMenuItem)
+      return (JMenuItem) c;
+    else
+      return null;
+  }
+
+  /**
+   * Returns number of items in the menu
+   *
+   * @return number of items in the menu
+   */
+  public int getItemCount()
+  {
+    // returns the number of items on 
+    // the menu, including separators.
+    return getComponents().length;
+  }
+
+  /**
+   * Checks if this menu is a tear-off menu.
+   *
+   * @return true if this menu is a tear-off menu and false otherwise
+   */
+  public boolean isTearOff()
+  {
+    // NOT YET IMPLEMENTED 
+    return false;
+  }
+
+  /**
+   * Returns number of menu components in this menu
+   *
+   * @return number of menu components in this menu
+   */
+  public int getMenuComponentCount()
+  {
+    return popupMenu.getComponentCount();
+  }
+
+  /**
+   * Returns menu component located at the givent index
+   * in the menu
+   *
+   * @param index index at which to get the menu component in the menu
+   *
+   * @return Menu Component located in the menu at the specified index
+   */
+  public Component getMenuComponent(int index)
+  {
+    return (Component) popupMenu.getComponentAtIndex(index);
+  }
+
+  /**
+   * Return components belonging to this menu
+   *
+   * @return components belonging to this menu
+   */
+  public Component[] getMenuComponents()
+  {
+    return popupMenu.getComponents();
+  }
+
+  /**
+   * Checks if this menu is a top level menu. The menu is top
+   * level menu if it is inside the menu bar. While if the menu
+   * inside some other menu, it is considered to be a pull-right menu.
+   *
+   * @return true if this menu is top level menu, and false otherwise
+   */
+  public boolean isTopLevelMenu()
+  {
+    if (getParent() instanceof JMenuBar)
+      return true;
+    else
+      return false;
+  }
+
+  /**
+   * Checks if given component exists in this menu. The submenus of
+   * this menu are checked as well
+   *
+   * @param component Component to look for
+   *
+   * @return true if the given component exists in this menu, and false otherwise
+   */
+  public boolean isMenuComponent(Component component)
+  {
+    return false;
+  }
+
+  /**
+   * Returns popup menu associated with the menu.
+   *
+   * @return popup menu associated with the menu.
+   */
+  public JPopupMenu getPopupMenu()
+  {
+    return popupMenu;
+  }
+
+  /**
+   * Adds MenuListener to the menu
+   *
+   * @param listener MenuListener to add
+   */
+  public void addMenuListener(MenuListener listener)
+  {
+    listenerList.add(MenuListener.class, listener);
+  }
+
+  /**
+   * Removes MenuListener from the menu
+   *
+   * @param listener MenuListener to remove
+   */
+  public void removeMenuListener(MenuListener listener)
+  {
+    listenerList.remove(MenuListener.class, listener);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuSelected() method of MenuListeners is called to indicated that the menu
+   * was selected.
+   */
+  protected void fireMenuSelected()
+  {
+    EventListener[] ll = listenerList.getListeners(MenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuListener) ll[i]).menuSelected(menuEvent);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuDeselected() method of MenuListeners is called to indicated that the menu
+   * was deselected.
+   */
+  protected void fireMenuDeselected()
+  {
+    EventListener[] ll = listenerList.getListeners(MenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuListener) ll[i]).menuDeselected(menuEvent);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuSelected() method of MenuListeners is called to indicated that the menu
+   * was cancelled. The menu is cancelled when it's popup menu is close without selection.
+   */
+  protected void fireMenuCanceled()
+  {
+    EventListener[] ll = listenerList.getListeners(MenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuListener) ll[i]).menuCanceled(menuEvent);
+  }
+
+  /**
+   * Creates WinListener that listens to the menu;s popup menu.
+   *
+   * @param popup JPopupMenu to listen to
+   *
+   * @return The WinListener
+   */
+  protected WinListener createWinListener(JPopupMenu popup)
+  {
+    return new WinListener(popup);
+  }
+
+  /**
+   * Method of the MenuElementInterface. It reacts to the selection
+   * changes in the menu. If this menu was selected, then it
+   * displayes popup menu associated with it and if this menu was
+   * deselected it hides the popup menu.
+   *
+   * @param changed true if the menu was selected and false otherwise
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    // if this menu selection is true, then activate this menu and 
+    // display popup associated with this menu
+    setSelected(changed);
+  }
+
+  /**
+   * Method of MenuElement interface. Returns sub components of
+   * this menu.
+   *
+   * @return array containing popupMenu that is associated with this menu
+   */
+  public MenuElement[] getSubElements()
+  {
+    return new MenuElement[] { popupMenu };
+  }
+
+  /**
+   * @return Returns reference to itself
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * This method is overriden with empty implementation, s.t the
+   * accelerator couldn't be set for the menu. The mnemonic should
+   * be used for the menu instead.
+   *
+   * @param keystroke accelerator for this menu
+   */
+  public void setAccelerator(KeyStroke keystroke)
+  {
+    throw new Error("setAccelerator() is not defined for JMenu.  Use setMnemonic() instead.");
+  }
+
+  /**
+   * This method process KeyEvent occuring when the menu is visible
+   *
+   * @param event The KeyEvent
+   */
+  protected void processKeyEvent(KeyEvent event)
+  {
+  }
+
+  /**
+   * Programatically performs click
+   *
+   * @param time Number of milliseconds for which this menu stays pressed
+   */
+  public void doClick(int time)
+  {
+    getModel().setArmed(true);
+    getModel().setPressed(true);
+    try
+      {
+	java.lang.Thread.sleep(time);
+      }
+    catch (java.lang.InterruptedException e)
+      {
+	// probably harmless
+      }
+
+    getModel().setPressed(false);
+    getModel().setArmed(false);
+    popupMenu.show(this, this.getWidth(), 0);
+  }
+
+  /**
+   * A string that describes this JMenu. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenu
+   */
+  protected String paramString()
+  {
+    return "JMenu";
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJMenu();
+
+    return accessibleContext;
+  }
+
+  protected class AccessibleJMenu extends AccessibleJMenuItem
+    implements AccessibleSelection
+  {
+    protected AccessibleJMenu()
+    {
+    }
+
+    public int getAccessibleChildrenCount()
+    {
+      return 0;
+    }
+
+    public Accessible getAccessibleChild(int value0)
+    {
+      return null;
+    }
+
+    public AccessibleSelection getAccessibleSelection()
+    {
+      return null;
+    }
+
+    public Accessible getAccessibleSelection(int value0)
+    {
+      return null;
+    }
+
+    public boolean isAccessibleChildSelected(int value0)
+    {
+      return false;
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.MENU;
+    }
+
+    public int getAccessibleSelectionCount()
+    {
+      return 0;
+    }
+
+    public void addAccessibleSelection(int value0)
+    {
+    }
+
+    public void removeAccessibleSelection(int value0)
+    {
+    }
+
+    public void clearAccessibleSelection()
+    {
+    }
+
+    public void selectAllAccessibleSelection()
+    {
+    }
+  }
+
+  protected class WinListener extends WindowAdapter implements Serializable
+  {
+    JPopupMenu popupMenu;
+    private static final long serialVersionUID = -6415815570638474823L;
+
+    public WinListener(JPopupMenu popup)
+    {
+    }
+
+    public void windowClosing(WindowEvent event)
+    {
+    }
+  }
+
+  /**
+   * This class listens to PropertyChangeEvents occuring in menu's action
+   */
+  protected class ActionChangedListener implements PropertyChangeListener
+  {
+    /** menu item associated with the action */
+    private JMenuItem menuItem;
+
+    /** Creates new ActionChangedListener and adds it to menuItem's action */
+    public ActionChangedListener(JMenuItem menuItem)
+    {
+      this.menuItem = menuItem;
+
+      Action a = menuItem.getAction();
+      if (a != null)
+	a.addPropertyChangeListener(this);
+    }
+
+    /**This method is invoked when some change occures in menuItem's action*/
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      // FIXME: Need to implement
+    }
+  }
+}
Index: javax/swing/JMenuBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenuBar.java,v
retrieving revision 1.2
diff -u -r1.2 JMenuBar.java
--- javax/swing/JMenuBar.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JMenuBar.java	6 Sep 2004 16:35:57 -0000
@@ -1,5 +1,5 @@
 /* JMenuBar.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,17 +35,453 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Point;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.plaf.MenuBarUI;
+import javax.swing.plaf.MenuItemUI;
+
 
-public class JMenuBar extends JComponent
+/**
+ * <p>
+ * JMenuBar is a container for menu's. For a menu bar to be seen on the
+ * screen, at least one menu should be added to it. Just like adding
+ * components to container, one can use add() to add menu's to the menu bar.
+ * Menu's will be displayed in the menu  bar in the order they were added.
+ * The JMenuBar uses selectionModel to keep track of selected menu index.
+ * JMenuBar's selectionModel will fire ChangeEvents to its registered 
+ * listeners when the selected index changes.
+ * </p>
+ */
+public class JMenuBar extends JComponent implements Accessible, MenuElement
 {
-  JMenuBar()
-    {
-    }
+  /** Fired in a PropertyChangeEvent when the "borderPainted" property changes. */
+  public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
+
+  /** Fired in a PropertyChangeEvent when the "model" changes. */
+  public static final String MODEL_CHANGED_PROPERTY = "model";
+  
+  /** Fired in a PropertyChangeEvent when the "margin" changes. */
+  public static final String MARGIN_CHANGED_PROPERTY = "margin";
+  private static final long serialVersionUID = -8191026883931977036L;
+
+  /** JMenuBar's model. It keeps track of selected menu's index */
+  private transient SingleSelectionModel selectionModel;
+
+  /* borderPainted property indicating if the menuBar's border will be painted*/
+  private boolean borderPainted;
+
+  /* margin between menu bar's border and its menues*/
+  private Insets margin;
+
+  /**
+   * Creates a new JMenuBar object.
+   */
+  public JMenuBar()
+  {
+    selectionModel = new DefaultSingleSelectionModel();
+    borderPainted = true;
+    updateUI();
+  }
+
+  /**
+   * Adds menu to the menu bar
+   *
+   * @param c menu to add
+   *
+   * @return reference to the added menu
+   */
+  public JMenu add(JMenu c)
+  {
+    c.setAlignmentX(Component.LEFT_ALIGNMENT);
+    super.add(c);
+    return c;
+  }
+
+  /**
+   * This method overrides addNotify() in the Container to register
+   * this menu bar with the current keyboard manager.
+   */
+  public void addNotify()
+  {
+    // FIXME: Should register this menu bar with the keyboard manager     
+    super.addNotify();
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+  /**
+   * Returns reference to this menu bar
+   *
+   * @return reference to this menu bar
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Returns component at the specified index.
+   *
+   * @param i index of the component to get
+   *
+   * @return component at the specified index. Null is returned if
+   * component at the specified index doesn't exist.
+   * @deprecated Replaced by getComponent(int)
+   */
+  public Component getComponentAtIndex(int i)
+  {
+    return getComponent(i);
+  }
+
+  /**
+   * Returns index of the specified component
+   *
+   * @param c Component to search for
+   *
+   * @return index of the specified component. -1 is returned if
+   * specified component doesnt' exist in the menu bar.
+   */
+  public int getComponentIndex(Component c)
+  {
+    Component[] comps = getComponents();
+
+    int index = -1;
+
+    for (int i = 0; i < comps.length; i++)
+      {
+	if (comps[i].equals(c))
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+
+    return index;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JMenu getHelpMenu()
+  {
+    return null;
+  }
+
+  /**
+   * Returns margin betweeen menu bar's border and its menues
+   *
+   * @return margin between menu bar's border and its menues
+   */
+  public Insets getMargin()
+  {
+    if (margin == null)
+      return new Insets(0, 0, 0, 0);
+    else
+      return margin;
+  }
+
+  /**
+   * Return menu at the specified index. If component at the
+   * specified index is not a menu, then null is returned.
+   *
+   * @param index index to look for the menu
+   *
+   * @return menu at specified index, or null if menu doesn't exist
+   * at the specified index.
+   */
+  public JMenu getMenu(int index)
+  {
+    if (getComponentAtIndex(index) instanceof JMenu)
+      return (JMenu) getComponentAtIndex(index);
+    else
+      return null;
+  }
+
+  /**
+   * Returns number of menu's in this menu bar
+   *
+   * @return number of menu's in this menu bar
+   */
+  public int getMenuCount()
+  {
+    return getComponentCount();
+  }
+
+  /**
+   * Returns selection model for this menu bar. SelectionModel
+   * keeps track of the selected menu in the menu bar. Whenever
+   * selected property of selectionModel changes, the ChangeEvent
+   * will be fired its ChangeListeners.
+   *
+   * @return selection model for this menu bar.
+   */
+  public SingleSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Method of MenuElement interface. It returns subcomponents
+   * of the menu bar, which are all the menues that it contains.
+   *
+   * @return MenuElement[] array containing menues in this menu bar
+   */
+  public MenuElement[] getSubElements()
+  {
+    MenuElement[] subElements = new MenuElement[getComponentCount()];
+
+    for (int i = 0; i < getComponentCount(); i++)
+      subElements[i] = (MenuElement) getMenu(i);
+
+    return subElements;
+  }
+
+  /**
+    * Set the "UI" property of the menu bar, which is a look and feel class
+    * responsible for handling the menuBar's input events and painting it.
+    *
+    * @return The current "UI" property
+    */
+  public MenuBarUI getUI()
+  {
+    return (MenuBarUI) ui;
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menu bar.
+   *
+   * @return The Look and Feel classID. "MenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return "MenuBarUI";
+  }
+
+  /**
+   * Returns true if menu bar paints its border and false otherwise
+   *
+   * @return true if menu bar paints its border and false otherwise
+   */
+  public boolean isBorderPainted()
+  {
+    return borderPainted;
+  }
+
+  /**
+   * Returns true if some menu in menu bar is selected.
+   *
+   * @return true if some menu in menu bar is selected and false otherwise
+   */
+  public boolean isSelected()
+  {
+    return selectionModel.isSelected();
+  }
+
+  /**
+   * This method does nothing by default. This method is need for the
+   * MenuElement interface to be implemented.
+   *
+   * @param isIncluded true if menuBar is included in the selection 
+   * and false otherwise
+   */
+  public void menuSelectionChanged(boolean isIncluded)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * Paints border of the menu bar, if its borderPainted property is set to 
+   * true.
+   *
+   * @param g The graphics context with which to paint the border
+   */
+  protected void paintBorder(Graphics g)
+  {
+    if (borderPainted)
+      getBorder().paintBorder(this, g, 0, 0, getSize(null).width,
+                              getSize(null).height);
+  }
+
+  /**
+   * A string that describes this JMenuBar. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenuBar
+   */
+  protected String paramString()
+  {
+    return "JMenuBar";
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processKeyEvent(KeyEvent e, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * Process mouse events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * This method overrides removeNotify() in the Container to
+   * unregister this menu bar from the current keyboard manager.
+   */
+  public void removeNotify()
+  {
+    // Must unregister this menu bar with the current keyboard manager.
+    super.removeNotify();
+  }
+
+  /**
+   * Sets painting status of the border. If 'b' is true then menu bar's
+   * border will be painted, and it will not be painted otherwise.
+   *
+   * @param b indicates if menu bar's border should be painted.
+   */
+  public void setBorderPainted(boolean b)
+  {
+    boolean old = borderPainted;
+    borderPainted = b;
+    if (b != old)
+      {
+	firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
+	revalidate();
+	repaint();
+      }
+  }
+
+  /**
+   * Sets help menu for this menu bar
+   *
+   * @param menu help menu
+   */
+  public void setHelpMenu(JMenu menu)
+  {
+  }
+
+  /**
+   * Sets the menu bar's "margin" bound property,  which represents
+   * distance between the menubar's border and its menus.
+   * icon. When marging property is modified, PropertyChangeEvent will
+   * be fired to menuBar's PropertyChangeListener's.
+   *
+   * @param m distance between the menubar's border and its menus.
+   *
+   */
+  public void setMargin(Insets m)
+  {
+    if (m.equals(this.margin))
+      {
+	Insets oldMargin = this.margin;
+	this.margin = m;
+	firePropertyChange(MARGIN_CHANGED_PROPERTY, oldMargin, margin);
+      }
+
+    this.margin = m;
+  }
+
+  /**
+   * Changes menu bar's selection to the specified menu.
+   * This method updates selected index of menu bar's selection model,
+   * which results in a model firing change event.
+   *
+   * @param sel menu to select
+   */
+  public void setSelected(Component sel)
+  {
+    int index = getComponentIndex(sel);
+    selectionModel.setSelectedIndex(index);
+  }
+
+  /**
+   * Sets menuBar's selection model to the one specified
+   *
+   * @param model SingleSelectionModel that needs to be set for this menu bar
+   */
+  public void setSelectionModel(SingleSelectionModel model)
+  {
+    selectionModel = model;
+    if (selectionModel != model)
+      {
+	SingleSelectionModel oldModel = selectionModel;
+
+	selectionModel = model;
+
+	firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel,
+	                   this.selectionModel);
+      }
+  }
+
+  /**
+   * Set the "UI" property of the menu bar, which is a look and feel class
+   * responsible for handling menuBar's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(MenuBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Set the "UI" property to a class constructed, via the {@link
+   * UIManager}, from the current look and feel.
+   */
+  public void updateUI()
+  {
+    MenuBarUI ui = ((MenuBarUI) UIManager.getUI(this));
+    setUI(ui);
+    invalidate();
+  }
 }
Index: javax/swing/JMenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenuItem.java,v
retrieving revision 1.2
diff -u -r1.2 JMenuItem.java
--- javax/swing/JMenuItem.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JMenuItem.java	6 Sep 2004 16:35:57 -0000
@@ -1,5 +1,5 @@
 /* JMenuItem.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,19 +35,22 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Component;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.EventListener;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
+import javax.swing.UIManager;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.event.MenuDragMouseEvent;
@@ -56,418 +59,620 @@
 import javax.swing.event.MenuKeyListener;
 import javax.swing.plaf.MenuItemUI;
 
+
 /**
- * JMenuItem
- * @author	Andrew Selkirk
- * @version	1.0
+ * <p>
+ * JMenuItem represents element in the menu. It inherits most of
+ * its functionality from AbstractButton, however its behavior somewhat
+ * varies from it. JMenuItem fire different kinds of events.
+ * PropertyChangeEvents are fired when menuItems properties are modified;
+ * ChangeEvents are fired when menuItem's state changes and actionEvents are
+ * fired when menu item is selected. In addition to this events menuItem also
+ * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
+ * the menu item or associated key with menu item is invoked respectively.
+ * </p>
  */
-public class JMenuItem extends AbstractButton implements Accessible, MenuElement {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJMenuItem
-	 */
-	protected class AccessibleJMenuItem extends AccessibleAbstractButton 
-			implements ChangeListener {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJMenuItem
-		 * @param component TODO
-		 */
-		AccessibleJMenuItem(JMenuItem component) {
-			super(component);
-			// TODO
-		} // AccessibleJMenuItem()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * stateChanged
-		 * @param event TODO
-		 */
-		public void stateChanged(ChangeEvent event) {
-			// TODO
-		} // stateChanged()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.MENU_ITEM;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJMenuItem
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "MenuItemUI";
-
-	/**
-	 * accelerator
-	 */
-	private KeyStroke accelerator;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JMenuItem
-	 */
-	public JMenuItem() {
-		// TODO
-	} // JMenuItem()
-
-	/**
-	 * Constructor JMenuItem
-	 * @param icon TODO
-	 */
-	public JMenuItem(Icon icon) {
-		// TODO
-	} // JMenuItem()
-
-	/**
-	 * Constructor JMenuItem
-	 * @param text TODO
-	 */
-	public JMenuItem(String text) {
-		// TODO
-	} // JMenuItem()
-
-	/**
-	 * Constructor JMenuItem
-	 * @param action TODO
-	 */
-	public JMenuItem(Action action) {
-		// TODO
-	} // JMenuItem()
-
-	/**
-	 * Constructor JMenuItem
-	 * @param text TODO
-	 * @param icon TODO
-	 */
-	public JMenuItem(String text, Icon icon) {
-		// TODO
-	} // JMenuItem()
-
-	/**
-	 * Constructor JMenuItem
-	 * @param text TODO
-	 * @param mnemonic TODO
-	 */
-	public JMenuItem(String text, int mnemonic) {
-		// TODO
-	} // JMenuItem()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * readObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 * @exception ClassNotFoundException TODO
-	 */
-	private void readObject(ObjectInputStream stream) 
-			throws IOException, ClassNotFoundException {
-		// TODO
-	} // readObject()
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * init
-	 * @param text TODO
-	 * @param icon TODO
-	 */
-	protected void init(String text, Icon icon) {
-		// TODO
-	} // init()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(MenuItemUI ui) {
-		super.setUI(ui);
-		// TODO
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((MenuItemUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * isArmed
-	 * @returns boolean
-	 */
-	public boolean isArmed() {
-		return false; // TODO
-	} // isArmed()
-
-	/**
-	 * setArmed
-	 * @param armed TODO
-	 */
-	public void setArmed(boolean armed) {
-		// TODO
-	} // setArmed()
-
-	/**
-	 * setEnabled
-	 * @param enabled TODO
-	 */
-	public void setEnabled(boolean enabled) {
-		// TODO
-	} // setEnabled()
-
-	/**
-	 * getAccelerator
-	 * @returns KeyStroke
-	 */
-	public KeyStroke getAccelerator() {
-		return null; // TODO
-	} // getAccelerator()
-
-	/**
-	 * setAccelerator
-	 * @param keystroke TODO
-	 */
-	public void setAccelerator(KeyStroke keystroke) {
-		// TODO
-	} // setAccelerator()
-
-	/**
-	 * configurePropertiesFromAction
-	 * @param action TODO
-	 */
-	protected void configurePropertiesFromAction(Action action) {
-		// TODO
-	} // configurePropertiesFromAction()
-
-	/**
-	 * createActionPropertyChangeListener
-	 * @param action TODO
-	 * @returns PropertyChangeListener
-	 */
-	protected PropertyChangeListener createActionPropertyChangeListener(Action action) {
-		return null; // TODO
-	} // createActionPropertyChangeListener()
-
-	/**
-	 * processMouseEvent
-	 * @param event TODO
-	 * @param path TODO
-	 * @param manager TODO
-	 */
-	public void processMouseEvent(MouseEvent event, MenuElement[] path,
-			MenuSelectionManager manager) {
-		// TODO
-	} // processMouseEvent()
-
-	/**
-	 * processKeyEvent
-	 * @param event TODO
-	 * @param path TODO
-	 * @param manager TODO
-	 */
-	public void processKeyEvent(KeyEvent event, MenuElement[] path,
-			MenuSelectionManager manager) {
-		// TODO
-	} // processKeyEvent()
-
-	/**
-	 * processMenuDragMouseEvent
-	 * @param event TODO
-	 */
-	public void processMenuDragMouseEvent(MenuDragMouseEvent event) {
-		// TODO
-	} // processMenuDragMouseEvent()
-
-	/**
-	 * processMenuKeyEvent
-	 * @param event TODO
-	 */
-	public void processMenuKeyEvent(MenuKeyEvent event) {
-		// TODO
-	} // processMenuKeyEvent()
-
-	/**
-	 * fireMenuDragMouseEntered
-	 * @param event TODO
-	 */
-	protected void fireMenuDragMouseEntered(MenuDragMouseEvent event) {
-		// TODO
-	} // fireMenuDragMouseEntered()
-
-	/**
-	 * fireMenuDragMouseExited
-	 * @param event TODO
-	 */
-	protected void fireMenuDragMouseExited(MenuDragMouseEvent event) {
-		// TODO
-	} // fireMenuDragMouseExited()
-
-	/**
-	 * fireMenuDragMouseDragged
-	 * @param event TODO
-	 */
-	protected void fireMenuDragMouseDragged(MenuDragMouseEvent event) {
-		// TODO
-	} // fireMenuDragMouseDragged()
-
-	/**
-	 * fireMenuDragMouseReleased
-	 * @param event TODO
-	 */
-	protected void fireMenuDragMouseReleased(MenuDragMouseEvent event) {
-		// TODO
-	} // fireMenuDragMouseReleased()
-
-	/**
-	 * fireMenuKeyPressed
-	 * @param event TODO
-	 */
-	protected void fireMenuKeyPressed(MenuKeyEvent event) {
-		// TODO
-	} // fireMenuKeyPressed()
-
-	/**
-	 * fireMenuKeyReleased
-	 * @param event TODO
-	 */
-	protected void fireMenuKeyReleased(MenuKeyEvent event) {
-		// TODO
-	} // fireMenuKeyReleased()
-
-	/**
-	 * fireMenuKeyTyped
-	 * @param event TODO
-	 */
-	protected void fireMenuKeyTyped(MenuKeyEvent event) {
-		// TODO
-	} // fireMenuKeyTyped()
-
-	/**
-	 * menuSelectionChanged
-	 * @param changed TODO
-	 */
-	public void menuSelectionChanged(boolean changed) {
-		// TODO
-	} // menuSelectionChanged()
-
-	/**
-	 * getSubElements
-	 * @returns MenuElement[]
-	 */
-	public MenuElement[] getSubElements() {
-		return null; // TODO
-	} // getSubElements()
-
-	/**
-	 * getComponent
-	 * @returns Component
-	 */
-	public Component getComponent() {
-		return null; // TODO
-	} // getComponent()
-
-	/**
-	 * addMenuDragMouseListener
-	 * @param listener TODO
-	 */
-	public void addMenuDragMouseListener(MenuDragMouseListener listener) {
-		// TODO
-	} // addMenuDragMouseListener()
-
-	/**
-	 * removeMenuDragMouseListener
-	 * @param listener TODO
-	 */
-	public void removeMenuDragMouseListener(MenuDragMouseListener listener) {
-		// TODO
-	} // removeMenuDragMouseListener()
-
-	/**
-	 * addMenuKeyListener
-	 * @param listener TODO
-	 */
-	public void addMenuKeyListener(MenuKeyListener listener) {
-		// TODO
-	} // addMenuKeyListener()
-
-	/**
-	 * removeMenuKeyListener
-	 * @param listener TODO
-	 */
-	public void removeMenuKeyListener(MenuKeyListener listener) {
-		// TODO
-	} // removeMenuKeyListener()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJMenuItem(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JMenuItem
+public class JMenuItem extends AbstractButton implements Accessible,
+                                                         MenuElement
+{
+  private static final long serialVersionUID = -1681004643499461044L;
+
+  /** name for the UI delegate for this menuItem. */
+  private static final String uiClassID = "MenuItemUI";
+
+  /** Combination of keyboard keys that can be used to activate this menu item */
+  private KeyStroke accelerator;
+
+  /**
+   * Creates a new JMenuItem object.
+   */
+  public JMenuItem()
+  {
+    super(null, null);
+  }
+
+  /**
+   * Creates a new JMenuItem with the given icon.
+   *
+   * @param icon Icon that will be displayed on the menu item
+   */
+  public JMenuItem(Icon icon)
+  {
+    // FIXME: The requestedFocusEnabled property should
+    // be set to false, when only icon is set for menu item.
+    super(null, icon);
+  }
+
+  /**
+   * Creates a new JMenuItem with the given label.
+   *
+   * @param text label for the menu item
+   */
+  public JMenuItem(String text)
+  {
+    super(text, null);
+  }
+
+  /**
+   * Creates a new JMenuItem associated with the specified action.
+   *
+   * @param action action for this menu item
+   */
+  public JMenuItem(Action action)
+  {
+    super(null, null);
+    super.setAction(action);
+  }
+
+  /**
+   * Creates a new JMenuItem with specified text and icon.
+   * Text is displayed to the left of icon by default.
+   *
+   * @param text label for this menu item
+   * @param icon icon that will be displayed on this menu item
+   */
+  public JMenuItem(String text, Icon icon)
+  {
+    super(text, icon);
+  }
+
+  /**
+   * Creates a new JMenuItem object.
+   *
+   * @param text label for this menu item
+   * @param mnemonic - Single key that can be used with a
+   * look-and-feel meta key to activate this menu item. However
+   * menu item should be visible on the screen when mnemonic is used.
+   */
+  public JMenuItem(String text, int mnemonic)
+  {
+    super(text, null);
+    setMnemonic(mnemonic);
+  }
+
+  private void readObject(ObjectInputStream stream)
+                   throws IOException, ClassNotFoundException
+  {
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * Initializes this menu item
+   *
+   * @param text label for this menu item
+   * @param icon icon to be displayed for this menu item
+   */
+  protected void init(String text, Icon icon)
+  {
+    super.init(text, icon);
+
+    // Initializes properties for this menu item, that are different
+    // from Abstract button properties. 
+    /* NOTE: According to java specifications paint_border should be set to false,
+      since menu item should not have a border. However running few java programs
+      it seems that menu items and menues can have a border. Commenting
+      out statement below for now. */
+    //borderPainted = false;
+    focusPainted = false;
+    horizontalAlignment = JButton.LEFT;
+    horizontalTextPosition = JButton.LEFT;
+  }
+
+  /**
+   * Set the "UI" property of the menu item, which is a look and feel class
+   * responsible for handling menuItem's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(MenuItemUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    MenuItemUI mi = ((MenuItemUI) UIManager.getUI(this));
+    setUI(mi);
+    invalidate();
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "MenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * Returns true if button's model is armed and false otherwise. The
+   * button model is armed if menu item has focus or it is selected.
+   *
+   * @return $boolean$ true if button's model is armed and false otherwise
+   */
+  public boolean isArmed()
+  {
+    return getModel().isArmed();
+  }
+
+  /**
+   * Sets menuItem's "ARMED" property
+   *
+   * @param armed DOCUMENT ME!
+   */
+  public void setArmed(boolean armed)
+  {
+    getModel().setArmed(armed);
+  }
+
+  /**
+   * Enable or disable menu item. When menu item is disabled,
+   * its text and icon are grayed out if they exist.
+   *
+   * @param enabled if true enable menu item, and disable otherwise.
+   */
+  public void setEnabled(boolean enabled)
+  {
+    super.setEnabled(enabled);
+  }
+
+  /**
+   * Return accelerator for this menu item.
+   *
+   * @return $KeyStroke$ accelerator for this menu item.
+   */
+  public KeyStroke getAccelerator()
+  {
+    return accelerator;
+  }
+
+  /**
+   * Sets accelerator for this menu item.
+   *
+   * @param keystroke accelerator for this menu item.
+   */
+  public void setAccelerator(KeyStroke keystroke)
+  {
+    this.accelerator = keystroke;
+  }
+
+  /**
+   * Configures menu items' properties from properties of the specified action.
+   * This method overrides configurePropertiesFromAction from AbstractButton
+   * to also set accelerator property.
+   *
+   * @param action action to configure properties from
+   */
+  protected void configurePropertiesFromAction(Action action)
+  {
+    super.configurePropertiesFromAction(action);
+
+    if (! (this instanceof JMenu) && action != null)
+      setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+  }
+
+  /**
+   * Creates PropertyChangeListener to listen for the changes in action
+   * properties.
+   *
+   * @param action action to listen to for property changes
+   *
+   * @return $PropertyChangeListener$ Listener that listens to changes in
+   * action properties.
+   */
+  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
+  {
+    return new PropertyChangeListener()
+      {
+	public void propertyChange(PropertyChangeEvent e)
+	{
+	  Action act = (Action) (e.getSource());
+	  configurePropertiesFromAction(act);
+	}
+      };
+  }
+
+  /**
+   * Process mouse events forwarded from MenuSelectionManager.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Fire MenuDragMouseEvents if mouse is being dragged.
+    boolean dragged
+      = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0;
+    if (dragged)
+      processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager));
+
+    switch (event.getID())
+      {
+      case MouseEvent.MOUSE_CLICKED:
+	break;
+      case MouseEvent.MOUSE_ENTERED:
+	if (isRolloverEnabled())
+	      model.setRollover(true);
+	break;
+      case MouseEvent.MOUSE_EXITED:
+	if (isRolloverEnabled())
+	      model.setRollover(false);
+
+	// for JMenu last element on the path is its popupMenu.
+	// JMenu shouldn't me disarmed.	
+	if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged)
+	  setArmed(false);
+	break;
+      case MouseEvent.MOUSE_PRESSED:
+	if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
+	  {
+	    model.setArmed(true);
+	    model.setPressed(true);
+	  }
+	break;
+      case MouseEvent.MOUSE_RELEASED:
+	break;
+      case MouseEvent.MOUSE_MOVED:
+	break;
+      case MouseEvent.MOUSE_DRAGGED:
+	break;
+      }
+  }
+
+  /**
+   * Creates MenuDragMouseEvent.
+   *
+   * @param event MouseEvent that occured while mouse was pressed.
+   * @param path Path the the menu element where the dragging event was
+   *        originated
+   * @param manager MenuSelectionManager for the current menu hierarchy.
+   *
+   * @return new MenuDragMouseEvent
+   */
+  private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event,
+                                                      MenuElement[] path,
+                                                      MenuSelectionManager manager)
+  {
+    return new MenuDragMouseEvent((Component) event.getSource(),
+                                  event.getID(), event.getWhen(),
+                                  event.getModifiers(), event.getX(),
+                                  event.getY(), event.getClickCount(),
+                                  event.isPopupTrigger(), path, manager);
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   */
+  public void processKeyEvent(KeyEvent event, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    // Need to implement.
+  }
+
+  /**
+   * This method fires MenuDragMouseEvents to registered listeners.
+   * Different types of MenuDragMouseEvents are fired depending
+   * on the observed mouse event.
+   *
+   * @param event Mouse
+   */
+  public void processMenuDragMouseEvent(MenuDragMouseEvent event)
+  {
+    switch (event.getID())
+      {
+      case MouseEvent.MOUSE_ENTERED:
+	fireMenuDragMouseEntered(event);
+	break;
+      case MouseEvent.MOUSE_EXITED:
+	fireMenuDragMouseExited(event);
+	break;
+      case MouseEvent.MOUSE_DRAGGED:
+	fireMenuDragMouseDragged(event);
+	break;
+      case MouseEvent.MOUSE_RELEASED:
+	fireMenuDragMouseReleased(event);
+	break;
+      }
+  }
+
+  /**
+   * This method fires MenuKeyEvent to registered listeners.
+   * Different types of MenuKeyEvents are fired depending
+   * on the observed key event.
+   *
+   * @param event DOCUMENT ME!
+   */
+  public void processMenuKeyEvent(MenuKeyEvent event)
+  {
+    // Need to implement.
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse entered menuItem while it was dragged
+   */
+  protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse has exited menu item, while it was dragged
+   */
+  protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse is being dragged over the menuItem
+   */
+  protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
+  }
+
+  /**
+   * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse was released while it was dragged over the menuItem
+   */
+  protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was pressed
+   */
+  protected void fireMenuKeyPressed(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyPressed(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was released
+   */
+  protected void fireMenuKeyReleased(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was typed.
+   *        The key is typed when it was pressed and then released
+   */
+  protected void fireMenuKeyTyped(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
+  }
+
+  /**
+   * Method of the MenuElement interface.
+   * This method is invoked by MenuSelectionManager when selection of
+   * this menu item has changed. If this menu item was selected then
+   * arm it's model, and disarm the model otherwise. The menu item
+   * is considered to be selected, and thus highlighted when its model
+   * is armed.
+   *
+   * @param changed indicates selection status of this menu item. If changed is
+   * true then menu item is selected and deselected otherwise.
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    if (changed)
+      {
+      model.setArmed(true);
+
+	if (this.getParent() instanceof JPopupMenu)
+	  ((JPopupMenu) this.getParent()).setSelected(this);
+      }
+    else
+      {
+      model.setArmed(false);
+
+	if (this.getParent() instanceof JPopupMenu)
+	  ((JPopupMenu) this.getParent()).getSelectionModel().clearSelection();
+      }
+  }
+
+  /**
+   * Method of the MenuElement interface.
+   *
+   * @return $MenuElement[]$ Returns array of sub-components for this menu
+   *         item. By default menuItem doesn't have any subcomponents and so
+   *             empty array is returned instead.
+   */
+  public MenuElement[] getSubElements()
+  {
+    return new MenuElement[0];
+  }
+
+  /**
+   * Returns reference to the component that will paint this menu item.
+   *
+   * @return $Component$ Component that will paint this menu item.
+   *         Simply returns reference to this menu item.
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Adds a MenuDragMouseListener to this menu item. When mouse
+   * is dragged over the menu item the MenuDragMouseEvents will be
+   * fired, and these listeners will be called.
+   *
+   * @param listener The new listener to add
+   */
+  public void addMenuDragMouseListener(MenuDragMouseListener listener)
+  {
+    listenerList.add(MenuDragMouseListener.class, listener);
+  }
+
+  /**
+   * Removes a MenuDragMouseListener from the menuItem's listener list.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeMenuDragMouseListener(MenuDragMouseListener listener)
+  {
+    listenerList.remove(MenuDragMouseListener.class, listener);
+  }
+
+  /**
+   * Returns all added MenuDragMouseListener objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public MenuDragMouseListener[] getMenuDragMouseListeners()
+  {
+    return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
+  }
+
+  /**
+   * Adds an MenuKeyListener to this menu item.  This listener will be
+   * invoked when MenuKeyEvents will be fired by this menu item.
+   *
+   * @param listener The new listener to add
+   */
+  public void addMenuKeyListener(MenuKeyListener listener)
+  {
+    listenerList.add(MenuKeyListener.class, listener);
+  }
+
+  /**
+   * Removes an MenuKeyListener from the menuItem's listener list.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeMenuKeyListener(MenuKeyListener listener)
+  {
+    listenerList.remove(MenuKeyListener.class, listener);
+  }
+
+  /**
+   * Returns all added MenuKeyListener objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public MenuKeyListener[] getMenuKeyListeners()
+  {
+    return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
+  }
+
+  /**
+   * A string that describes this JMenuItem. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenuItem
+   */
+  protected String paramString()
+  {
+    return "JMenuItem";
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJMenuItem();
+
+    return accessibleContext;
+  }
+
+  protected class AccessibleJMenuItem extends AccessibleAbstractButton
+    implements ChangeListener
+  {
+    private static final long serialVersionUID = 6748924232082076534L;
+
+    /**
+     * Creates a new AccessibleJMenuItem object.
+     */
+    AccessibleJMenuItem()
+    {
+      //super(component);
+    }
+
+    public void stateChanged(ChangeEvent event)
+    {
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.MENU_ITEM;
+    }
+  }
+}
Index: javax/swing/JOptionPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JOptionPane.java,v
retrieving revision 1.2
diff -u -r1.2 JOptionPane.java
--- javax/swing/JOptionPane.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JOptionPane.java	6 Sep 2004 16:35:57 -0000
@@ -1,5 +1,5 @@
-/* JOptionPane.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JOptionPane.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,365 +35,1515 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
-import java.awt.BorderLayout;
 import java.awt.Component;
 import java.awt.Dialog;
+import java.awt.Dimension;
 import java.awt.Frame;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.Icon;
+import javax.swing.JInternalFrame;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
 import javax.swing.plaf.OptionPaneUI;
 
-public class JOptionPane extends JComponent 
-{
-    public static final int DEFAULT_OPTION        = 0;
-    public static final int YES_NO_OPTION         = 1;
-    public static final int YES_NO_CANCEL_OPTION  = 2;
-    public static final int OK_CANCEL_OPTION      = 3;
-    public static final int YES_OPTION            = 4;
-    public static final int NO_OPTION             = 5;
-    public static final int CANCEL_OPTION         = 6;
-    public static final int OK_OPTION             = 7;
-    public static final int CLOSED_OPTION         = 8;
-
-    public static final int ERROR_MESSAGE         = 0;
-    public static final int INFORMATION_MESSAGE   = 1;
-    public static final int WARNING_MESSAGE       = 2;
-    public static final int QUESTION_MESSAGE      = 3;
-    public static final int PLAIN_MESSAGE         = 4;
-
-    final static String VALUE_PROPERTY = "value_prop";
-    final static String INPUT_VALUE_PROPERTY = "input_value_prop";
-    
-    final static String UNINITIALIZED_VALUE = "uninit";
-
-    // Ronald: shouldnt by public ?
-    public Object msg;
-    public int mtype;
-    public int otype;
-    public Icon icon;
-    public Object []args;
-    public Object init;
-
-    public JDialog dialog;
-
-    /*****************************************************************************
-     *
-     *
-     *  joptionpanels
-     *
-     *
-     ***********************************/
-
-    JOptionPane()
-    {
-	this("mess");
-    }
-    
-    JOptionPane(Object m)
-    {
-	this(m, PLAIN_MESSAGE);
-    }
-    
-    JOptionPane(Object m,
-		 int mtype)
-    {
-	this(m, mtype, DEFAULT_OPTION);
-    }
-
-    JOptionPane(Object m,
-		int mtype,
-		int otype)
-    {
-	this(m, mtype, otype, null);
-    }
- 
-    JOptionPane(Object m,
-		 int mtype,
-		 int otype,
-		 Icon icon)
-    {
-	this(m, mtype, otype, icon, null);
-    }
 
-    JOptionPane(Object m,
-		 int mtype,
-		 int otype,
-		 Icon icon,
-		 Object []args)
-    {
-	this(m, mtype, otype, icon, args, null);
-    }
-
-    JOptionPane(Object msg,
-		int mtype,
-		int otype,
-		Icon icon,
-		Object []args,
-		Object init)
+/**
+ * This class creates different types of JDialogs and JInternalFrames that can
+ * ask users for input or pass on information. JOptionPane can be used by
+ * calling one of the show static methods or  by creating an instance of
+ * JOptionPane and calling createDialog or createInternalFrame.
+ */
+public class JOptionPane extends JComponent implements Accessible
+{
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 686071432213084821L;
+  
+    /**
+     * Creates a new AccessibleJOptionPane object.
+     */
+    protected AccessibleJOptionPane()
     {
-	//	this(m, mtype, otype, icon, args, init);
-	this.msg   = msg;
-	this.mtype = mtype;
-	this.otype = otype;
-	this.icon  = icon;
-	this.args  = args;
-	this.init  = init;
-	
-	updateUI();
     }
 
-
-    /*****************************************************************************
-     *
-     *
-     *
+    /**
+     * DOCUMENT ME!
      *
-     *
-     ***********************************/
-
-    Object val;
-    public void setValue(Object v)  
-    {   val = v;       }
-    public Object getValue()
-    {	return val;    }
-
-    public String getUIClassID()
-    {	return "JOptionPane";    }
-
-
-    public void setUI(OptionPaneUI ui) {
-        super.setUI(ui);
-    }
-    
-    public OptionPaneUI getUI() {
-        return (OptionPaneUI)ui;
-    }
-    
-    public void updateUI() {
-	setUI((OptionPaneUI)UIManager.getUI(this));
-    }
-
-
-    public AccessibleContext getAccessibleContext()
-    {
-	return null;
-    }
-    
-    protected  String paramString()
-    {
-	return "JOptionPane";
-    }
-    
-    public static void showMessageDialog(Component frame,
-				  String msg,
-				  String title,
-				  int bla)
-    {
-	DoShowOptionDialog(frame,
-			  msg,
-			  title,
-			  bla,
-			  0,
-			  null,
-			  null,
-			  null);
-    }
-
-    public static void showMessageDialog(Component frame,
-				 String msg,
-				 String title,
-				 int bla,
-				 Icon icon)
-    {
-	DoShowOptionDialog(frame,
-				 msg,
-				 title,
-				 bla,
-				 0,
-				 icon,
-				 null,
-				 null);
-    }
-
-    public static void showMessageDialog(Component frame,
-				  String msg)
-    {
-	showMessageDialog(frame,
-			  msg,
-			  null);
-    }
-    
-
-    public static void showMessageDialog(Component frame,
-				  String msg,
-				  Icon icon)
-    {	
-	//System.out.println("++++++++++++++++++creating message dialog:"+msg + ", frame="+frame);
-         DoShowOptionDialog(frame, 
-				msg, 
-				"Message",				
-				DEFAULT_OPTION, 
-				PLAIN_MESSAGE,
-				icon,
-				null,
-				null);
-    }
-
-    public static int showConfirmDialog(JFrame frame,
-				 String yes,
-				 String no, 
-				 int bla)
-    {
-	return 0;
-    }
-
-    public static String showInputDialog(JFrame frame,
-			     String msg, 
-			     String title, 
-			     int opt_type, 
-			     int msg_type,
-			     Icon icon, 
-			     Object[] opts, 
-			     Object init)
-    {
-	return (String) DoShowOptionDialog(frame,
-				msg, 
-				title, 
-				opt_type, 
-				msg_type,
-				icon, 
-				opts, 
-				init);
-    }
-
-    public static Object showInputDialog(JFrame frame,
-			     String msg, 
-			     String title, 
-			     int opt_type, 
-			     Icon icon, 
-			     Object[] opts, 
-			     Object init)
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
     {
-	return DoShowOptionDialog(frame,
-				msg, 
-				title, 
-				opt_type, 
-				0, //msg_type,
-				icon, 
-				opts, 
-				init);
+      return null;
     }
+  }
 
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 5231143276678566796L;
+  
+  /** The value returned when cancel option is selected. */
+  public static final int CANCEL_OPTION = 2;
+
+  /** The value returned when the dialog is closed without a selection. */
+  public static final int CLOSED_OPTION = -1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int DEFAULT_OPTION = -1;
+
+  /** The value returned when the no option is selected. */
+  public static final int NO_OPTION = 1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int OK_CANCEL_OPTION = 2;
+
+  /** The value returned when the ok option is selected. */
+  public static final int OK_OPTION = 0;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int YES_NO_CANCEL_OPTION = 1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int YES_NO_OPTION = 0;
+
+  /** The value returned when the yes option is selected. */
+  public static final int YES_OPTION = 0;
+
+  /** Identifier for the error message type. */
+  public static final int ERROR_MESSAGE = 0;
+
+  /** Identifier for the information message type. */
+  public static final int INFORMATION_MESSAGE = 1;
+
+  /** Identifier for the plain message type. */
+  public static final int PLAIN_MESSAGE = -1;
+
+  /** Identifier for the question message type. */
+  public static final int QUESTION_MESSAGE = 3;
+
+  /** Identifier for the warning message type. */
+  public static final int WARNING_MESSAGE = 2;
+
+  /**
+   * The identifier for the propertyChangeEvent when the icon property
+   * changes.
+   */
+  public static final String ICON_PROPERTY = "icon";
+
+  /**
+   * The identifier for the propertyChangeEvent when the initialSelectionValue
+   * property changes.
+   */
+  public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the initialValue property
+   * changes.
+   */
+  public static final String INITIAL_VALUE_PROPERTY = "initialValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the inputValue property
+   * changes.
+   */
+  public static final String INPUT_VALUE_PROPERTY = "inputValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the message property
+   * changes.
+   */
+  public static final String MESSAGE_PROPERTY = "message";
+
+  /**
+   * The identifier for the propertyChangeEvent when the messageType property
+   * changes.
+   */
+  public static final String MESSAGE_TYPE_PROPERTY = "messageType";
+
+  /**
+   * The identifier for the propertyChangeEvent when the optionType property
+   * changes.
+   */
+  public static final String OPTION_TYPE_PROPERTY = "optionType";
+
+  /**
+   * The identifier for the propertyChangeEvent when the options property
+   * changes.
+   */
+  public static final String OPTIONS_PROPERTY = "options";
+
+  /**
+   * The identifier for the propertyChangeEvent when the selectionValues
+   * property changes.
+   */
+  public static final String SELECTION_VALUES_PROPERTY = "selectionValues";
+
+  /**
+   * The identifier for the propertyChangeEvent when the value property
+   * changes.
+   */
+  public static final String VALUE_PROPERTY = "value";
+
+  /**
+   * The identifier for the propertyChangeEvent when the wantsInput property
+   * changes.
+   */
+  public static final String WANTS_INPUT_PROPERTY = "wantsInput";
+
+  /** The value returned when the inputValue is uninitialized. */
+  public static Object UNINITIALIZED_VALUE = "uninitializedValue";
+
+  /** The icon displayed in the dialog/internal frame. */
+  protected Icon icon;
+
+  /** The initial selected value in the input component. */
+  protected Object initialSelectionValue;
+
+  /** The object that is initially selected for options. */
+  protected Object initialValue;
+
+  /** The value the user inputs. */
+  protected Object inputValue = UNINITIALIZED_VALUE;
+
+  /** The message displayed in the dialog/internal frame. */
+  protected Object message;
+
+  /** The type of message displayed. */
+  protected int messageType = PLAIN_MESSAGE;
+
+  /**
+   * The options (usually buttons) aligned at the bottom for the user to
+   * select.
+   */
+  protected Object[] options;
+
+  /** The type of options to display. */
+  protected int optionType = DEFAULT_OPTION;
+
+  /** The input values the user can select. */
+  protected Object[] selectionValues;
+
+  /** The value returned by selecting an option. */
+  protected Object value = UNINITIALIZED_VALUE;
+
+  /** Whether the Dialog/InternalFrame needs input. */
+  protected boolean wantsInput;
+
+  /** The common frame used when no parent is provided. */
+  private static Frame privFrame = SwingUtilities.getOwnerFrame();
+
+  /**
+   * Creates a new JOptionPane object using a message of "JOptionPane
+   * message", using the PLAIN_MESSAGE type and DEFAULT_OPTION.
+   */
+  public JOptionPane()
+  {
+    this("JOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message using the
+   * PLAIN_MESSAGE type and DEFAULT_OPTION.
+   *
+   * @param message The message to display.
+   */
+  public JOptionPane(Object message)
+  {
+    this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message and messageType
+   * and DEFAULT_OPTION.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   */
+  public JOptionPane(Object message, int messageType)
+  {
+    this(message, messageType, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType and
+   * optionType.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   */
+  public JOptionPane(Object message, int messageType, int optionType)
+  {
+    this(message, messageType, optionType, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType and icon.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   */
+  public JOptionPane(Object message, int messageType, int optionType, Icon icon)
+  {
+    this(message, messageType, optionType, icon, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType, icon and options.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   * @param options The options given.
+   */
+  public JOptionPane(Object message, int messageType, int optionType,
+                     Icon icon, Object[] options)
+  {
+    this(message, messageType, optionType, icon, options, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType, icon, options and initialValue. The initialValue will be
+   * focused initially.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   * @param options The options given.
+   * @param initialValue The component to focus on initially.
+   *
+   * @throws IllegalArgumentException If the messageType or optionType are not
+   *         legal values.
+   */
+  public JOptionPane(Object message, int messageType, int optionType,
+                     Icon icon, Object[] options, Object initialValue)
+  {
+    this.message = message;
+    if (! validMessageType(messageType))
+      throw new IllegalArgumentException("Message Type not legal value.");
+    this.messageType = messageType;
+    if (! validOptionType(optionType))
+      throw new IllegalArgumentException("Option Type not legal value.");
+    this.optionType = optionType;
+    this.icon = icon;
+    this.options = options;
+    this.initialValue = initialValue;
+
+    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+    updateUI();
+    invalidate();
+    repaint();
+  }
+
+  /**
+   * This method creates a new JDialog that is either centered around the
+   * parent's frame or centered on the screen (if the parent is null). The
+   * JDialog will not be resizable and will be modal. Once the JDialog is
+   * disposed, the inputValue and value properties will  be set by the
+   * optionPane.
+   *
+   * @param parentComponent The parent of the Dialog.
+   * @param title The title in the bar of the JDialog.
+   *
+   * @return A new JDialog based on the JOptionPane configuration.
+   */
+  public JDialog createDialog(Component parentComponent, String title)
+  {
+    Frame toUse = getFrameForComponent(parentComponent);
+    if (toUse == null)
+      toUse = getRootFrame();
+
+    JDialog dialog = new JDialog(toUse, title);
+    inputValue = UNINITIALIZED_VALUE;
+    value = UNINITIALIZED_VALUE;
+
+    // FIXME: This dialog should be centered on the parent
+    // or at the center of the screen (if the parent is null)
+    // Need getGraphicsConfiguration to return non-null in
+    // order for that to work so we know how large the 
+    // screen is.
+    dialog.getContentPane().add(this);
+    dialog.setModal(true);
+    dialog.setResizable(false);
+    dialog.invalidate();
+    dialog.repaint();
+
+    return dialog;
+  }
+
+  /**
+   * This method creates a new JInternalFrame that is in the JDesktopPane
+   * which contains the parentComponent given. If no suitable JDesktopPane
+   * can be found from the parentComponent given, a RuntimeException will be
+   * thrown.
+   *
+   * @param parentComponent The parent to find a JDesktopPane from.
+   * @param title The title of the JInternalFrame.
+   *
+   * @return A new JInternalFrame based on the JOptionPane configuration.
+   *
+   * @throws RuntimeException If no suitable JDesktopPane is found.
+   */
+  public JInternalFrame createInternalFrame(Component parentComponent,
+                                            String title)
+                                     throws RuntimeException
+  {
+    JDesktopPane toUse = getDesktopPaneForComponent(parentComponent);
+    if (toUse == null)
+      throw new RuntimeException("parentComponent does not have a valid parent");
+
+    JInternalFrame frame = new JInternalFrame(title);
+
+    inputValue = UNINITIALIZED_VALUE;
+    value = UNINITIALIZED_VALUE;
+
+    frame.setClosable(true);
+    toUse.add(frame);
+
+    // FIXME: JLayeredPane broken? See bug # 16576
+    // frame.setLayer(JLayeredPane.MODAL_LAYER);
+    return frame;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJOptionPane();
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the JDesktopPane for the given parentComponent or
+   * null if none can be found.
+   *
+   * @param parentComponent The component to look in.
+   *
+   * @return The JDesktopPane for the given component or null if none can be
+   *         found.
+   */
+  public static JDesktopPane getDesktopPaneForComponent(Component parentComponent)
+  {
+    return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                            parentComponent);
+  }
+
+  /**
+   * This method returns the Frame for the given parentComponent or null if
+   * none can be found.
+   *
+   * @param parentComponent The component to look in.
+   *
+   * @return The Frame for the given component or null if none can be found.
+   */
+  public static Frame getFrameForComponent(Component parentComponent)
+  {
+    return (Frame) SwingUtilities.getAncestorOfClass(Frame.class,
+                                                     parentComponent);
+  }
+
+  /**
+   * This method returns the icon displayed.
+   *
+   * @return The icon displayed.
+   */
+  public Icon getIcon()
+  {
+    return icon;
+  }
+
+  /**
+   * This method returns the value initially selected from the list of values
+   * the user can input.
+   *
+   * @return The initial selection value.
+   */
+  public Object getInitialSelectionValue()
+  {
+    return initialSelectionValue;
+  }
+
+  /**
+   * This method returns the value that is focused from the list of options.
+   *
+   * @return The initial value from options.
+   */
+  public Object getInitialValue()
+  {
+    return initialValue;
+  }
+
+  /**
+   * This method returns the value that the user input.
+   *
+   * @return The user's input value.
+   */
+  public Object getInputValue()
+  {
+    return inputValue;
+  }
+
+  /**
+   * This method returns the maximum characters per line. By default, this is
+   * Integer.MAX_VALUE.
+   *
+   * @return The maximum characters per line.
+   */
+  public int getMaxCharactersPerLineCount()
+  {
+    return Integer.MAX_VALUE;
+  }
+
+  /**
+   * This method returns the message displayed.
+   *
+   * @return The message displayed.
+   */
+  public Object getMessage()
+  {
+    return message;
+  }
+
+  /**
+   * This method returns the message type.
+   *
+   * @return The message type.
+   */
+  public int getMessageType()
+  {
+    return messageType;
+  }
+
+  /**
+   * This method returns the options.
+   *
+   * @return The options.
+   */
+  public Object[] getOptions()
+  {
+    return options;
+  }
+
+  /**
+   * This method returns the option type.
+   *
+   * @return The option type.
+   */
+  public int getOptionType()
+  {
+    return optionType;
+  }
+
+  /**
+   * This method returns the Frame used by JOptionPane dialog's that have no
+   * parent.
+   *
+   * @return The Frame used by dialogs that have no parent.
+   */
+  public static Frame getRootFrame()
+  {
+    return privFrame;
+  }
+
+  /**
+   * This method returns the selection values.
+   *
+   * @return The selection values.
+   */
+  public Object[] getSelectionValues()
+  {
+    return selectionValues;
+  }
+
+  /**
+   * This method returns the UI used by the JOptionPane.
+   *
+   * @return The UI used by the JOptionPane.
+   */
+  public OptionPaneUI getUI()
+  {
+    return (OptionPaneUI) ui;
+  }
+
+  /**
+   * This method returns an identifier to determine which UI class will act as
+   * the UI.
+   *
+   * @return The UI identifier.
+   */
+  public String getUIClassID()
+  {
+    return "OptionPaneUI";
+  }
+
+  /**
+   * This method returns the value that the user selected out of options.
+   *
+   * @return The value that the user selected out of options.
+   */
+  public Object getValue()
+  {
+    return value;
+  }
+
+  /**
+   * This method returns whether this JOptionPane wants input.
+   *
+   * @return Whether this JOptionPane wants input.
+   */
+  public boolean getWantsInput()
+  {
+    return wantsInput;
+  }
+
+  /**
+   * This method returns a String that describes this JOptionPane.
+   *
+   * @return A String that describes this JOptionPane.
+   */
+  protected String paramString()
+  {
+    return "JOptionPane";
+  }
+
+  /**
+   * This method requests focus for the initial value.
+   */
+  public void selectInitialValue()
+  {
+    if (ui != null)
+      ((OptionPaneUI) ui).selectInitialValue(this);
+  }
+
+  /**
+   * This method changes the icon property.
+   *
+   * @param newIcon The new icon to use.
+   */
+  public void setIcon(Icon newIcon)
+  {
+    if (icon != newIcon)
+      {
+	Icon old = icon;
+	icon = newIcon;
+	firePropertyChange(ICON_PROPERTY, old, icon);
+      }
+  }
+
+  /**
+   * This method changes the initial selection property.
+   *
+   * @param newValue The new initial selection.
+   */
+  public void setInitialSelectionValue(Object newValue)
+  {
+    if (initialSelectionValue != newValue)
+      {
+	Object old = initialSelectionValue;
+	initialSelectionValue = newValue;
+	firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, old,
+	                   initialSelectionValue);
+      }
+  }
+
+  /**
+   * This method changes the initial value property.
+   *
+   * @param newValue The new initial value.
+   */
+  public void setInitialValue(Object newValue)
+  {
+    if (initialValue != newValue)
+      {
+	Object old = initialValue;
+	initialValue = newValue;
+	firePropertyChange(INITIAL_VALUE_PROPERTY, old, initialValue);
+      }
+  }
+
+  /**
+   * This method changes the inputValue property.
+   *
+   * @param newValue The new inputValue.
+   */
+  public void setInputValue(Object newValue)
+  {
+    if (inputValue != newValue)
+      {
+	Object old = inputValue;
+	inputValue = newValue;
+	firePropertyChange(INPUT_VALUE_PROPERTY, old, inputValue);
+      }
+  }
+
+  /**
+   * This method changes the message property.
+   *
+   * @param newMessage The new message.
+   */
+  public void setMessage(Object newMessage)
+  {
+    if (message != newMessage)
+      {
+	Object old = message;
+	message = newMessage;
+	firePropertyChange(MESSAGE_PROPERTY, old, message);
+      }
+  }
+
+  /**
+   * This method changes the messageType property.
+   *
+   * @param newType The new messageType.
+   *
+   * @throws IllegalArgumentException If the messageType is not valid.
+   */
+  public void setMessageType(int newType)
+  {
+    if (! validMessageType(newType))
+      throw new IllegalArgumentException("Message Type not legal value.");
+    if (newType != messageType)
+      {
+	int old = messageType;
+	messageType = newType;
+	firePropertyChange(MESSAGE_TYPE_PROPERTY, old, messageType);
+      }
+  }
+
+  /**
+   * This method changes the options property.
+   *
+   * @param newOptions The new options.
+   */
+  public void setOptions(Object[] newOptions)
+  {
+    if (options != newOptions)
+      {
+	Object[] old = options;
+	options = newOptions;
+	firePropertyChange(OPTIONS_PROPERTY, old, options);
+      }
+  }
+
+  /**
+   * This method changes the optionType property.
+   *
+   * @param newType The new optionType.
+   *
+   * @throws IllegalArgumentException If the optionType is not valid.
+   */
+  public void setOptionType(int newType)
+  {
+    if (! validOptionType(newType))
+      throw new IllegalArgumentException("Option Type not legal value.");
+    if (newType != optionType)
+      {
+	int old = optionType;
+	optionType = newType;
+	firePropertyChange(OPTION_TYPE_PROPERTY, old, optionType);
+      }
+  }
+
+  /**
+   * This method changes the Frame used for JOptionPane dialogs that have no
+   * parent.
+   *
+   * @param newRootFrame The Frame to use for dialogs that have no parent.
+   */
+  public static void setRootFrame(Frame newRootFrame)
+  {
+    privFrame = newRootFrame;
+  }
+
+  /**
+   * This method changes the selectionValues property.
+   *
+   * @param newValues The new selectionValues.
+   */
+  public void setSelectionValues(Object[] newValues)
+  {
+    if (newValues != selectionValues)
+      {
+	if (newValues != null)
+	  wantsInput = true;
+	Object[] old = selectionValues;
+	selectionValues = newValues;
+	firePropertyChange(SELECTION_VALUES_PROPERTY, old, selectionValues);
+      }
+  }
+
+  /**
+   * This method sets the UI used with the JOptionPane.
+   *
+   * @param ui The UI used with the JOptionPane.
+   */
+  public void setUI(OptionPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets the value has been selected out of options.
+   *
+   * @param newValue The value that has been selected out of options.
+   */
+  public void setValue(Object newValue)
+  {
+    if (value != newValue)
+      {
+	Object old = value;
+	value = newValue;
+	firePropertyChange(VALUE_PROPERTY, old, value);
+      }
+  }
+
+  /**
+   * This method changes the wantsInput property.
+   *
+   * @param newValue Whether this JOptionPane requires input.
+   */
+  public void setWantsInput(boolean newValue)
+  {
+    if (wantsInput != newValue)
+      {
+	boolean old = wantsInput;
+	wantsInput = newValue;
+	firePropertyChange(WANTS_INPUT_PROPERTY, old, wantsInput);
+      }
+  }
+
+  /**
+   * This method shows a confirmation dialog with the title "Select an Option"
+   * and displays the given message. The parent frame will be the same as the
+   * parent frame of the given parentComponent. This method returns the
+   * option chosen by the user.
+   *
+   * @param parentComponent The parentComponent to find a frame in.
+   * @param message The message to display.
+   *
+   * @return The option that was selected.
+   */
+  public static int showConfirmDialog(Component parentComponent, Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    JDialog dialog = pane.createDialog(parentComponent, "Select an Option");
+
+    dialog.pack();
+    dialog.show();
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message,
+   * optionType and title. The frame that owns the dialog will be the same
+   * frame that holds the given parentComponent. This method returns the
+   * option that was chosen.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   *
+   * @return The option that was chosen.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType)
+  {
+    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message, title,
+   * messageType and optionType. The frame owner will be the same frame as
+   * the one that holds the given parentComponent. This method returns the
+   * option selected by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messageType.
+   *
+   * @return The selected option.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType, int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message, title,
+   * optionType, messageType and icon. The frame owner will be the same as
+   * the one that holds the given parentComponent. This method returns the
+   * option selected by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messsageType.
+   * @param icon The icon displayed.
+   *
+   * @return The selected option.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType, int messageType,
+                                      Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method will show a QUESTION_MESSAGE input dialog with the given
+   * message. No selectionValues is set so the Look and Feel will usually
+   * give the user a TextField to fill out. The frame owner will be the same
+   * frame that holds the given parentComponent. This method will return the
+   * value entered by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   *
+   * @return The value entered by the user.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method will show a QUESTION_MESSAGE type input dialog with the given
+   * message and initialSelectionValue. Since there is no selectionValues
+   * set, the Look and Feel will usually give a TextField to fill out. The
+   * frame owner will be the same as the one that holds the given
+   * parentComponent. This method will return the value entered by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message to display.
+   * @param initialSelectionValue The initially selected value.
+   *
+   * @return The value the user input.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method displays a new input dialog with the given message, title and
+   * messageType. Since no selectionValues value is given, the Look and Feel
+   * will usually give the user a TextField to input data to. This method
+   * returns the value the user inputs.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message to display.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   *
+   * @return The value the user input.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an input dialog with the given message, title,
+   * messageType, icon, selectionValues, and initialSelectionValue. This
+   * method returns the value that the user selects.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   * @param selectionValues The list of values to select from.
+   * @param initialSelectionValue The initially selected value.
+   *
+   * @return The user selected value.
+   */
+  public static Object showInputDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType, Icon icon,
+                                       Object[] selectionValues,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    pane.setIcon(icon);
+    pane.setSelectionValues(selectionValues);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows a QUESTION_MESSAGE type input dialog. Since no
+   * selectionValues is set, the Look and Feel will usually give the user a
+   * TextField to input data to. This method returns the value the user
+   * inputs.
+   *
+   * @param message The message to display.
+   *
+   * @return The user selected value.
+   */
+  public static String showInputDialog(Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(null, null);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows a QUESTION_MESSAGE type input dialog. Since no
+   * selectionValues is set, the Look and Feel will usually give the user a
+   * TextField to input data to. The input component will be initialized with
+   * the initialSelectionValue. This method returns the value the user
+   * inputs.
+   *
+   * @param message The message to display.
+   * @param initialSelectionValue The initialSelectionValue.
+   *
+   * @return The user selected value.
+   */
+  public static String showInputDialog(Object message,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JDialog dialog = pane.createDialog(null, null);
+    dialog.pack();
+    dialog.show();
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message.
+   * The internal frame dialog will be placed in the first JDesktopPane
+   * ancestor of the given parentComponent. This method will return the value
+   * selected.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   *
+   * @return The value selected.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame, pane);
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * optionType and title. The internal frame dialog will be placed in the
+   * first JDesktopPane ancestor of the given parentComponent.  This method
+   * will return the selected value.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param optionType The option type.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType)
+  {
+    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * title, optionTypes and icon for the given message type. The internal
+   * confirmation dialog will be placed in the first  instance of
+   * JDesktopPane ancestor of the given parentComponent.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title of the dialog.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType, int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * title, option type, message type, and icon. The internal frame dialog
+   * will be placed in the first JDesktopPane ancestor  that is found in the
+   * given parentComponent. This method returns  the selected value.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType, int messageType,
+                                              Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message. The
+   * internal frame dialog will be placed in the first JDesktopPane ancestor
+   * of the given parent component. This method returns the value input by
+   * the user.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   *
+   * @return The user selected value.
+   */
+  public static String showInternalInputDialog(Component parentComponent,
+                                               Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    pane.setWantsInput(true);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame, pane);
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message,  title
+   * and message type. The internal input dialog will be placed in the first
+   * JDesktopPane ancestor found in the given parent component. This method
+   * will return the input value given by the user.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   *
+   * @return The user input value.
+   */
+  public static String showInternalInputDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message, title
+   * message type, icon, selection value list and initial selection value.
+   * The internal frame dialog will be placed in the first JDesktopPane
+   * ancestor found in the given parent component. This method returns the
+   * input value from the user.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   * @param selectionValues The selection value list.
+   * @param initialSelectionValue The initial selection value.
+   *
+   * @return The user input value.
+   */
+  public static Object showInternalInputDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType, Icon icon,
+                                               Object[] selectionValues,
+                                               Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    pane.setIcon(icon);
+    pane.setSelectionValues(selectionValues);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message. The
+   * internal frame dialog will be placed in the first JDesktopPane ancestor
+   * found in the given parent component.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame, pane);
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message,
+   * title and message type. The internal message dialog is placed in the
+   * first JDesktopPane ancestor found in the given parent component.
+   *
+   * @param parentComponent The parent component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message,
+   * title, message type and icon. The internal message dialog is placed in
+   * the first JDesktopPane ancestor found in the given parent component.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType, Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setIcon(icon);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+  }
+
+  /**
+   * This method displays an internal option dialog with the given message,
+   * title, option type, message type, icon, option list, and initial option
+   * value. The internal option dialog is placed in the first JDesktopPane
+   * ancestor found in the parent component. This method returns the option
+   * selected.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message displayed.
+   * @param title The title displayed.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   * @param options The array of options.
+   * @param initialValue The initial value selected.
+   *
+   * @return The option that was selected.
+   */
+  public static int showInternalOptionDialog(Component parentComponent,
+                                             Object message, String title,
+                                             int optionType, int messageType,
+                                             Icon icon, Object[] options,
+                                             Object initialValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
+                                       options, initialValue);
+
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame, pane);
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method shows an INFORMATION_MESSAGE type message dialog.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.pack();
+    dialog.show();
+  }
+
+  /**
+   * This method shows a message dialog with the given message, title and
+   * messageType.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+  }
+
+  /**
+   * This method shows a message dialog with the given message, title,
+   * messageType and icon.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType, Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setIcon(icon);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+  }
+
+  /**
+   * This method shows an option dialog with the given message, title,
+   * optionType, messageType, icon, options and initialValue. This method
+   * returns the option that was selected.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   * @param options The options to choose from.
+   * @param initialValue The initial value.
+   *
+   * @return The selected option.
+   */
+  public static int showOptionDialog(Component parentComponent,
+                                     Object message, String title,
+                                     int optionType, int messageType,
+                                     Icon icon, Object[] options,
+                                     Object initialValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
+                                       options, initialValue);
+
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.pack();
+    dialog.show();
+
+    return ((Integer) pane.getValue()).intValue();
+  }
+
+  /**
+   * This method resets the UI to the Look and Feel default.
+   */
+  public void updateUI()
+  {
+    setUI((OptionPaneUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns true if the key is a valid messageType.
+   *
+   * @param key The key to check.
+   *
+   * @return True if key is valid.
+   */
+  private boolean validMessageType(int key)
+  {
+    switch (key)
+      {
+      case ERROR_MESSAGE:
+      case INFORMATION_MESSAGE:
+      case PLAIN_MESSAGE:
+      case QUESTION_MESSAGE:
+      case WARNING_MESSAGE:
+	return true;
+      }
+    return false;
+  }
+
+  /**
+   * This method returns true if the key is a valid optionType.
+   *
+   * @param key The key to check.
+   *
+   * @return True if key is valid.
+   */
+  private boolean validOptionType(int key)
+  {
+    switch (key)
+      {
+      case DEFAULT_OPTION:
+      case OK_CANCEL_OPTION:
+      case YES_NO_CANCEL_OPTION:
+      case YES_NO_OPTION:
+	return true;
+      }
+    return false;
+  }
+
+  /**
+   * This helper method makes the JInternalFrame wait until it is notified by
+   * an InternalFrameClosing event. This method also adds the given
+   * JOptionPane to the JInternalFrame and sizes it according to the
+   * JInternalFrame's preferred size.
+   *
+   * @param f The JInternalFrame to make modal.
+   * @param pane The JOptionPane to add to the JInternalFrame.
+   */
+  private static void startModal(JInternalFrame f, JOptionPane pane)
+  {
+    f.getContentPane().add(pane);
+    f.pack();
+    f.show();
+
+    Dimension pref = f.getPreferredSize();
+    f.setBounds(0, 0, pref.width, pref.height);
+
+    synchronized (f)
+      {
+	final JInternalFrame tmp = f;
+	tmp.toFront();
 
-    // everybody comes here eventually
-    public static int showOptionDialog(Component frame,
-				String msg, 
-				String title, 
-				int opt_type, 
-				int msg_type,
-				Icon icon, 
-				Object[] opts, 
-				Object init)
-    {
-	Integer a = (Integer) DoShowOptionDialog(frame,
-						 msg, 
-						 title, 
-						 opt_type, 
-						 msg_type,
-						 icon, 
-						 opts, 
-						 init);
-	if (a == null)
-	    return -1;
-	return a.intValue();
-    }
-    
-    public static Object DoShowOptionDialog(Component frame,
-				   String msg, 
-				   String title, 
-				   int opt_type, 
-				   int msg_type,
-				   Icon icon, 
-				   Object[] opts, 
-				   Object init)
-    {
-	
-	JOptionPane p = new JOptionPane(msg,
-					msg_type,
-					opt_type,
-					icon,
-					opts,
-					init);
-	System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ " + p.msg);
-
-	
-	JDialog a;
-
-	if (frame == null)
-	    {
-		a = new JDialog((Frame)frame,
-				title,
-				true);
-	    }
-	else if (frame instanceof Dialog)
+	f.addInternalFrameListener(new InternalFrameAdapter()
 	    {
-		a = new JDialog((Dialog) frame,
-				title,
-				true);
-	    }
-	else if (frame instanceof Frame)
-	    {
-		a = new JDialog((Frame) frame,
-				title,
-				true);
-	    }
-	else
-	    {
-		System.out.println("HUUUUHHH, not a frame or dialog !");
-		
-		a = new JDialog((Frame)null,
-				title,
-				true);
-	    }
-
-	p.dialog = a;
-	
-	a.getContentPane().setLayout(new BorderLayout());
-	a.getContentPane().add(p,
-			       BorderLayout.CENTER);
-	// package the deal
-	a.pack();
-	
-	a.setVisible(true);
-	
-	Object s = p.getValue();
-
-	System.out.println("RESULT FROM DIALOG = " + s);
-
-	if (s == null)
-	    return null;
-	
-	return s;
-    }
-
+	      public void internalFrameClosed(InternalFrameEvent e)
+	      {
+		synchronized (tmp)
+		  {
+		    tmp.removeInternalFrameListener(this);
+		    tmp.notifyAll();
+		  }
+	      }
+	    });
+	try
+	  {
+	    while (! f.isClosed())
+	      f.wait();
+	  }
+	catch (InterruptedException ignored)
+	  {
+	  }
+      }
+  }
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: javax/swing/JPanel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JPanel.java,v
retrieving revision 1.3
diff -u -r1.3 JPanel.java
--- javax/swing/JPanel.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JPanel.java	6 Sep 2004 16:35:57 -0000
@@ -85,7 +85,7 @@
     } 
 
     public String getUIClassID()
-    {	return "JPanel";    }
+    {	return "PanelUI";    }
 
 
     public void setUI(PanelUI ui) {
Index: javax/swing/JPasswordField.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JPasswordField.java,v
retrieving revision 1.3
diff -u -r1.3 JPasswordField.java
--- javax/swing/JPasswordField.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JPasswordField.java	6 Sep 2004 16:35:57 -0000
@@ -49,60 +49,36 @@
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public class JPasswordField extends JTextField {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJPasswordField
-	 */
-	protected class AccessibleJPasswordField extends AccessibleJTextField {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJPasswordField
-		 * @param component TODO
-		 */
-		protected AccessibleJPasswordField(JPasswordField component) {
-			super(component);
-			// TODO
-		} // AccessibleJPasswordField()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.PASSWORD_TEXT;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJPasswordField
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+public class JPasswordField extends JTextField
+{
+  /**
+   * AccessibleJPasswordField
+   */
+  protected class AccessibleJPasswordField extends AccessibleJTextField
+  {
+    private static final long serialVersionUID = -8477039424200681086L;
+
+    /**
+     * Constructor AccessibleJPasswordField
+     */
+    protected AccessibleJPasswordField()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PASSWORD_TEXT;
+    }
+  }
 
 	/**
 	 * uiClassID
 	 */
-	private static final String uiClassID = "PasswordFIeldUI";
+	private static final String uiClassID = "PasswordFieldUI";
 
 	/**
 	 * echoChar.  Default is 0
@@ -254,16 +230,15 @@
 		return null; // TODO
 	} // paramString()
 
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJPasswordField(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JPasswordField
+  /**
+   * getAccessibleContext
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJPasswordField();
+
+    return accessibleContext;
+  }
+}
Index: javax/swing/JPopupMenu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JPopupMenu.java,v
retrieving revision 1.3
diff -u -r1.3 JPopupMenu.java
--- javax/swing/JPopupMenu.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JPopupMenu.java	6 Sep 2004 16:35:57 -0000
@@ -1,4 +1,4 @@
-/* JPopupMenu.java --
+/* JPopupMenu.java
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -37,639 +37,1059 @@
 
 package javax.swing;
 
+import java.awt.BorderLayout;
 import java.awt.Component;
+import java.awt.Container;
 import java.awt.Dimension;
+import java.awt.Frame;
 import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
 import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Panel;
+import java.awt.Point;
+import java.awt.Window;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.EventListener;
+import java.util.Vector;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
+import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
 import javax.swing.plaf.PopupMenuUI;
 
+
 /**
- * JPopupMenu
- * @author	Andrew Selkirk
- * @version	1.0
+ * JPopupMenu is a container that is used to display popup menu's menu
+ * items. By default JPopupMenu is a lightweight container, however if it
+ * is the case that JPopupMenu's bounds are outside of main window, then
+ * heawyweight container will be used to display menu items. It is also
+ * possible to change JPopupMenu's default  behavior and set JPopupMenu
+ * to always use heavyweight container.
+ *
+ * JPopupMenu can be displayed anywhere; it is a floating free popup menu.
+ * However before JPopupMenu is diplayed, its invoker property should be set.
+ * JPopupMenu's invoker is a component relative to which popup menu is
+ * displayed.
+ *
+ * JPopupMenu fires PopupMenuEvents to its registered listeners. Whenever
+ * JPopupMenu becomes visible on the screen then PopupMenuEvent indicating
+ * that popup menu became visible will be fired. In the case when
+ * JPopupMenu becomes invisible or cancelled without selection, then
+ * popupMenuBecomeInvisible() or popupMenuCancelled() methods of
+ * PopupMenuListeners will be invoked.
+ *
+ * JPopupMenu also fires PropertyChangeEvents when its bound properties 
+ * change.In addittion to inheritted bound properties, JPopupMenu has 
+ * 'visible' bound property. When JPopupMenu becomes visible/invisible on
+ * the screen it fires PropertyChangeEvents to its registered 
+ * PropertyChangeListeners.
  */
 public class JPopupMenu extends JComponent implements Accessible, MenuElement
 {
+  private static final long serialVersionUID = -8336996630009646009L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Separator
-	 */
-	public static class Separator extends JSeparator {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor Separator
-		 */
-		public Separator() {
-			// TODO
-		} // Separator()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getUIClassID
-		 * @returns String
-		 */
-		public String getUIClassID() {
-			return null; // TODO
-		} // getUIClassID()
-
-
-	} // Separator
-
-	/**
-	 * AccessibleJPopupMenu
-	 */
-	protected class AccessibleJPopupMenu extends AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJPopupMenu
-		 * @param component TODO
-		 */
-		protected AccessibleJPopupMenu(JPopupMenu component) {
-			super(component);
-			// TODO
-		} // AccessibleJPopupMenu()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.POPUP_MENU;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJPopupMenu
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "PopupMenuUI";
-
-	/**
-	 * invoker
-	 */
-	transient Component invoker;
-
-	/**
-	 * desiredLocationX
-	 */
-	private int desiredLocationX;
-
-	/**
-	 * desiredLocationY
-	 */
-	private int desiredLocationY;
-
-	/**
-	 * label
-	 */
-	private String label;
-
-	/**
-	 * paintBorder
-	 */
-	private boolean paintBorder;
-
-	/**
-	 * margin
-	 */
-	private Insets margin;
-
-	/**
-	 * defaultLWPopupEnabledKey
-	 */
-	private static final Object defaultLWPopupEnabledKey = null; // TODO
-
-	/**
-	 * lightWeightPopupEnabled
-	 */
-	private boolean lightWeightPopupEnabled;
-
-	/**
-	 * selectionModel
-	 */
-	private SingleSelectionModel selectionModel;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JPopupMenu
-	 */
-	public JPopupMenu() {
-		// TODO
-	} // JPopupMenu()
-
-	/**
-	 * Constructor JPopupMenu
-	 * @param label TODO
-	 */
-	public JPopupMenu(String label) {
-		// TODO
-	} // JPopupMenu()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * readObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 * @exception ClassNotFoundException TODO
-	 */
-	private void readObject(ObjectInputStream stream) 
-			throws IOException, ClassNotFoundException {
-		// TODO
-	} // readObject()
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * add
-	 * @param item TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(JMenuItem item) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param text TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(String text) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * add
-	 * @param action TODO
-	 * @returns JMenuItem
-	 */
-	public JMenuItem add(Action action) {
-		return null; // TODO
-	} // add()
-
-	/**
-	 * remove
-	 * @param index TODO
-	 */
-	public void remove(int index) {
-		// TODO
-	} // remove()
-
-	/**
-	 * insert
-	 * @param action TODO
-	 * @param index TODO
-	 */
-	public void insert(Action action, int index) {
-		// TODO
-	} // insert()
-
-	/**
-	 * insert
-	 * @param component TODO
-	 * @param index TODO
-	 */
-	public void insert(Component component, int index) {
-		// TODO
-	} // insert()
-
-	/**
-	 * paintBorder
-	 * @param graphics TODO
-	 */
-	protected void paintBorder(Graphics graphics) {
-		// TODO
-	} // paintBorder()
-
-	/**
-	 * getDefaultLightWeightPopupEnabled
-	 * @returns boolean
-	 */
-	public static boolean getDefaultLightWeightPopupEnabled() {
-		return false; // TODO
-	} // getDefaultLightWeightPopupEnabled()
-
-	/**
-	 * setDefaultLightWeightPopupEnabled
-	 * @param enabled TODO
-	 */
-	public static void setDefaultLightWeightPopupEnabled(boolean enabled) {
-		// TODO
-	} // setDefaultLightWeightPopupEnabled()
-
-	/**
-	 * getUI
-	 * @returns PopupMenuUI
-	 */
-	public PopupMenuUI getUI() {
-		return (PopupMenuUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(PopupMenuUI ui) {
-		super.setUI(ui);
-		// TODO
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((PopupMenuUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getSelectionModel
-	 * @returns SingleSelectionModel
-	 */
-	public SingleSelectionModel getSelectionModel() {
-		return null; // TODO
-	} // getSelectionModel()
-
-	/**
-	 * setSelectionModel
-	 * @param model TODO
-	 */
-	public void setSelectionModel(SingleSelectionModel model) {
-		// TODO
-	} // setSelectionModel()
-
-	/**
-	 * createActionComponent
-	 * @param action TODO
-	 * @returns JMenuItem
-	 */
-	protected JMenuItem createActionComponent(Action action) {
-		return null; // TODO
-	} // createActionComponent()
-
-	/**
-	 * createActionChangeListener
-	 * @param item TODO
-	 * @returns PropertyChangeListener
-	 */
-	protected PropertyChangeListener createActionChangeListener(JMenuItem item) {
-		return null; // TODO
-	} // createActionChangeListener()
-
-	/**
-	 * isLightWeightPopupEnabled
-	 * @returns boolean
-	 */
-	public boolean isLightWeightPopupEnabled() {
-		return false; // TODO
-	} // isLightWeightPopupEnabled()
-
-	/**
-	 * setLightWeightPopupEnabled
-	 * @param enabled TODO
-	 */
-	public void setLightWeightPopupEnabled(boolean enabled) {
-		// TODO
-	} // setLightWeightPopupEnabled()
-
-	/**
-	 * getLabel
-	 * @returns String
-	 */
-	public String getLabel() {
-		return null; // TODO
-	} // getLabel()
-
-	/**
-	 * setLabel
-	 * @param label TODO
-	 */
-	public void setLabel(String label) {
-		// TODO
-	} // setLabel()
-
-	/**
-	 * addSeparator
-	 */
-	public void addSeparator() {
-		// TODO
-	} // addSeparator()
-
-	/**
-	 * addPopupMenuListener
-	 * @param listener TODO
-	 */
-	public void addPopupMenuListener(PopupMenuListener listener) {
-		// TODO
-	} // addPopupMenuListener()
-
-	/**
-	 * removePopupMenuListener
-	 * @param listener TODO
-	 */
-	public void removePopupMenuListener(PopupMenuListener listener) {
-		// TODO
-	} // removePopupMenuListener()
-
-	/**
-	 * firePopupMenuWillBecomeVisible
-	 */
-	protected void firePopupMenuWillBecomeVisible() {
-		// TODO
-	} // firePopupMenuWillBecomeVisible()
-
-	/**
-	 * firePopupMenuWillBecomeInvisible
-	 */
-	protected void firePopupMenuWillBecomeInvisible() {
-		// TODO
-	} // firePopupMenuWillBecomeInvisible()
-
-	/**
-	 * firePopupMenuCanceled
-	 */
-	protected void firePopupMenuCanceled() {
-		// TODO
-	} // firePopupMenuCanceled()
-
-	/**
-	 * pack
-	 */
-	public void pack() {
-		// TODO
-	} // pack()
-
-	/**
-	 * isVisible
-	 * @returns boolean
-	 */
-	public boolean isVisible() {
-		return false; // TODO
-	} // isVisible()
-
-	/**
-	 * setVisible
-	 * @param visible TODO
-	 */
-	public void setVisible(boolean visible) {
-		// TODO
-	} // setVisible()
-
-	/**
-	 * setLocation
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	public void setLocation(int x, int y) {
-		// TODO
-	} // setLocation()
-
-	/**
-	 * isPopupMenu
-	 * @returns boolean
-	 */
-	private boolean isPopupMenu() {
-		return false; // TODO
-	} // isPopupMenu()
-
-	/**
-	 * getInvoker
-	 * @returns Component
-	 */
-	public Component getInvoker() {
-		return null; // TODO
-	} // getInvoker()
-
-	/**
-	 * setInvoker
-	 * @param component TODO
-	 */
-	public void setInvoker(Component component) {
-		// TODO
-	} // setInvoker()
-
-	/**
-	 * show
-	 * @param component TODO
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	public void show(Component component, int x, int y) {
-		// TODO
-	} // show()
-
-	/**
-	 * getRootPopupMenu
-	 * @returns JPopupMenu
-	 */
-	JPopupMenu getRootPopupMenu() {
-		return null; // TODO
-	} // getRootPopupMenu()
-
-	/**
-	 * getComponentAtIndex
-	 * @param index TODO
-	 * @returns Component
-	 */
-	public Component getComponentAtIndex(int index) {
-		return null; // TODO
-	} // getComponentAtIndex()
-
-	/**
-	 * getComponentIndex
-	 * @param component TODO
-	 * @returns int
-	 */
-	public int getComponentIndex(Component component) {
-		return 0; // TODO
-	} // getComponentIndex()
-
-	/**
-	 * setPopupSize
-	 * @param size TODO
-	 */
-	public void setPopupSize(Dimension size) {
-		// TODO
-	} // setPopupSize()
-
-	/**
-	 * setPopupSize
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	public void setPopupSize(int x, int y) {
-		// TODO
-	} // setPopupSize()
-
-	/**
-	 * setSelected
-	 * @param selected TODO
-	 */
-	public void setSelected(Component selected) {
-		// TODO
-	} // setSelected()
-
-	/**
-	 * isBorderPainted
-	 * @returns boolean
-	 */
-	public boolean isBorderPainted() {
-		return false; // TODO
-	} // isBorderPainted()
-
-	/**
-	 * setBorderPainted
-	 * @param painted TODO
-	 */
-	public void setBorderPainted(boolean painted) {
-		// TODO
-	} // setBorderPainted()
-
-	/**
-	 * getMargin
-	 * @returns Insets
-	 */
-	public Insets getMargin() {
-		return null; // TODO
-	} // getMargin()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * processMouseEvent
-	 * @param event TODO
-	 * @param path TODO
-	 * @param manager TODO
-	 */
-	public void processMouseEvent(MouseEvent event, MenuElement[] path,
-			MenuSelectionManager manager) {
-		// TODO
-	} // processMouseEvent()
-
-	/**
-	 * processKeyEvent
-	 * @param event TODO
-	 * @param path TODO
-	 * @param manager TODO
-	 */
-	public void processKeyEvent(KeyEvent event, MenuElement[] path,
-			MenuSelectionManager manager) {
-		// TODO
-	} // processKeyEvent()
-
-	/**
-	 * menuSelectionChanged
-	 * @param changed TODO
-	 */
-	public void menuSelectionChanged(boolean changed) {
-		// TODO
-	} // menuSelectionChanged()
-
-	/**
-	 * getSubElements
-	 * @returns MenuElement[]
-	 */
-	public MenuElement[] getSubElements() {
-		return null; // TODO
-	} // getSubElements()
-
-	/**
-	 * getComponent
-	 * @returns Component
-	 */
-	public Component getComponent() {
-		return null; // TODO
-	} // getComponent()
-
-	/**
-	 * isPopupTrigger
-	 * @param event TODO
-	 * @returns boolean
-	 */
-	public boolean isPopupTrigger(MouseEvent event) {
-		return false; // TODO
-	} // isPopupTrigger()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJPopupMenu(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
+  /** name for the UI delegate for this menuItem. */
+  private static final String uiClassID = "PopupMenuUI";
 
+  /** Fire a PropertyChangeEvent when the "borderPainted" property changes. */
+  public static final String LABEL_CHANGED_PROPERTY = "label";
 
-} // JPopupMenu
+  /* indicates if popup's menu border should be painted*/
+  private boolean borderPainted = true;
+
+  /** Flag indicating whether lightweight, mediumweight or heavyweight popup
+     is used to display menu items.
+
+     These are the possible cases:
+
+     1. if DefaultLightWeightPopupEnabled true
+         (i)  use lightweight container if popup feets inside top-level window
+         (ii) only use heavyweight container (JWindow) if popup doesn't fit.
+
+     2. if DefaultLightWeightPopupEnabled false
+         (i) if popup fits, use awt.Panel (mediumWeight)
+         (ii) if popup doesn't fit, use JWindow (heavyWeight)
+  */
+  private static boolean DefaultLightWeightPopupEnabled = true;
+
+  /* Component that invokes popup menu. */
+  transient Component invoker;
+
+  /* Label for this popup menu. It is not used in most of the look and feel themes. */
+  private String label;
+
+  /*Amount of space between menuItem's in JPopupMenu and JPopupMenu's border */
+  private Insets margin;
+
+  /** Indicates whether ligthWeight container can be used to display popup
+     menu. This flag is the same as DefaultLightWeightPopupEnabled, but setting
+     this flag can change popup menu after creation of the object */
+  private boolean lightWeightPopupEnabled;
+
+  /** SelectionModel that keeps track of menu selection. */
+  private SingleSelectionModel selectionModel;
+
+  /* Popup that is used to display JPopupMenu */
+  private transient Popup popup;
+
+  /* Location of the popup */
+  private Point popupLocation;
+
+  /* Field indicating if popup menu is visible or not */
+  private boolean visible = false;
+  
+  /* Bound Property indicating visibility of the popup menu*/
+  public static final String VISIBLE_CHANGED_PROPERTY = "visible";
+
+  /**
+   * Creates a new JPopupMenu object.
+   */
+  public JPopupMenu()
+  {
+    updateUI();
+
+    lightWeightPopupEnabled = DefaultLightWeightPopupEnabled;
+    selectionModel = new DefaultSingleSelectionModel();
+    super.setVisible(false);
+  }
+
+  /**
+   * Creates a new JPopupMenu with specified label
+   *
+   * @param label Label for popup menu.
+   */
+  public JPopupMenu(String label)
+  {
+    setLabel(label);
+  }
+
+  private void readObject(ObjectInputStream stream)
+                   throws IOException, ClassNotFoundException
+  {
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * Adds given menu item to the popup menu
+   *
+   * @param item menu item to add to the popup menu
+   *
+   * @return menu item that was added to the popup menu
+   */
+  public JMenuItem add(JMenuItem item)
+  {
+    this.insert(item, -1);
+    return item;
+  }
+
+  /**
+   * Constructs menu item with a specified label and adds it to
+   * popup menu
+   *
+   * @param text label for the menu item to be added
+   *
+   * @return constructed menu item that was added to the popup menu
+   */
+  public JMenuItem add(String text)
+  {
+    JMenuItem item = new JMenuItem(text);
+    return add(item);
+  }
+
+  /**
+   * Constructs menu item associated with the specified action
+   * and adds it to the popup menu
+   *
+   * @param action Action for the new menu item
+   *
+   * @return menu item that was added to the menu
+   */
+  public JMenuItem add(Action action)
+  {
+    JMenuItem item = createActionComponent(action);
+
+    if (action != null)
+      action.addPropertyChangeListener(createActionChangeListener(item));
+
+    return add(item);
+  }
+
+  /**
+   * Revomes component at the given index from the menu.
+   *
+   * @param index index of the component that will be removed in the menu
+   */
+  public void remove(int index)
+  {
+    super.remove(index);
+
+    GridBagConstraints constraints = new GridBagConstraints();
+    constraints.fill = GridBagConstraints.BOTH;
+    constraints.weightx = 100.0;
+    constraints.weighty = 100.0;
+
+    Component[] items = getComponents();
+    for (int i = index; i < items.length; i++)
+      {
+	constraints.gridy = i;
+	super.add(items[i], constraints, i);
+      }
+  }
+
+  /**
+   * Create menu item associated with the given action
+   * and inserts it into the popup menu at the specified index
+   *
+   * @param action Action for the new menu item
+   * @param index index in the popup menu at which to insert new menu item.
+   */
+  public void insert(Action action, int index)
+  {
+    JMenuItem item = new JMenuItem(action);
+    this.insert(item, index);
+  }
+
+  /**
+   * Insert given component to the popup menu at the
+   * specified index
+   *
+   * @param component Component to insert
+   * @param index Index at which to insert given component
+   */
+  public void insert(Component component, int index)
+  {
+    GridBagConstraints constraints = new GridBagConstraints();
+    constraints.fill = GridBagConstraints.BOTH;
+    constraints.weightx = 100.0;
+    constraints.weighty = 100.0;
+
+    if (index == -1)
+      index = getComponents().length;
+
+    constraints.gridy = index;
+    super.add(component, constraints, index);
+
+    // need to change constraints for the components that were moved by 1
+    // due to the insertion
+    if (index != -1)
+      {
+	Component[] items = getComponents();
+
+	for (int i = index + 1; i < items.length; i++)
+	  {
+	    constraints.gridy = i;
+	    super.add(items[i], constraints, i);
+	  }
+      }
+  }
+
+  /**
+   * Paints popup menu's border if borderPainted is true
+   *
+   * @param graphics graphics context used to paint this popup's menu border.
+   */
+  protected void borderPainted(Graphics graphics)
+  {
+    if (borderPainted)
+      getBorder().paintBorder(this, graphics, 0, 0, getSize(null).width,
+                              getSize(null).height);
+  }
+
+  /**
+   * Returns flag indicating if newly created JPopupMenu will use
+   * heavyweight or lightweight container to display its menu items
+   *
+   * @return true if JPopupMenu will use lightweight container to display
+   * menu items by default, and false otherwise.
+   */
+  public static boolean getDefaultLightWeightPopupEnabled()
+  {
+    return DefaultLightWeightPopupEnabled;
+  }
+
+  /**
+   * Sets whether JPopupMenu should use ligthWeight container to
+   * display it menu items by default
+   *
+   * @param enabled true if JPopupMenu should use lightweight container
+   * for displaying its menu items, and false otherwise.
+   */
+  public static void setDefaultLightWeightPopupEnabled(boolean enabled)
+  {
+    DefaultLightWeightPopupEnabled = enabled;
+  }
+
+  /**
+   * This method returns the UI used to display the JPopupMenu.
+   *
+   * @return The UI used to display the JPopupMenu.
+   */
+  public PopupMenuUI getUI()
+  {
+    return (PopupMenuUI) ui;
+  }
+
+  /**
+   * Set the "UI" property of the menu item, which is a look and feel class
+   * responsible for handling popupMenu's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(PopupMenuUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((PopupMenuUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "PopupMenuUI"
+   */
+  public String getUIClassID()
+  {
+    return "PopupMenuUI";
+  }
+
+  /**
+   * Returns selectionModel used by this popup menu to keep
+   * track of the selection.
+   *
+   * @return popup menu's selection model
+   */
+  public SingleSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Sets selection model for this popup menu
+   *
+   * @param model new selection model of this popup menu
+   */
+  public void setSelectionModel(SingleSelectionModel model)
+  {
+    if (selectionModel != model)
+      {
+	SingleSelectionModel oldModel = this.selectionModel;
+      }
+  }
+
+  /**
+   * Creates new menu item associated with a given action.
+   *
+   * @param action Action used to create new menu item
+   *
+   * @return new created menu item associated with a given action.
+   */
+  protected JMenuItem createActionComponent(Action action)
+  {
+    return new JMenuItem(action);
+  }
+
+  /**
+   * Creates PropertyChangeListener that listens to PropertyChangeEvents
+   * occuring in the Action associated with given menu item in this popup menu.
+   *
+   * @param item MenuItem
+   *
+   * @return The PropertyChangeListener
+   */
+  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
+  {
+    return new ActionChangeListener();
+  }
+
+  /**
+   * Returns true if this popup menu will display its menu item in
+   * a lightweight container and false otherwise.
+   *
+   * @return true if this popup menu will display its menu items
+   * in a lightweight container and false otherwise.
+   */
+  public boolean isLightWeightPopupEnabled()
+  {
+    return lightWeightPopupEnabled;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param enabled DOCUMENT ME!
+   */
+  public void setLightWeightPopupEnabled(boolean enabled)
+  {
+    lightWeightPopupEnabled = enabled;
+  }
+
+  /**
+   * Returns label for this popup menu
+   *
+   * @return label for this popup menu
+   */
+  public String getLabel()
+  {
+    return label;
+  }
+
+  /**
+   * Sets label for this popup menu. This method fires PropertyChangeEvent
+   * when the label property is changed. Please note that most
+   * of the Look & Feel will ignore this property.
+   *
+   * @param label label for this popup menu
+   */
+  public void setLabel(String label)
+  {
+    if (label != this.label)
+      {
+	String oldLabel = this.label;
+    this.label = label;
+	firePropertyChange(LABEL_CHANGED_PROPERTY, oldLabel, label);
+      }
+  }
+
+  /**
+   * Adds separator to this popup menu
+   */
+  public void addSeparator()
+  {
+    // insert separator at the end of the list of menu items    
+    this.insert(new Separator(), -1);
+  }
+
+  /**
+   * Adds popupMenuListener to listen for PopupMenuEvents fired
+   * by the JPopupMenu
+   *
+   * @param listener PopupMenuListener to add to JPopupMenu
+   */
+  public void addPopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.add(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Removes PopupMenuListener from JPopupMenu's list of listeners
+   *
+   * @param listener PopupMenuListener which needs to be removed
+   */
+  public void removePopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.remove(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Returns array of PopupMenuListeners that are listening to JPopupMenu
+   *
+   * @return Array of PopupMenuListeners that are listening to JPopupMenu
+   */
+  public PopupMenuListener[] getPopupMenuListeners()
+  {
+    return ((PopupMenuListener[]) listenerList.getListeners(PopupMenuListener.class));
+  }
+
+  /**
+   * This method calls popupMenuWillBecomeVisible() of popup menu's
+   * PopupMenuListeners. This method is invoked just before popup menu
+   * will appear on the screen.
+   */
+  protected void firePopupMenuWillBecomeVisible()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuWillBecomeVisible(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This method calls popupMenuWillBecomeInvisible() of popup
+   * menu's PopupMenuListeners. This method is invoked just before popup
+   * menu will disappear from the screen
+   */
+  protected void firePopupMenuWillBecomeInvisible()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuWillBecomeInvisible(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This method calls popupMenuCanceled() of popup menu's PopupMenuListeners.
+   * This method is invoked just before popup menu is cancelled. This happens
+   * when popup menu is closed without selecting any of its menu items. This
+   * usually happens when the top-level window is resized or moved.
+   */
+  protected void firePopupMenuCanceled()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuCanceled(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This methods sets popup menu's size to its' preferred size. If the
+   * popup menu's size is previously set it will be ignored.
+   */
+  public void pack()
+  {
+    super.setSize(null);
+  }
+
+  /**
+   * Return visibility of the popup menu
+   *
+   * @return true if popup menu is visible on the screen and false otherwise.
+   */
+  public boolean isVisible()
+  {
+    return visible;
+  }
+
+  /**
+   * Sets visibility property of this popup menu. If the property is
+   * set to true then popup menu will be dispayed and popup menu will
+   * hide itself if visible property is set to false.
+   *
+   * @param visible true if popup menu will become visible and false otherwise.
+   */
+  public void setVisible(boolean visible)
+  {
+    boolean old = isVisible();
+    this.visible = visible;
+    if (old != isVisible())
+      {
+	firePropertyChange(VISIBLE_CHANGED_PROPERTY, old, (boolean) isVisible());
+	if (visible)
+	  {
+	    firePopupMenuWillBecomeVisible();
+	    Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
+
+	    boolean fit = true;
+	    Dimension size;
+
+	    // Determine the size of the popup menu
+	    if (this.getSize().width == 0 && this.getSize().width == 0)
+	      size = this.getPreferredSize();
+	    else
+	      size = this.getSize();
+
+	    if ((size.width > (rootContainer.getWidth() - popupLocation.x))
+	        || (size.height > (rootContainer.getHeight() - popupLocation.y)))
+	      fit = false;
+	    if (lightWeightPopupEnabled && fit)
+	      popup = new LightWeightPopup(this);
+	    else
+	      {
+		if (fit)
+		  popup = new MediumWeightPopup(this);
+		else
+		  popup = new HeavyWeightPopup(this);
+	      }
+	    if (popup instanceof LightWeightPopup
+	        || popup instanceof MediumWeightPopup)
+	      {
+		JLayeredPane layeredPane;
+		layeredPane = SwingUtilities.getRootPane(invoker)
+		                            .getLayeredPane();
+		Point p = new Point(popupLocation.x, popupLocation.y);
+		SwingUtilities.convertPointFromScreen(p, layeredPane);
+		popup.show(p.x, p.y, size.width, size.height);  
+	      }
+	    else
+	      {
+		// Subtract insets of the top-level container if popup menu's
+		// top-left corner is inside it.
+		    Insets insets = rootContainer.getInsets();
+		    popup.show(popupLocation.x - insets.left,
+		               popupLocation.y - insets.top, size.width,
+		               size.height);
+		  }
+	  }
+	else
+	  {
+	    firePopupMenuWillBecomeInvisible();
+	    popup.hide();
+	  }
+      }
+  }
+
+  /**
+   * Sets location of the popup menu.
+   *
+   * @param x X coordinate of the popup menu's location
+   * @param y Y coordinate of the popup menu's location
+   */
+  public void setLocation(int x, int y)
+  {
+    if (popupLocation == null)
+      popupLocation = new Point();
+
+    popupLocation.x = x;
+    popupLocation.y = y;
+  }
+
+  /**
+   * Returns popup menu's invoker.
+   *
+   * @return popup menu's invoker
+   */
+  public Component getInvoker()
+  {
+    return invoker;
+  }
+
+  /**
+   * Sets popup menu's invoker.
+   *
+   * @param component The new invoker of this popup menu
+   */
+  public void setInvoker(Component component)
+  {
+    invoker = component;
+  }
+
+  /**
+   * This method displays JPopupMenu on the screen at the specified
+   * location. Note that x and y coordinates given to this method
+   * should be expressed in terms of the popup menus' invoker.
+   *
+   * @param component Invoker for this popup menu
+   * @param x x-coordinate of the popup menu relative to the specified invoker
+   * @param y y-coordiate of the popup menu relative to the specified invoker
+   */
+  public void show(Component component, int x, int y)
+  {
+    setInvoker(component);
+    Point p = new Point(x, y);
+    SwingUtilities.convertPointToScreen(p, component);
+    setLocation(p.x, p.y);
+    setVisible(true);
+  }
+
+  /**
+   * Returns component located at the specified index in the popup menu
+   *
+   * @param index index of the component to return
+   *
+   * @return component located at the specified index in the popup menu
+   *
+   * @deprecated Replaced by getComponent(int)
+   */
+  public Component getComponentAtIndex(int index)
+  {
+    return getComponent(index);
+  }
+
+  /**
+   * Returns index of the specified component in the popup menu
+   *
+   * @param component Component to look for
+   *
+   * @return index of the specified component in the popup menu
+   */
+  public int getComponentIndex(Component component)
+  {
+    Component[] items = getComponents();
+
+    for (int i = 0; i < items.length; i++)
+      {
+	if (items[i].equals(component))
+	  return i;
+      }
+
+    return -1;
+  }
+
+  /**
+   * Sets size of the popup
+   *
+   * @param size Dimensions representing new size of the popup menu
+   */
+  public void setPopupSize(Dimension size)
+  {
+    super.setSize(size);
+  }
+
+  /**
+   * Sets size of the popup menu
+   *
+   * @param width width for the new size
+   * @param height height for the new size
+   */
+  public void setPopupSize(int width, int height)
+  {
+    super.setSize(width, height);
+  }
+
+  /**
+   * Selects specified component in this popup menu.
+   *
+   * @param selected component to select
+   */
+  public void setSelected(Component selected)
+  {
+    int index = getComponentIndex(selected);
+    selectionModel.setSelectedIndex(index);
+  }
+
+  /**
+   * Checks if this popup menu paints its border.
+   *
+   * @return true if this popup menu paints its border and false otherwise.
+   */
+  public boolean isBorderPainted()
+  {
+    return borderPainted;
+  }
+
+  /**
+   * Sets if the border of the popup menu should be
+   * painter or not.
+   *
+   * @param painted true if the border should be painted and false otherwise
+   */
+  public void setBorderPainted(boolean painted)
+  {
+    borderPainted = painted;
+  }
+
+  /**
+   * Returns margin for this popup menu.
+   *
+   * @return margin for this popup menu.
+   */
+  public Insets getMargin()
+  {
+    return margin;
+  }
+
+  /**
+   * A string that describes this JPopupMenu. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenuItem
+   */
+  protected String paramString()
+  {
+    return "JPopupMenu";
+  }
+
+  /**
+  * Process mouse events forwarded from MenuSelectionManager. This method 
+  * doesn't do anything. It is here to conform to the MenuElement interface.
+  *
+  * @param event event forwarded from MenuSelectionManager
+  * @param path path to the menu element from which event was generated
+  * @param manager MenuSelectionManager for the current menu hierarchy
+  */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Empty Implementation. This method is needed for the implementation
+    // of MenuElement interface
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processKeyEvent(KeyEvent event, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    // Empty Implementation. This method is needed for the implementation
+    // of MenuElement interface
+  }
+
+  /**
+   * Method of MenuElement Interface. It is invoked when
+   * popupMenu's selection has changed
+   *
+   * @param changed true if this popupMenu is part of current menu
+   * hierarchy and false otherwise.
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    if (! changed)
+      setVisible(false);
+  }
+
+  /**
+   * Return subcomonents of this popup menu.
+   *
+   * @return Array containing menuItem's of belonging to this popup menu.
+   */
+  public MenuElement[] getSubElements()
+  {
+    Component[] items = getComponents();
+    MenuElement[] subElements = new MenuElement[items.length];
+
+    for (int i = 0; i < items.length; i++)
+      subElements[i] = (MenuElement) items[i];
+
+    return subElements;
+  }
+
+  /**
+   * Method of the MenuElement interface. Returns reference to itself.
+   *
+   * @return Returns reference to itself
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Checks if observing mouse event should trigger popup
+   * menu to show on the screen.
+   *
+   * @param event MouseEvent to check
+   *
+   * @return true if the observing mouse event is popup trigger and false otherwise
+   */
+  public boolean isPopupTrigger(MouseEvent event)
+  {
+    return ((PopupMenuUI) getUI()).isPopupTrigger(event);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJPopupMenu();
+
+    return accessibleContext;
+  }
+
+  /**
+   * This interface is used to display menu items of the JPopupMenu
+   */
+  private interface Popup
+  {
+    /**
+     * Displays container on the screen
+     *
+     * @param x x-coordinate of popup menu's location on the screen
+     * @param y y-coordinate of popup menu's location on the screen
+     * @param width width of the container that is used to display menu
+     * item's for popup menu
+     * @param height height of the container that is used to display menu
+     * item's for popup menu
+     */
+    void show(int x, int y, int width, int height);
+
+    /**
+     * Hides container used to display popup menu item's from the screen
+     */
+    void hide();
+  }
+
+  /**
+   * This class represents Popup menu that uses light weight container
+   * to display its contents.
+   */
+  private class LightWeightPopup extends Container implements Popup
+  {
+    /**
+     * Creates a new LightWeightPopup menu
+     *
+     * @param c Container containing menu items
+     */
+    private Component c;
+
+    public LightWeightPopup(Container c)
+    {
+      this.c = c;
+    }
+
+    /**
+     * Displayes lightweight container with menu items to the screen
+     *
+     * @param x x-coordinate of lightweight container on the screen
+     * @param y y-coordinate of lightweight container on the screen
+     * @param width width of the lightweight container
+     * @param height height of the lightweight container
+     */
+    public void show(int x, int y, int width, int height)
+    {
+      JLayeredPane layeredPane;
+      layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
+      c.setBounds(x, y, width, height);
+      layeredPane.add(c, JLayeredPane.POPUP_LAYER, 0);
+    }
+
+    /**
+     * Hides lightweight container from the screen
+     */
+    public void hide()
+    {
+      // FIXME: Right now the lightweight container is removed from JLayered
+      // pane. It is probably would be better in order to improve performance
+      // to make the container invisible instead of removing it everytime.
+      JLayeredPane layeredPane;
+      layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
+      int index = layeredPane.getIndexOf(c);
+      layeredPane.remove(index);
+    }
+  }
+
+  /**
+   * MediumWeightPopup is an AWT Panel with JPopupMenu's menu items.
+   * It is used to display JPopupMenu's menu items on the screen
+   */
+  private class MediumWeightPopup extends Panel implements Popup
+  {
+    /**
+     * Creates a new MediumWeightPopup object.
+     *
+     * @param c Container with JPopupMenu's menu items
+     */
+    public MediumWeightPopup(Container c)
+    {
+      this.add(c);
+    }
+
+    /**
+     * Displays AWT Panel with its components on the screen
+     *
+     * @param x x-coordinate of the upper-left corner of the panel's
+     * @param y y-coordinate of the upper-left corner of the panel's
+     * @param width width of the panel
+     * @param height height of the panel
+     */
+    public void show(int x, int y, int width, int height)
+    {
+      JLayeredPane layeredPane;
+      layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
+      layeredPane.add(this, JLayeredPane.POPUP_LAYER, 0);
+      this.setBounds(x, y, width, height);
+    }
+
+    /**
+     * Hides This panel from the screen
+     */
+    public void hide()
+    {
+      // FIXME: Right now the lightweight container is removed from JLayered
+      // pane. It is probably would be better in order to improve performance
+      // to make the container invisible instead of removing it everytime.
+      JLayeredPane layeredPane;
+      layeredPane = SwingUtilities.getRootPane(invoker).getLayeredPane();
+      int index = layeredPane.getIndexOf(this);
+      layeredPane.remove(index);
+    }
+  }
+
+  /**
+   * HeavyWeightPopup is JWindow that is used to display JPopupMenu menu item's
+   * on the screen
+   */
+  private class HeavyWeightPopup extends JWindow implements Popup
+  {
+    /**
+     * Creates a new HeavyWeightPopup object.
+     *
+     * @param c Container containing menu items
+     */
+    public HeavyWeightPopup(Container c)
+    {
+      this.setContentPane(c);
+    }
+
+    /**
+     * Displays JWindow container JPopupMenu's menu items to the screen
+     *
+     * @param x x-coordinate of JWindow containing menu items
+     * @param y y-coordinate of JWindow containing menu items
+     * @param width width of the JWindow
+     * @param height height of the JWindow
+     */
+    public void show(int x, int y, int width, int height)
+    {
+      this.setBounds(x, y, width, height);
+      this.show();
+    }
+
+    /**
+     * Hides JWindow with menu item's from the screen.
+     */
+    public void hide()
+    {
+      super.hide();
+    }
+  }
+
+  /**
+   * This is the separator that can be used in popup menu.
+   */
+  public static class Separator extends JSeparator
+  {
+    public Separator()
+    {
+    }
+
+    public String getUIClassID()
+    {
+      return "PopupMenuSeparatorUI";
+    }
+  }
+
+  protected class AccessibleJPopupMenu extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = 7423261328879849768L;
+
+    protected AccessibleJPopupMenu()
+    {
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.POPUP_MENU;
+    }
+  }
+
+  /* This class resizes popup menu and repaints popup menu appropriately if one
+   of item's action has changed */
+  protected class ActionChangeListener implements PropertyChangeListener
+  {
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      JPopupMenu.this.revalidate();
+      JPopupMenu.this.repaint();
+    }
+  }
+}
Index: javax/swing/JProgressBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JProgressBar.java,v
retrieving revision 1.3
diff -u -r1.3 JProgressBar.java
--- javax/swing/JProgressBar.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/JProgressBar.java	6 Sep 2004 16:35:58 -0000
@@ -38,8 +38,7 @@
 package javax.swing;
 
 import java.awt.Graphics;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
+
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
@@ -49,440 +48,624 @@
 import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ProgressBarUI;
 
+
 /**
- * JProgressBar
- * @author	Andrew Selkirk
- * @version	1.0
+ * <p>
+ * The ProgressBar is a widget that displays in two modes. In 
+ * determinate mode, it displays fills a percentage of its bar
+ * based on its current value. In indeterminate mode, it creates
+ * box and bounces it between its bounds.
+ * </p>
+ *
+ * <p>
+ * JProgressBars have the following properties:
+ * </p>
+ * 
+ * <table>
+ * <tr><th> Property         </td><th> Stored in   </td><th> Bound? </td></tr>
+ * <tr><td> borderPainted    </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> changeListeners  </td><td> progressBar </td><td> no     </td></tr>
+ * <tr><td> indeterminate    </td><td> progressBar </td><td> yes    </td></tr> 
+ * <tr><td> maximum          </td><td> model       </td><td> no     </td></tr>
+ * <tr><td> minimum          </td><td> model       </td><td> no     </td></tr>
+ * <tr><td> model            </td><td> progressBar </td><td> no     </td></tr> 
+ * <tr><td> orientation      </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> percentComplete  </td><td> progressBar </td><td> no     </td></tr>
+ * <tr><td> string           </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> stringPainted    </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> value            </td><td> model       </td><td> no     </td></tr>
+ * </table>
  */
-public class JProgressBar extends JComponent implements SwingConstants, Accessible
+public class JProgressBar extends JComponent implements SwingConstants,
+                                                        Accessible
 {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-
-	/**
-	 * AccessibleJProgressBar
-	 */
-	protected class AccessibleJProgressBar extends AccessibleJComponent 
-			implements AccessibleValue {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJProgressBar
-		 * @param component TODO
-		 */
-		protected AccessibleJProgressBar(JProgressBar component) {
-			super(component);
-			// TODO
-		} // AccessibleJProgressBar()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.PROGRESS_BAR;
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleValue
-		 * @returns AccessibleValue
-		 */
-		public AccessibleValue getAccessibleValue() {
-			return null; // TODO
-		} // getAccessibleValue()
-
-		/**
-		 * getCurrentAccessibleValue
-		 * @returns Number
-		 */
-		public Number getCurrentAccessibleValue() {
-			return null; // TODO
-		} // getCurrentAccessibleValue()
-
-		/**
-		 * setCurrentAccessibleValue
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean setCurrentAccessibleValue(Number value0) {
-			return false; // TODO
-		} // setCurrentAccessibleValue()
-
-		/**
-		 * getMinimumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMinimumAccessibleValue() {
-			return null; // TODO
-		} // getMinimumAccessibleValue()
-
-		/**
-		 * getMaximumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMaximumAccessibleValue() {
-			return null; // TODO
-		} // getMaximumAccessibleValue()
-
-
-	} // AccessibleJProgressBar
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "ProgressBarUI";
-
-	/**
-	 * orientation
-	 */
-	protected int orientation;
-
-	/**
-	 * paintBorder
-	 */
-	protected boolean paintBorder;
-
-	/**
-	 * model
-	 */
-	protected BoundedRangeModel model;
-
-	/**
-	 * progressString
-	 */
-	protected String progressString;
-
-	/**
-	 * paintString
-	 */
-	protected boolean paintString;
-
-	/**
-	 * changeEvent
-	 */
-	protected transient ChangeEvent changeEvent;
-
-	/**
-	 * changeListener
-	 */
-	protected ChangeListener changeListener;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JProgressBar
-	 */
-	public JProgressBar() {
-		// TODO
-	} // JProgressBar()
-
-	/**
-	 * Constructor JProgressBar
-	 * @param orientation TODO
-	 */
-	public JProgressBar(int orientation) {
-		// TODO
-	} // JProgressBar()
-
-	/**
-	 * Constructor JProgressBar
-	 * @param minimum TODO
-	 * @param maximum TODO
-	 */
-	public JProgressBar(int minimum, int maximum) {
-		// TODO
-	} // JProgressBar()
-
-	/**
-	 * Constructor JProgressBar
-	 * @param minimum TODO
-	 * @param maximum TODO
-	 * @param orientation TODO
-	 */
-	public JProgressBar(int minimum, int maximum, int orientation) {
-		// TODO
-	} // JProgressBar()
-
-	/**
-	 * Constructor JProgressBar
-	 * @param model TODO
-	 */
-	public JProgressBar(BoundedRangeModel model) {
-		// TODO
-	} // JProgressBar()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getValue
-	 * @returns int
-	 */
-	public int getValue() {
-		return 0; // TODO
-	} // getValue()
-
-	/**
-	 * setValue
-	 * @param value TODO
-	 */
-	public void setValue(int value) {
-		// TODO
-	} // setValue()
-
-	/**
-	 * paintBorder
-	 * @param graphics TODO
-	 */
-	protected void paintBorder(Graphics graphics) {
-		// TODO
-	} // paintBorder()
-
-	/**
-	 * getOrientation
-	 * @returns int
-	 */
-	public int getOrientation() {
-		return 0; // TODO
-	} // getOrientation()
-
-	/**
-	 * setOrientation
-	 * @param orientation TODO
-	 */
-	public void setOrientation(int orientation) {
-		// TODO
-	} // setOrientation()
-
-	/**
-	 * isStringPainted
-	 * @returns boolean
-	 */
-	public boolean isStringPainted() {
-		return false; // TODO
-	} // isStringPainted()
-
-	/**
-	 * setStringPainted
-	 * @param painted TODO
-	 */
-	public void setStringPainted(boolean painted) {
-		// TODO
-	} // setStringPainted()
-
-	/**
-	 * getString
-	 * @returns String
-	 */
-	public String getString() {
-		return null; // TODO
-	} // getString()
-
-	/**
-	 * setString
-	 * @param string TODO
-	 */
-	public void setString(String string) {
-		// TODO
-	} // setString()
-
-	/**
-	 * getPercentComplete
-	 * @returns double
-	 */
-	public double getPercentComplete() {
-		return 0.0; // TODO
-	} // getPercentComplete()
-
-	/**
-	 * isBorderPainted
-	 * @returns boolean
-	 */
-	public boolean isBorderPainted() {
-		return false; // TODO
-	} // isBorderPainted()
-
-	/**
-	 * setBorderPainted
-	 * @param painted TODO
-	 */
-	public void setBorderPainted(boolean painted) {
-		// TODO
-	} // setBorderPainted()
-
-	/**
-	 * getUI
-	 * @returns ProgressBarUI
-	 */
-	public ProgressBarUI getUI() {
-		return (ProgressBarUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(ProgressBarUI ui) {
-		super.setUI(ui);
-		// TODO
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((ProgressBarUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * createChangeListener
-	 * @returns ChangeListener
-	 */
-	protected ChangeListener createChangeListener() {
-		return null; // TODO
-	} // createChangeListener()
-
-	/**
-	 * addChangeListener
-	 * @param listener TODO
-	 */
-	public void addChangeListener(ChangeListener listener) {
-		// TODO
-	} // addChangeListener()
-
-	/**
-	 * removeChangeListener
-	 * @param listener TODO
-	 */
-	public void removeChangeListener(ChangeListener valulistener) {
-		// TODO
-	} // removeChangeListener()
-
-	/**
-	 * fireStateChanged
-	 */
-	protected void fireStateChanged() {
-		// TODO
-	} // fireStateChanged()
-
-	/**
-	 * getModel
-	 * @returns BoundedRangeModel
-	 */
-	public BoundedRangeModel getModel() {
-		return null; // TODO
-	} // getModel()
-
-	/**
-	 * setModel
-	 * @param model TODO
-	 */
-	public void setModel(BoundedRangeModel model) {
-		// TODO
-	} // setModel()
-
-	/**
-	 * getMinimum
-	 * @returns int
-	 */
-	public int getMinimum() {
-		return 0; // TODO
-	} // getMinimum()
-
-	/**
-	 * setMinimum
-	 * @param minimum TODO
-	 */
-	public void setMinimum(int minimum) {
-		// TODO
-	} // setMinimum()
-
-	/**
-	 * getMaximum
-	 * @returns int
-	 */
-	public int getMaximum() {
-		return 0; // TODO
-	} // getMaximum()
-
-	/**
-	 * setMaximum
-	 * @param maximum TODO
-	 */
-	public void setMaximum(int maximum) {
-		// TODO
-	} // setMaximum()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJProgressBar(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JProgressBar
+  /**
+   * AccessibleJProgressBar
+   */
+  protected class AccessibleJProgressBar extends AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -2938130009392721813L;
+  
+    /**
+     * Constructor AccessibleJProgressBar
+     *
+     * @param component TODO
+     */
+    protected AccessibleJProgressBar()
+    {
+    } 
+
+    /**
+     * getAccessibleStateSet
+     *
+     * @return AccessibleStateSet
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null; 
+    } 
+
+    /**
+     * getAccessibleRole
+     *
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PROGRESS_BAR;
+    } 
+
+    /**
+     * getAccessibleValue
+     *
+     * @return AccessibleValue
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    } 
+
+    /**
+     * getCurrentAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    } 
+
+    /**
+     * setCurrentAccessibleValue
+     *
+     * @param value0 TODO
+     *
+     * @return boolean
+     */
+    public boolean setCurrentAccessibleValue(Number value0)
+    {
+      return false; 
+    } 
+
+    /**
+     * getMinimumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null; 
+    } 
+
+    /**
+     * getMaximumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null; 
+    } 
+  } 
+
+  private static final long serialVersionUID = 1980046021813598781L;
+  
+  /** Fired in a PropertyChangeEvent when the "borderPainted" property changes. */
+  public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
+  
+  /** Fired in a PropertyChangeEvent when the "orientation" property changes. */
+  public static final String ORIENTATION_CHANGED_PROPERTY = "orientation";
+  
+  /** Fired in a PropertyChangeEvent when the "string" property changes. */
+  public static final String STRING_CHANGED_PROPERTY = "string";
+  
+  /** Fired in a PropertyChangeEvent when the "stringPainted" property changes. */
+  public static final String STRING_PAINTED_CHANGED_PROPERTY = "stringPainted";
+  
+  /** Fired in a PropertyChangeEvent when the "indeterminate" property changes. */
+  public static final String INDETERMINATE_CHANGED_PROPERTY = "indeterminate";
+
+  /** Whether the ProgressBar is determinate. */
+  private transient boolean indeterminate = false;
+
+  /** The orientation of the ProgressBar */
+  protected int orientation = HORIZONTAL;
+
+  /** Whether borders should be painted. */
+  protected boolean paintBorder = true;
+
+  /** The model describing this ProgressBar. */
+  protected BoundedRangeModel model;
+
+  /** The string that is displayed by the ProgressBar. */
+  protected String progressString;
+
+  /** Whether the string should be painted. */
+  protected boolean paintString = false;
+
+  /** The static changeEvent passed to all ChangeListeners. */
+  protected transient ChangeEvent changeEvent;
+
+  /** The ChangeListener that listens to the model. */
+  protected ChangeListener changeListener;
+
+  /**
+   * Creates a new horizontally oriented JProgressBar object 
+   * with a minimum of 0 and a maximum of 100.
+   */
+  public JProgressBar()
+  {
+    this(0, 100, HORIZONTAL);
+  }
+
+  /**
+   * Creates a new JProgressBar object with a minimum of 0,
+   * a maximum of 100, and the given orientation.
+   *
+   * @param orientation The orientation of the JProgressBar.
+   */
+  public JProgressBar(int orientation)
+  {
+    this(0, 100, orientation);
+  }
+
+  /**
+   * Creates a new horizontally oriented JProgressBar object
+   * with the given minimum and maximum.
+   *
+   * @param minimum The minimum of the JProgressBar.
+   * @param maximum The maximum of the JProgressBar.
+   */
+  public JProgressBar(int minimum, int maximum)
+  {
+    this(minimum, maximum, HORIZONTAL);
+  }
+
+  /**
+   * Creates a new JProgressBar object with the given minimum,
+   * maximum, and orientation.
+   *
+   * @param minimum The minimum of the JProgressBar.
+   * @param maximum The maximum of the JProgressBar.
+   * @param orientation The orientation of the JProgressBar.
+   */
+  public JProgressBar(int minimum, int maximum, int orientation)
+  {
+    model = new DefaultBoundedRangeModel(minimum, 0, minimum, maximum);
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation + " is not a legal orientation");    
+    this.orientation = orientation;
+    changeListener = createChangeListener();
+    model.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * Creates a new horizontally oriented JProgressBar object 
+   * with the given model.
+   *
+   * @param model The model to be used with the JProgressBar.
+   */
+  public JProgressBar(BoundedRangeModel model)
+  {
+    this.model = model;
+    changeListener = createChangeListener();
+    model.addChangeListener(changeListener);
+    updateUI();    
+  }
+
+  /**
+   * This method returns the current value of the JProgressBar.
+   *
+   * @return The current value of the JProgressBar.
+   */
+  public int getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * This method sets the value of the JProgressBar.
+   *
+   * @param value The value of the JProgressBar.
+   */
+  public void setValue(int value)
+  {
+    model.setValue(value);
+  }
+
+  /**
+   * This method paints the border of the JProgressBar
+   *
+   * @param graphics The graphics object to paint with.
+   */
+  protected void paintBorder(Graphics graphics)
+  {
+    getBorder().paintBorder(this, graphics, 0, 0,
+                            getWidth(),
+                            getHeight());
+  }
+
+  /**
+   * This method returns the orientation of the JProgressBar.
+   *
+   * @return The orientation of the JProgressBar.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method changes the orientation property. The orientation of the 
+   * JProgressBar can be either horizontal or vertical.
+   *
+   * @param orientation The orientation of the JProgressBar.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != VERTICAL && orientation != HORIZONTAL)
+      throw new IllegalArgumentException("orientation must be one of VERTICAL or HORIZONTAL");
+    if (this.orientation != orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange(ORIENTATION_CHANGED_PROPERTY, oldOrientation,
+	                   this.orientation);
+      }
+  }
+
+  /**
+   * This method returns whether the progressString will be painted.
+   *
+   * @return Whether the string is painted.
+   */
+  public boolean isStringPainted()
+  {
+    return paintString;
+  }
+
+  /**
+   * This method changes the stringPainted property.
+   *
+   * @param painted Whether the string is painted.
+   */
+  public void setStringPainted(boolean painted)
+  {
+    if (paintString != painted)
+      {
+	boolean oldPainted = paintString;
+	paintString = painted;
+	firePropertyChange(STRING_PAINTED_CHANGED_PROPERTY, oldPainted,
+	                   paintString);
+      }
+  }
+
+  /**
+   * This method returns the string that is painted if the 
+   * stringPainted property is set to true. If there is no
+   * string set, it will return a string containing the 
+   * JProgressBar's value as a percent.
+   *
+   * @return The string that is painted.
+   */
+  public String getString()
+  {
+    if (progressString != null)
+      return progressString;
+    else
+      return (int) (getPercentComplete() * 100) + "%";
+  }
+
+  /**
+   * This method changes the string property. The string
+   * given will be the one painted. If you want to 
+   * revert to the default string given, set the
+   * string to null.
+   *
+   * @param string The string to be painted.
+   */
+  public void setString(String string)
+  {
+    if (((string == null || progressString == null) &&
+        string != progressString) || (string != null &&
+	! string.equals(progressString)))
+      {
+	String oldString = progressString;
+	progressString = string;
+	firePropertyChange(STRING_CHANGED_PROPERTY, oldString, progressString);
+      }
+  }
+
+  /**
+   * This method returns the percent of the bar
+   * that is "complete". (This is the amount value / (max - min)).
+   *
+   * @return DOCUMENT ME!
+   */
+  public double getPercentComplete()
+  {
+    if (getMaximum() == getMinimum())
+      return 1.0;
+    else
+      return (double) (model.getValue() - model.getMinimum()) / (model
+                                                                 .getMaximum()
+             - model.getMinimum());
+  }
+
+  /**
+   * This method returns whether the border is painted.
+   *
+   * @return Whether the border is painted.
+   */
+  public boolean isBorderPainted()
+  {
+    return paintBorder;
+  }
+
+  /**
+   * This method changes the borderPainted property.
+   *
+   * @param painted Whether the border is painted.
+   */
+  public void setBorderPainted(boolean painted)
+  {
+    if (painted != paintBorder)
+      {
+	boolean oldPainted = paintBorder;
+	paintBorder = painted;
+	firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, oldPainted,
+	                   paintBorder);
+      }
+  }
+
+  /**
+   * This method returns the JProgressBar's UI delegate.
+   *
+   * @return This JProgressBar's UI delegate.
+   */
+  public ProgressBarUI getUI()
+  {
+    return (ProgressBarUI) ui;
+  }
+
+  /**
+   * This method changes the UI property for this JProgressBar.
+   *
+   * @param ui The new UI delegate.
+   */
+  public void setUI(ProgressBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method reverts the UI delegate for this JProgressBar
+   * to the default for this Look and Feel.
+   */
+  public void updateUI()
+  {
+    setUI((ProgressBarUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns the identifier to allow the UIManager
+   * to pick the correct class to act as the UI for
+   * this JProgressBar.
+   *
+   * @return The UIClassID: "ProgressBarUI".
+   */
+  public String getUIClassID()
+  {
+    return "ProgressBarUI";
+  }
+
+  /**
+   * This method returns a ChangeListener that gets registered
+   * model. By default, the ChangeListener, propagates the 
+   * ChangeEvents to the ChangeListeners of the JProgressBar.
+   *
+   * @return A new ChangeListener.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ChangeListener()
+      {
+	public void stateChanged(ChangeEvent ce)
+	{
+	  fireStateChanged();
+	}
+      };
+  }
+
+  /**
+   * This method adds a ChangeListener to this JProgressBar.
+   *
+   * @param listener The ChangeListener to add to this JProgressBar.
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method removes a ChangeListener from this JProgressBar.
+   *
+   * @param listener The ChangeListener to remove from this JProgressBar.
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+  
+  /**
+   * This method returns an array of all ChangeListeners listening to this
+   * progress bar.
+   *
+   * @return An array of ChangeListeners listening to this progress bar.
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }  
+
+  /**
+   * This method is called when the JProgressBar receives a ChangeEvent
+   * from its model. This simply propagates the event (changing the source
+   * to the JProgressBar) to the JProgressBar's listeners.
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (changeListeners[i] == ChangeListener.class)
+	  ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * This method returns the model used with this JProgressBar.
+   *
+   * @return The model used with this JProgressBar.
+   */
+  public BoundedRangeModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * This method changes the model property for this JProgressBar.
+   *
+   * @param model The model to use with this JProgressBar.
+   */
+  public void setModel(BoundedRangeModel model)
+  {
+    if (model != this.model)
+      {
+        this.model.removeChangeListener(changeListener);
+	this.model = model;
+	this.model.addChangeListener(changeListener);
+	fireStateChanged();
+      }
+  }
+
+  /**
+   * This method returns the minimum value of this JProgressBar.
+   *
+   * @return The minimum value of this JProgressBar.
+   */
+  public int getMinimum()
+  {
+    return model.getMinimum();
+  }
+
+  /**
+   * This method sets the minimum value of this JProgressBar.
+   *
+   * @param minimum The minimum value of this JProgressBar.
+   */
+  public void setMinimum(int minimum)
+  {
+    model.setMinimum(minimum);
+  }
+
+  /**
+   * This method returns the maximum value of this JProgressBar.
+   *
+   * @return The maximum value of this JProgressBar.
+   */
+  public int getMaximum()
+  {
+    return model.getMaximum();
+  }
+
+  /**
+   * This method sets the maximum value of this JProgressBar.
+   *
+   * @param maximum The maximum value of this JProgressBar.
+   */
+  public void setMaximum(int maximum)
+  {
+    model.setMaximum(maximum);
+  }
+
+  /**
+   * This method returns a string that can be used to 
+   * describe this JProgressBar. This method is usually
+   * only used for debugging purposes.
+   *
+   * @return A string that describes this JProgressBar.
+   */
+  protected String paramString()
+  {
+    return "JProgressBar";
+  }
+
+  /**
+   * This method changes the indeterminate property. If the
+   * JProgressBar is determinate, it paints a percentage
+   * of the bar described by its value. If it is indeterminate,
+   * it simply bounces a box between the ends of the bar; the 
+   * value of the JProgressBar is ignored.
+   *
+   * @param newValue Whether the JProgressBar is indeterminate.
+   */
+  public void setIndeterminate(boolean newValue)
+  {
+    if (indeterminate != newValue)
+      {
+	boolean olddeter = indeterminate;
+	indeterminate = newValue;
+	firePropertyChange(INDETERMINATE_CHANGED_PROPERTY, olddeter,
+	                   indeterminate);
+      }
+  }
+
+  /**
+   * This method returns whether the JProgressBar is indeterminate.
+   *
+   * @return Whether this JProgressBar is indeterminate.
+   */
+  public boolean isIndeterminate()
+  {
+    return indeterminate;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJProgressBar();
+    
+    return accessibleContext;
+  } 
+}
Index: javax/swing/JRadioButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JRadioButton.java,v
retrieving revision 1.2
diff -u -r1.2 JRadioButton.java
--- javax/swing/JRadioButton.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JRadioButton.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
 /* JRadioButton.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,31 +42,49 @@
 
 public class JRadioButton extends JToggleButton
 {
-    public JRadioButton()
-    {
-	this(null, null);
-    }
-    public JRadioButton(Action a)
-    {
-	this();
-	setAction(a);
-    }
+  private static final long serialVersionUID = 7751949583255506856L;
 
-    public JRadioButton(Icon icon)
-    { 
-	this(null, icon);
-    }    
+  public JRadioButton()
+  {
+    this(null, null);
+  }
+    
+  public JRadioButton(Action a)
+  {
+    this();
+    setAction(a);
+  }
+
+  public JRadioButton(Icon icon)
+  { 
+    this(null, icon);
+  }    
   
-    public JRadioButton(String text)
-    {
-	this(text, null);
-    }
+  public JRadioButton(Icon icon, boolean selected)
+  { 
+    this(null, icon, selected);
+  }    
+  
+  public JRadioButton(String text)
+  {
+    this(text, null);
+  }
+
+  public JRadioButton(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
       
-    public JRadioButton(String text, Icon icon)
-    {
-	super(text, icon);
-    }
-
+  public JRadioButton(String text, Icon icon)
+  {
+    super(text, icon);
+    borderPainted = false;
+    contentAreaFilled = false;
+  }
+      
+  public JRadioButton(String text, Icon icon, boolean selected)
+  {
+  }
     
     public AccessibleContext getAccessibleContext()
     {
@@ -76,8 +94,9 @@
   
     public String getUIClassID()
     {
-	//Returns a string that specifies the name of the L&F class that renders this component.  
-	return "JRadioButton";
+	//Returns a string that specifies the name of the Look and Feel
+	//class that renders this component.  
+	return "RadioButtonUI";
     }
   
     protected  String paramString()
Index: javax/swing/JRadioButtonMenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JRadioButtonMenuItem.java,v
retrieving revision 1.3
diff -u -r1.3 JRadioButtonMenuItem.java
--- javax/swing/JRadioButtonMenuItem.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/JRadioButtonMenuItem.java	6 Sep 2004 16:35:58 -0000
@@ -42,183 +42,172 @@
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
 
 /**
- * JRadioButtonMenuItem
- * @author	Andrew Selkirk
- * @version	1.0
+ * This class represents JRadioButtonMenuItem. Its behaviour is very similar
+ * to JRadioButton. Just like JRadioButton, user can check and uncheck this
+ * menu item by clicking on it. JRadioButtonMenuItem uses ToggleButtonModel
+ * to keep track of its selection. If the JRadioButtonMenuItem is included in
+ * the button group, then only one JRadioButtonMenuItem can be selected at
+ * one time.
  */
 public class JRadioButtonMenuItem extends JMenuItem implements Accessible
 {
+  private static final long serialVersionUID = 8482658191548521743L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJRadioButtonMenuItem
-	 */
-	protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJRadioButtonMenuItem
-		 * @param component TODO
-		 */
-		protected AccessibleJRadioButtonMenuItem(JRadioButtonMenuItem component) {
-			super(component);
-			// TODO
-		} // AccessibleJRadioButtonMenuItem()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.RADIO_BUTTON;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJRadioButtonMenuItem
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "RadioButtonMenuItemUI";
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 */
-	public JRadioButtonMenuItem() {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param icon TODO
-	 */
-	public JRadioButtonMenuItem(Icon icon) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param text TODO
-	 */
-	public JRadioButtonMenuItem(String text) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param action TODO
-	 */
-	public JRadioButtonMenuItem(Action action) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param text TODO
-	 * @param icon TODO
-	 */
-	public JRadioButtonMenuItem(String text, Icon icon) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param text TODO
-	 * @param selected TODO
-	 */
-	public JRadioButtonMenuItem(String text, boolean selected) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param icon TODO
-	 * @param selected TODO
-	 */
-	public JRadioButtonMenuItem(Icon icon, boolean selected) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-	/**
-	 * Constructor JRadioButtonMenuItem
-	 * @param text TODO
-	 * @param icon TODO
-	 * @param selected TODO
-	 */
-	public JRadioButtonMenuItem(String text, Icon icon, boolean selected) {
-		// TODO
-	} // JRadioButtonMenuItem()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * requestFocus
-	 */
-	public void requestFocus() {
-		// TODO
-	} // requestFocus()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJRadioButtonMenuItem(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
+  /** name for the UI delegate for this radio button menu item. */
+  private static final String uiClassID = "RadioButtonMenuItemUI";
 
-} // JRadioButtonMenuItem
+  /**
+   * Creates a new JRadioButtonMenuItem object.
+   */
+  public JRadioButtonMenuItem()
+  {
+    this(null, null);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified icon
+   *
+   * @param icon Icon to be used for this menu item
+   */
+  public JRadioButtonMenuItem(Icon icon)
+  {
+    this(null, icon);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label
+   *
+   * @param text Label for this menu item
+   */
+  public JRadioButtonMenuItem(String text)
+  {
+    this(text, null);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem using specified action
+   *
+   * @param action Action for this menu item
+   */
+  public JRadioButtonMenuItem(Action action)
+  {
+    this();
+    setAction(action);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label and icon
+   *
+   * @param text Label for this menu item
+   * @param icon Icon for this menu item
+   */
+  public JRadioButtonMenuItem(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label
+   * and marked selected if 'selected' is true.
+   *
+   * @param text Text for this menu item
+   * @param selected Selected state of this menu item
+   */
+  public JRadioButtonMenuItem(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified icon
+   * and given selected state
+   *
+   * @param icon Icon for this menu item
+   * @param selected Selected state for this menu item
+   */
+  public JRadioButtonMenuItem(Icon icon, boolean selected)
+  {
+    this(null, icon, selected);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label,
+   * icon and selected state.
+   *
+   * @param text Label for this menu item
+   * @param icon Icon to be use for this menu item
+   * @param selected selected state of this menu item
+   */
+  public JRadioButtonMenuItem(String text, Icon icon, boolean selected)
+  {
+    super(text, icon);
+    setModel(new JToggleButton.ToggleButtonModel());
+    model.setSelected(selected);
+  }
+
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "JRadioButtonMenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * This method overrides JComponent.requestFocus with an empty
+   * implementation, since JRadioButtonMenuItems should not
+   * receve focus in general.
+   */
+  public void requestFocus()
+  {
+    //  Should do nothing here
+  }
+
+  /**
+   * A string that describes this JRadioButtonMenuItem. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JRadioButtonMenuItem
+   */
+  protected String paramString()
+  {
+    return "JRadioButtonMenuItem";
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJRadioButtonMenuItem();
+
+    return accessibleContext;
+  }
+
+  protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem
+  {
+    private static final long serialVersionUID = 4381471510145292179L;
+
+    /**
+     * Creates a new AccessibleJRadioButtonMenuItem object.
+     */
+    protected AccessibleJRadioButtonMenuItem()
+    {
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.RADIO_BUTTON;
+    }
+  }
+}
Index: javax/swing/JRootPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JRootPane.java,v
retrieving revision 1.3
diff -u -r1.3 JRootPane.java
--- javax/swing/JRootPane.java	22 Nov 2003 00:03:35 -0000	1.3
+++ javax/swing/JRootPane.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
 /* JRootPane.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.BorderLayout;
@@ -45,168 +44,498 @@
 import java.awt.LayoutManager;
 import java.awt.LayoutManager2;
 import java.io.Serializable;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.RootPaneUI;
 
 /**
- * This class is where JComponents are added to.
- * Unlike awt where you could just say frame.add(),
- * with swing you need to say frame.getRootPane() 
- * (which delivers an instance of this class)
- * and add your components to that.
- *
- * It is implemented by several 'layers' (pane() should be read as plane()) 
- * each on top of the others
- * where you can add components to. 
+ * This class is where JComponents are added to. Unlike awt where you could
+ * just say frame.add(), with swing you need to say frame.getRootPane()
+ * (which delivers an instance of this class) and add your components to
+ * that. It is implemented by several 'layers' (pane() should be read as
+ * plane()) each on top of the others where you can add components to.
  * (getContentPane(), getGlassPane(), getLayeredPane())
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
 public class JRootPane extends JComponent
 {
-    //  The class used to obtain the accessible role for this object.
-    static protected class AccessibleJRootPane
+  //  The class used to obtain the accessible role for this object.
+  protected static class AccessibleJRootPane
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 1082432482784468088L;
+
+    /**
+     * Creates a new <code>AccessibleJRootPane</code> object.
+     */
+    protected AccessibleJRootPane()
     {
     }
-  
-    //A custom layout manager  
-    static protected class RootLayout extends BorderLayout
-    {
-      public Dimension preferredLayoutSize ( Container c )
-	{	    
-	  Dimension p = super.preferredLayoutSize(c);
-	  System.out.println("              PREF-SIZE from RootLayout = " + p);
-	  return p;
-	}        
-    }
-  
-    /***********************************************************/
-
-  
-    //The glass pane that overlays the menu bar and content pane, so it can intercept mouse movements and such.
-    protected  Component glassPane;
-  
-    //The layered pane that manages the menu bar and content pane.
-    protected  JLayeredPane layeredPane;
-  
-    // The menu bar.
-    protected  JMenuBar menuBar;
-  
-    protected Container contentPane;
-
-    /********************************************************/
-
-    public String getUIClassID()
-    {	return "JPanel";    }
-
-    
-    void setJMenuBar(JMenuBar m)
-    {  menuBar = m; }
-
-    JMenuBar getJMenuBar()
-    {  return menuBar; }
-    
-
-    public Container getContentPane()
-    {
-	if (contentPane == null)
-	    {
-		setContentPane(createContentPane());
-	    }
-	return contentPane;
-    }
-
-    public void setContentPane(Container p)
-    {
-	contentPane = p;    
-	getLayeredPane().add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
-    }
-
-    protected void addImpl(Component comp,
-			  Object constraints,
-			  int index)
-    {
-	super.addImpl(comp, constraints, index);
-	//System.out.println("don't do that !");
-    } 
-
-    public Component getGlassPane() 
-    {
-	if (glassPane == null)
-	    setGlassPane(createGlassPane());
-	return glassPane;    
-    }
-
-    public void setGlassPane(Component f)
-    {
-	if (glassPane != null)
-	    remove(glassPane);
-
-	glassPane = f; 
-
-	glassPane.setVisible(false);
-	add(glassPane, 0);
-    }
 
-    public JLayeredPane getLayeredPane() 
-    {
-	if (layeredPane == null)
-	    setLayeredPane(createLayeredPane());
-	return layeredPane;    
-    }
-    public void setLayeredPane(JLayeredPane f)
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.ROOT_PANE;
+    }
+  }
+
+  // Custom Layout Manager for JRootPane. It positions contentPane and 
+  // menuBar withing its layeredPane.
+  protected class RootLayout implements LayoutManager2, Serializable
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -4100116998559815027L;
+
+    /**
+     * Creates a new <code>RootLayout</code> object.
+     */
+    protected RootLayout()
     {
-	if (layeredPane != null)
-	    remove(layeredPane);
-	
-	layeredPane = f; 
-	add(f, -1);
     }
     
+    /**
+     * DOCUMENT ME!
+     *
+     * @param comp DOCUMENT ME!
+     * @param constraints DOCUMENT ME!
+     */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     * @param comp DOCUMENT ME!
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float getLayoutAlignmentX(Container target)
+    {
+      return target.getAlignmentX();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float getLayoutAlignmentY(Container target)
+    {
+      return target.getAlignmentY();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     */
+    public void invalidateLayout(Container target)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void layoutContainer(Container c)
+    {
+      Dimension menuBarSize;
+      Dimension containerSize = c.getSize(null);
+      Dimension contentPaneSize = contentPane.getPreferredSize();
+
+      /*
+       if size of top-level window wasn't set then just set
+       contentPane and menuBar to its preferred sizes.
+       Otherwise, if the size of top-level window was specified then
+       set menuBar to its preferred size and make content pane
+       to fit into the remaining space
+
+
+       +-------------------------------+
+       |  JLayeredPane                 |
+       |  +--------------------------+ |
+       |  | menuBar                  | |
+       |  +--------------------------+ |
+       |  +--------------------------+ |
+       |  |contentPane               | |
+       |  |                          | |
+       |  |                          | |
+       |  |                          | |
+       |  +--------------------------+ |
+       +-------------------------------+
+
+      */
+      if (containerSize.width == 0 && containerSize.height == 0)
+        {
+	  if (menuBar != null)
+	    {
+	      int maxWidth;
+	      menuBarSize = menuBar.getPreferredSize();
+	      maxWidth = Math.max(menuBarSize.width, contentPaneSize.width);
+	      menuBar.setBounds(0, 0, maxWidth, menuBarSize.height);
+	      glassPane.setBounds(0, menuBarSize.height, maxWidth,
+	                          contentPaneSize.height);
+	      contentPane.setBounds(0, menuBarSize.height, maxWidth,
+	                            contentPaneSize.height);
+	      layeredPane.setSize(maxWidth,
+	                          menuBarSize.height + contentPaneSize.height);
+	    }
+	  else
+	    {
+	      glassPane.setBounds(0, 0, contentPaneSize.width,
+	                          contentPaneSize.height);
+	      contentPane.setBounds(0, 0, contentPaneSize.width,
+	                            contentPaneSize.height);
+	      layeredPane.setSize(contentPaneSize.width, contentPaneSize.height);
+	    }
+        }
+      else
+        {
+	  if (menuBar != null)
+	    {
+	      menuBarSize = menuBar.getPreferredSize();
+	      if (menuBarSize.height > containerSize.height)
+		menuBarSize.height = containerSize.height;
+	      menuBar.setBounds(0, 0, containerSize.width, menuBarSize.height);
+	      int remainingHeight = containerSize.height - menuBarSize.height;
+	      glassPane.setBounds(0, menuBarSize.height, containerSize.width,
+	                          containerSize.height - menuBarSize.height);
+	      contentPane.setBounds(0, menuBarSize.height,
+	                            containerSize.width,
+	                            (containerSize.height - menuBarSize.height));
+	    }
+	  else
+	    {
+	      glassPane.setBounds(0, 0, containerSize.width,
+	                          containerSize.height);
+	    contentPane.setBounds(0, 0, containerSize.width,
+	                          containerSize.height);
+	    }
 
-    /********************************************************/
-
-    JRootPane()
-    {
-	setLayout(createRootLayout());
-	
-	getGlassPane();
-	getLayeredPane();
-	getContentPane();
-
-	setDoubleBuffered(true);
-	updateUI();
-    }
-
-    protected LayoutManager createRootLayout() {
-        return new RootLayout();
-    } 
-
-    JComponent createContentPane()
-    {
-	JPanel p = new JPanel();
-	p.setName(this.getName()+".contentPane");
-	p.setLayout(new BorderLayout());
-	//	p.setVisible(true);
-
-	System.out.println("Created ContentPane: " + p);
-	return p;
-    }
-
-    Component createGlassPane()
-    {
-	JPanel p = new JPanel();
-	p.setName(this.getName()+".glassPane");
-	p.setLayout(new BorderLayout());
-	p.setVisible(false);
-	
-	System.out.println("created the glasspane: "+p);
-	return p;
+	  layeredPane.setSize(containerSize.width, containerSize.height);
+        }
     }
 
-    JLayeredPane createLayeredPane()
-    {
-	JLayeredPane l = new JLayeredPane();
-	return l;
-    }    
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension maximumLayoutSize(Container target)
+    {
+      return preferredLayoutSize(target);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension minimumLayoutSize(Container target)
+    {
+      return preferredLayoutSize(target);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension preferredLayoutSize(Container c)
+    {
+      Dimension menuBarSize;
+      Dimension prefSize;
+
+      Dimension containerSize = c.getSize();
+      Dimension contentPaneSize = contentPane.getPreferredSize();
+
+      if (containerSize.width == 0 && containerSize.height == 0)
+        {
+	  if (menuBar != null)
+	    {
+	      int maxWidth;
+	      menuBarSize = menuBar.getPreferredSize();
+	      maxWidth = Math.max(menuBarSize.width, contentPaneSize.width);
+	      prefSize = new Dimension(maxWidth,
+	                               contentPaneSize.height
+	                               + menuBarSize.height);
+	    }
+	  else
+	    prefSize = contentPaneSize;
+        }
+      else
+	prefSize = c.getSize();
+
+      return prefSize;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param comp DOCUMENT ME!
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+    }
+  }
+
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 8690748000348575668L;
+
+  /** DOCUMENT ME! */
+  protected Component glassPane;
+
+  /** DOCUMENT ME! */
+  protected JLayeredPane layeredPane;
+
+  /** DOCUMENT ME! */
+  protected JMenuBar menuBar;
+
+  /** DOCUMENT ME! */
+  protected Container contentPane;
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param m DOCUMENT ME!
+   */
+  public void setJMenuBar(JMenuBar m)
+  {
+    menuBar = m;
+    getLayeredPane().add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return menuBar;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Container getContentPane()
+  {
+    if (contentPane == null)
+      setContentPane(createContentPane());
+    return contentPane;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param p DOCUMENT ME!
+   */
+  public void setContentPane(Container p)
+  {
+    contentPane = p;
+    getLayeredPane().add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param comp DOCUMENT ME!
+   * @param constraints DOCUMENT ME!
+   * @param index DOCUMENT ME!
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    super.addImpl(comp, constraints, index);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Component getGlassPane()
+  {
+    if (glassPane == null)
+      setGlassPane(createGlassPane());
+    return glassPane;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param f DOCUMENT ME!
+   */
+  public void setGlassPane(Component f)
+  {
+    if (glassPane != null)
+      remove(glassPane);
+
+    glassPane = f;
+
+    glassPane.setVisible(false);
+    add(glassPane, 0);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    if (layeredPane == null)
+      setLayeredPane(createLayeredPane());
+    return layeredPane;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param f DOCUMENT ME!
+   */
+  public void setLayeredPane(JLayeredPane f)
+  {
+    if (layeredPane != null)
+      remove(layeredPane);
+
+    layeredPane = f;
+    add(f, -1);
+  }
+
+  /**
+   * Creates a new <code>JRootPane</code> object.
+   */
+  public JRootPane()
+  {
+    setLayout(createRootLayout());
+    getGlassPane();
+    getLayeredPane();
+    getContentPane();
+    setDoubleBuffered(true);
+    updateUI();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected LayoutManager createRootLayout()
+  {
+    return new RootLayout();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected JComponent createContentPane()
+  {
+    JPanel p = new JPanel();
+    p.setName(this.getName() + ".contentPane");
+    p.setLayout(new BorderLayout());
+    return p;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected Component createGlassPane()
+  {
+    JPanel p = new JPanel();
+    p.setName(this.getName() + ".glassPane");
+    p.setLayout(new BorderLayout());
+    p.setVisible(false);
+    p.setOpaque(false);
+    return p;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected JLayeredPane createLayeredPane()
+  {
+    JLayeredPane l = new JLayeredPane();
+    l.setLayout(null);
+    return l;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public RootPaneUI getUI()
+  {
+    return (RootPaneUI) ui;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param ui DOCUMENT ME!
+   */
+  public void setUI(RootPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void updateUI()
+  {
+    setUI((RootPaneUI) UIManager.getUI(this));
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public String getUIClassID()
+  {
+    return "RootPaneUI";
+  }
 }
Index: javax/swing/JScrollBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JScrollBar.java,v
retrieving revision 1.2
diff -u -r1.2 JScrollBar.java
--- javax/swing/JScrollBar.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JScrollBar.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
-/* JScrollBar.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JScrollBar.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,13 +35,701 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Adjustable;
+import java.awt.Dimension;
+import java.awt.event.AdjustmentEvent;
 import java.awt.event.AdjustmentListener;
+
 import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ScrollBarUI;
 
-public class JScrollBar extends JComponent
+
+/**
+ * The JScrollBar. Two buttons control how the values that the 
+ * scroll bar can take. You can also drag the thumb or click the track
+ * to move the scroll bar. Typically, the JScrollBar is used with
+ * other components to translate the value of the bar to the viewable
+ * contents of the other components.
+ */
+public class JScrollBar extends JComponent implements Adjustable, Accessible
 {
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJScrollBar extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -7758162392045586663L;
+    
+    /**
+     * Creates a new AccessibleJSlider object.
+     *
+     * @param value0 DOCUMENT ME!
+     */
+    protected AccessibleJScrollBar()
+    {
+      super();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * setCurrentAccessibleValue
+     *
+     * @param value0 TODO
+     *
+     * @return boolean
+     */
+    public boolean setCurrentAccessibleValue(Number value0)
+    {
+      return false;
+    }
+
+    /**
+     * getMinimumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * getMaximumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null;
+    }
+  }
+
+  private static final long serialVersionUID = -8195169869225066566L;
+  
+  /** Fired in a PropertyChangeEvent when the "blockIncrement" changes. */
+  public static final String BLOCK_INCREMENT_CHANGED_PROPERTY = "blockIncrement";
+
+  /** Fired in a PropertyChangeEvent when the "model" changes. */
+  public static final String MODEL_CHANGED_PROPERTY = "model";
+
+  /** Fired in a PropertyChangeEvent when the "orientation" changes. */
+  public static final String ORIENTATION_CHANGED_PROPERTY = "orientation";
+
+  /** Fired in a PropertyChangeEvent when the "unitIncrement" changes. */
+  public static final String UNIT_INCREMENT_CHANGED_PROPERTY = "unitIncrement";
+
+  /** How much the thumb moves when moving in a block. */
+  protected int blockIncrement = 10;
+
+  /** The model that holds the scroll bar's data. */
+  protected BoundedRangeModel model;
+
+  /** The orientation of the scroll bar. */
+  protected int orientation = SwingConstants.VERTICAL;
+
+  /** How much the thumb moves when moving in a unit. */
+  protected int unitIncrement = 1;
+
+  /** The ChangeListener that listens to the model. */
+  private transient ChangeListener changeListener;
+
+  /** The ChangeEvent that's fired. */
+  private transient ChangeEvent changeEvent;
+
+  /** 
+   * Creates a new horizontal JScrollBar object with a minimum
+   * of 0, a maxmium of 100, a value of 0 and an extent of 10.
+   */
+  public JScrollBar()
+  {
+    this(SwingConstants.VERTICAL, 0, 10, 0, 100);
+  }
+
+  /**
+   * Creates a new JScrollBar object with a minimum of 0, a 
+   * maximum of 100, a value of 0, an extent of 10 and the given
+   * orientation.
+   *
+   * @param orientation The orientation of the JScrollBar.
+   */
+  public JScrollBar(int orientation)
+  {
+    this(orientation, 0, 10, 0, 100);
+  }
+
+  /**
+   * Creates a new JScrollBar object with the given orientation, 
+   * value, min, max, and extent.
+   *
+   * @param orientation The orientation to use.
+   * @param value The value to use.
+   * @param extent The extent to use.
+   * @param min The minimum value of the scrollbar.
+   * @param max The maximum value of the scrollbar.
+   */
+  public JScrollBar(int orientation, int value, int extent, int min, int max)
+  {
+    model = new DefaultBoundedRangeModel(value, extent, min, max);
+    if (orientation != SwingConstants.HORIZONTAL
+        && orientation != SwingConstants.VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");
+    this.orientation = orientation;
+    changeListener = createChangeListener();
+    model.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * This method sets the UI of this scrollbar to
+   * the given UI.
+   *
+   * @param ui The UI to use with this scrollbar.
+   */
+  public void setUI(ScrollBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method returns the UI that is being used
+   * with this scrollbar.
+   *
+   * @return The scrollbar's current UI.
+   */
+  public ScrollBarUI getUI()
+  {
+    return (ScrollBarUI) ui;
+  }
+
+  /**
+   * This method changes the UI to be the
+   * default for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((ScrollBarUI) UIManager.getUI(this));
+    invalidate();
+    repaint();
+  }
+
+  /**
+   * This method returns an identifier to 
+   * choose the correct UI delegate for the
+   * scrollbar.
+   *
+   * @return The identifer to choose the UI delegate; "ScrollBarUI"
+   */
+  public String getUIClassID()
+  {
+    return "ScrollBarUI";
+  }
+
+  /**
+   * This method returns the orientation of the scrollbar.
+   *
+   * @return The orientation of the scrollbar.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method sets the orientation of the scrollbar.
+   *
+   * @param orientation The orientation of the scrollbar.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != SwingConstants.HORIZONTAL
+        && orientation != SwingConstants.VERTICAL)
+      throw new IllegalArgumentException("orientation must be one of HORIZONTAL or VERTICAL");
+    if (orientation != this.orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange(ORIENTATION_CHANGED_PROPERTY, oldOrientation,
+	                   this.orientation);
+      }
+  }
+
+  /**
+   * This method returns the model being used with 
+   * the scrollbar.
+   *
+   * @return The scrollbar's model.
+   */
+  public BoundedRangeModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * This method sets the model to use with
+   * the scrollbar.
+   *
+   * @param newModel The new model to use with the scrollbar.
+   */
+  public void setModel(BoundedRangeModel newModel)
+  {
+    if (model != newModel)
+      {
+	BoundedRangeModel oldModel = model;
+	model = newModel;
+	oldModel.removeChangeListener(changeListener);
+	model.addChangeListener(changeListener);
+	firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel, model);
+      }
+  }
+
+  /**
+   * This method returns how much the scrollbar's value
+   * should change for a unit increment depending on the 
+   * given direction.
+   *
+   * @param direction The direction to scroll in.
+   *
+   * @return The amount the scrollbar's value will change given the direction.
+   */
+  public int getUnitIncrement(int direction)
+  {
+    return direction * unitIncrement;
+  }
+
+  /**
+   * This method sets the unitIncrement property.
+   *
+   * @param unitIncrement The new unitIncrement.
+   */
+  public void setUnitIncrement(int unitIncrement)
+  {
+    if (unitIncrement != this.unitIncrement)
+      {
+	int oldInc = this.unitIncrement;
+	this.unitIncrement = unitIncrement;
+	firePropertyChange(UNIT_INCREMENT_CHANGED_PROPERTY, oldInc,
+	                   this.unitIncrement);
+      }
+  }
+
+  /**
+   * The method returns how much the scrollbar's value
+   * should change for a block increment depending on
+   * the given direction.
+   *
+   * @param direction The direction to scroll in.
+   *
+   * @return The amount the scrollbar's value will change given the direction.
+   */
+  public int getBlockIncrement(int direction)
+  {
+    return direction * blockIncrement;
+  }
+
+  /**
+   * This method sets the blockIncrement property.
+   *
+   * @param blockIncrement The new blockIncrement.
+   */
+  public void setBlockIncrement(int blockIncrement)
+  {
+    if (blockIncrement != this.blockIncrement)
+      {
+	int oldInc = this.blockIncrement;
+	this.blockIncrement = blockIncrement;
+	firePropertyChange(BLOCK_INCREMENT_CHANGED_PROPERTY, oldInc,
+	                   this.blockIncrement);
+      }
+  }
+
+  /**
+   * This method returns the unitIncrement.
+   *
+   * @return The unitIncrement.
+   */
+  public int getUnitIncrement()
+  {
+    return unitIncrement;
+  }
+
+  /**
+   * This method returns the blockIncrement.
+   *
+   * @return The blockIncrement.
+   */
+  public int getBlockIncrement()
+  {
+    return blockIncrement;
+  }
+
+  /**
+   * This method returns the value of the scrollbar.
+   *
+   * @return The value of the scrollbar.
+   */
+  public int getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * This method changes the value of the scrollbar.
+   *
+   * @param value The new value of the scrollbar.
+   */
+  public void setValue(int value)
+  {
+    if (isEnabled() && value != getValue())
+    {
+      model.setValue(value);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, value);
+    }
+  }
+
+  /**
+   * This method returns the visible amount (AKA extent). 
+   * The visible amount can be used by UI delegates to 
+   * determine the size of the thumb.
+   *
+   * @return The visible amount (AKA extent).
+   */
+  public int getVisibleAmount()
+  {
+    return model.getExtent();
+  }
+
+  /**
+   * This method sets the visible amount (AKA extent).
+   *
+   * @param extent The visible amount (AKA extent).
+   */
+  public void setVisibleAmount(int extent)
+  {
+    if (extent != getVisibleAmount())
+    {
+      model.setExtent(extent);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, extent);
+    }
+  }
+
+  /**
+   * This method returns the minimum value of the scrollbar.
+   *
+   * @return The minimum value of the scrollbar.
+   */
+  public int getMinimum()
+  {
+    return model.getMinimum();
+  }
+
+  /**
+   * This method sets the minimum value of the scrollbar.
+   *
+   * @param minimum The minimum value of the scrollbar.
+   */
+  public void setMinimum(int minimum)
+  {
+    if (minimum != getMinimum())
+    {
+      model.setMinimum(minimum);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, minimum);
+    }
+  }
+
+  /**
+   * This method returns the maximum value of the scrollbar.
+   *
+   * @return The maximum value of the scrollbar.
+   */
+  public int getMaximum()
+  {
+    return model.getMaximum();
+  }
+
+  /**
+   * This method sets the maximum value of the scrollbar.
+   *
+   * @param maximum The maximum value of the scrollbar.
+   */
+  public void setMaximum(int maximum)
+  {
+    if (maximum != getMaximum())
+    {
+      model.setMaximum(maximum);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, maximum);
+    }
+  }
+
+  /**
+   * This method returns the model's isAjusting value.
+   *
+   * @return The model's isAdjusting value.
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return model.getValueIsAdjusting();
+  }
+
+  /**
+   * This method sets the model's isAdjusting value.
+   *
+   * @param b The new isAdjusting value.
+   */
+  public void setValueIsAdjusting(boolean b)
+  {
+    model.setValueIsAdjusting(b);
+  }
+
+  /**
+   * This method sets the value, extent, minimum and 
+   * maximum.
+   *
+   * @param newValue The new value.
+   * @param newExtent The new extent.
+   * @param newMin The new minimum.
+   * @param newMax The new maximum.
+   */
+  public void setValue(int newValue, int newExtent, int newMin, int newMax)
+  {
+    if (!isEnabled())
+      newValue = model.getValue();
+    // It seems to be that on any change the value is fired.
+    if (newValue != getValue() || newExtent != getVisibleAmount() ||
+        newMin != getMinimum() || newMax != getMaximum())
+    {
+      model.setRangeProperties(newValue, newExtent, newMin, newMax,
+                               model.getValueIsAdjusting());
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, newValue);
+    }
+  }
+
+  /**
+   * This method creates a new ChangeListener.
+   *
+   * @return A new ChangeListener.
+   */
+  private ChangeListener createChangeListener()
+  {
+    return new ChangeListener()
+      {
+	public void stateChanged(ChangeEvent e)
+	{
+	  fireStateChanged();
+	}
+      };
+  }
+
+  /**
+   * This method is called whenever the model fires a ChangeEvent. It should
+   * propagate the ChangeEvent to its listeners with a new ChangeEvent that
+   * identifies the scroll bar as the source.
+   */
+  private void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (changeListeners[i] == ChangeListener.class)
+	  ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * This method adds a ChangeListener to the scroll bar.
+   *
+   * @param listener The listener to add.
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method removes a ChangeListener from the scroll bar.
+   *
+   * @param listener The listener to remove.
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method returns an array of all ChangeListeners listening to this
+   * scroll bar.
+   *
+   * @return An array of ChangeListeners listening to this scroll bar.
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * This method adds an AdjustmentListener to the scroll bar.
+   *
+   * @param listener The listener to add.
+   */
+  public void addAdjustmentListener(AdjustmentListener listener)
+  {
+    listenerList.add(AdjustmentListener.class, listener);
+  }
+
+  /**
+   * This method removes an AdjustmentListener from the scroll bar. 
+   *
+   * @param listener The listener to remove.
+   */
+  public void removeAdjustmentListener(AdjustmentListener listener)
+  {
+    listenerList.remove(AdjustmentListener.class, listener);
+  }
+
+  /**
+   * This method returns an arry of all AdjustmentListeners listening to 
+   * this scroll bar.
+   *
+   * @return An array of AdjustmentListeners listening to this scroll bar.
+   */
+  public AdjustmentListener[] getAdjustmentListeners()
+  {
+    return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class);
+  }
+
+  /**
+   * This method is called to fired AdjustmentEvents to the listeners
+   * of this scroll bar. All AdjustmentEvents that are fired
+   * will have an ID of ADJUSTMENT_VALUE_CHANGED and a type of
+   * TRACK. 
+   *
+   * @param id The ID of the adjustment event.
+   * @param type The Type of change.
+   * @param value The new value for the property that was changed..
+   */
+  protected void fireAdjustmentValueChanged(int id, int type, int value)
+  {
+    Object[] adjustmentListeners = listenerList.getListenerList();
+    AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, 
+                                            AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+					    AdjustmentEvent.TRACK,
+					    value);
+    for (int i = adjustmentListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (adjustmentListeners[i] == AdjustmentListener.class)
+	  ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent);
+      }
+  }
+
+  /**
+   * This method returns the minimum size for this scroll bar.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize()
+  {
+    return ui.getMinimumSize(this);
+  }
+
+  /**
+   * This method returns the maximum size for this scroll bar.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize()
+  {
+    return ui.getMaximumSize(this);
+  }
+
+  /**
+   * This method overrides the setEnabled in JComponent.
+   * When the scroll bar is disabled, the knob cannot
+   * be moved.
+   *
+   * @param x Whether the scrollbar is enabled.
+   */
+  public void setEnabled(boolean x)
+  {
+    // nothing special needs to be done here since we 
+    // just check the enabled setting before changing the value.
+    super.setEnabled(x);
+  }
+
+  /**
+   * A string that describes this JScrollBar. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JScrollBar.
+   */
+  protected String paramString()
+  {
+    return "JScrollBar";
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJScrollBar();
+    return accessibleContext;
+  }
 }
Index: javax/swing/JScrollPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JScrollPane.java,v
retrieving revision 1.2
diff -u -r1.2 JScrollPane.java
--- javax/swing/JScrollPane.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JScrollPane.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
 /* JScrollPane.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,96 +39,611 @@
 package javax.swing;
 
 import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Rectangle;
+
 import javax.accessibility.Accessible;
+import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ScrollPaneUI;
+import javax.swing.plaf.UIResource;
 
-public class JScrollPane extends JComponent implements Accessible, ScrollPaneConstants
+/**
+ * <table>
+ * <tr><th>Property                    </th><th>Stored in       </th><th>Bound?</th></tr>
+ * <tr><td>columnHeader                </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>columnHeaderView            </td><td>columnHeader    </td><td>no    </td></tr>
+ * <tr><td>componentOrientation        </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>horizontalScrollBar         </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>horizontalScrollBarPolicy   </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>layout                      </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>rowHeader                   </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>rowHeaderView               </td><td>rowHeader       </td><td>no    </td></tr>
+ * <tr><td>validateRoot                </td><td>scrollPane      </td><td>no    </td></tr>
+ * <tr><td>verticalScrollBar           </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>verticalScrollBarPolicy     </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewport                    </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewportBorder              </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewportBorderBounds        </td><td>scrollPane      </td><td>no    </td></tr>
+ * <tr><td>viewportView                </td><td>viewport        </td><td>no    </td></tr>
+ * <tr><td>wheelScrollingEnabled       </td><td>scrollPane      </td><td>yes   </td></tr>
+ * </table>
+ */
+public class JScrollPane 
+  extends JComponent 
+  implements Accessible, ScrollPaneConstants
 {
-    protected JViewport  columnHeader;
-    protected JViewport  rowHeader;
-
-    protected Component  lowerLeft;
-    protected Component  lowerRight;
-    protected Component  upperLeft;
-    protected Component  upperRight;
-
-    protected JScrollBar horizontalScrollBar;
-    protected int        horizontalScrollBarPolicy;
-    protected JScrollBar verticalScrollBar;
-    protected int        verticalScrollBarPolicy;
-
-    protected JViewport  viewport;
-
-
-    public JScrollPane() 
-    {
-	this(null, 0, 0);
-    }
+  private static final long serialVersionUID = 5203525440012340014L;
+  
+  protected JViewport columnHeader;
+  protected JViewport rowHeader;
+
+  protected Component lowerLeft;
+  protected Component lowerRight;
+  protected Component upperLeft;
+  protected Component upperRight;
+
+  protected JScrollBar horizontalScrollBar;
+  protected int horizontalScrollBarPolicy;
+  protected JScrollBar verticalScrollBar;
+  protected int verticalScrollBarPolicy;
+
+  protected JViewport viewport;
+  
+  Border viewportBorder;
+  boolean wheelScrollingEnabled;
+  ChangeListener scrollListener;  
+
+  public static final String COLUMN_HEADER_CHANGED_PROPERTY = "columnHeader";
+  public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY = "componentOrientation";
+  public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY = "horizontalScrollBar";
+  public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "horizontalScrollBarPolicy";
+  public static final String LAYOUT_CHANGED_PROPERTY = "layout";
+  public static final String ROW_HEADER_CHANGED_PROPERTY = "rowHeader";
+  public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY = "verticalScrollBar";
+  public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "verticalScrollBarPolicy";
+  public static final String VIEWPORT_CHANGED_PROPERTY = "viewport";
+  public static final String VIEWPORT_BORDER_CHANGED_PROPERTY = "viewportBorder";
+  public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY = "wheelScrollingEnabled";
+
+  public JViewport getColumnHeader()
+  {
+    return columnHeader;
+  }
+
+  public Component getCorner(String key) {
+    if (getComponentOrientation() 
+        == ComponentOrientation.LEFT_TO_RIGHT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_LEFT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+      }
+    else if (getComponentOrientation() 
+             == ComponentOrientation.RIGHT_TO_LEFT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_LEFT_CORNER;
+      }
+
+    if (key == LOWER_RIGHT_CORNER)
+      return lowerRight;
+    else if (key == UPPER_RIGHT_CORNER)
+      return upperRight;
+    else if (key == LOWER_LEFT_CORNER)
+      return lowerLeft;
+    else if (key == UPPER_LEFT_CORNER)
+      return upperLeft;
+    return null;
+  }
+
+  public JScrollBar getHorizontalScrollBar()
+  {
+    return horizontalScrollBar;
+  }
+
+  public int getHorizontalScrollBarPolicy()
+  {
+    return horizontalScrollBarPolicy;
+  }
+
+  public JViewport getRowHeader()
+  {
+    return rowHeader;
+  }
+
+  public JScrollBar getVerticalScrollBar()
+  {
+    return verticalScrollBar;
+  }
+
+  public int getVerticalScrollBarPolicy()
+  {
+    return verticalScrollBarPolicy;
+  }
+
+  public JViewport getViewport()
+  {
+    return viewport;
+  }
+
+  public Border getViewportBorder()
+  {
+    return viewportBorder;
+  }
+
+  public Rectangle getViewportBorderBounds()
+  {
+    if (viewportBorder == null)
+      {
+        if (getViewport() == null)
+          return new Rectangle(0,0,0,0);
+        else
+          return getViewport().getBounds();
+      }
+    else
+      {
+        Insets i = viewportBorder.getBorderInsets(getViewport());
+        if (getViewport() == null)
+          return new Rectangle(0,0,
+                               i.left+i.right, i.top+i.bottom);
+        else
+          {
+            Rectangle b = getViewport().getBounds();
+            return new Rectangle(b.x - i.left, 
+                                 b.y - i.top,
+                                 b.width + i.left + i.right, 
+                                 b.height + i.top + i.bottom);
+          }
+      }
+  }
+  
+  public boolean isWheelScrollingEnabled()
+  {
+    return wheelScrollingEnabled;
+  }
+
+
+
+  private void sync()
+  {
+    LayoutManager m = super.getLayout();
+    if (m != null && m instanceof ScrollPaneLayout)
+      {
+        ScrollPaneLayout sl = (ScrollPaneLayout) m;
+        sl.syncWithScrollPane(this);
+      }
+  }
+
+  private void removeNonNull(Component c)
+  {
+    if (c != null)
+      remove(c);
+  }
+
+  private void addNonNull(Component c)
+  {
+    if (c != null)
+      add(c);
+  }
+
+  public void setComponentOrientation(ComponentOrientation co)
+  {
+    ComponentOrientation old = super.getComponentOrientation();
+    super.setComponentOrientation(co);
+    firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY, old, co);
+    sync();
+  }
+
+  public void setColumnHeader(JViewport h)
+  {
+    JViewport old = columnHeader;
+    removeNonNull(old);
+    columnHeader = h;
+    addNonNull(h);
+    firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY, old, h);
+    sync();
+  }
+
+  public void setColumnHeaderView(Component c)
+  {
+    if (columnHeader == null)
+      setColumnHeader(createViewport());
+    columnHeader.setView(c);
+    sync();
+  }
+
+  public void setCorner(String key, Component c)
+  {
+    if (getComponentOrientation() 
+        == ComponentOrientation.LEFT_TO_RIGHT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_LEFT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+      }
+    else if (getComponentOrientation() 
+             == ComponentOrientation.RIGHT_TO_LEFT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_LEFT_CORNER;
+      }
+
+    if (key == LOWER_RIGHT_CORNER)
+      {
+        removeNonNull(lowerRight);
+        lowerRight = c;
+        addNonNull(c);
+      }
+    else if (key == UPPER_RIGHT_CORNER)
+      {
+        removeNonNull(upperRight);
+        upperRight = c;
+        addNonNull(c);
+      }
+    else if (key == LOWER_LEFT_CORNER)
+      {
+        removeNonNull(lowerLeft);
+        lowerLeft = c;
+        addNonNull(c);
+      }
+    else if (key == UPPER_LEFT_CORNER)
+      {
+        removeNonNull(upperLeft);
+        upperLeft = c;
+        addNonNull(c);
+      }
+    else
+      throw new IllegalArgumentException("unknown corner " + key);
+    sync();
+  }
+
+  public void setHorizontalScrollBar(JScrollBar h)
+  {
+    JScrollBar old = horizontalScrollBar;
+    removeNonNull(old);
+    horizontalScrollBar = h;
+    addNonNull(h);
+    firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY, old, h);
+    sync();
+
+    if (old != null)
+      {
+        BoundedRangeModel model = old.getModel();
+        if (model != null)
+          model.removeChangeListener(scrollListener);
+      }
+    if (h != null)
+      {
+        BoundedRangeModel model = h.getModel();
+        if (model != null)
+          model.addChangeListener(scrollListener);
+      }
+  }
+
+  public void setHorizontalScrollBarPolicy(int h)
+  {    
+    if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
+        && h != HORIZONTAL_SCROLLBAR_NEVER
+        && h != HORIZONTAL_SCROLLBAR_ALWAYS)
+      throw new IllegalArgumentException("unknown horizontal scrollbar policy");    
+    int old = horizontalScrollBarPolicy;
+    horizontalScrollBarPolicy = h;
+    firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, h);
+    sync();
+  }
+
+  public void setLayout(LayoutManager l)
+  {
+    LayoutManager old = super.getLayout();
+    ScrollPaneLayout tmp = (ScrollPaneLayout) l;
+    super.setLayout(l);
+    tmp.syncWithScrollPane(this);
+    firePropertyChange(LAYOUT_CHANGED_PROPERTY, old, l);
+    sync();
+  }
+
+  public void setRowHeader(JViewport v)
+  {
+    JViewport old = rowHeader;
+    removeNonNull(old);
+    rowHeader = v;
+    addNonNull(v);
+    firePropertyChange(ROW_HEADER_CHANGED_PROPERTY, old, v);
+    sync();
+  }
+
+  public void setRowHeaderView(Component c)
+  {
+    if (rowHeader == null)
+      setRowHeader(createViewport());
+    rowHeader.setView(c);
+    sync();
+  }
+
+  public void setVerticalScrollBar(JScrollBar v)
+  {
+    JScrollBar old = verticalScrollBar;
+    removeNonNull(old);
+    verticalScrollBar = v;
+    addNonNull(v);
+    firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY, old, v);
+    sync();
+
+    if (old != null)
+      {
+        BoundedRangeModel model = old.getModel();
+        if (model != null)
+          model.removeChangeListener(scrollListener);
+      }
+    if (v != null)
+      {
+        BoundedRangeModel model = v.getModel();
+        if (model != null)
+          model.addChangeListener(scrollListener);
+      }
+  }
+
+  public void setVerticalScrollBarPolicy(int v)
+  {
+    if (v != VERTICAL_SCROLLBAR_AS_NEEDED
+        && v != VERTICAL_SCROLLBAR_NEVER
+        && v != VERTICAL_SCROLLBAR_ALWAYS)
+      throw new IllegalArgumentException("unknown vertical scrollbar policy");    
+    int old = verticalScrollBarPolicy;
+    verticalScrollBarPolicy = v;
+    firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, v);
+    sync();
+  }
+
+  public void setWheelScrollingEnabled(boolean b)
+  {
+    boolean old = wheelScrollingEnabled;
+    wheelScrollingEnabled = b;
+    firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY, old, b);
+    sync();
+  }
+
+  public void setViewport(JViewport v)
+  {
+    JViewport old = viewport;
+    removeNonNull(old);
+    if (old != null)
+      old.removeChangeListener(scrollListener);
+    viewport = v;
+    if (v != null)
+      v.addChangeListener(scrollListener);
+    addNonNull(v);
+    revalidate();
+    repaint();
+    firePropertyChange(VIEWPORT_CHANGED_PROPERTY, old, v);
+    sync();
+  }
+
+  public void setViewportBorder(Border b)
+  {
+    Border old = viewportBorder;
+    viewportBorder = b;
+    firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY, old, b);
+    sync();
+  }
     
-    public JScrollPane(Component view) 
-    {
-	this(view, 0, 0);
-    }
+  public void setViewportView(Component view)
+  {
+    if (getViewport() == null)
+      {
+        setViewport(createViewport());
+      }
+	
+    if (view != null)
+      {
+        getViewport().setView(view);
+      }
+    sync();
+  }
+
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  ChangeListener createScrollListener()
+  {
+    return new ChangeListener() 
+      {
+        
+        public void stateChanged(ChangeEvent event)
+        {
+          JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
+          JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
+          JViewport vp = JScrollPane.this.getViewport();
+
+          if (vp != null && event.getSource() == vp)
+            {
+              // if the viewport changed, we should update the VSB / HSB
+              // models according to the new vertical and horizontal sizes
+
+              Rectangle vr = vp.getViewRect();
+              Dimension vs = vp.getViewSize();
+              if (vsb != null
+                  && (vsb.getMinimum() != 0
+                      || vsb.getMaximum() != vs.height
+                      || vsb.getValue() != vr.y
+                      || vsb.getVisibleAmount() != vr.height))
+                  vsb.setValue(vr.y, vr.height, 0, vs.height);
+
+              if (hsb != null
+                  && (hsb.getMinimum() != 0
+                      || hsb.getMaximum() != vs.width
+                      || hsb.getValue() != vr.width
+                      || hsb.getVisibleAmount() != vr.height))
+                hsb.setValue(vr.x, vr.width, 0, vs.width);
+            }
+          else
+            {
+              // otherwise we got a change update from either the VSB or
+              // HSB model, and we need to update the viewport positions of
+              // both the main viewport and any row or column headers to
+              // match.
+
+              int xpos = 0;
+              int ypos = 0;
+              
+              if (vsb != null)
+                ypos = vsb.getValue();
+              
+              if (hsb != null)
+                xpos = hsb.getValue();
+
+              Point pt = new Point(xpos, ypos);
+
+              if (vp != null
+                  && vp.getViewPosition() != pt)
+                vp.setViewPosition(pt);
+
+              pt.x = 0;
+
+              if (rowHeader != null 
+                  && rowHeader.getViewPosition() != pt)
+                rowHeader.setViewPosition(pt);
+              
+              pt.x = xpos;
+              pt.y = 0;
+
+              if (columnHeader != null 
+                  && columnHeader.getViewPosition() != pt)
+                columnHeader.setViewPosition(pt);
+
+            }
+        }
+      };
+  }
+
+
+  public JScrollPane() 
+  {
+    this(null);
+  }
     
+  public JScrollPane(Component view) 
+  {
+    this(view, 
+         VERTICAL_SCROLLBAR_AS_NEEDED, 
+         HORIZONTAL_SCROLLBAR_AS_NEEDED);
+  }
+
+  public JScrollPane(int vsbPolicy, int hsbPolicy) 
+  {
+    this(null, vsbPolicy, hsbPolicy);
+  }
+
+  public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) 
+  {
+    scrollListener = createScrollListener();
+    setVerticalScrollBarPolicy(vsbPolicy);
+    setVerticalScrollBar(createVerticalScrollBar());
+    setHorizontalScrollBarPolicy(hsbPolicy);
+    setHorizontalScrollBar(createHorizontalScrollBar());
+    setViewportView(view);
+    setLayout(new ScrollPaneLayout());
+    setOpaque(false);
+    updateUI();
+  }
+
+  
+  public JScrollBar createHorizontalScrollBar()
+  {
+    return new ScrollBar(SwingConstants.HORIZONTAL);
+  }
+
+  public JScrollBar createVerticalScrollBar()
+  {
+    return new ScrollBar(SwingConstants.VERTICAL);
+  }
     
-    public JScrollPane(int vsbPolicy, int hsbPolicy) 
+  public JViewport createViewport()
+  {
+    return new JViewport();
+  }
+
+
+  public String getUIClassID()
+  {
+    return "ScrollPaneUI";
+  }
+  
+  public void updateUI()
+  {
+    ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
+    setUI(b);
+  }  
+
+
+  class ScrollBar 
+    extends JScrollBar
+    implements UIResource
+  {
+    public ScrollBar(int orientation)
     {
-	this(null, 0, 0);
+      super(orientation);
     }
 
-    public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) 
+    public int getBlockIncrement(int direction)
     {
-	setViewportView(view);
-        setOpaque(true);
-	updateUI();
+      Component view = JScrollPane.this.getViewport().getView();
+      if (view == null || (! (view instanceof Scrollable)))
+        return super.getBlockIncrement(direction);
+      else
+        {
+          Scrollable s = (Scrollable) view;
+          return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(), 
+                                               this.getOrientation(),
+                                               direction);
+        }
     }
 
-    public String getUIClassID()
+    public int getUnitIncrement(int direction)
     {
-	//Returns a string that specifies the name of the L&F class that renders this component.  
-	return "JScrollPane";
+      Component view = JScrollPane.this.getViewport().getView();
+      if (view == null || (! (view instanceof Scrollable)))
+        return super.getUnitIncrement(direction);
+      else
+        {
+          Scrollable s = (Scrollable) view;
+          return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(), 
+                                              this.getOrientation(),
+                                              direction);
+        }
     }
 
-    public JViewport getViewport()
-    {
-	return viewport;
-    }
 
-    public JViewport createViewport()
-    {
-	return new JViewport();
-    }
-    
-    public void setViewport(JViewport v)
-    {
-	if (viewport != null)
-	    remove(viewport);
-
-	viewport = v;	
-	
-	add(v);
-	
-	revalidate();
-	repaint();
-    }
-    
-   public  void updateUI()
-    {
-	ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
-	setUI(b);
-    }
-
-
-    public void setViewportView(Component view)
-    {
-	if (getViewport() == null)
-	    {
-		setViewport(createViewport());
-	    }
-	
-	if (view != null)
-	    {
-		getViewport().setView(view);
-	    }
-    }
+  }
+  
 }
Index: javax/swing/JSeparator.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JSeparator.java,v
retrieving revision 1.3
diff -u -r1.3 JSeparator.java
--- javax/swing/JSeparator.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/JSeparator.java	6 Sep 2004 16:35:58 -0000
@@ -37,190 +37,172 @@
 
 package javax.swing;
 
-import java.io.IOException;
-import java.io.ObjectOutputStream;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.swing.plaf.SeparatorUI;
 
+
 /**
- * JSeparator
- * @author	Andrew Selkirk
- * @version	1.0
+ * The JSeparator. It is mostly used to divide/space out
+ * components.
  */
-public class JSeparator extends JComponent 
-  implements SwingConstants, Accessible
+public class JSeparator extends JComponent implements SwingConstants,
+                                                      Accessible
 {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJSeparator
-	 */
-	protected class AccessibleJSeparator extends AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJSeparator
-		 * @param component TODO
-		 */
-		protected AccessibleJSeparator(JSeparator component) {
-			super(component);
-			// TODO
-		} // AccessibleJSeparator()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.SEPARATOR;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJSeparator
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "SeparatorUI";
-
-	/**
-	 * orientation
-	 */
-	private int orientation;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JSeparator
-	 */
-	public JSeparator() {
-		this(HORIZONTAL);
-	} // JSeparator()
-
-	/**
-	 * Constructor JSeparator
-	 * @param value0 TODO
-	 */
-	public JSeparator(int orientation) {
-		this.orientation = orientation;
-		// TODO
-	} // JSeparator()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getUI
-	 * @returns SeparatorUI
-	 */
-	public SeparatorUI getUI() {
-		return (SeparatorUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(SeparatorUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((SeparatorUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getOrientation
-	 * @returns int
-	 */
-	public int getOrientation() {
-		return orientation;
-	} // getOrientation()
-
-	/**
-	 * setOrientation
-	 * @param orientation TODO
-	 */
-	public void setOrientation(int orientation) {
-		this.orientation = orientation;
-		// TODO
-	} // setOrientation()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * isFocusTraversable
-	 * @returns boolean
-	 */
-	public boolean isFocusTraversable() {
-		return false;
-	} // isFocusTraversable()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJSeparator(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JSeparator
+  /**
+   * AccessibleJSeparator
+   */
+  protected class AccessibleJSeparator extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = 916332890553201095L;
+  
+    /**
+     * Constructor AccessibleJSeparator
+     *
+     * @param component TODO
+     */
+    protected AccessibleJSeparator()
+    {
+    }
+
+    /**
+     * getAccessibleRole
+     *
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.SEPARATOR;
+    }
+  }
+
+  private static final long serialVersionUID = 125301223445282357L;
+  
+  /** The orientation of the JSeparator. */
+  private transient int orientation = HORIZONTAL;
+
+  /**
+   * Creates a new horizontal JSeparator object.
+   */
+  public JSeparator()
+  {
+    this(HORIZONTAL);
+  }
+
+  /**
+   * Creates a new JSeparator object with the given orientation.
+   *
+   * @param orientation The orientation of the JSeparator.
+   */
+  public JSeparator(int orientation)
+  {
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a valid orientation.");
+    this.orientation = orientation;
+    updateUI();
+  }
+
+  /**
+   * This method returns the UI delegate being
+   * used with the JSeparator.
+   *
+   * @return SeparatorUI The JSeparator's UI delegate.
+   */
+  public SeparatorUI getUI()
+  {
+    return (SeparatorUI) ui;
+  }
+
+  /**
+   * This method sets the UI delegate to use
+   * with the JSeparator.
+   *
+   * @param ui The UI delegate to use.
+   */
+  public void setUI(SeparatorUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method resets the UI delegate to the 
+   * default for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SeparatorUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns the identifier string
+   * that is used to determine the UI delegate
+   * from the current look and feel.
+   *
+   * @return String The identifier string for the UI.
+   */
+  public String getUIClassID()
+  {
+    return "SeparatorUI";
+  }
+
+  /**
+   * This method returns the JSeparator's orientation.
+   *
+   * @return int The JSeparator's orientation.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method changes the JSeparator's orientation.
+   *
+   * @param orientation The JSeparator's orientation.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a valid orientation.");
+    this.orientation = orientation;
+  }
+
+  /**
+   * This method returns a string desribing the JSeparator.
+   * Normally only used in debugging.
+   *
+   * @return String A string describing the JSeparator.
+   */
+  protected String paramString()
+  {
+    return "JSeparator";
+  }
+
+  /**
+   * This method overrides the isFocusTraversable method from
+   * Component to false. JSeparator cannot be focused on.
+   *
+   * @return boolean False.
+   */
+  public boolean isFocusTraversable()
+  {
+    return false;
+  }
+
+  /**
+   * getAccessibleContext
+   *
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSeparator();
+    
+    return accessibleContext;
+  }
+}
Index: javax/swing/JSlider.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JSlider.java,v
retrieving revision 1.3
diff -u -r1.3 JSlider.java
--- javax/swing/JSlider.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/JSlider.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
 /* JSlider.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,14 +35,16 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
-import java.io.IOException;
-import java.io.ObjectOutputStream;
+import java.awt.Dimension;
+import java.awt.MenuContainer;
+import java.awt.image.ImageObserver;
 import java.io.Serializable;
 import java.util.Dictionary;
+import java.util.Enumeration;
 import java.util.Hashtable;
+
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
@@ -52,650 +54,888 @@
 import javax.swing.event.ChangeListener;
 import javax.swing.plaf.SliderUI;
 
+
 /**
- * JSlider
- * @author	Andrew Selkirk
- * @version	1.0
+ * <p>
+ * The JSlider is a Swing component that allows selection of a value within a
+ * range by adjusting a thumb in a track. The values for the minimum,
+ * maximum, extent and value are stored in a {@link
+ * DefaultBoundedRangeModel}.
+ * </p>
+ * 
+ * <p>
+ * JSliders have the following properties:
+ * </p>
+ * 
+ * <table>
+ * <tr><th> Property         </th><th> Stored in </th><th> Bound? </th></tr>
+ * <tr><td> extent           </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> inverted         </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> labelTable       </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> majorTickSpacing </td><td> slider    </td><td> yes    </td></tr> 
+ * <tr><td> maximum          </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> minimum          </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> minorTickSpacing </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> model            </td><td> slider    </td><td> yes    </td></tr> 
+ * <tr><td> orientation      </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> paintLabels      </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> paintTicks       </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> snapToTicks      </td><td> slider    </td><td> no     </td></tr>
+ * <tr><td> value            </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> valueIsAdjusting </td><td> model     </td><td> no     </td></tr>
+ * </table>
+ * 
+ * <p>
+ * The various behavioral aspects of these properties follows:
+ * </p>
+ * 
+ * <ul>
+ * <li>
+ * When non-bound properties stored in the slider change, the slider fires
+ * ChangeEvents to its ChangeListeners.
+ * </li>
+ * <li>
+ * When bound properties stored in the slider change, the slider fires
+ * PropertyChangeEvents to its PropertyChangeListeners
+ * </li>
+ * <li>
+ * If any of the model's properties change, it fires a ChangeEvent to its
+ * ChangeListeners, which include the slider.
+ * </li>
+ * <li>
+ * If the slider receives a ChangeEvent from its model, it will propagate the
+ * ChangeEvent to its ChangeListeners, with the ChangeEvent's "source"
+ * property set to refer to the slider, rather than the model.
+ * </li>
+ * </ul>
  */
-public class JSlider
-  extends JComponent
-  implements SwingConstants, Accessible
+public class JSlider extends JComponent implements SwingConstants, Accessible,
+                                                   ImageObserver,
+                                                   MenuContainer, Serializable
 {
+  /** DOCUMENT ME! */
   static final long serialVersionUID = -1441275936141218479L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-
-	/**
-	 * AccessibleJSlider
-	 */
-	protected class AccessibleJSlider extends JComponent.AccessibleJComponent implements AccessibleValue {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJSlider
-		 * @param value0 TODO
-		 */
-		protected AccessibleJSlider(JSlider value0) {
-			super(value0);
-			// TODO
-		} // AccessibleJSlider()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return null; // TODO
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleValue
-		 * @returns AccessibleValue
-		 */
-		public AccessibleValue getAccessibleValue() {
-			return null; // TODO
-		} // getAccessibleValue()
-
-		/**
-		 * getCurrentAccessibleValue
-		 * @returns Number
-		 */
-		public Number getCurrentAccessibleValue() {
-			return null; // TODO
-		} // getCurrentAccessibleValue()
-
-		/**
-		 * setCurrentAccessibleValue
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean setCurrentAccessibleValue(Number value0) {
-			return false; // TODO
-		} // setCurrentAccessibleValue()
-
-		/**
-		 * getMinimumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMinimumAccessibleValue() {
-			return null; // TODO
-		} // getMinimumAccessibleValue()
-
-		/**
-		 * getMaximumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMaximumAccessibleValue() {
-			return null; // TODO
-		} // getMaximumAccessibleValue()
-
-
-	} // AccessibleJSlider
-
-	/**
-	 * ModelListener
-	 */
-	private class ModelListener implements ChangeListener, Serializable {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor ModelListener
-		 * @param value0 TODO
-		 */
-		private ModelListener(JSlider value0) {
-			// TODO
-		} // ModelListener()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * stateChanged
-		 * @param value0 TODO
-		 */
-		public void stateChanged(ChangeEvent value0) {
-			// TODO
-		} // stateChanged()
-
-
-	} // ModelListener
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "SliderUI";
-
-	/**
-	 * paintTicks
-	 */
-	private boolean paintTicks;
-
-	/**
-	 * paintTrack
-	 */
-	private boolean paintTrack;
-
-	/**
-	 * paintLabels
-	 */
-	private boolean paintLabels;
-
-	/**
-	 * isInverted
-	 */
-	private boolean isInverted;
-
-	/**
-	 * sliderModel
-	 */
-	protected BoundedRangeModel sliderModel;
-
-	/**
-	 * majorTickSpacing
-	 */
-	protected int majorTickSpacing;
-
-	/**
-	 * minorTickSpacing
-	 */
-	protected int minorTickSpacing;
-
-	/**
-	 * snapToTicks
-	 */
-	protected boolean snapToTicks;
-
-	/**
-	 * snapToValue
-	 */
-	boolean snapToValue;
-
-	/**
-	 * orientation
-	 */
-	protected int orientation;
-
-	/**
-	 * labelTable
-	 */
-	private Dictionary labelTable;
-
-	/**
-	 * changeListener
-	 */
-	protected ChangeListener changeListener;
-
-	/**
-	 * changeEvent
-	 */
-	protected transient ChangeEvent changeEvent;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JSlider
-	 */
-	public JSlider() {
-		// TODO
-	} // JSlider()
-
-	/**
-	 * Constructor JSlider
-	 * @param value0 TODO
-	 */
-	public JSlider(int orientation) {
-		// TODO
-	} // JSlider()
-
-	/**
-	 * Constructor JSlider
-	 * @param minimum TODO
-	 * @param maximum TODO
-	 */
-	public JSlider(int minimum, int maximum) {
-		// TODO
-	} // JSlider()
-
-	/**
-	 * Constructor JSlider
-	 * @param minimum TODO
-	 * @param maximum TODO
-	 * @param value TODO
-	 */
-	public JSlider(int minimum, int maximum, int value) {
-		// TODO
-	} // JSlider()
-
-	/**
-	 * Constructor JSlider
-	 * @param orientation TODO
-	 * @param minimum TODO
-	 * @param maximum TODO
-	 * @param value TODO
-	 */
-	public JSlider(int orientation, int minimum, int maximum, int value) {
-		// TODO
-	} // JSlider()
-
-	/**
-	 * Constructor JSlider
-	 * @param value0 TODO
-	 */
-	public JSlider(BoundedRangeModel model) {
-		// TODO
-	} // JSlider()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getValue
-	 * @returns int
-	 */
-	public int getValue() {
-		return 0; // TODO
-	} // getValue()
-
-	/**
-	 * setValue
-	 * @param value0 TODO
-	 */
-	public void setValue(int value) {
-		// TODO
-	} // setValue()
-
-	/**
-	 * getUI
-	 * @returns SliderUI
-	 */
-	public SliderUI getUI() {
-		return (SliderUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(SliderUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((SliderUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * createChangeListener
-	 * @returns ChangeListener
-	 */
-	protected ChangeListener createChangeListener() {
-		return null; // TODO
-	} // createChangeListener()
-
-	/**
-	 * addChangeListener
-	 * @param listener TODO
-	 */
-	public void addChangeListener(ChangeListener listener) {
-		// TODO
-	} // addChangeListener()
-
-	/**
-	 * removeChangeListener
-	 * @param listener TODO
-	 */
-	public void removeChangeListener(ChangeListener listener) {
-		// TODO
-	} // removeChangeListener()
-
-	/**
-	 * fireStateChanged
-	 */
-	protected void fireStateChanged() {
-		// TODO
-	} // fireStateChanged()
-
-	/**
-	 * getModel
-	 * @returns BoundedRangeModel
-	 */
-	public BoundedRangeModel getModel() {
-		return null; // TODO
-	} // getModel()
-
-	/**
-	 * setModel
-	 * @param model TODO
-	 */
-	public void setModel(BoundedRangeModel model) {
-		// TODO
-	} // setModel()
-
-	/**
-	 * getMinimum
-	 * @returns int
-	 */
-	public int getMinimum() {
-		return 0; // TODO
-	} // getMinimum()
-
-	/**
-	 * setMinimum
-	 * @param minimum TODO
-	 */
-	public void setMinimum(int minimum) {
-		// TODO
-	} // setMinimum()
-
-	/**
-	 * getMaximum
-	 * @returns int
-	 */
-	public int getMaximum() {
-		return 0; // TODO
-	} // getMaximum()
-
-	/**
-	 * setMaximum
-	 * @param maximum TODO
-	 */
-	public void setMaximum(int maximum) {
-		// TODO
-	} // setMaximum()
-
-	/**
-	 * getValueIsAdjusting
-	 * @returns boolean
-	 */
-	public boolean getValueIsAdjusting() {
-		return false; // TODO
-	} // getValueIsAdjusting()
-
-	/**
-	 * setValueIsAdjusting
-	 * @param adjusting TODO
-	 */
-	public void setValueIsAdjusting(boolean adjusting) {
-		// TODO
-	} // setValueIsAdjusting()
-
-	/**
-	 * getExtent
-	 * @returns int
-	 */
-	public int getExtent() {
-		return 0; // TODO
-	} // getExtent()
-
-	/**
-	 * setExtent
-	 * @param vextent TODO
-	 */
-	public void setExtent(int extent) {
-		// TODO
-	} // setExtent()
-
-	/**
-	 * getOrientation
-	 * @returns int
-	 */
-	public int getOrientation() {
-		return 0; // TODO
-	} // getOrientation()
-
-	/**
-	 * setOrientation
-	 * @param orientation TODO
-	 */
-	public void setOrientation(int orientation) {
-		// TODO
-	} // setOrientation()
-
-	/**
-	 * getLabelTable
-	 * @returns Dictionary
-	 */
-	public Dictionary getLabelTable() {
-		return null; // TODO
-	} // getLabelTable()
-
-	/**
-	 * setLabelTable
-	 * @param table TODO
-	 */
-	public void setLabelTable(Dictionary table) {
-		// TODO
-	} // setLabelTable()
-
-	/**
-	 * updateLabelUIs
-	 */
-	protected void updateLabelUIs() {
-		// TODO
-	} // updateLabelUIs()
-
-	/**
-	 * createStandardLabels
-	 * @param increment TODO
-	 * @returns Hashtable
-	 */
-	public Hashtable createStandardLabels(int increment) {
-		return null; // TODO
-	} // createStandardLabels()
-
-	/**
-	 * createStandardLabels
-	 * @param increment TODO
-	 * @param start TODO
-	 * @returns Hashtable
-	 */
-	public Hashtable createStandardLabels(int increment, int start) {
-		return null; // TODO
-	} // createStandardLabels()
-
-	/**
-	 * getInverted
-	 * @returns boolean
-	 */
-	public boolean getInverted() {
-		return false; // TODO
-	} // getInverted()
-
-	/**
-	 * setInverted
-	 * @param inverted TODO
-	 */
-	public void setInverted(boolean inverted) {
-		// TODO
-	} // setInverted()
-
-	/**
-	 * getMajorTickSpacing
-	 * @returns int
-	 */
-	public int getMajorTickSpacing() {
-		return 0; // TODO
-	} // getMajorTickSpacing()
-
-	/**
-	 * setMajorTickSpacing
-	 * @param spacing TODO
-	 */
-	public void setMajorTickSpacing(int spacing) {
-		// TODO
-	} // setMajorTickSpacing()
-
-	/**
-	 * getMinorTickSpacing
-	 * @returns int
-	 */
-	public int getMinorTickSpacing() {
-		return 0; // TODO
-	} // getMinorTickSpacing()
-
-	/**
-	 * setMinorTickSpacing
-	 * @param spacing TODO
-	 */
-	public void setMinorTickSpacing(int spacing) {
-		// TODO
-	} // setMinorTickSpacing()
-
-	/**
-	 * getSnapToTicks
-	 * @returns boolean
-	 */
-	public boolean getSnapToTicks() {
-		return false; // TODO
-	} // getSnapToTicks()
-
-	/**
-	 * getSnapToValue
-	 * @returns boolean
-	 */
-	boolean getSnapToValue() {
-		return false; // TODO
-	} // getSnapToValue()
-
-	/**
-	 * setSnapToTicks
-	 * @param snap TODO
-	 */
-	public void setSnapToTicks(boolean snap) {
-		// TODO
-	} // setSnapToTicks()
-
-	/**
-	 * getPaintTicks
-	 * @returns boolean
-	 */
-	public boolean getPaintTicks() {
-		return false; // TODO
-	} // getPaintTicks()
-
-	/**
-	 * setPaintTicks
-	 * @param paint TODO
-	 */
-	public void setPaintTicks(boolean paint) {
-		// TODO
-	} // setPaintTicks()
-
-	/**
-	 * getPaintTrack
-	 * @returns boolean
-	 */
-	public boolean getPaintTrack() {
-		return false; // TODO
-	} // getPaintTrack()
-
-	/**
-	 * setPaintTrack
-	 * @param paint TODO
-	 */
-	public void setPaintTrack(boolean paint) {
-		// TODO
-	} // setPaintTrack()
-
-	/**
-	 * getPaintLabels
-	 * @returns boolean
-	 */
-	public boolean getPaintLabels() {
-		return false; // TODO
-	} // getPaintLabels()
-
-	/**
-	 * setPaintLabels
-	 * @param paint TODO
-	 */
-	public void setPaintLabels(boolean paint) {
-		// TODO
-	} // setPaintLabels()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJSlider(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JSlider
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJSlider extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -6301740148041106789L;
+  
+    /**
+     * Creates a new AccessibleJSlider object.
+     *
+     * @param value0 DOCUMENT ME!
+     */
+    protected AccessibleJSlider()
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * setCurrentAccessibleValue
+     *
+     * @param value0 TODO
+     *
+     * @return boolean
+     */
+    public boolean setCurrentAccessibleValue(Number value0)
+    {
+      return false;
+    }
+
+    /**
+     * getMinimumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * getMaximumAccessibleValue
+     *
+     * @return Number
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null;
+    }
+  }
+
+  /** Fired in a PropertyChangeEvent when the "inverted" property changes. */
+  public static final String INVERTED_CHANGED_PROPERTY = "inverted";
+
+  /** Fired in a PropertyChangeEvent when the "labelTable" property changes. */
+  public static final String LABEL_TABLE_CHANGED_PROPERTY = "labelTable";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "majorTickSpacing" property
+   * changes.
+   */
+  public static final String MAJOR_TICK_SPACING_CHANGED_PROPERTY = "majorTickSpacing";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "minorTickSpacing" property
+   * changes.
+   */
+  public static final String MINOR_TICK_SPACING_CHANGED_PROPERTY = "minorTickSpacing";
+
+  /** Fired in a PropertyChangeEvent when the "model" property changes. */
+  public static final String MODEL_CHANGED_PROPERTY = "model";
+
+  /** Fired in a PropertyChangeEvent when the "orientation" property changes. */
+  public static final String ORIENTATION_CHANGED_PROPERTY = "orientation";
+
+  /** Fired in a PropertyChangeEvent when the "paintLabels" property changes. */
+  public static final String PAINT_LABELS_CHANGED_PROPERTY = "paintLabels";
+
+  /** Fired in a PropertyChangeEvent when the "paintTicks" property changes. */
+  public static final String PAINT_TICKS_CHANGED_PROPERTY = "paintTicks";
+  
+  /** Whether or not this slider paints its ticks. */
+  private transient boolean paintTicks = false;
+
+  /** Whether or not this slider paints its track. */
+  private transient boolean paintTrack = true;
+
+  /** Whether or not this slider paints its labels. */
+  private transient boolean paintLabels = false;
+
+  /**
+   * A dictionary of (Integer, Component) pairs where each Component is a
+   * JLabel and the Integer determines where the label will be painted.
+   */
+  private transient Dictionary labelTable;
+
+  /** The model used to describe the slider. */
+  protected BoundedRangeModel sliderModel;
+
+  /** The space between major ticks. */
+  protected int majorTickSpacing;
+
+  /** The space between minor ticks. */
+  protected int minorTickSpacing;
+
+  /** Whether the slider snaps its values to ticks. */
+  protected boolean snapToTicks = true;
+
+  /** The orientation of the slider. */
+  protected int orientation = HORIZONTAL;
+
+  /** Whether the slider is inverted. */
+  private transient boolean isInverted;
+
+  /** The ChangeListener that listens to the model. */
+  protected ChangeListener changeListener;
+
+  /** The ChangeEvent that is passed to all listeners of this slider. */
+  protected transient ChangeEvent changeEvent;
+
+  /**
+   * Creates a new horizontal JSlider object with a minimum of 0, a maximum of
+   * 100, and a value of 50.
+   */
+  public JSlider()
+  {
+    this(HORIZONTAL, 0, 100, 50);
+  }
+
+  /**
+   * Creates a new JSlider object with the given orientation and a minimum of
+   * 0, a maximum of 100, and a value of 50.
+   *
+   * @param orientation The orientation of the slider.
+   */
+  public JSlider(int orientation)
+  {
+    this(orientation, 0, 100, 50);
+  }
+
+  /**
+   * Creates a new horizontal JSlider object with the given maximum and
+   * minimum and a value that is  halfway between the minimum and the
+   * maximum.
+   *
+   * @param minimum The minimum value of the JSlider.
+   * @param maximum The maximum value of the JSlider.
+   */
+  public JSlider(int minimum, int maximum)
+  {
+    this(HORIZONTAL, minimum, maximum, (maximum + minimum) / 2);
+  }
+
+  /**
+   * Creates a new horizontal JSlider object with the given minimum, maximum,
+   * and value.
+   *
+   * @param minimum The minimum value of the JSlider.
+   * @param maximum The maximum value of the JSlider.
+   * @param value The initial value of the JSlider.
+   */
+  public JSlider(int minimum, int maximum, int value)
+  {
+    this(HORIZONTAL, minimum, maximum, value);
+  }
+
+  /**
+   * Creates a new JSlider object with the given orientation, minimum,
+   * maximum, and value.
+   *
+   * @param orientation The orientation of the JSlider.
+   * @param minimum The minimum value of the JSlider.
+   * @param maximum The maximum value of the JSlider.
+   * @param value The initial value of the JSlider.
+   */
+  public JSlider(int orientation, int minimum, int maximum, int value)
+  {
+    sliderModel = new DefaultBoundedRangeModel(value, 0, minimum, maximum);
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation + " is not a legal orientation");
+    this.orientation = orientation;
+    changeListener = createChangeListener();
+    sliderModel.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * Creates a new horizontal JSlider object with the given model.
+   *
+   * @param model The model the slider will be created with.
+   */
+  public JSlider(BoundedRangeModel model)
+  {
+    if (model == null)
+      sliderModel = new DefaultBoundedRangeModel(50, 0, 0, 100);
+    else
+      sliderModel = model;
+    changeListener = createChangeListener();
+    sliderModel.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * This method returns the current value of the slider.
+   *
+   * @return The value of the slider stored in the model.
+   */
+  public int getValue()
+  {
+    return sliderModel.getValue();
+  }
+
+  /**
+   * This method sets the value of the slider.
+   *
+   * @param value The slider's new value.
+   */
+  public void setValue(int value)
+  {
+    sliderModel.setValue(value);
+  }
+
+  /**
+   * This method returns the slider's UI delegate.
+   *
+   * @return The slider's UI delegate.
+   */
+  public SliderUI getUI()
+  {
+    return (SliderUI) ui;
+  }
+
+  /**
+   * This method sets the slider's UI delegate.
+   *
+   * @param ui A SliderUI object to use with this slider.
+   */
+  public void setUI(SliderUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets this slider's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SliderUI) UIManager.getUI(this));
+    invalidate();
+    repaint();
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the slider.
+   *
+   * @return The Look and Feel classID. "SliderUI"
+   */
+  public String getUIClassID()
+  {
+    return "SliderUI";
+  }
+
+  /**
+   * Creates a ChangeListener for this Slider.
+   *
+   * @return A new ChangeListener.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ChangeListener()
+      {
+	public void stateChanged(ChangeEvent ce)
+	{
+	  // No need to trigger a repaint since the UI listens to the model
+	  // as well. All we need to do is pass on the stateChanged event 
+	  // to our listeners.
+	  fireStateChanged();
+	}
+      };
+  }
+
+  /**
+   * This method registers a listener to this slider. The listener will be
+   * informed of new ChangeEvents.
+   *
+   * @param listener The listener to register.
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method removes a listener from this slider.
+   *
+   * @param listener The listener to remove.
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method is called whenever the model fires a ChangeEvent. It should
+   * propagate the ChangeEvent to its listeners with a new ChangeEvent that
+   * identifies the slider as the source.
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (changeListeners[i] == ChangeListener.class)
+	  ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * This method returns an array of all ChangeListeners listening to this
+   * slider.
+   *
+   * @return An array of ChangeListeners listening to this slider.
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * This method returns the model of the slider.
+   *
+   * @return The slider's model.
+   */
+  public BoundedRangeModel getModel()
+  {
+    return sliderModel;
+  }
+
+  /**
+   * This method changes the "model" property. It also needs  to unregister
+   * any listeners to the old model and register any listeners to the new
+   * model.
+   *
+   * @param model The model to use with the slider.
+   */
+  public void setModel(BoundedRangeModel model)
+  {
+    // I didn't do the null pointer check on purpose.
+    // If you try it with Sun's, it'll go ahead and set it to null
+    // and bork the next time it tries to access the model.
+    if (model != sliderModel)
+      {
+	BoundedRangeModel oldModel = sliderModel;
+	sliderModel = model;
+	oldModel.removeChangeListener(changeListener);
+	sliderModel.addChangeListener(changeListener);
+	firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel, sliderModel);
+      }
+  }
+
+  /**
+   * This method returns the minimum value of the slider.
+   *
+   * @return The minimum value of the slider.
+   */
+  public int getMinimum()
+  {
+    return sliderModel.getMinimum();
+  }
+
+  /**
+   * This method sets the minimum value of the slider.
+   *
+   * @param minimum The minimum value of the slider.
+   */
+  public void setMinimum(int minimum)
+  {
+    sliderModel.setMinimum(minimum);
+  }
+
+  /**
+   * This method returns the maximum value of the slider.
+   *
+   * @return The maximum value of the slider.
+   */
+  public int getMaximum()
+  {
+    return sliderModel.getMaximum();
+  }
+
+  /**
+   * This method sets the maximum value of the slider.
+   *
+   * @param maximum The maximum value of the slider.
+   */
+  public void setMaximum(int maximum)
+  {
+    sliderModel.setMaximum(maximum);
+  }
+
+  /**
+   * This method returns this slider's isAdjusting value which is true if the
+   * thumb is being dragged.
+   *
+   * @return The slider's isAdjusting value.
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return sliderModel.getValueIsAdjusting();
+  }
+
+  /**
+   * This method sets the isAdjusting value for the slider.
+   *
+   * @param adjusting The slider's isAdjusting value.
+   */
+  public void setValueIsAdjusting(boolean adjusting)
+  {
+    sliderModel.setValueIsAdjusting(adjusting);
+  }
+
+  /**
+   * This method returns the extent value for this slider.
+   *
+   * @return The extent value for this slider.
+   */
+  public int getExtent()
+  {
+    return sliderModel.getExtent();
+  }
+
+  /**
+   * This method sets the extent value for this slider.
+   *
+   * @param extent The extent value for this slider.
+   */
+  public void setExtent(int extent)
+  {
+    sliderModel.setExtent(extent);
+  }
+
+  /**
+   * This method returns the slider orientation.
+   *
+   * @return The orientation of the slider.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method changes the "orientation" property of this slider. If the
+   * orientation is not VERTICAL or HORIZONTAL, this method does nothing.
+   *
+   * @param orientation The orientation of this slider.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != VERTICAL && orientation != HORIZONTAL)
+      throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
+    if (orientation != this.orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange(ORIENTATION_CHANGED_PROPERTY, oldOrientation,
+	                   this.orientation);
+      }
+  }
+
+  /**
+   * This method returns the label table for this slider.
+   *
+   * @return The label table for this slider.
+   */
+  public Dictionary getLabelTable()
+  {
+    return labelTable;
+  }
+
+  /**
+   * This method changes the "labelTable" property of this slider.
+   *
+   * @param table The label table for this slider.
+   */
+  public void setLabelTable(Dictionary table)
+  {
+    if (table != labelTable)
+      {
+	Dictionary oldTable = labelTable;
+	labelTable = table;
+	firePropertyChange(LABEL_TABLE_CHANGED_PROPERTY, oldTable, labelTable);
+      }
+  }
+
+  /**
+   * This method is called to reset UI delegates for the labels in the
+   * labelTable to a default for the current look and feel.
+   */
+  protected void updateLabelUIs()
+  {
+    if (labelTable == null)
+      return;
+    for (Enumeration list = labelTable.elements(); list.hasMoreElements();)
+      {
+	JLabel label = (JLabel) list.nextElement();
+	label.updateUI();
+      }
+  }
+
+  /**
+   * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
+   * label table for this slider. The labels will start from the sliders
+   * minimum and increase by the increment. Each  label will have a text
+   * string indicating their integer value.
+   *
+   * @param increment The increment to between labels.
+   *
+   * @return A hashtable with the labels and their keys.
+   */
+  public Hashtable createStandardLabels(int increment)
+  {
+    return createStandardLabels(increment, sliderModel.getMinimum());
+  }
+
+  /**
+   * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
+   * label table for this slider. The labels will start from the given start
+   * value and increase by the increment. Each  label will have a text string
+   * indicating their integer value.
+   *
+   * @param increment The increment to between labels.
+   * @param start The value to start from.
+   *
+   * @return A hashtable with the labels and their keys.
+   */
+  public Hashtable createStandardLabels(int increment, int start)
+  {
+    Hashtable table = new Hashtable();
+    JLabel label;
+    Dimension dim;
+
+    int max = sliderModel.getMaximum();
+
+    for (int i = start; i <= max; i += increment)
+      {
+	label = new JLabel(String.valueOf(i));
+	label.setVerticalAlignment(CENTER);
+	label.setHorizontalAlignment(CENTER);
+	
+	// Make sure these labels have the width and height
+	// they want.
+	dim = label.getPreferredSize();
+	label.setBounds(label.getX(), label.getY(),
+	                (int) dim.getWidth(),
+			(int) dim.getHeight()); 
+	table.put(new Integer(i), label);
+      }
+    return table;
+  }
+
+  /**
+   * This method returns whether the slider is inverted. Horizontal sliders
+   * that are not inverted will have the minimums on the left. If they are
+   * inverted, the minimums will be  on the right. Vertical sliders that are
+   * not inverted will have the minimums at the bottom. If they are inverted,
+   * the minimums will be at the top.
+   *
+   * @return Whether this slider is inverted.
+   */
+  public boolean getInverted()
+  {
+    return isInverted;
+  }
+
+  /**
+   * This method changes the "inverted" property for this slider.Horizontal
+   * sliders  that are not inverted will have the minimums on the left. If
+   * they are inverted, the minimums will be  on the right. Vertical sliders
+   * that are not inverted will have the minimums at the bottom. If they are
+   * inverted, the minimums will be at the top. However, if the slider's
+   * componentOrientation is set to RIGHT_TO_LEFT, then everything gets
+   * reversed again.
+   *
+   * @param inverted Whether the slider should be inverted.
+   */
+  public void setInverted(boolean inverted)
+  {
+    if (isInverted != inverted)
+      {
+	boolean oldInverted = isInverted;
+	isInverted = inverted;
+	firePropertyChange(INVERTED_CHANGED_PROPERTY, oldInverted, isInverted);
+      }
+  }
+
+  /**
+   * This method returns the amount of units between each major tick mark.
+   *
+   * @return The amount of units between each major tick mark.
+   */
+  public int getMajorTickSpacing()
+  {
+    return majorTickSpacing;
+  }
+
+  /**
+   * This method changes the "majorTickSpacing" property for this slider. The
+   * major tick spacing is the amount of units between each major tick mark.
+   *
+   * @param spacing The amount of units between each major tick mark.
+   */
+  public void setMajorTickSpacing(int spacing)
+  {
+    if (majorTickSpacing != spacing)
+      {
+	int oldSpacing = majorTickSpacing;
+	majorTickSpacing = spacing;
+	firePropertyChange(MAJOR_TICK_SPACING_CHANGED_PROPERTY, oldSpacing,
+	                   majorTickSpacing);
+      }
+  }
+
+  /**
+   * This method returns the amount of units between each minor tick mark.
+   *
+   * @return The amount of units between each minor tick mark.
+   */
+  public int getMinorTickSpacing()
+  {
+    return minorTickSpacing;
+  }
+
+  /**
+   * This method changes the "minorTickSpacing" property for this slider. The
+   * minor tick spacing is the amount of units between each minor tick mark.
+   *
+   * @param spacing The amount of units between each minor tick mark.
+   */
+  public void setMinorTickSpacing(int spacing)
+  {
+    if (minorTickSpacing != spacing)
+      {
+	int oldSpacing = minorTickSpacing;
+	minorTickSpacing = spacing;
+	firePropertyChange(MINOR_TICK_SPACING_CHANGED_PROPERTY, oldSpacing,
+	                   minorTickSpacing);
+      }
+  }
+
+  /**
+   * This method returns whether this slider is snapping to ticks.  Sliders
+   * that snap to ticks will automatically move the thumb to the nearest tick
+   * mark.
+   *
+   * @return Whether this slider snaps to ticks.
+   */
+  public boolean getSnapToTicks()
+  {
+    return snapToTicks;
+  }
+
+  /**
+   * This method sets whether this slider will snap to ticks. Sliders that
+   * snap to ticks will automatically move the thumb to the nearest tick
+   * mark.
+   *
+   * @param snap Whether this slider snaps to ticks.
+   */
+  public void setSnapToTicks(boolean snap)
+  {
+    if (snap != snapToTicks)
+      {
+	snapToTicks = snap;
+	fireStateChanged();
+      }
+  }
+
+  /**
+   * This method returns whether the slider will paint its tick marks. In
+   * addition to setting this property to true, one of minor tick spacing  or
+   * major tick spacing must be set to a value greater than 0 in order for
+   * ticks to be painted.
+   *
+   * @return Whether ticks will be painted.
+   */
+  public boolean getPaintTicks()
+  {
+    return paintTicks;
+  }
+
+  /**
+   * This method changes the "paintTicks" property for this slider. In
+   * addition to setting this property to true, one of minor tick spacing  or
+   * major tick spacing must be set to a value greater than 0 in order for
+   * ticks to be painted.
+   *
+   * @param paint Whether ticks will be painted.
+   */
+  public void setPaintTicks(boolean paint)
+  {
+    if (paint != paintTicks)
+      {
+	boolean oldPaintTicks = paintTicks;
+	paintTicks = paint;
+	firePropertyChange(PAINT_TICKS_CHANGED_PROPERTY, oldPaintTicks,
+	                   paintTicks);
+      }
+  }
+
+  /**
+   * This method returns whether the track will be painted.
+   *
+   * @return Whether the track will be painted.
+   */
+  public boolean getPaintTrack()
+  {
+    return paintTrack;
+  }
+
+  /**
+   * This method sets whether the track will be painted.
+   *
+   * @param paint Whether the track will be painted.
+   */
+  public void setPaintTrack(boolean paint)
+  {
+    paintTrack = paint;
+  }
+
+  /**
+   * This method returns whether labels will be painted.
+   *
+   * @return Whether labels will be painted.
+   */
+  public boolean getPaintLabels()
+  {
+    return paintLabels;
+  }
+
+  /**
+   * This method changes the "paintLabels" property.
+   *
+   * @param paint Whether labels will be painted.
+   */
+  public void setPaintLabels(boolean paint)
+  {
+    if (paint != paintLabels)
+      {
+	boolean oldPaintLabels = paintLabels;
+	paintLabels = paint;
+	firePropertyChange(PAINT_LABELS_CHANGED_PROPERTY, oldPaintLabels,
+	                   paintLabels);
+      }
+  }
+
+  /**
+   * This method is used primarily for debugging purposes and returns a string
+   * that can be used to represent this slider.
+   *
+   * @return A string representing this slider.
+   */
+  protected String paramString()
+  {
+    return "JSlider";
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSlider();
+    
+    return accessibleContext;
+  }
+}
Index: javax/swing/JSpinner.java
===================================================================
RCS file: javax/swing/JSpinner.java
diff -N javax/swing/JSpinner.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/JSpinner.java	6 Sep 2004 16:35:58 -0000
@@ -0,0 +1,482 @@
+/* JSpinner.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.LayoutManager;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.util.EventListener;
+import javax.swing.border.EtchedBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import javax.swing.plaf.SpinnerUI;
+
+
+/**
+ * A JSpinner is a component which typically contains a numeric value and a
+ * way to manipulate the value.
+ *
+ * @author Ka-Hing Cheung
+ * @version 1.0
+ */
+public class JSpinner extends JComponent
+{
+  /**
+   * DOCUMENT ME!
+   */
+  public static class StubEditor extends JLabel implements ChangeListener
+  {
+    /** DOCUMENT ME! */
+    private JLabel label;
+
+    /** DOCUMENT ME! */
+    private JButton up;
+
+    /** DOCUMENT ME! */
+    private JButton down;
+
+    /** DOCUMENT ME! */
+    private JSpinner spinner;
+
+    /**
+     * Creates a new StubEditor object.
+     *
+     * @param spinner DOCUMENT ME!
+     */
+    public StubEditor(JSpinner spinner)
+    {
+      this.spinner = spinner;
+      setBorder(new EtchedBorder());
+      setHorizontalAlignment(SwingConstants.TRAILING);
+      stateChanged(null); /* fill in the label */
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void stateChanged(ChangeEvent evt)
+    {
+      setText(String.valueOf(spinner.getValue()));
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public static class DefaultEditor extends JPanel implements ChangeListener,
+                                                              PropertyChangeListener,
+                                                              LayoutManager
+  {
+    /**
+     * Creates a new DefaultEditor object.
+     *
+     * @param spinner DOCUMENT ME!
+     */
+    public DefaultEditor(JSpinner spinner)
+    {
+      spinner.addChangeListener(this);
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     */
+    public void commitEdit()
+    {
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param spinner DOCUMENT ME!
+     */
+    public void dismiss(JSpinner spinner)
+    {
+      spinner.removeChangeListener(this);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public JFormattedTextField getTextField()
+    {
+      return null;
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     */
+    public void layoutContainer(Container parent)
+    {
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return null;
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      return null;
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+    } /* TODO */
+    /**
+     * DOCUMENT ME!
+     *
+     * @param evt DOCUMENT ME!
+     */
+    public void stateChanged(ChangeEvent evt)
+    {
+    } /* TODO */
+    /* no-ops */
+    public void removeLayoutComponent(Component child)
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     * @param child DOCUMENT ME!
+     */
+    public void addLayoutComponent(String name, Component child)
+    {
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public static class NumberEditor extends DefaultEditor
+  {
+    /**
+     * Creates a new NumberEditor object.
+     *
+     * @param spinner DOCUMENT ME!
+     */
+    public NumberEditor(JSpinner spinner)
+    {
+      super(spinner);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public DecimalFormat getFormat()
+    {
+      return null;
+    }
+  }
+
+  /** DOCUMENT ME! */
+  private SpinnerModel model;
+
+  /** DOCUMENT ME! */
+  private JComponent editor;
+
+  /** DOCUMENT ME! */
+  private EventListenerList listenerList = new EventListenerList();
+
+  /** DOCUMENT ME! */
+  private ChangeListener listener = new ChangeListener()
+    {
+      public void stateChanged(ChangeEvent evt)
+      {
+	fireStateChanged();
+      }
+    };
+
+  /**
+   * Creates a JSpinner with <code>SpinnerNumberModel</code>
+   *
+   * @see javax.swing.SpinnerNumberModel
+   */
+  public JSpinner()
+  {
+    this(new SpinnerNumberModel());
+  }
+
+  /**
+   * Creates a JSpinner with the specific model and sets the default editor
+   *
+   * @param model DOCUMENT ME!
+   */
+  public JSpinner(SpinnerModel model)
+  {
+    this.model = model;
+    model.addChangeListener(listener);
+    setEditor(createEditor(model));
+    updateUI();
+  }
+
+  /**
+   * If the editor is <code>JSpinner.DefaultEditor</code>, then forwards the
+   * call to it, otherwise do nothing.
+   *
+   * @throws ParseException DOCUMENT ME!
+   */
+  public void commitEdit() throws ParseException
+  {
+    if (editor instanceof DefaultEditor)
+      ((DefaultEditor) editor).commitEdit();
+  }
+
+  /**
+   * Gets the current editor
+   *
+   * @return the current editor
+   *
+   * @see #setEditor
+   */
+  public JComponent getEditor()
+  {
+    return editor;
+  }
+
+  /**
+   * Changes the current editor to the new editor. This methods should remove
+   * the old listeners (if any) and adds the new listeners (if any).
+   *
+   * @param editor the new editor
+   *
+   * @throws IllegalArgumentException DOCUMENT ME!
+   *
+   * @see #getEditor
+   */
+  public void setEditor(JComponent editor)
+  {
+    if (editor == null)
+      throw new IllegalArgumentException("editor may not be null");
+
+    if (this.editor instanceof DefaultEditor)
+      ((DefaultEditor) editor).dismiss(this);
+    else if (this.editor instanceof ChangeListener)
+      removeChangeListener((ChangeListener) this.editor);
+
+    if (editor instanceof ChangeListener)
+      addChangeListener((ChangeListener) editor);
+
+    this.editor = editor;
+  }
+
+  /**
+   * Gets the underly model.
+   *
+   * @return the underly model
+   */
+  public SpinnerModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * Gets the next value without changing the current value.
+   *
+   * @return the next value
+   *
+   * @see javax.swing.SpinnerModel#getNextValue
+   */
+  public Object getNextValue()
+  {
+    return model.getNextValue();
+  }
+
+  /**
+   * Gets the previous value without changing the current value.
+   *
+   * @return the previous value
+   *
+   * @see javax.swing.SpinnerModel#getPreviousValue
+   */
+  public Object getPreviousValue()
+  {
+    return model.getPreviousValue();
+  }
+
+  /**
+   * Gets the <code>SpinnerUI</code> that handles this spinner
+   *
+   * @return the <code>SpinnerUI</code>
+   */
+  public SpinnerUI getUI()
+  {
+    return (SpinnerUI) ui;
+  }
+
+  /**
+   * Gets the current value of the spinner, according to the underly model,
+   * not the UI.
+   *
+   * @return the current value
+   *
+   * @see javax.swing.SpinnerModel#getValue
+   */
+  public Object getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param value DOCUMENT ME!
+   */
+  public void setValue(Object value)
+  {
+    model.setValue(value);
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for this spinner.
+   *
+   * @return The UIClass identifier. "SpinnerUI"
+   */
+  public String getUIClassID()
+  {
+    return "SpinnerUI";
+  }
+
+  /**
+   * This method resets the spinner's UI delegate to the default UI for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SpinnerUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method sets the spinner's UI delegate.
+   *
+   * @param ui The spinner's UI delegate.
+   */
+  public void setUI(SpinnerUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Adds a <code>ChangeListener</code>
+   *
+   * @param listener the listener to add
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Remove a particular listener
+   *
+   * @param listener the listener to remove
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * Gets all the <code>ChangeListener</code>s
+   *
+   * @return all the <code>ChangeListener</code>s
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s
+   * added to this <code>JSpinner</code>
+   */
+  protected void fireStateChanged()
+  {
+    ChangeEvent evt = new ChangeEvent(this);
+    ChangeListener[] listeners = getChangeListeners();
+
+    for (int i = 0; i < listeners.length; ++i)
+      listeners[i].stateChanged(evt);
+  }
+
+  /**
+   * Creates an editor for this <code>JSpinner</code>. Really, it should be a
+   * <code>JSpinner.DefaultEditor</code>, but since that should be
+   * implemented by a JFormattedTextField, and one is not written, I am just
+   * using a dummy one backed by a JLabel.
+   *
+   * @param model DOCUMENT ME!
+   *
+   * @return the default editor
+   */
+  protected JComponent createEditor(SpinnerModel model)
+  {
+    return new StubEditor(this);
+  } /* TODO */}
Index: javax/swing/JSplitPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JSplitPane.java,v
retrieving revision 1.2
diff -u -r1.2 JSplitPane.java
--- javax/swing/JSplitPane.java	10 Jan 2004 21:07:43 -0000	1.2
+++ javax/swing/JSplitPane.java	6 Sep 2004 16:35:58 -0000
@@ -1,5 +1,5 @@
-/* JSplitPane.java --
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* JSplitPane.java -- 
+   Copyright (C) 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,614 +35,782 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
+
 package javax.swing;
 
 import java.awt.Component;
 import java.awt.Graphics;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleValue;
+import javax.swing.UIManager;
 import javax.swing.plaf.SplitPaneUI;
 
+
 /**
- * JSplitPane
- * @author	Andrew Selkirk
- * @version	1.0
+ * This class implements JSplitPane. It is used to divide two components. By
+ * dragging the SplitPane's divider, the user can resize the two components.
+ * Note that the divider cannot resize a component to smaller than it's
+ * minimum size.
  */
-public class JSplitPane extends JComponent implements Accessible {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJSplitPane
-	 */
-	protected class AccessibleJSplitPane extends AccessibleJComponent 
-			implements AccessibleValue {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJSplitPane
-		 * @param component TODO
-		 */
-		protected AccessibleJSplitPane(JSplitPane component) {
-			super(component);
-			// TODO
-		} // AccessibleJSplitPane()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.SPLIT_PANE;
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleValue
-		 * @returns AccessibleValue
-		 */
-		public AccessibleValue getAccessibleValue() {
-			return null; // TODO
-		} // getAccessibleValue()
-
-		/**
-		 * getCurrentAccessibleValue
-		 * @returns Number
-		 */
-		public Number getCurrentAccessibleValue() {
-			return null; // TODO
-		} // getCurrentAccessibleValue()
-
-		/**
-		 * setCurrentAccessibleValue
-		 * @param value0 TODO
-		 * @returns boolean
-		 */
-		public boolean setCurrentAccessibleValue(Number value0) {
-			return false; // TODO
-		} // setCurrentAccessibleValue()
-
-		/**
-		 * getMinimumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMinimumAccessibleValue() {
-			return null; // TODO
-		} // getMinimumAccessibleValue()
-
-		/**
-		 * getMaximumAccessibleValue
-		 * @returns Number
-		 */
-		public Number getMaximumAccessibleValue() {
-			return null; // TODO
-		} // getMaximumAccessibleValue()
-
-
-	} // AccessibleJSplitPane
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "SplitPaneUI";
-
-	/**
-	 * VERTICAL_SPLIT
-	 */
-	public static final int VERTICAL_SPLIT = 0;
-
-	/**
-	 * HORIZONTAL_SPLIT
-	 */
-	public static final int HORIZONTAL_SPLIT = 1;
-
-	/**
-	 * LEFT
-	 */
-	public static final String LEFT = "left";
-
-	/**
-	 * RIGHT
-	 */
-	public static final String RIGHT = "right";
-
-	/**
-	 * TOP
-	 */
-	public static final String TOP = "top";
-
-	/**
-	 * BOTTOM
-	 */
-	public static final String BOTTOM = "bottom";
-
-	/**
-	 * DIVIDER
-	 */
-	public static final String DIVIDER = "divider";
-
-	/**
-	 * ORIENTATION_PROPERTY
-	 */
-	public static final String ORIENTATION_PROPERTY = "orientation";
-
-	/**
-	 * CONTINUOUS_LAYOUT_PROPERTY
-	 */
-	public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
-
-	/**
-	 * DIVIDER_SIZE_PROPERTY
-	 */
-	public static final String DIVIDER_SIZE_PROPERTY = "dividerSize";
-
-	/**
-	 * ONE_TOUCH_EXPANDABLE_PROPERTY
-	 */
-	public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = "oneTouchExpandable";
-
-	/**
-	 * LAST_DIVIDER_LOCATION_PROPERTY
-	 */
-	public static final String LAST_DIVIDER_LOCATION_PROPERTY = "lastDividerLocation";
-
-	/**
-	 * DIVIDER_LOCATION_PROPERTY
-	 */
-	public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation";
-
-	/**
-	 * RESIZE_WEIGHT_PROPERTY
-	 */
-	public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight";
-
-	/**
-	 * orientation
-	 */
-	protected int orientation;
-
-	/**
-	 * continuousLayout
-	 */
-	protected boolean continuousLayout;
-
-	/**
-	 * leftComponent
-	 */
-	protected Component leftComponent;
-
-	/**
-	 * rightComponent
-	 */
-	protected Component rightComponent;
-
-	/**
-	 * dividerSize
-	 */
-	protected int dividerSize;
-
-	/**
-	 * oneTouchExpandable
-	 */
-	protected boolean oneTouchExpandable;
-
-	/**
-	 * lastDividerLocation
-	 */
-	protected int lastDividerLocation;
-
-	/**
-	 * resizeWeight
-	 */
-	private double resizeWeight;
-
-	/**
-	 * dividerLocation
-	 */
-	private int dividerLocation;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JSplitPane
-	 */
-	public JSplitPane() {
-		// TODO
-	} // JSplitPane()
-
-	/**
-	 * Constructor JSplitPane
-	 * @param value0 TODO
-	 */
-	public JSplitPane(int value0) {
-		// TODO
-	} // JSplitPane()
-
-	/**
-	 * Constructor JSplitPane
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public JSplitPane(int value0, boolean value1) {
-		// TODO
-	} // JSplitPane()
-
-	/**
-	 * Constructor JSplitPane
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @param value2 TODO
-	 */
-	public JSplitPane(int value0, Component value1, Component value2) {
-		// TODO
-	} // JSplitPane()
-
-	/**
-	 * Constructor JSplitPane
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @param value2 TODO
-	 * @param value3 TODO
-	 */
-	public JSplitPane(int value0, boolean value1, Component value2, Component value3) {
-		// TODO
-	} // JSplitPane()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * remove
-	 * @param value0 TODO
-	 */
-	public void remove(Component value0) {
-		// TODO
-	} // remove()
-
-	/**
-	 * remove
-	 * @param value0 TODO
-	 */
-	public void remove(int value0) {
-		// TODO
-	} // remove()
-
-	/**
-	 * removeAll
-	 */
-	public void removeAll() {
-		// TODO
-	} // removeAll()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(SplitPaneUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * getUI
-	 * @returns SplitPaneUI
-	 */
-	public SplitPaneUI getUI() {
-		return (SplitPaneUI) ui;
-	} // getUI()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((SplitPaneUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * setDividerSize
-	 * @param value0 TODO
-	 */
-	public void setDividerSize(int value0) {
-		// TODO
-	} // setDividerSize()
-
-	/**
-	 * getDividerSize
-	 * @returns int
-	 */
-	public int getDividerSize() {
-		return 0; // TODO
-	} // getDividerSize()
-
-	/**
-	 * setLeftComponent
-	 * @param value0 TODO
-	 */
-	public void setLeftComponent(Component value0) {
-		// TODO
-	} // setLeftComponent()
-
-	/**
-	 * getLeftComponent
-	 * @returns Component
-	 */
-	public Component getLeftComponent() {
-		return null; // TODO
-	} // getLeftComponent()
-
-	/**
-	 * setTopComponent
-	 * @param value0 TODO
-	 */
-	public void setTopComponent(Component value0) {
-		// TODO
-	} // setTopComponent()
-
-	/**
-	 * getTopComponent
-	 * @returns Component
-	 */
-	public Component getTopComponent() {
-		return null; // TODO
-	} // getTopComponent()
-
-	/**
-	 * setRightComponent
-	 * @param value0 TODO
-	 */
-	public void setRightComponent(Component value0) {
-		// TODO
-	} // setRightComponent()
-
-	/**
-	 * getRightComponent
-	 * @returns Component
-	 */
-	public Component getRightComponent() {
-		return null; // TODO
-	} // getRightComponent()
-
-	/**
-	 * setBottomComponent
-	 * @param value0 TODO
-	 */
-	public void setBottomComponent(Component value0) {
-		// TODO
-	} // setBottomComponent()
-
-	/**
-	 * getBottomComponent
-	 * @returns Component
-	 */
-	public Component getBottomComponent() {
-		return null; // TODO
-	} // getBottomComponent()
-
-	/**
-	 * setOneTouchExpandable
-	 * @param value0 TODO
-	 */
-	public void setOneTouchExpandable(boolean value0) {
-		// TODO
-	} // setOneTouchExpandable()
-
-	/**
-	 * isOneTouchExpandable
-	 * @returns boolean
-	 */
-	public boolean isOneTouchExpandable() {
-		return false; // TODO
-	} // isOneTouchExpandable()
-
-	/**
-	 * setLastDividerLocation
-	 * @param value0 TODO
-	 */
-	public void setLastDividerLocation(int value0) {
-		// TODO
-	} // setLastDividerLocation()
-
-	/**
-	 * getLastDividerLocation
-	 * @returns int
-	 */
-	public int getLastDividerLocation() {
-		return 0; // TODO
-	} // getLastDividerLocation()
-
-	/**
-	 * setOrientation
-	 * @param value0 TODO
-	 */
-	public void setOrientation(int value0) {
-		// TODO
-	} // setOrientation()
-
-	/**
-	 * getOrientation
-	 * @returns int
-	 */
-	public int getOrientation() {
-		return 0; // TODO
-	} // getOrientation()
-
-	/**
-	 * setContinuousLayout
-	 * @param value0 TODO
-	 */
-	public void setContinuousLayout(boolean value0) {
-		// TODO
-	} // setContinuousLayout()
-
-	/**
-	 * isContinuousLayout
-	 * @returns boolean
-	 */
-	public boolean isContinuousLayout() {
-		return false; // TODO
-	} // isContinuousLayout()
-
-	/**
-	 * setResizeWeight
-	 * @param value0 TODO
-	 */
-	public void setResizeWeight(double value0) {
-		// TODO
-	} // setResizeWeight()
-
-	/**
-	 * getResizeWeight
-	 * @returns double
-	 */
-	public double getResizeWeight() {
-		return 0.0; // TODO
-	} // getResizeWeight()
-
-	/**
-	 * resetToPreferredSizes
-	 */
-	public void resetToPreferredSizes() {
-		// TODO
-	} // resetToPreferredSizes()
-
-	/**
-	 * setDividerLocation
-	 * @param value0 TODO
-	 */
-	public void setDividerLocation(double value0) {
-		// TODO
-	} // setDividerLocation()
-
-	/**
-	 * setDividerLocation
-	 * @param value0 TODO
-	 */
-	public void setDividerLocation(int value0) {
-		// TODO
-	} // setDividerLocation()
-
-	/**
-	 * getDividerLocation
-	 * @returns int
-	 */
-	public int getDividerLocation() {
-		return 0; // TODO
-	} // getDividerLocation()
-
-	/**
-	 * getMinimumDividerLocation
-	 * @returns int
-	 */
-	public int getMinimumDividerLocation() {
-		return 0; // TODO
-	} // getMinimumDividerLocation()
-
-	/**
-	 * getMaximumDividerLocation
-	 * @returns int
-	 */
-	public int getMaximumDividerLocation() {
-		return 0; // TODO
-	} // getMaximumDividerLocation()
-
-	/**
-	 * isValidateRoot
-	 * @returns boolean
-	 */
-	public boolean isValidateRoot() {
-		return false; // TODO
-	} // isValidateRoot()
-
-	/**
-	 * addImpl
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @param value2 TODO
-	 */
-	protected void addImpl(Component value0, Object value1, int value2) {
-		// TODO
-	} // addImpl()
-
-	/**
-	 * paintChildren
-	 * @param value0 TODO
-	 */
-	protected void paintChildren(Graphics value0) {
-		// TODO
-	} // paintChildren()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
-
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJSplitPane(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JSplitPane
+public class JSplitPane extends JComponent implements Accessible
+{
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+  private static final long serialVersionUID = -1788116871416305366L;
+  
+    /**
+     * Creates a new AccessibleJSplitPane object.
+     *
+     * @param value0 DOCUMENT ME!
+     */
+    protected AccessibleJSplitPane()
+    {
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param value0 DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean setCurrentAccessibleValue(Number value0)
+    {
+      return false;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null;
+    }
+  }
+
+  private static final long serialVersionUID = -5634142046175988380L;
+  
+  /** The constraints string used to add components to the bottom. */
+  public static final String BOTTOM = "bottom";
+
+  /** The property fired when the continuousLayout property changes. */
+  public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
+
+  /** The property fired when the divider property changes. */
+  public static final String DIVIDER = "divider";
+
+  /** The property fired when the divider location property changes. */
+  public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation";
+
+  /** The property fired when the divider size property changes. */
+  public static final String DIVIDER_SIZE_PROPERTY = "dividerSize";
+
+  /**
+   * The value of the orientation when the components are split horizontally.
+   */
+  public static final int HORIZONTAL_SPLIT = 1;
+
+  /** The property fired when the last divider location property changes. */
+  public static final String LAST_DIVIDER_LOCATION_PROPERTY = "lastDividerLocation";
+
+  /** The constraints string used to add components to the left. */
+  public static final String LEFT = "left";
+
+  /** The property fired when the one touch expandable property changes. */
+  public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = "oneTouchExpandable";
+
+  /** The property fired when the orientation property changes. */
+  public static final String ORIENTATION_PROPERTY = "orientation";
+
+  /** The property fired when the resize weight property changes. */
+  public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight";
+
+  /** The constraints string used to add components to the right. */
+  public static final String RIGHT = "right";
+
+  /** The constraints string used to add components to the top. */
+  public static final String TOP = "top";
+
+  /** The value of the orientation when the components are split vertically. */
+  public static final int VERTICAL_SPLIT = 0;
+
+  /** Whether the JSplitPane uses continuous layout. */
+  protected boolean continuousLayout;
+
+  /** Whether the JSplitPane uses one touch expandable buttons. */
+  protected boolean oneTouchExpandable = false;
+
+  // This is the master dividerSize variable and sets the BasicSplitPaneDivider one accordingly
+
+  /** The size of the divider. */
+  protected int dividerSize = 10;
+
+  /** The last location of the divider given by the UI. */
+  protected int lastDividerLocation;
+
+  /** The orientation of the JSplitPane. */
+  protected int orientation;
+
+  /** The component on the top or left. */
+  protected Component leftComponent;
+
+  /** The component on the right or bottom. */
+  protected Component rightComponent;
+
+  /** Determines how extra space should be allocated. */
+  private transient double resizeWeight;
+
+  /**
+   * Creates a new JSplitPane object with the given orientation, layout mode,
+   * and left and right components.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newContinuousLayout The layout mode to use.
+   * @param newLeftComponent The left component.
+   * @param newRightComponent The right component.
+   *
+   * @throws IllegalArgumentException DOCUMENT ME!
+   */
+  public JSplitPane(int newOrientation, boolean newContinuousLayout,
+                    Component newLeftComponent, Component newRightComponent)
+  {
+    if (newOrientation != HORIZONTAL_SPLIT && newOrientation != VERTICAL_SPLIT)
+      throw new IllegalArgumentException("orientation is invalid.");
+    orientation = newOrientation;
+    continuousLayout = newContinuousLayout;
+    setLeftComponent(newLeftComponent);
+    setRightComponent(newRightComponent);
+
+    updateUI();
+  }
+
+  /**
+   * Creates a new JSplitPane object using nonContinuousLayout mode, the given
+   * orientation and left and right components.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newLeftComponent The left component.
+   * @param newRightComponent The right component.
+   */
+  public JSplitPane(int newOrientation, Component newLeftComponent,
+                    Component newRightComponent)
+  {
+    this(newOrientation, false, newLeftComponent, newRightComponent);
+  }
+
+  /**
+   * Creates a new JSplitPane object with the given layout mode and
+   * orientation.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newContinuousLayout The layout mode to use.
+   */
+  public JSplitPane(int newOrientation, boolean newContinuousLayout)
+  {
+    this(newOrientation, newContinuousLayout, null, null);
+  }
+
+  /**
+   * Creates a new JSplitPane object using a nonContinuousLayout mode and the
+   * given orientation.
+   *
+   * @param newOrientation The orientation to use.
+   */
+  public JSplitPane(int newOrientation)
+  {
+    this(newOrientation, false, null, null);
+  }
+
+  /**
+   * Creates a new JSplitPane object using HORIZONTAL_SPLIT and a
+   * nonContinuousLayout mode.
+   */
+  public JSplitPane()
+  {
+    this(HORIZONTAL_SPLIT, false, null, null);
+  }
+
+  /**
+   * This method adds a component to the JSplitPane. The constraints object is
+   * a string that identifies where this component should go. If the
+   * constraints is not a known one, it will throw an
+   * IllegalArgumentException. The valid constraints are LEFT, TOP, RIGHT,
+   * BOTTOM and DIVIDER.
+   *
+   * @param comp The component to add.
+   * @param constraints The constraints string to use.
+   * @param index Where to place to component in the list of components.
+   *
+   * @throws IllegalArgumentException When the constraints is not a known identifier.
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    int left = 0;
+    int right = 1;
+    int div = 2;
+    int place;
+    if (constraints == null)
+      {
+	if (leftComponent == null)
+	  constraints = LEFT;
+	else if (rightComponent == null)
+	  constraints = RIGHT;
+      }
+
+    if (constraints instanceof String)
+      {
+	String placement = (String) constraints;
+
+	if (placement.equals(BOTTOM) || placement.equals(RIGHT))
+	  {
+	    if (rightComponent != null)
+		remove(rightComponent);
+	    rightComponent = comp;
+	  }
+	else if (placement.equals(LEFT) || placement.equals(TOP))
+	  {
+	    if (leftComponent != null)
+	      remove(leftComponent);
+	    leftComponent = comp;
+	  }
+	else if (placement.equals(DIVIDER))
+	  constraints = null;
+	else
+	  throw new IllegalArgumentException("Constraints is not a known identifier.");
+
+	super.addImpl(comp, constraints, index);
+      }
+    invalidate();
+    layout();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSplitPane();
+    
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the bottom component.
+   *
+   * @return The bottom component.
+   */
+  public Component getBottomComponent()
+  {
+    return rightComponent;
+  }
+
+  /**
+   * This method returns the location of the divider. This method is passed to
+   * the UI.
+   *
+   * @return The location of the divider.
+   */
+  public int getDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the size of the divider.
+   *
+   * @return The size of the divider.
+   */
+  public int getDividerSize()
+  {
+    return dividerSize;
+  }
+
+  /**
+   * This method returns the last divider location.
+   *
+   * @return The last divider location.
+   */
+  public int getLastDividerLocation()
+  {
+    return lastDividerLocation;
+  }
+
+  /**
+   * This method returns the left component.
+   *
+   * @return The left component.
+   */
+  public Component getLeftComponent()
+  {
+    return leftComponent;
+  }
+
+  /**
+   * This method returns the maximum divider location. This method is passed
+   * to  the UI.
+   *
+   * @return DOCUMENT ME!
+   */
+  public int getMaximumDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getMaximumDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the minimum divider location. This method is passed
+   * to the UI.
+   *
+   * @return The minimum divider location.
+   */
+  public int getMinimumDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getMinimumDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the orientation that the JSplitPane is using.
+   *
+   * @return The current orientation.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method returns the current resize weight.
+   *
+   * @return The current resize weight.
+   */
+  public double getResizeWeight()
+  {
+    return resizeWeight;
+  }
+
+  /**
+   * This method returns the right component.
+   *
+   * @return The right component.
+   */
+  public Component getRightComponent()
+  {
+    return rightComponent;
+  }
+
+  /**
+   * This method returns the top component.
+   *
+   * @return The top component.
+   */
+  public Component getTopComponent()
+  {
+    return leftComponent;
+  }
+
+  /**
+   * This method returns the UI.
+   *
+   * @return The UI.
+   */
+  public SplitPaneUI getUI()
+  {
+    return (SplitPaneUI) ui;
+  }
+
+  /**
+   * This method returns true if the JSplitPane is using a continuousLayout.
+   *
+   * @return True if using a continuousLayout.
+   */
+  public boolean isContinuousLayout()
+  {
+    return continuousLayout;
+  }
+
+  /**
+   * This method returns true if the divider has one touch expandable buttons.
+   *
+   * @return True if one touch expandable is used.
+   */
+  public boolean isOneTouchExpandable()
+  {
+    return oneTouchExpandable;
+  }
+
+  /**
+   * This method returns true.
+   *
+   * @return true.
+   */
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  /**
+   * This method overrides JComponent's paintChildren so the UI can be
+   * messaged when the children have finished painting.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintChildren(Graphics g)
+  {
+    super.paintChildren(g);
+    if (ui != null)
+      ((SplitPaneUI) ui).finishedPaintingChildren(this, g);
+  }
+
+  /**
+   * This method returns a String that describes this JSplitPane. The string
+   * is primarily used for debugging purposes.
+   *
+   * @return A String used for debugging purposes.
+   */
+  protected String paramString()
+  {
+    return "JSplitPane";
+  }
+
+  /**
+   * This method removes the given component from the JSplitPane.
+   *
+   * @param component The Component to remove.
+   */
+  public void remove(Component component)
+  {
+    if (component == leftComponent)
+      leftComponent = null;
+    else if (component == rightComponent)
+      rightComponent = null;
+    super.remove(component);
+  }
+
+  /**
+   * This method removes the component at the given index.
+   *
+   * @param index The index of the component to remove.
+   */
+  public void remove(int index)
+  {
+    Component component = getComponent(index);
+    if (component == leftComponent)
+      leftComponent = null;
+    else if (component == rightComponent)
+      rightComponent = null;
+    super.remove(index);
+  }
+
+  /**
+   * This method removes all components from the JSplitPane.
+   */
+  public void removeAll()
+  {
+    leftComponent = null;
+    rightComponent = null;
+    super.removeAll();
+  }
+
+  /**
+   * This method resets all children of the JSplitPane to their preferred
+   * sizes.
+   */
+  public void resetToPreferredSizes()
+  {
+    if (ui != null)
+      ((SplitPaneUI) ui).resetToPreferredSizes(this);
+  }
+
+  /**
+   * This method sets the bottom component.
+   *
+   * @param comp The Component to be placed at the bottom.
+   */
+  public void setBottomComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, BOTTOM);
+    else
+      add(new JButton("right button"), BOTTOM);
+  }
+
+  /**
+   * This method sets the layout mode for the JSplitPane.
+   *
+   * @param newContinuousLayout Whether the JSplitPane is in continuousLayout
+   *        mode.
+   */
+  public void setContinuousLayout(boolean newContinuousLayout)
+  {
+    if (newContinuousLayout != continuousLayout)
+      {
+	boolean oldValue = continuousLayout;
+	continuousLayout = newContinuousLayout;
+	firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue,
+	                   continuousLayout);
+      }
+  }
+
+  /**
+   * This method sets the location of the divider. A value of 0 sets the
+   * divider to the farthest left. A value of 1 sets the divider to the
+   * farthest right.
+   *
+   * @param proportionalLocation A double that describes the location of the
+   *        divider.
+   *
+   * @throws IllegalArgumentException DOCUMENT ME!
+   */
+  public void setDividerLocation(double proportionalLocation)
+  {
+    if (proportionalLocation > 1 || proportionalLocation < 0)
+      throw new IllegalArgumentException("proportion has to be between 0 and 1.");
+
+    int max = (orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight();
+    setDividerLocation((int) (proportionalLocation * max));
+  }
+
+  /**
+   * This method sets the location of the divider.
+   *
+   * @param location The location of the divider.
+   */
+  public void setDividerLocation(int location)
+  {
+    if (ui != null && location != getDividerLocation())
+      {
+	int oldLocation = getDividerLocation();
+	((SplitPaneUI) ui).setDividerLocation(this, location);
+	firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldLocation, location);
+      }
+  }
+
+  /**
+   * This method sets the size of the divider.
+   *
+   * @param newSize The size of the divider.
+   */
+  public void setDividerSize(int newSize)
+  {
+    if (newSize != dividerSize)
+      {
+	int oldSize = dividerSize;
+	dividerSize = newSize;
+	firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, dividerSize);
+      }
+  }
+
+  // This doesn't appear to do anything when set from user side.
+  // so it probably is only used from the UI side to change the
+  // lastDividerLocation var.
+
+  /**
+   * This method sets the last location of the divider.
+   *
+   * @param newLastLocation The last location of the divider.
+   */
+  public void setLastDividerLocation(int newLastLocation)
+  {
+    if (newLastLocation != lastDividerLocation)
+      {
+	int oldValue = lastDividerLocation;
+	lastDividerLocation = newLastLocation;
+	firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldValue,
+	                   lastDividerLocation);
+      }
+  }
+
+  /**
+   * This method sets the left component.
+   *
+   * @param comp The left component.
+   */
+  public void setLeftComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, LEFT);
+    else
+      add(new JButton("left button"), LEFT);
+  }
+
+  /**
+   * This method sets whether the divider has one touch expandable buttons.
+   * The one touch expandable buttons can expand the size of either component
+   * to the maximum allowed size.
+   *
+   * @param newValue Whether the divider will have one touch expandable
+   *        buttons.
+   */
+  public void setOneTouchExpandable(boolean newValue)
+  {
+    if (newValue != oneTouchExpandable)
+      {
+	boolean oldValue = oneTouchExpandable;
+	oneTouchExpandable = newValue;
+	firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue,
+	                   oneTouchExpandable);
+      }
+  }
+
+  /**
+   * This method sets the orientation of the JSplitPane.
+   *
+   * @param orientation The orientation of the JSplitPane.
+   *
+   * @throws IllegalArgumentException DOCUMENT ME!
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
+      throw new IllegalArgumentException("orientation must be one of VERTICAL_SPLIT, HORIZONTAL_SPLIT");
+    if (orientation != this.orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange(ORIENTATION_PROPERTY, oldOrientation,
+	                   this.orientation);
+      }
+  }
+
+  /**
+   * This method determines how extra space will be distributed among the left
+   * and right components. A value of 0 will allocate all extra space to the
+   * right component. A value of 1 indicates that all extra space will go to
+   * the left component. A value in between 1 and 0 will split the space
+   * accordingly.
+   *
+   * @param value The resize weight.
+   */
+  public void setResizeWeight(double value)
+  {
+    resizeWeight = value;
+  }
+
+  /**
+   * This method sets the right component.
+   *
+   * @param comp The right component.
+   */
+  public void setRightComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, RIGHT);
+    else
+	add(new JButton("right button"), RIGHT);
+  }
+
+  /**
+   * This method sets the top component.
+   *
+   * @param comp The top component.
+   */
+  public void setTopComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, TOP);
+    else
+      add(new JButton("left button"), TOP);
+  }
+
+  /**
+   * This method sets the UI used by the JSplitPane.
+   *
+   * @param ui The UI to use.
+   */
+  public void setUI(SplitPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method resets the UI to the one specified by the current Look and
+   * Feel.
+   */
+  public void updateUI()
+  {
+    setUI((SplitPaneUI) UIManager.getUI(this));
+    invalidate();
+    repaint();
+  }
+
+  /**
+   * This method returns a string identifier to determine which UI class it
+   * needs.
+   *
+   * @return A string that identifies it's UI class.
+   */
+  public String getUIClassID()
+  {
+    return "SplitPaneUI";
+  }
+}
Index: javax/swing/JTabbedPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JTabbedPane.java,v
retrieving revision 1.2
diff -u -r1.2 JTabbedPane.java
--- javax/swing/JTabbedPane.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JTabbedPane.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
-/* JTabbedPane.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JTabbedPane.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,96 +35,1459 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.io.Serializable;
 import java.util.Vector;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.plaf.TabbedPaneUI;
+import javax.swing.plaf.UIResource;
+
 
-public class JTabbedPane extends JComponent implements Accessible, SwingConstants
+/**
+ * <p>
+ * This is a container for components. One component is displayed at a time.
+ * Users can switch between components by clicking on tabs.
+ * </p>
+ * 
+ * <p>
+ * Tabs can be oriented in several ways. They can be above, below, left and
+ * right of the component. Tabs can either wrap around (by creating multiple
+ * rows of tabs) or they can be scrolled (where only a subset of the  tabs
+ * can be seen at once). More tabs can be added by calling the
+ * add/addTab/insertTab methods.
+ * </p>
+ */
+public class JTabbedPane extends JComponent implements Serializable,
+                                                       Accessible,
+                                                       SwingConstants
 {
-    class Tab
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
+    implements AccessibleSelection, ChangeListener
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 7610530885966830483L;
+
+    /**
+     * Creates a new AccessibleJTabbedPane object.
+     */
+    public AccessibleJTabbedPane()
+    {
+      super();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void stateChanged(ChangeEvent e)
     {
-	Icon icon;
-	String name, descr;
-	Component tab;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
 
-	Tab(String name,
-	    Icon icon,
-	    Component tab,
-	    String descr)
-	{
-	    this.name = name;
-	    this.icon = icon;
-	    this.tab  = tab;
-	    this.descr = descr;
-	}
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getAccessibleChildrenCount()
+    {
+      return 0;
     }
-    
-    private Vector tabs = new Vector();
 
-    public JTabbedPane()
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Accessible getAccessibleChild(int i)
     {
+      return null;
     }
 
-    public void addTab(String name,
-		Component panel)		
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleSelection getAccessibleSelection()
     {
-	addTab(name, null, panel, null);
+      return null;
     }
-    public void addTab(String name,
-		Icon icon,
-		Component panel)		
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param p DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Accessible getAccessibleAt(Point p)
     {
-	addTab(name, icon, panel, null);
+      return null;
     }
-    public void addTab(String name,
-		Icon icon,
-		Component panel,
-		String descr)
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public int getAccessibleSelectionCount()
     {
-	tabs.addElement(new Tab(name, icon, panel, descr));
+      return 0;
     }
 
-    public int getTabCount()
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Accessible getAccessibleSelection(int i)
     {
-	return tabs.size();
+      return null;
     }
-    public Component getComponentAt(int i)
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean isAccessibleChildSelected(int i)
     {
-	Tab t = (Tab) tabs.elementAt(i);
-	return t.tab;
+      return false;
     }
-    
-    public String getUIClassID()
-    {	return "JTabbedPane";    }
 
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void addAccessibleSelection(int i)
+    {
+    }
 
-    public void setUI(TabbedPaneUI ui) {
-        super.setUI(ui);
+    /**
+     * DOCUMENT ME!
+     *
+     * @param i DOCUMENT ME!
+     */
+    public void removeAccessibleSelection(int i)
+    {
     }
-    
-    public TabbedPaneUI getUI() {
-        return (TabbedPaneUI)ui;
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void clearAccessibleSelection()
+    {
     }
-    
-    public void updateUI()
+
+    /**
+     * DOCUMENT ME!
+     */
+    public void selectAllAccessibleSelection()
     {
-        setUI((TabbedPaneUI)UIManager.getUI(this));
     }
-    
-    public AccessibleContext getAccessibleContext()
+  }
+
+  /**
+   * A helper class that listens for changes to the model.
+   */
+  protected class ModelListener implements ChangeListener, Serializable
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 497359819958114132L;
+
+    /**
+     * Creates a new ModelListener object.
+     */
+    protected ModelListener()
     {
-	return null;
     }
-    
-   protected  String paramString()
+
+    /**
+     * This method is called whenever the model  is changed.
+     *
+     * @param e The ChangeEvent that is passed from the model.
+     */
+    public void stateChanged(ChangeEvent e)
     {
-	return "JTabbedPane";
+      // Propagate to our listeners.
+      fireStateChanged();
     }
+  }
+
+  /**
+   * A private class that holds all the information  for each tab.
+   */
+  private class Page
+  {
+    /** The tooltip string. */
+    private String tip;
+
+    /** The component associated with the tab. */
+    private Component component;
+
+    /** The active icon associated with the tab. */
+    private transient Icon icon;
+
+    /** The disabled icon associated with the tab. */
+    private transient Icon disabledIcon;
+
+    /** The tab's enabled status. */
+    private transient boolean enabled = true;
+
+    /** The string painted on the tab. */
+    private transient String title;
+
+    /** The background color of the tab. */
+    private transient Color bg;
+
+    /** The foreground color of the tab. */
+    private transient Color fg;
+
+    /** The mnemonic associated with the tab. */
+    private transient int mnemonicKey;
+
+    /** The index of the underlined character in the string. */
+    private transient int underlinedChar = -1;
+
+    /**
+     * Creates a new data storage for the tab.
+     *
+     * @param title The string displayed on the tab.
+     * @param icon The active icon displayed on the tab.
+     * @param component The component associated with the tab.
+     * @param tip The tooltip associated with the tab.
+     */
+    protected Page(String title, Icon icon, Component component, String tip)
+    {
+      this.title = title;
+      this.icon = icon;
+      this.component = component;
+      this.tip = tip;
+    }
+
+    /**
+     * This method returns the component associated with the tab.
+     *
+     * @return The component associated with the tab.
+     */
+    public Component getComponent()
+    {
+      return component;
+    }
+
+    /**
+     * This method sets the component associated with the tab.
+     *
+     * @param c The component associated with the tab.
+     */
+    public void setComponent(Component c)
+    {
+      remove(component);
+      this.component = c;
+      add(c);
+    }
+
+    /**
+     * This method returns the tooltip string.
+     *
+     * @return The tooltip string.
+     */
+    public String getTip()
+    {
+      return tip;
+    }
+
+    /**
+     * This method sets the tooltip string.
+     *
+     * @param tip The tooltip string.
+     */
+    public void setTip(String tip)
+    {
+      this.tip = tip;
+    }
+
+    /**
+     * This method returns the background color.
+     *
+     * @return The background color.
+     */
+    public Color getBackground()
+    {
+      return bg;
+    }
+
+    /**
+     * This method sets the background color.
+     *
+     * @param background The background color.
+     */
+    public void setBackground(Color background)
+    {
+      bg = background;
+    }
+
+    /**
+     * This method returns the foreground color.
+     *
+     * @return The foreground color.
+     */
+    public Color getForeground()
+    {
+      return fg;
+    }
+
+    /**
+     * This method sets the foreground color.
+     *
+     * @param foreground The foreground color.
+     */
+    public void setForeground(Color foreground)
+    {
+      fg = foreground;
+    }
+
+    /**
+     * This method returns the title associated with the tab.
+     *
+     * @return The title of the tab.
+     */
+    public String getTitle()
+    {
+      return title;
+    }
+
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = 1614381073220130939L;
+
+    /**
+     * This method sets the title of the tab.
+     *
+     * @param text The title of the tab.
+     */
+    public void setTitle(String text)
+    {
+      title = text;
+      if (title != null && title.length() <= underlinedChar)
+	setDisplayedMnemonicIndex(title.length() - 1);
+    }
+
+    /**
+     * This method returns the active icon.
+     *
+     * @return The active icon.
+     */
+    public Icon getIcon()
+    {
+      return icon;
+    }
+
+    /**
+     * This method sets the active icon.
+     *
+     * @param icon The active icon.
+     */
+    public void setIcon(Icon icon)
+    {
+      this.icon = icon;
+    }
+
+    /**
+     * This method returns the disabled icon.
+     *
+     * @return The disabled icon.
+     */
+    public Icon getDisabledIcon()
+    {
+      if (disabledIcon == null && icon instanceof ImageIcon)
+	setDisabledIcon(icon);
+      return disabledIcon;
+    }
+
+    /**
+     * This method sets the disabled icon.
+     *
+     * @param disabledIcon The disabled icon.
+     */
+    public void setDisabledIcon(Icon disabledIcon)
+    {
+      this.disabledIcon = disabledIcon;
+    }
+
+    /**
+     * This method returns whether the tab is enabled.
+     *
+     * @return Whether the tab is enabled.
+     */
+    public boolean isEnabled()
+    {
+      return enabled;
+    }
+
+    /**
+     * This method sets whether the tab is enabled.
+     *
+     * @param enabled Whether this tab is enabled.
+     */
+    public void setEnabled(boolean enabled)
+    {
+      this.enabled = enabled;
+    }
+
+    /**
+     * This method returns the mnemonic.
+     *
+     * @return The mnemonic.
+     */
+    public int getMnemonic()
+    {
+      return (int) mnemonicKey;
+    }
+
+    /**
+     * This method sets the mnemonic. If the title is set, it will update the
+     * mnemonicIndex.
+     *
+     * @param key The mnemonic.
+     */
+    public void setMnemonic(int key)
+    {
+      setMnemonic((char) key);
+    }
+
+    /**
+     * This method sets the mnemonic. If the title is set, it will update the
+     * mnemonicIndex.
+     *
+     * @param aChar The mnemonic.
+     */
+    public void setMnemonic(char aChar)
+    {
+      mnemonicKey = aChar;
+      if (title != null)
+	setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
+    }
+
+    /**
+     * This method returns the mnemonicIndex.
+     *
+     * @return The mnemonicIndex.
+     */
+    public int getDisplayedMnemonicIndex()
+    {
+      return underlinedChar;
+    }
+
+    /**
+     * This method sets the mnemonicIndex.
+     *
+     * @param index The mnemonicIndex.
+     *
+     * @throws IllegalArgumentException If index less than -1 || index greater
+     *         or equal to title.length.
+     */
+    public void setDisplayedMnemonicIndex(int index)
+                                   throws IllegalArgumentException
+    {
+      if (index < -1 || title != null && index >= title.length())
+	throw new IllegalArgumentException();
+
+      if (title == null || title.charAt(index) != mnemonicKey)
+	index = -1;
+
+      underlinedChar = index;
+    }
+  }
+
+  /** Fired in a PropertyChangeEvent when the "model" property changes. */
+  public static final String MODEL_CHANGED_PROPERTY = "model";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "tabPlacement" property changes.
+   */
+  public static final String TAB_PLACEMENT_CHANGED_PROPERTY = "tabPlacement";
+
+  /**
+   * Fired in a PropertyChangeEvent when the "tabLayoutPolicy" property
+   * changes.
+   */
+  public static final String TAB_LAYOUT_POLICY_CHANGED_PROPERTY = "tabLayoutPolicy";
+
+  /** The changeEvent used to fire changes to listeners. */
+  protected ChangeEvent changeEvent;
+
+  /** The listener that listens to the model. */
+  protected ChangeListener changeListener;
+
+  /** The model that describes this JTabbedPane. */
+  protected SingleSelectionModel model;
+
+  /** Indicates that the TabbedPane is in scrolling mode. */
+  public static final int SCROLL_TAB_LAYOUT = 1;
+
+  /** Indicates that the TabbedPane is in wrap mode. */
+  public static final int WRAP_TAB_LAYOUT = 0;
+
+  /** The current tabPlacement of the TabbedPane. */
+  protected int tabPlacement = SwingConstants.TOP;
+
+  /** The current tabLayoutPolicy of the TabbedPane. */
+  private transient int layoutPolicy;
+
+  /** The list of tabs associated with the TabbedPane. */
+  transient Vector tabs = new Vector();
+
+  /**
+   * Creates a new JTabbedPane object with tabs on top and using wrap tab
+   * layout.
+   */
+  public JTabbedPane()
+  {
+    this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
+  }
+
+  /**
+   * Creates a new JTabbedPane object using wrap tab layout  and the given
+   * tabPlacement.
+   *
+   * @param tabPlacement Where the tabs will be placed.
+   */
+  public JTabbedPane(int tabPlacement)
+  {
+    this(tabPlacement, WRAP_TAB_LAYOUT);
+  }
+
+  /**
+   * Creates a new JTabbedPane object with the given tabPlacement and
+   * tabLayoutPolicy.
+   *
+   * @param tabPlacement Where the tabs will be placed.
+   * @param tabLayoutPolicy The way tabs will be placed.
+   *
+   * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
+   *         not valid.
+   */
+  public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
+  {
+    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+        && tabPlacement != LEFT)
+      throw new IllegalArgumentException("tabPlacement is not valid.");
+    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+    this.tabPlacement = tabPlacement;
+    layoutPolicy = tabLayoutPolicy;
+
+    changeEvent = new ChangeEvent(this);
+    changeListener = createChangeListener();
+
+    model = new DefaultSingleSelectionModel();
+    model.addChangeListener(changeListener);
+
+    updateUI();
+  }
+
+  /**
+   * This method returns the UI used to display the JTabbedPane.
+   *
+   * @return The UI used to display the JTabbedPane.
+   */
+  public TabbedPaneUI getUI()
+  {
+    return (TabbedPaneUI) ui;
+  }
+
+  /**
+   * This method sets the UI used to display the JTabbedPane.
+   *
+   * @param ui The UI used to display the JTabbedPane.
+   */
+  public void setUI(TabbedPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method restores the UI to the defaults given by the UIManager.
+   */
+  public void updateUI()
+  {
+    setUI((TabbedPaneUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns a string identifier that  is used to determine which
+   * UI will be used with  the JTabbedPane.
+   *
+   * @return A string identifier for the UI.
+   */
+  public String getUIClassID()
+  {
+    return "TabbedPaneUI";
+  }
+
+  /**
+   * This method creates a ChangeListener that is used to  listen to the model
+   * for events.
+   *
+   * @return A ChangeListener to listen to the model.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ModelListener();
+  }
+
+  /**
+   * This method adds a ChangeListener to the JTabbedPane.
+   *
+   * @param l The ChangeListener to add.
+   */
+  public void addChangeListener(ChangeListener l)
+  {
+    listenerList.add(ChangeListener.class, l);
+  }
+
+  /**
+   * This method removes a ChangeListener to the JTabbedPane.
+   *
+   * @param l The ChangeListener to remove.
+   */
+  public void removeChangeListener(ChangeListener l)
+  {
+    listenerList.remove(ChangeListener.class, l);
+  }
+
+  /**
+   * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (changeListeners[i] == ChangeListener.class)
+	  ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * This method returns all ChangeListeners registered with the JTabbedPane.
+   *
+   * @return The ChangeListeners registered with the JTabbedPane.
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) super.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * This method returns the model used with the JTabbedPane.
+   *
+   * @return The JTabbedPane's model.
+   */
+  public SingleSelectionModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * This method changes the model property of the JTabbedPane.
+   *
+   * @param model The new model to use with the JTabbedPane.
+   */
+  public void setModel(SingleSelectionModel model)
+  {
+    if (model != this.model)
+      {
+	SingleSelectionModel oldModel = this.model;
+	this.model.removeChangeListener(changeListener);
+	this.model = model;
+	this.model.addChangeListener(changeListener);
+	firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel, this.model);
+      }
+  }
+
+  /**
+   * This method returns the tabPlacement.
+   *
+   * @return The tabPlacement used with the JTabbedPane.
+   */
+  public int getTabPlacement()
+  {
+    return tabPlacement;
+  }
+
+  /**
+   * This method changes the tabPlacement property of the JTabbedPane.
+   *
+   * @param tabPlacement The tabPlacement to use.
+   *
+   * @throws IllegalArgumentException If tabPlacement is not one of TOP,
+   *         BOTTOM, LEFT, or RIGHT.
+   */
+  public void setTabPlacement(int tabPlacement)
+  {
+    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+        && tabPlacement != LEFT)
+      throw new IllegalArgumentException("tabPlacement is not valid.");
+    if (tabPlacement != this.tabPlacement)
+      {
+	int oldPlacement = this.tabPlacement;
+	this.tabPlacement = tabPlacement;
+	firePropertyChange(TAB_PLACEMENT_CHANGED_PROPERTY, oldPlacement,
+	                   this.tabPlacement);
+      }
+  }
+
+  /**
+   * This method returns the tabLayoutPolicy.
+   *
+   * @return The tabLayoutPolicy.
+   */
+  public int getTabLayoutPolicy()
+  {
+    return layoutPolicy;
+  }
+
+  /**
+   * This method changes the tabLayoutPolicy property of the JTabbedPane.
+   *
+   * @param tabLayoutPolicy The tabLayoutPolicy to use.
+   *
+   * @throws IllegalArgumentException If tabLayoutPolicy is not one of
+   *         SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
+   */
+  public void setTabLayoutPolicy(int tabLayoutPolicy)
+  {
+    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+    if (tabLayoutPolicy != layoutPolicy)
+      {
+	int oldPolicy = layoutPolicy;
+	layoutPolicy = tabLayoutPolicy;
+	firePropertyChange(TAB_LAYOUT_POLICY_CHANGED_PROPERTY, oldPolicy,
+	                   layoutPolicy);
+      }
+  }
+
+  /**
+   * This method returns the index of the tab that is currently selected.
+   *
+   * @return The index of the selected tab.
+   */
+  public int getSelectedIndex()
+  {
+    return model.getSelectedIndex();
+  }
+
+  /**
+   * This method checks the index.
+   *
+   * @param index The index to check.
+   * @param start DOCUMENT ME!
+   * @param end DOCUMENT ME!
+   *
+   * @throws IndexOutOfBoundsException DOCUMENT ME!
+   */
+  private void checkIndex(int index, int start, int end)
+  {
+    if (index < start || index >= end)
+      throw new IndexOutOfBoundsException("Index < " + start + " || Index >= "
+                                          + end);
+  }
+
+  /**
+   * This method sets the selected index. This method will hide the old
+   * component and show the new component.
+   *
+   * @param index The index to set it at.
+   */
+  public void setSelectedIndex(int index)
+  {
+    checkIndex(index, -1, tabs.size());
+    if (index != getSelectedIndex())
+      {
+	if (getSelectedIndex() != -1 && getSelectedComponent() != null)
+	  getSelectedComponent().hide();
+	if (index != -1 && getComponentAt(index) != null)
+	  getComponentAt(index).show();
+	model.setSelectedIndex(index);
+      }
+  }
+
+  /**
+   * This method returns the component at the selected index.
+   *
+   * @return The component at the selected index.
+   */
+  public Component getSelectedComponent()
+  {
+    return getComponentAt(getSelectedIndex());
+  }
+
+  /**
+   * This method sets the component at the selected index.
+   *
+   * @param c The component associated with the selected index.
+   */
+  public void setSelectedComponent(Component c)
+  {
+    if (c.getParent() == this)
+      setSelectedIndex(indexOfComponent(c));
+    else
+      setComponentAt(getSelectedIndex(), c);
+  }
+
+  /**
+   * This method inserts tabs into JTabbedPane. This includes adding the
+   * component to the JTabbedPane and hiding it.
+   *
+   * @param title The title of the tab.
+   * @param icon The tab's icon.
+   * @param component The component associated with the tab.
+   * @param tip The tooltip for the tab.
+   * @param index The index to insert the tab at.
+   */
+  public void insertTab(String title, Icon icon, Component component,
+                        String tip, int index)
+  {
+    Page p = new Page(title, icon, component, tip);
+    tabs.insertElementAt(p, index);
+
+    // Hide the component so we don't see it. Do it before we parent it
+    // so we don't trigger a repaint.
+    if (component != null)
+      {
+	component.hide();
+	super.add(component);
+      }
+
+    if (getSelectedIndex() == -1)
+      setSelectedIndex(0);
+
+    layout();
+    repaint();
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title The title of the tab.
+   * @param icon The icon for the tab.
+   * @param component The associated component.
+   * @param tip The associated tooltip.
+   */
+  public void addTab(String title, Icon icon, Component component, String tip)
+  {
+    insertTab(title, icon, component, tip, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title The title of the tab.
+   * @param icon The icon for the tab.
+   * @param component The associated component.
+   */
+  public void addTab(String title, Icon icon, Component component)
+  {
+    insertTab(title, icon, component, null, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title The title of the tab.
+   * @param component The associated component.
+   */
+  public void addTab(String title, Component component)
+  {
+    insertTab(title, null, component, null, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. The title of the tab is the
+   * Component's name. If the Component is an instance of UIResource, it
+   * doesn't add the tab and instead add the component directly to the
+   * JTabbedPane.
+   *
+   * @param component The associated component.
+   *
+   * @return The Component that was added.
+   */
+  public Component add(Component component)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(component.getName(), null, component, null, tabs.size());
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane.
+   *
+   * @param title The title of the tab.
+   * @param component The associated component.
+   *
+   * @return The Component that was added.
+   */
+  public Component add(String title, Component component)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(title, null, component, null, tabs.size());
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane.
+   *
+   * @param component The associated component.
+   * @param index The index to insert the tab at.
+   *
+   * @return The Component that was added.
+   */
+  public Component add(Component component, int index)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(component.getName(), null, component, null, index);
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane. If the constraints object is an
+   * icon, it will be used as the tab's icon. If the constraints object is a
+   * string, we will use it as the title.
+   *
+   * @param component The associated component.
+   * @param constraints The constraints object.
+   */
+  public void add(Component component, Object constraints)
+  {
+    add(component, constraints, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane. If the constraints object is an
+   * icon, it will be used as the tab's icon. If the constraints object is a
+   * string, we will use it as the title.
+   *
+   * @param component The associated component.
+   * @param constraints The constraints object.
+   * @param index The index to insert the tab at.
+   */
+  public void add(Component component, Object constraints, int index)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      {
+	if (constraints instanceof String)
+	  insertTab((String) constraints, null, component, null, index);
+	else
+	  insertTab(component.getName(),
+	            (constraints instanceof Icon) ? (Icon) constraints : null,
+	            component, null, index);
+      }
+  }
+
+  /**
+   * The tab and it's associated component are removed. After the component
+   * has been removed from the JTabbedPane, it's set visible to ensure that
+   * it can be seen.
+   *
+   * @param index The index of the tab to remove.
+   */
+  public void removeTabAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    Component c = getComponentAt(index);
+    super.remove(index);
+    c.show();
+    tabs.remove(index);
+  }
+
+  /**
+   * This method removes the component from the JTabbedPane. After the
+   * component has been removed from the JTabbedPane, it's  set visible to
+   * ensure that it can be seen.
+   *
+   * @param component The Component to remove.
+   */
+  public void remove(Component component)
+  {
+    // This simply removes the component.
+    int index = indexOfComponent(component);
+    super.remove(component);
+    component.show();
+    setComponentAt(index, null);
+  }
+
+  /**
+   * This method removes the tab and component from the JTabbedPane. It simply
+   * calls removeTabAt(int index).
+   *
+   * @param index The index of the tab to remove.
+   */
+  public void remove(int index)
+  {
+    removeTabAt(index);
+  }
+
+  /**
+   * This method removes all tabs and associated components from the
+   * JTabbedPane.
+   */
+  public void removeAll()
+  {
+    for (int i = tabs.size() - 1; i >= 0; i--)
+      removeTabAt(i);
+  }
+
+  /**
+   * This method returns how many tabs are in the JTabbedPane.
+   *
+   * @return The number of tabs in the JTabbedPane.
+   */
+  public int getTabCount()
+  {
+    return tabs.size();
+  }
+
+  /**
+   * This method returns the number of runs used  to paint the JTabbedPane.
+   *
+   * @return The number of runs.
+   */
+  public int getTabRunCount()
+  {
+    return ((TabbedPaneUI) ui).getTabRunCount(this);
+  }
+
+  /**
+   * This method returns the tab title given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The title for the tab.
+   */
+  public String getTitleAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getTitle();
+  }
+
+  /**
+   * This method returns the active icon given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The active icon for the tab.
+   */
+  public Icon getIconAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getIcon();
+  }
+
+  /**
+   * This method returns the disabled icon given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The disabled icon for the tab.
+   */
+  public Icon getDisabledIconAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getDisabledIcon();
+  }
+
+  /**
+   * This method returns the tooltip string for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The tooltip string for the tab.
+   */
+  public String getToolTipTextAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getTip();
+  }
+
+  /**
+   * This method returns the foreground color for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The foreground color for the tab.
+   */
+  public Color getForegroundAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getForeground();
+  }
+
+  /**
+   * This method returns the background color for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The background color for the tab.
+   */
+  public Color getBackgroundAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getBackground();
+  }
+
+  /**
+   * This method returns the component associated with the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The component associated with the tab.
+   */
+  public Component getComponentAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getComponent();
+  }
+
+  /**
+   * This method returns whether this tab is enabled. Disabled tabs cannot be
+   * selected.
+   *
+   * @param index The index of the tab.
+   *
+   * @return Whether the tab is enabled.
+   */
+  public boolean isEnabledAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).isEnabled();
+  }
+
+  /**
+   * This method returns the mnemonic for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   *
+   * @return The mnemonic for the tab.
+   */
+  public int getMnemonicAt(int tabIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
+  }
+
+  /**
+   * This method returns the mnemonic index for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   *
+   * @return The mnemonic index for the tab.
+   */
+  public int getDisplayedMnemonicIndexAt(int tabIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
+  }
+
+  /**
+   * This method returns the bounds of the tab given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return A rectangle describing the bounds of the tab.
+   */
+  public Rectangle getBoundsAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((TabbedPaneUI) ui).getTabBounds(this, index);
+  }
+
+  /**
+   * This method sets the title of the tab.
+   *
+   * @param index The index of the tab.
+   * @param title The new title.
+   */
+  public void setTitleAt(int index, String title)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setTitle(title);
+  }
+
+  /**
+   * This method sets the icon of the tab.
+   *
+   * @param index The index of the tab.
+   * @param icon The new icon.
+   */
+  public void setIconAt(int index, Icon icon)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setIcon(icon);
+  }
+
+  /**
+   * This method sets the disabled icon of the tab.
+   *
+   * @param index The index of the tab.
+   * @param disabledIcon The new disabled icon.
+   */
+  public void setDisabledIconAt(int index, Icon disabledIcon)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
+  }
+
+  /**
+   * This method sets the tooltip text of the tab.
+   *
+   * @param index The index of the tab.
+   * @param toolTipText The tooltip text.
+   */
+  public void setToolTipTextAt(int index, String toolTipText)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setTip(toolTipText);
+  }
+
+  /**
+   * This method sets the background color of the tab.
+   *
+   * @param index The index of the tab.
+   * @param background The background color of the tab.
+   */
+  public void setBackgroundAt(int index, Color background)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setBackground(background);
+  }
+
+  /**
+   * This method sets the foreground color of the tab.
+   *
+   * @param index The index of the tab.
+   * @param foreground The foreground color of the tab.
+   */
+  public void setForegroundAt(int index, Color foreground)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setForeground(foreground);
+  }
+
+  /**
+   * This method sets whether the tab is enabled.
+   *
+   * @param index The index of the tab.
+   * @param enabled Whether the tab is enabled.
+   */
+  public void setEnabledAt(int index, boolean enabled)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setEnabled(enabled);
+  }
+
+  /**
+   * This method sets the component associated with the tab.
+   *
+   * @param index The index of the tab.
+   * @param component The component associated with the tab.
+   */
+  public void setComponentAt(int index, Component component)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setComponent(component);
+  }
+
+  /**
+   * This method sets the displayed mnemonic index of the tab.
+   *
+   * @param tabIndex The index of the tab.
+   * @param mnemonicIndex The mnemonic index.
+   */
+  public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
+  }
+
+  /**
+   * This method sets the mnemonic for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   * @param mnemonic The mnemonic.
+   */
+  public void setMnemonicAt(int tabIndex, int mnemonic)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
+  }
+
+  /**
+   * This method finds the index of a tab given the title.
+   *
+   * @param title The title that belongs to a tab.
+   *
+   * @return The index of the tab that has the title or -1 if not found.
+   */
+  public int indexOfTab(String title)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getTitle().equals(title))
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method finds the index of a tab given the icon.
+   *
+   * @param icon The icon that belongs to a tab.
+   *
+   * @return The index of the tab that has the icon or -1 if not found.
+   */
+  public int indexOfTab(Icon icon)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getIcon() == icon)
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method finds the index of a tab given the component.
+   *
+   * @param component A component associated with a tab.
+   *
+   * @return The index of the tab that has this component or -1 if not found.
+   */
+  public int indexOfComponent(Component component)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getComponent() == component)
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method returns a tab index given an (x,y) location. The origin of
+   * the (x,y) pair will be the JTabbedPane's top left position. The  tab
+   * returned will be the one that contains the point. This method is
+   * delegated to the UI.
+   *
+   * @param x The x coordinate of the point.
+   * @param y The y coordinate of the point.
+   *
+   * @return The index of the tab that contains the point.
+   */
+  public int indexAtLocation(int x, int y)
+  {
+    return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
+  }
+
+  /**
+   * This method returns the tooltip text given a mouse event.
+   *
+   * @param event The mouse event.
+   *
+   * @return The tool tip text that is associated with this mouse event.
+   */
+  public String getToolTipText(MouseEvent event)
+  {
+    int index = indexAtLocation(event.getX(), event.getY());
+    return ((Page) tabs.elementAt(index)).getTip();
+  }
+
+  /**
+   * This method returns a string representation of this JTabbedPane. It is
+   * mainly used for debugging purposes.
+   *
+   * @return A string representation of this JTabbedPane.
+   */
+  protected String paramString()
+  {
+    return "JTabbedPane";
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJTabbedPane();
+    return accessibleContext;
+  }
 }
Index: javax/swing/JTable.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JTable.java,v
retrieving revision 1.4
diff -u -r1.4 JTable.java
--- javax/swing/JTable.java	11 Jun 2003 13:20:39 -0000	1.4
+++ javax/swing/JTable.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
 /* JTable.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,169 +42,1520 @@
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Rectangle;
-import java.util.Hashtable;
 import java.util.Vector;
+import java.util.Hashtable;
+
 import javax.accessibility.Accessible;
-import javax.swing.event.ChangeEvent;
+import javax.accessibility.AccessibleContext;
 import javax.swing.event.CellEditorListener;
+import javax.swing.event.ChangeEvent;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TableColumnModelEvent;
 import javax.swing.event.TableColumnModelListener;
 import javax.swing.event.TableModelEvent;
 import javax.swing.event.TableModelListener;
+import javax.swing.plaf.TableUI;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
 import javax.swing.table.JTableHeader;
-import javax.swing.table.TableModel;
 import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
 import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
 
 public class JTable extends JComponent
   implements TableModelListener, Scrollable, TableColumnModelListener,
              ListSelectionListener, CellEditorListener, Accessible
 {
-  public static final int AUTO_RESIZE_ALL_COLUMNS = 4;
-  public static final int AUTO_RESIZE_LAST_COLUMN = 3;
-  public static final int AUTO_RESIZE_NEXT_COLUMN = 1;
+  private static final long serialVersionUID = 3876025080382781659L;
+
+
+  /**
+   * When resizing columns, do not automatically change any columns. In this
+   * case the table should be enclosed in a {@link JScrollPane} in order to
+   * accomodate cases in which the table size exceeds its visible area.
+   */
   public static final int AUTO_RESIZE_OFF = 0;
+
+  /**
+   * When resizing column <code>i</code>, automatically change only the
+   * single column <code>i+1</code> to provide or absorb excess space
+   * requirements.
+   */
+  public static final int AUTO_RESIZE_NEXT_COLUMN = 1;
+
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change all columns in the range <code>[i+1,
+   * n)</code>, uniformly, to provide or absorb excess space requirements.
+   */
   public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
   
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change all columns in the range <code>[0,
+   * n)</code> (with the exception of column i) uniformly, to provide or
+   * absorb excess space requirements.
+   */
+  public static final int AUTO_RESIZE_ALL_COLUMNS = 4;
+
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change column <code>n-1</code> (the last column
+   * in the table) to provide or absorb excess space requirements.
+   */
+  public static final int AUTO_RESIZE_LAST_COLUMN = 3;
+
+
+  /**
+   * A table mapping {@link java.lang.Class} objects to 
+   * {@link TableCellEditor} objects. This table is consulted by the 
+   * 
+   */
+  protected Hashtable defaultEditorsByColumnClass;
+  protected Hashtable defaultRenderersByColumnClass;
+  protected int editingColumn;
+  protected int editingRow;
+
+  /**
+   * Whether or not the table should automatically compute a matching
+   * {@link TableColumnModel} and assign it to the {@link #columnModel}
+   * property when the {@link #dataModel} property is changed. 
+   *
+   * @see #setModel()
+   * @see #createColumnsFromModel()
+   * @see #setColumnModel()
+   * @see #setAutoCreateColumnsFromModel()
+   * @see #getAutoCreateColumnsFromModel()
+   */
+  protected boolean autoCreateColumnsFromModel;
+
+  /**
+   * A numeric code specifying the resizing behavior of the table. Must be
+   * one of {@link #AUTO_RESIZE_ALL_COLUMNS} (the default), {@link
+   * #AUTO_RESIZE_LAST_COLUMN}, {@link #AUTO_RESIZE_NEXT_COLUMN}, {@link
+   * #AUTO_RESIZE_SUBSEQUENT_COLUMNS}, or {@link #AUTO_RESIZE_OFF}.
+   * 
+   * @see #doLayout()
+   * @see #setAutoResizeMode()
+   * @see #getAutoResizeMode()
+   */
+  protected int autoResizeMode;
+
+  /**
+   * The height in pixels of any row of the table. All rows in a table are
+   * of uniform height. This differs from column width, which varies on a
+   * per-column basis, and is stored in the individual columns of the
+   * {@link #columnModel}.
+   * 
+   * @see #getRowHeight()
+   * @see #setRowHeight()
+   * @see TableColumn#getWidth()
+   * @see TableColumn#setWidth()
+   */
+  protected int rowHeight;
+
+  /**
+   * The height in pixels of the gap left between any two rows of the table. 
+   * 
+   * @see #setRowMargin()
+   * @see #getRowHeight()
+   * @see #getInterCellSpacing()
+   * @see #setInterCellSpacing()
+   * @see TableColumnModel#getColumnMargin()
+   * @see TableColumnModel#setColumnMargin()
+   */
+  protected int rowMargin;
+
+  /**
+   * Whether or not the table should allow row selection. If the table
+   * allows both row <em>and</em> column selection, it is said to allow
+   * "cell selection". Previous versions of the JDK supported cell
+   * selection as an independent concept, but it is now represented solely
+   * in terms of simultaneous row and column selection.
+   *
+   * @see TableColumnModel#columnSelectionAllowed()
+   * @see #setRowSelectionAllowed()
+   * @see #getRowSelectionAllowed()
+   * @see #getCellSelectionEnabled()
+   * @see #setCellSelectionEnabled()
+   */
+  protected boolean rowSelectionAllowed;
+
+  /**
+   * @deprecated Use {@link #rowSelectionAllowed}, {@link
+   * #columnSelectionAllowed}, or the combined methods {@link
+   * getCellSelectionEnabled} and {@link setCellSelectionEnabled}.
+   */
+  protected boolean cellSelectionEnabled;
+  
+  /**
+   * The model for data stored in the table. Confusingly, the published API
+   * requires that this field be called <code>dataModel</code>, despite its
+   * property name. The table listens to its model as a {@link
+   * TableModelListener}.
+   *
+   * @see #tableChanged()
+   * @see TableModel#addTableModelListener()
+   */
+  protected TableModel dataModel;
+
+  /**
+   * <p>A model of various aspects of the columns of the table, <em>not
+   * including</em> the data stored in them. The {@link TableColumnModel}
+   * is principally concerned with holding a set of {@link TableColumn}
+   * objects, each of which describes the display parameters of a column
+   * and the numeric index of the column from the data model which the
+   * column is presenting.</p>
+   *
+   * <p>The TableColumnModel also contains a {@link ListSelectionModel} which
+   * indicates which columns are currently selected. This selection model
+   * works in combination with the {@link selectionModel} of the table
+   * itself to specify a <em>table selection</em>: a combination of row and
+   * column selections.</p>
+   *
+   * <p>Most application programmers do not need to work with this property
+   * at all: setting {@link #autoCreateColumnsFromModel} will construct the
+   * columnModel automatically, and the table acts as a facade for most of
+   * the interesting properties of the columnModel anyways.</p>
+   * 
+   * @see #setColumnModel()
+   * @see #getColumnModel()
+   */
+  protected TableColumnModel columnModel;
+
+  /**
+   * A model of the rows of this table which are currently selected. This
+   * model is used in combination with the column selection model held as a
+   * member of the {@link columnModel} property, to represent the rows and
+   * columns (or both: cells) of the table which are currently selected.
+   *
+   * @see #rowSelectionAllowed
+   * @see #setSelectionModel()
+   * @see #getSelectionModel()
+   * @see TableColumnModel#getSelectionModel()
+   * @see ListSelectionModel#addListSelectionListener()   
+   */
+  protected ListSelectionModel selectionModel;
+
+  /**
+   * The accessibleContext property.
+   */
+  protected AccessibleContext accessibleContext;
+
+  /**
+   * The current cell editor. 
+   */
+  protected TableCellEditor cellEditor;
+
+  /**
+   * Whether or not drag-and-drop is enabled on this table.
+   *
+   * @see #setDragEnabled()
+   * @see #getDragEnabled()
+   */
+  protected boolean dragEnabled;
+
+  /**
+   * The color to paint the grid lines of the table, when either {@link
+   * #showHorizontalLines} or {@link #showVerticalLines} is set.
+   *
+   * @see #setGridColor()
+   * @see #getGridColor()
+   */
+  protected Color gridColor;
+
+  /**
+   * The size this table would prefer its viewport assume, if it is
+   * contained in a {@link JScrollPane}.
+   *
+   * @see #setPreferredScrollableViewportSize()
+   * @see #getPreferredScrollableViewportSize()
+   */
+  protected Dimension preferredScrollableViewportSize;
+
+  /**
+   * The color to paint the background of selected cells. Fires a property
+   * change event with name {@link #SELECTION_BACKGROUND_CHANGED_PROPERTY}
+   * when its value changes.
+   *
+   * @see #setSelectionBackground()
+   * @see #getSelectionBackground()
+   */
+  Color selectionBackground;
+
+  /**
+   * The name carried in property change events when the {@link
+   * #selectionBackground} property changes.
+   */
+  private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY = "selectionBackground";
+
+  /**
+   * The color to paint the foreground of selected cells. Fires a property
+   * change event with name {@link #SELECTION_FOREGROUND_CHANGED_PROPERTY}
+   * when its value changes.
+   *
+   * @see #setSelectionForeground()
+   * @see #getSelectionForeground()
+   */
+  Color selectionForeground;
+
+  /**
+   * The name carried in property change events when the
+   * {@link #selectionForeground} property changes.
+   */
+  private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground";
+
+  /**
+   * The showHorizontalLines property.
+   */
+  protected boolean showHorizontalLines;
+
+  /**
+   * The showVerticalLines property.
+   */
+  protected boolean showVerticalLines;
+
+  /**
+   * The tableHeader property.
+   */
+  protected JTableHeader tableHeader;
+
+  
+  /**
+   * Creates a new <code>JTable</code> instance.
+   */
   public JTable ()
   {
-    throw new Error ("Not implemented");
+    this(null, null, null);
   }
 
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param numRows an <code>int</code> value
+   * @param numColumns an <code>int</code> value
+   */
   public JTable (int numRows, int numColumns)
   {
-    throw new Error ("Not implemented");
+    this(new DefaultTableModel(numRows, numColumns));
   }
 
-  public JTable (Object[][] rowData, Object[] columnNames)
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param data an <code>Object[][]</code> value
+   * @param columnNames an <code>Object[]</code> value
+   */
+  public JTable(Object[][] data, Object[] columnNames)
   {
-    throw new Error ("Not implemented");
+    this(new DefaultTableModel(data, columnNames));
   }
 
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param dm a <code>TableModel</code> value
+   */
   public JTable (TableModel dm)
   {
-    throw new Error ("Not implemented");
+    this(dm, null, null);
   }
 
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param dm a <code>TableModel</code> value
+   * @param cm a <code>TableColumnModel</code> value
+   */
   public JTable (TableModel dm, TableColumnModel cm)
   {
-    throw new Error ("Not implemented");
+    this(dm, cm, null);
   }
 
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param dm a <code>TableModel</code> value
+   * @param cm a <code>TableColumnModel</code> value
+   * @param sm a <code>ListSelectionModel</code> value
+   */
   public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm)
   {
-    throw new Error ("Not implemented");
+    this.dataModel = dm == null ? createDefaultDataModel() : dm;
+    setSelectionModel(sm == null ? createDefaultListSelectionModel() : sm);
+
+    this.columnModel = cm;
+    this.autoCreateColumnsFromModel = false;
+    if (cm == null)
+      {
+        this.autoCreateColumnsFromModel = true;
+        createColumnsFromModel();
+      }
+    this.columnModel.addColumnModelListener(this);
+    
+    this.defaultRenderersByColumnClass = new Hashtable();
+    this.defaultEditorsByColumnClass = new Hashtable();
+
+    this.autoResizeMode = AUTO_RESIZE_ALL_COLUMNS;
+    this.rowHeight = 16;
+    this.rowMargin = 1;
+    this.rowSelectionAllowed = true;
+    // this.accessibleContext = new AccessibleJTable();
+    this.cellEditor = null;
+    this.dragEnabled = false;
+    this.preferredScrollableViewportSize = new Dimension(450,400);
+    this.showHorizontalLines = true;
+    this.showVerticalLines = true;
+    setInterCellSpacing(new Dimension(1,1));
+    setTableHeader(new JTableHeader(columnModel));
+    updateUI();
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance.
+   *
+   * @param data a <code>Vector</code> value
+   * @param columnNames a <code>Vector</code> value
+   */
+  public JTable(Vector data, Vector columnNames)
+  {
+    this(new DefaultTableModel(data, columnNames));
+  }
+
+  /**
+   * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code>
+   */
+  public static JScrollPane createScrollPaneForTable(JTable table)
+  {
+    return new JScrollPane(table);
+  }
+ 
+  protected TableColumnModel createDefaultColumnModel()
+  {
+    return new DefaultTableColumnModel();
+  }
+
+  protected TableModel createDefaultDataModel()
+  {
+    return new DefaultTableModel();
   }
 
-  public JTable (Vector rowData, Vector columnNames)
+  protected ListSelectionModel createDefaultListSelectionModel()
   {
-    throw new Error ("Not implemented");
+    return new DefaultListSelectionModel();
   }
 
+  private void createColumnsFromModel()
+  {
+    if (dataModel == null)
+      return;
+
+    TableColumnModel cm = createDefaultColumnModel();
+
+    for (int i = 0; i < dataModel.getColumnCount(); ++i)
+      {
+        cm.addColumn(new TableColumn(i));
+      }
+    this.setColumnModel(cm);
+  }
+
+  // listener support 
+
   public void columnAdded (TableColumnModelEvent event)
   {
-    throw new Error ("Not implemented");
+    revalidate();
+    repaint();
   }
 
   public void columnMarginChanged (ChangeEvent event)
   {
-    throw new Error ("Not implemented");
+    revalidate();
+    repaint();
   }
-  
+
   public void columnMoved (TableColumnModelEvent event)
   {
-    throw new Error ("Not implemented");
+    revalidate();
+    repaint();
   }
-  
+
   public void columnRemoved (TableColumnModelEvent event)
   {
-    throw new Error ("Not implemented");
+    revalidate();
+    repaint();
   }
   
   public void columnSelectionChanged (ListSelectionEvent event)
   {
-    throw new Error ("Not implemented");
+    repaint();
   }
- 
+
   public void editingCanceled (ChangeEvent event)
   {
-    throw new Error ("Not implemented");
+    repaint();
   }
 
   public void editingStopped (ChangeEvent event)
   {
-    throw new Error ("Not implemented");
+    repaint();
   }
 
-  public TableColumnModel getColumnModel ()
-  {
-    throw new Error ("Not implemented");
-  }
-  
-  public Dimension getPreferredScrollableViewportSize ()
+  public void tableChanged (TableModelEvent event)
   {
-    throw new Error ("Not implemented");
+    repaint();
   }
 
-  public int getScrollableBlockIncrement (Rectangle visibleRect, int orientation, int direction)
+  public void valueChanged (ListSelectionEvent event)
   {
-    throw new Error ("Not implemented");
+    repaint();
   }
 
-  public boolean getScrollableTracksViewportHeight ()
+
+  /** 
+   * Calculate the visible rectangle for a particular row and column. The
+   * row and column are specified in visual terms; the column may not match
+   * the {@link #dataModel} column.
+   *
+   * @param row the visible row to get the cell rectangle of
+   *
+   * @param column the visible column to get the cell rectangle of, which may
+   * differ from the {@link #dataModel} column
+   *
+   * @param includeSpacing whether or not to include the cell margins in the
+   * resulting cell. If <code>false</code>, the result will only contain the
+   * inner area of the target cell, not including its margins.
+   *
+   * @return a rectangle enclosing the specified cell
+   */
+  public Rectangle getCellRect(int row,
+                               int column,
+                               boolean includeSpacing)
+  {
+    int height = getHeight();
+    int width = columnModel.getColumn(column).getWidth();
+    int x_gap = columnModel.getColumnMargin();
+    int y_gap = rowMargin;
+
+    column = Math.max(0, Math.min(column, getColumnCount() - 1));
+    row = Math.max(0, Math.min(row, getRowCount() - 1));
+
+    int x = 0;
+    int y = (height + y_gap) * row;
+
+    for (int i = 0; i < column; ++i)
+      {        
+        x += columnModel.getColumn(i).getWidth();
+        x += x_gap;
+      }
+
+    if (includeSpacing)
+      return new Rectangle(x, y, width, height);
+    else
+      return new Rectangle(x, y, width - x_gap, height - y_gap);
+  }
+
+  public void clearSelection()
+  {
+    selectionModel.clearSelection();
+  }
+
+  /**
+   * Get the value of the {@link #selectedRow} property by delegation to
+   * the {@link ListSelectionModel#getMinSelectionIndex} method of the
+   * {@link #selectionModel} field.
+   *
+   * @return The current value of the selectedRow property
+   */
+  public int getSelectedRow ()
   {
-    throw new Error ("Not implemented");
+    return selectionModel.getMinSelectionIndex();
   }
   
-  public boolean getScrollableTracksViewportWidth ()
+  /**
+   * Get the value of the {@link #selectionModel} property.
+   *
+   * @return The current value of the property
+   */
+  public ListSelectionModel getSelectionModel()
   {
-    throw new Error ("Not implemented");
-  }
+    if (! rowSelectionAllowed)
+      return null;
 
-  public int getScrollableUnitIncrement (Rectangle visibleRect, int orientation, int direction)
+    return selectionModel;
+  }
+  
+  public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
   {
-    throw new Error ("Not implemented");
+    if (orientation == SwingConstants.VERTICAL)
+      return visibleRect.height * direction;
+    else
+      return visibleRect.width * direction;
   }
 
-  public int getSelectedRow ()
+  /**
+   * Get the value of the {@link #scrollableTracksViewportHeight} property.
+   *
+   * @return The constant value <code>false</code>
+   */
+
+  public boolean getScrollableTracksViewportHeight()
   {
-    throw new Error ("Not implemented");
+    return false;
   }
   
-  public ListSelectionModel getSelectionModel ()
-  {
-    throw new Error ("Not implemented");
+  /**
+   * Get the value of the {@link #scrollableTracksViewportWidth} property.
+   *
+   * @return <code>true</code> unless the {@link autoResizeMode} prperty is
+   * <code>AUTO_RESIZE_OFF</code>
+   */
+
+  public boolean getScrollableTracksViewportWidth()
+  {
+    if (autoResizeMode == AUTO_RESIZE_OFF)
+      return false;
+    else
+      return true;
+  }
+
+  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
+  {
+    // FIXME: I don't exactly know what sun does here. in both cases they
+    // pick values which do *not* simply expose the next cell in a given
+    // scroll direction.
+
+    if (orientation == SwingConstants.VERTICAL)
+      return rowHeight;
+    else
+      {
+        int sum = 0;
+        for (int i = 0; i < getColumnCount(); ++i)
+          sum += columnModel.getColumn(0).getWidth();
+        return getColumnCount() == 0 ? 10 : sum / getColumnCount();
+      }
+  }
+
+
+  public TableCellEditor getCellEditor(int row, int column)
+  {
+    TableCellEditor editor = columnModel.getColumn(column).getCellEditor();
+
+    if (editor == null)
+      editor = getDefaultEditor(dataModel.getColumnClass(column));
+
+    return editor;
+  }
+
+  public TableCellEditor getDefaultEditor(Class columnClass)
+  {
+    if (defaultEditorsByColumnClass.containsKey(columnClass))
+      return (TableCellEditor) defaultEditorsByColumnClass.get(columnClass);
+    else
+      {
+        TableCellEditor r = new DefaultCellEditor(new JTextField());
+        defaultEditorsByColumnClass.put(columnClass, r);
+        return r;
+      }
+  }
+
+
+
+  public TableCellRenderer getCellRenderer(int row, int column)
+  {
+    TableCellRenderer renderer =
+      columnModel.getColumn(column).getCellRenderer();
+    
+    if (renderer == null)
+      renderer = getDefaultRenderer(dataModel.getColumnClass(column));
+    
+    return renderer;
+  }
+
+  public TableCellRenderer getDefaultRenderer(Class columnClass)
+  {
+    if (defaultRenderersByColumnClass.containsKey(columnClass))
+      return (TableCellRenderer) defaultRenderersByColumnClass.get(columnClass);
+    else
+      {
+        TableCellRenderer r = new DefaultTableCellRenderer();
+        defaultRenderersByColumnClass.put(columnClass, r);
+        return r;
+      }
+  }
+
+  public int convertColumnIndexToModel(int vc)
+  {
+    if (vc < 0)
+      return vc;
+    else if (vc > getColumnCount())
+      return -1;
+    else
+      return columnModel.getColumn(vc).getModelIndex();
+  }
+
+  public int convertColumnIndexToView(int mc)
+  {
+    if (mc < 0)
+      return mc;
+    int ncols = getColumnCount();
+    for (int vc = 0; vc < ncols; ++vc)
+      {
+        if (columnModel.getColumn(vc).getModelIndex() == mc)
+          return vc;
+      }
+    return -1;
+  }
+
+  public Component prepareRenderer(TableCellRenderer renderer,
+                                   int row,
+                                   int column)
+  {
+    boolean rsa = getRowSelectionAllowed();
+    boolean csa = getColumnSelectionAllowed();
+    boolean rs = rsa ? getSelectionModel().isSelectedIndex(row) : false;
+    boolean cs = csa ? columnModel.getSelectionModel().isSelectedIndex(column) : false;
+    boolean isSelected = ((rsa && csa && rs && cs) 
+                          || (rsa && !csa && rs) 
+                          || (!rsa && csa && cs));
+    
+    return renderer.getTableCellRendererComponent(this,
+                                                  dataModel.getValueAt(row, 
+                                                                       convertColumnIndexToView(column)),
+                                                  isSelected,
+                                                  false, // hasFocus
+                                                  row, column);
+  }
+
+
+  /**
+   * Get the value of the {@link #autoCreateColumnsFromModel} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getAutoCreateColumnsFromModel()
+  {
+    return autoCreateColumnsFromModel;
+  }
+
+  /**
+   * Get the value of the {@link #autoResizeMode} property.
+   *
+   * @return The current value of the property
+   */
+  public int getAutoResizeMode()
+  {
+    return autoResizeMode;
+  }
+
+  /**
+   * Get the value of the {@link #rowHeight} property.
+   *
+   * @return The current value of the property
+   */
+  public int getRowHeight()
+  {
+    return rowHeight;
+  }
+
+  /**
+   * Get the value of the {@link #rowMargin} property.
+   *
+   * @return The current value of the property
+   */
+  public int getRowMargin()
+  {
+    return rowMargin;
+  }
+
+  /**
+   * Get the value of the {@link #rowSelectionAllowed} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getRowSelectionAllowed()
+  {
+    return rowSelectionAllowed;
+  }
+
+  /**
+   * Get the value of the {@link #cellSelectionEnabled} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getCellSelectionEnabled()
+  {
+    return getColumnSelectionAllowed() && getRowSelectionAllowed();
+  }
+
+  /**
+   * Get the value of the {@link #dataModel} property.
+   *
+   * @return The current value of the property
+   */
+  public TableModel getModel()
+  {
+    return dataModel;
+  }
+
+  /**
+   * Get the value of the {@link #columnCount} property by
+   * delegation to the @{link #dataModel} field.
+   *
+   * @return The current value of the columnCount property
+   */
+  public int getColumnCount()
+  {
+    return dataModel.getColumnCount();
+  }
+
+  /**
+   * Get the value of the {@link #rowCount} property by
+   * delegation to the @{link #dataModel} field.
+   *
+   * @return The current value of the rowCount property
+   */
+  public int getRowCount()
+  {
+    return dataModel.getRowCount();
+  }
+
+  /**
+   * Get the value of the {@link #columnModel} property.
+   *
+   * @return The current value of the property
+   */
+  public TableColumnModel getColumnModel()
+  {
+    return columnModel;
+  }
+
+  /**
+   * Get the value of the {@link #selectedColumn} property by
+   * delegation to the @{link #columnModel} field.
+   *
+   * @return The current value of the selectedColumn property
+   */
+  public int getSelectedColumn()
+  {
+    return columnModel.getSelectionModel().getMinSelectionIndex();
+  }
+
+  private static int countSelections(ListSelectionModel lsm)
+  {
+    int lo = lsm.getMinSelectionIndex();
+    int hi = lsm.getMaxSelectionIndex();
+    int sum = 0;
+    if (lo != -1 && hi != -1)
+      {
+        switch (lsm.getSelectionMode())
+          {
+          case ListSelectionModel.SINGLE_SELECTION:
+            sum = 1;
+            break;
+            
+          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
+            sum = hi - lo;
+            break;
+            
+          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
+            for (int i = lo; i < hi; ++i)
+              if (lsm.isSelectedIndex(i))        
+                ++sum;
+            break;
+          }
+      }
+    return sum;
+  }
+
+  private static int[] getSelections(ListSelectionModel lsm)
+  {
+    int sz = countSelections(lsm);
+    int [] ret = new int[sz];
+
+    int lo = lsm.getMinSelectionIndex();
+    int hi = lsm.getMaxSelectionIndex();
+    int j = 0;
+    java.util.ArrayList ls = new java.util.ArrayList();
+    if (lo != -1 && hi != -1)
+      {
+        switch (lsm.getSelectionMode())
+          {
+          case ListSelectionModel.SINGLE_SELECTION:
+            ret[0] = lo;
+            break;      
+      
+          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:            
+            for (int i = lo; i < hi; ++i)
+              ret[j++] = i;
+            break;
+            
+          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
+            for (int i = lo; i < hi; ++i)
+              if (lsm.isSelectedIndex(i))        
+                ret[j++] = i;
+            break;
+          }
+      }
+    return ret;
+  }
+
+  /**
+   * Get the value of the {@link #selectedColumnCount} property by
+   * delegation to the @{link #columnModel} field.
+   *
+   * @return The current value of the selectedColumnCount property
+   */  
+  public int getSelectedColumnCount()
+  {
+    return countSelections(columnModel.getSelectionModel());
+  }
+
+  /**
+   * Get the value of the {@link #selectedColumns} property by
+   * delegation to the @{link #columnModel} field.
+   *
+   * @return The current value of the selectedColumns property
+   */
+  public int[] getSelectedColumns()
+  {
+    return getSelections(columnModel.getSelectionModel());
+  }
+
+  /**
+   * Get the value of the {@link #columnSelectionAllowed} property.
+   *
+   * @return The current value of the columnSelectionAllowed property
+   */
+  public boolean getColumnSelectionAllowed()
+  {
+    return getColumnModel().getColumnSelectionAllowed();
+  }
+
+  /**
+   * Get the value of the {@link #selectedRowCount} property by
+   * delegation to the @{link #selectionModel} field.
+   *
+   * @return The current value of the selectedRowCount property
+   */
+  public int getSelectedRowCount()
+  {
+    return countSelections(selectionModel);
+  }
+
+  /**
+   * Get the value of the {@link #selectedRows} property by
+   * delegation to the @{link #selectionModel} field.
+   *
+   * @return The current value of the selectedRows property
+   */
+  public int[] getSelectedRows()
+  {
+    return getSelections(selectionModel);
+  }
+
+  /**
+   * Get the value of the {@link #accessibleContext} property.
+   *
+   * @return The current value of the property
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return accessibleContext;
+  }
+
+  /**
+   * Get the value of the {@link #cellEditor} property.
+   *
+   * @return The current value of the property
+   */
+  public TableCellEditor getCellEditor()
+  {
+    return cellEditor;
+  }
+
+  /**
+   * Get the value of the {@link #dragEnabled} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getDragEnabled()
+  {
+    return dragEnabled;
+  }
+
+  /**
+   * Get the value of the {@link #gridColor} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getGridColor()
+  {
+    return gridColor;
+  }
+
+  /**
+   * Get the value of the {@link #interCellSpacing} property.
+   *
+   * @return The current value of the property
+   */
+  public Dimension getInterCellSpacing()
+  {
+    return new Dimension(columnModel.getColumnMargin(), rowMargin);
+  }
+
+  /**
+   * Get the value of the {@link #preferredScrollableViewportSize} property.
+   *
+   * @return The current value of the property
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    return preferredScrollableViewportSize;
+  }
+
+  /**
+   * Get the value of the {@link #selectionBackground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionBackground()
+  {
+    return selectionBackground;
+  }
+
+  /**
+   * Get the value of the {@link #selectionForeground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionForeground()
+  {
+    return selectionForeground;
+  }
+
+  /**
+   * Get the value of the {@link #showHorizontalLines} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getShowHorizontalLines()
+  {
+    return showHorizontalLines;
+  }
+
+  /**
+   * Get the value of the {@link #showVerticalLines} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getShowVerticalLines()
+  {
+    return showVerticalLines;
+  }
+
+  /**
+   * Get the value of the {@link #tableHeader} property.
+   *
+   * @return The current value of the property
+   */
+  public JTableHeader getTableHeader()
+  {
+    return tableHeader;
+  }
+
+  /**
+   * Set the value of the {@link #autoCreateColumnsFromModel} property.
+   *
+   * @param a The new value of the autoCreateColumnsFromModel property
+   */ 
+  public void setAutoCreateColumnsFromModel(boolean a)
+  {
+    autoCreateColumnsFromModel = a;
+  }
+
+  /**
+   * Set the value of the {@link #autoResizeMode} property.
+   *
+   * @param a The new value of the autoResizeMode property
+   */ 
+  public void setAutoResizeMode(int a)
+  {
+    autoResizeMode = a;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #rowHeight} property.
+   *
+   * @param r The new value of the rowHeight property
+   */ 
+  public void setRowHeight(int r)
+  {
+    rowHeight = r;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #rowMargin} property.
+   *
+   * @param r The new value of the rowMargin property
+   */ 
+  public void setRowMargin(int r)
+  {
+    rowMargin = r;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #rowSelectionAllowed} property.
+   *
+   * @param r The new value of the rowSelectionAllowed property
+   */ 
+  public void setRowSelectionAllowed(boolean r)
+  {
+    rowSelectionAllowed = r;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #cellSelectionEnabled} property.
+   *
+   * @param c The new value of the cellSelectionEnabled property
+   */ 
+  public void setCellSelectionEnabled(boolean c)
+  {
+    setColumnSelectionAllowed(c);
+    setRowSelectionAllowed(c);
+    // for backward-compatibility sake:
+    cellSelectionEnabled = true;
+  }
+
+  /**
+   * <p>Set the value of the {@link #dataModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link TableModelListener} from
+   * previous {@link #dataModel} and register it with new parameter
+   * <code>m</code>.</p>
+   *
+   * @param m The new value of the model property
+   */ 
+  public void setModel(TableModel m)
+  {
+    if (m == null)
+      throw new IllegalArgumentException();
+    TableModel tmp = dataModel;
+    if (autoCreateColumnsFromModel)
+      createColumnsFromModel();
+    if (tmp != null)
+      tmp.removeTableModelListener(this);
+    if (m != null)
+      m.addTableModelListener(this);
+    dataModel = m;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #columnModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link TableColumnModelListener}
+   * from previous {@link #columnModel} and register it with new parameter
+   * <code>c</code>.</p>
+   *
+   * @param c The new value of the columnModel property
+   */ 
+  public void setColumnModel(TableColumnModel c)
+  {
+    if (c == null)
+      throw new IllegalArgumentException();
+    TableColumnModel tmp = columnModel;
+    if (tmp != null)
+      tmp.removeColumnModelListener(this);
+    if (c != null)
+      c.addColumnModelListener(this);
+    columnModel = c;
+    if (dataModel != null && columnModel != null)
+      {
+        int ncols = getColumnCount();
+        for (int i = 0; i < ncols; ++i)
+          columnModel.getColumn(i).setHeaderValue(dataModel.getColumnName(i));
+      }
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #columnSelectionAllowed} property.
+   *
+   * @param c The new value of the property
+   */ 
+  public void setColumnSelectionAllowed(boolean c)
+  {
+    getColumnModel().setColumnSelectionAllowed(c);
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link ListSelectionListener}
+   * from previous {@link #selectionModel} and register it with new
+   * parameter <code>s</code>.</p>
+   *
+   * @param s The new value of the selectionModel property
+   */ 
+  public void setSelectionModel(ListSelectionModel s)
+  {
+    if (s == null)
+      throw new IllegalArgumentException();
+    ListSelectionModel tmp = selectionModel;
+    if (tmp != null)
+      tmp.removeListSelectionListener(this);
+    if (s != null)
+      s.addListSelectionListener(this);
+    selectionModel = s;
+  }
+
+  /**
+   * Set the value of the {@link #selectionMode} property by
+   * delegation to the {@link #selectionModel} field.
+   *
+   * @param s The new value of the property
+   */ 
+  public void setSelectionMode(int s)
+  {
+    selectionModel.setSelectionMode(s);
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #cellEditor} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link CellEditorListener} from
+   * previous {@link #cellEditor} and register it with new parameter
+   * <code>c</code>.</p>
+   *
+   * @param c The new value of the cellEditor property
+   */ 
+  public void setCellEditor(TableCellEditor c)
+  {
+    TableCellEditor tmp = cellEditor;
+    if (tmp != null)
+      tmp.removeCellEditorListener(this);
+    if (c != null)
+      c.addCellEditorListener(this);
+    cellEditor = c;
+  }
+
+  /**
+   * Set the value of the {@link #dragEnabled} property.
+   *
+   * @param d The new value of the dragEnabled property
+   */ 
+  public void setDragEnabled(boolean d)
+  {
+    dragEnabled = d;
+  }
+
+  /**
+   * Set the value of the {@link #gridColor} property.
+   *
+   * @param g The new value of the gridColor property
+   */ 
+  public void setGridColor(Color g)
+  {
+    gridColor = g;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #interCellSpacing} property.
+   *
+   * @param i The new value of the interCellSpacing property
+   */ 
+  public void setInterCellSpacing(Dimension i)
+  {
+    rowMargin = i.height;
+    columnModel.setColumnMargin(i.width);
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #preferredScrollableViewportSize} property.
+   *
+   * @param p The new value of the preferredScrollableViewportSize property
+   */ 
+  public void setPreferredScrollableViewportSize(Dimension p)
+  {
+    preferredScrollableViewportSize = p;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionBackground} property.</p>
+   *
+   * <p>Fire a PropertyChangeEvent with name {@link
+   * #SELECTION_BACKGROUND_CHANGED_PROPERTY} to registered listeners, if
+   * selectionBackground changed.</p>
+   *
+   * @param s The new value of the selectionBackground property
+   */ 
+  public void setSelectionBackground(Color s)
+  {
+    Color tmp = selectionBackground;
+    selectionBackground = s;
+    if (((tmp == null && s != null)
+         || (s == null && tmp != null)
+         || (tmp != null && s != null && !tmp.equals(s))))
+      firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY, tmp, s);
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionForeground} property.</p>
+   *
+   * <p>Fire a PropertyChangeEvent with name {@link
+   * SELECTION_FOREGROUND_CHANGED_PROPERTY} to registered listeners, if
+   * selectionForeground changed.</p>
+   *
+   * @param s The new value of the selectionForeground property
+   */ 
+  public void setSelectionForeground(Color s)
+  {
+    Color tmp = selectionForeground;
+    selectionForeground = s;
+    if (((tmp == null && s != null)
+         || (s == null && tmp != null)
+         || (tmp != null && s != null && !tmp.equals(s))))
+      firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY, tmp, s);
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #showGrid} property.
+   *
+   * @param s The new value of the showGrid property
+   */ 
+  public void setShowGrid(boolean s)
+  {
+    setShowVerticalLines(s);
+    setShowHorizontalLines(s);
+  }
+
+  /**
+   * Set the value of the {@link #showHorizontalLines} property.
+   *
+   * @param s The new value of the showHorizontalLines property
+   */ 
+  public void setShowHorizontalLines(boolean s)
+  {
+    showHorizontalLines = s;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #showVerticalLines} property.
+   *
+   * @param s The new value of the showVerticalLines property
+   */ 
+  public void setShowVerticalLines(boolean s)
+  {
+    showVerticalLines = s;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #tableHeader} property.
+   *
+   * @param t The new value of the tableHeader property
+   */ 
+  public void setTableHeader(JTableHeader t)
+  {
+    if (tableHeader != null)
+      tableHeader.setTable(null);
+    tableHeader = t;
+    if (tableHeader != null)
+      tableHeader.setTable(this);
+    revalidate();
+    repaint();
+  }
+
+  protected void configureEnclosingScrollPane()
+  {
+    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
+    if (jsp != null && tableHeader != null)
+      {
+        jsp.setColumnHeaderView(tableHeader);
+      }
+  }
+
+  protected void unconfigureEnclosingScrollPane()
+  {
+    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
+    if (jsp != null)
+      {
+        jsp.setColumnHeaderView(null);
+      }    
+  }
+
+
+  public void addNotify()
+  {
+    super.addNotify();
+    configureEnclosingScrollPane();
+  }
+
+  public void removeNotify()
+  {
+    super.addNotify();
+    unconfigureEnclosingScrollPane();
+  }
+
+
+  /**
+   * Sun javadocs describe an unusual implementation of
+   * <code>doLayout</code> which involves some private interfaces. We try
+   * to implement the same algorithm as is documented, but using the
+   * columnModel directly. We still use a private helper method, but it has
+   * a simpler signature.
+   */
+
+  private void distributeSpill(TableColumn[] cols, int spill)
+  {
+    int MIN = 0;
+    int MAX = 0;
+    int PREF = 0;
+
+    int[] min = new int[cols.length];
+    int[] max = new int[cols.length];
+    int[] pref = new int[cols.length];
+
+    for (int i = 0; i < cols.length; ++i)
+      {
+        pref[i] = cols[i].getPreferredWidth();
+        min[i] = cols[i].getMinWidth();
+        max[i] = cols[i].getMaxWidth();
+        PREF += pref[i];
+        MIN += min[i];
+        MAX += max[i];
+      }
+
+    for (int i = 0; i < cols.length; ++i)
+      {
+        int adj = 0;
+        if (spill > 0)          
+          adj = (spill * (pref[i] - min[i])) / (PREF - MIN);
+        else
+          adj = (spill * (max[i] - pref[i])) / (MAX - PREF);
+        cols[i].setWidth(pref[i] + adj);        
+      }    
   }
-
-  public void tableChanged (TableModelEvent event)
+  
+  public void doLayout()
   {
-    throw new Error ("Not implemented");
-  }
+    TableColumn resizingColumn = null;
 
-  public void setModel (TableModel model)
+    int ncols = getColumnCount();
+    if (ncols < 1)
+      return;
+
+    int[] pref = new int[ncols];
+    int prefSum = 0;
+    int rCol = -1;
+
+    if (tableHeader != null)
+      resizingColumn = tableHeader.getResizingColumn();
+
+    for (int i = 0; i < ncols; ++i)
+      {
+        TableColumn col = columnModel.getColumn(i);
+        int p = col.getWidth();
+        pref[i] = p;
+        prefSum += p;
+        if (resizingColumn == col)
+          rCol = i;
+      }
+
+    int spill = prefSum - getWidth();
+
+    if (resizingColumn != null)
+      {
+        TableColumn col;
+        TableColumn [] cols;
+
+        switch (getAutoResizeMode())
+          {
+          case AUTO_RESIZE_LAST_COLUMN:
+            col = columnModel.getColumn(ncols-1);
+            col.setWidth(col.getPreferredWidth() + spill);
+            break;
+            
+          case AUTO_RESIZE_NEXT_COLUMN:
+            col = columnModel.getColumn(ncols-1);
+            col.setWidth(col.getPreferredWidth() + spill);
+            break;
+
+          case AUTO_RESIZE_ALL_COLUMNS:
+            cols = new TableColumn[ncols];
+            for (int i = 0; i < ncols; ++i)
+              cols[i] = columnModel.getColumn(i);
+            distributeSpill(cols, spill);
+            break;
+
+          case AUTO_RESIZE_SUBSEQUENT_COLUMNS:
+            cols = new TableColumn[ncols];
+            for (int i = rCol; i < ncols; ++i)
+              cols[i] = columnModel.getColumn(i);
+            distributeSpill(cols, spill);
+            break;
+
+          case AUTO_RESIZE_OFF:
+          default:
+          }
+      }
+    else
+      {
+        TableColumn [] cols = new TableColumn[ncols];
+        for (int i = 0; i < ncols; ++i)
+          cols[i] = columnModel.getColumn(i);
+        distributeSpill(cols, spill);        
+      }
+  }
+  
+  public void sizeColumnsToFit(boolean lastColumnOnly)
   {
-    throw new Error ("Not implemented");
+    doLayout();
   }
 
-  public void setSelectionMode (int selectionMode)
+  public void sizeColumnsToFit(int resizingColumn)
   {
-    throw new Error ("Not implemented");
+    doLayout();
   }
 
-  public void setSelectionModel (ListSelectionModel model)
+
+  public String getUIClassID()
   {
-    throw new Error ("Not implemented");
+    return "TableUI";
   }
 
-  public void setShowGrid (boolean showGrid)
+  public TableUI getUI()
   {
-    throw new Error ("Not implemented");
+    return (TableUI) ui;
   }
 
-  public void valueChanged (ListSelectionEvent event)
+  public void updateUI()
   {
-    throw new Error ("Not implemented");
+    setUI((TableUI) UIManager.getUI(this));
+    revalidate();
+    repaint();
   }
-} // class JTable
+
+}
Index: javax/swing/JTextArea.java
===================================================================
RCS file: javax/swing/JTextArea.java
diff -N javax/swing/JTextArea.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/JTextArea.java	6 Sep 2004 16:35:59 -0000
@@ -0,0 +1,252 @@
+/* JTextArea.java -- 
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.awt.Dimension;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
+public class JTextArea extends JTextComponent
+{
+  private static final long serialVersionUID = -6141680179310439825L;
+  
+  private int rows;
+  private int columns;
+  private boolean wrapping;
+  private int tabSize = 8;
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   */
+  public JTextArea()
+  {
+    this(null, null, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param text the initial text
+   */
+  public JTextArea(String text)
+  {
+    this(null, text, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(int rows, int columns)
+  {
+    this(null, null, rows, columns);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param text the initial text
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(String text, int rows, int columns)
+  {
+    this(null, text, rows, columns);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param the document model to use
+   */
+  public JTextArea(Document doc)
+  {
+    this(doc, null, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param the document model to use
+   * @param text the initial text
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(Document doc, String text, int rows, int columns)
+  {
+    setDocument(doc == null ? createDefaultModel() : doc);
+    setText(text);
+    setRows(rows);
+    setColumns(columns);
+  }
+
+  /**
+   * Appends some text.
+   *
+   * @param toAppend the text to append
+   */
+  public void append(String toAppend)
+  {
+    setText(getText() + toAppend);
+  }
+
+  /**
+   * Creates the default document model.
+   *
+   * @return a new default model
+   */
+  protected Document createDefaultModel()
+  {
+    return new PlainDocument();
+  }
+
+
+  public boolean getScrollableTracksViewportWidth()
+  {
+    return wrapping ? true : super.getScrollableTracksViewportWidth();
+  }
+
+  /**
+   * Returns the UI class ID string.
+   *
+   * @return the string "TextAreaUI"
+   */
+  public String getUIClassID()
+  {
+    return "TextAreaUI";
+  }
+
+  /**
+   * Returns the current number of columns.
+   *
+   * @return number of columns
+   */
+  public int getColumns()
+  {
+    return columns;
+  }
+  
+  /**
+   * Sets the number of rows.
+   *
+   * @param columns number of columns
+   *
+   * @exception IllegalArgumentException if columns is negative
+   */
+  public void setColumns(int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+
+    this.columns = columns;
+  }
+
+  /**
+   * Returns the current number of rows.
+   *
+   * @return number of rows
+   */
+  public int getRows()
+  {
+    return rows;
+  }
+
+  /**
+   * Sets the number of rows.
+   *
+   * @param columns number of columns
+   *
+   * @exception IllegalArgumentException if rows is negative
+   */
+  public void setRows(int rows)
+  {
+    if (rows < 0)
+      throw new IllegalArgumentException();
+
+    this.rows = rows;
+  }
+
+  /**
+   * Checks whethet line wrapping is enabled.
+   *
+   * @return true if line wrapping is enabled, false otherwise
+   */
+  public boolean getLineWrap()
+  {
+    return wrapping;
+  }
+
+  /**
+   * Enables/disables line wrapping.
+   *
+   * @param wrapping true to enable line wrapping, false otherwise
+   */
+  public void setLineWrap(boolean flag)
+  {
+    if (wrapping == flag)
+      return;
+
+    boolean oldValue = wrapping;
+    wrapping = flag;
+    firePropertyChange("lineWrap", oldValue, wrapping);
+  }
+
+  public int getTabSize()
+  {
+    return tabSize;
+  }
+
+  public void setTabSize(int newSize)
+  {
+    if (tabSize == newSize)
+      return;
+    
+    int oldValue = tabSize;
+    tabSize = newSize;
+    firePropertyChange("tabSize", oldValue, tabSize);
+  }
+}
Index: javax/swing/JTextField.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JTextField.java,v
retrieving revision 1.2
diff -u -r1.2 JTextField.java
--- javax/swing/JTextField.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JTextField.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
-/* JTextField.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JTextField.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,74 +35,241 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.Vector;
 import javax.accessibility.AccessibleStateSet;
 import javax.swing.text.Document;
 import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
 
-public class JTextField extends JEditorPane
+public class JTextField extends JTextComponent
+  implements SwingConstants
 {
+  /**
+   * AccessibleJTextField
+   */
+  protected class AccessibleJTextField extends AccessibleJTextComponent
+  {
+    private static final long serialVersionUID = 8255147276740453036L;
 
-	/**
-	 * AccessibleJTextField
-	 */
-	protected class AccessibleJTextField extends AccessibleJTextComponent {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJTextField
-		 * @param component TODO
-		 */
-		protected AccessibleJTextField(JTextField component) {
-			super(component);
-			// TODO
-		} // AccessibleJTextField()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
+    /**
+     * Constructor AccessibleJTextField
+     */
+    protected AccessibleJTextField()
+    {
+    }
 
+    /**
+     * getAccessibleStateSet
+     * @return AccessibleStateSet
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null;
+    }
+  }
 
-	} // AccessibleJTextField
+  private static final long serialVersionUID = 353853209832607592L;
 
+  public static final String notifyAction = "notify-field-accept";
+  
+  private int columns;
 
-    Vector actions = new Vector();
+  private int align;
 
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   */
   public JTextField()
   {
+    this(null, null, 0);
   }
 
-    public JTextField(int a)
-    {
-    }
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param text the initial text
+   */
+  public JTextField(String text)
+  {
+    this(null, text, 0);
+  }
+  
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(int columns)
+  {
+    this(null, null, columns);
+  }
 
-    public void addActionListener(ActionListener l)
-    {
-	actions.addElement(l);
-    }
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param text the initial text
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(String text, int columns)
+  {
+    this(null, text, columns);
+  }
 
-    public void removeActionListener(ActionListener l)
-    {
-	actions.removeElement(l);
-    }
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param doc the document to use
+   * @param text the initial text
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(Document doc, String text, int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+    
+    this.columns = columns;
+    
+    setDocument(doc == null ? createDefaultModel() : doc);
 
-    public void selectAll()
-    {
-    }
+    if (text != null)
+      setText(text);
+  }
+
+  /**
+   * Creates the default model for this text field.
+   * This implementation returns an instance of <code>PlainDocument</code>.
+   *
+   * @return a new instance of the default model
+   */
+  protected Document createDefaultModel()
+  {
+    return new PlainDocument();
+  }
+
+  /**
+   * Returns the class ID for the UI.
+   *
+   * @return "TextFieldUI";
+   */
+  public String getUIClassID()
+  {
+    return "TextFieldUI";
+  }
+
+  /**
+   * Adds a new listener object to this text field.
+   *
+   * @param listener the listener to add
+   */
+  public void addActionListener(ActionListener listener)
+  {
+    listenerList.add(ActionListener.class, listener);
+  }
+
+  /**
+   * Removes a listener object from this text field.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeActionListener(ActionListener listener)
+  {
+    listenerList.remove(ActionListener.class, listener);
+  }
+
+  /**
+   * Returns all registered <code>ActionListener</code> objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) getListeners(ActionListener.class);
+  }
+
+  /**
+   * Sends an action event to all registered
+   * <code>ActionListener</code> objects.
+   */
+  protected void fireActionPerformed()
+  {
+    ActionEvent event = new ActionEvent(this, 0, notifyAction);
+    ActionListener[] listeners = getActionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].actionPerformed(event);
+  }
+
+  /**
+   * Returns the number of columns of this text field.
+   *
+   * @return the number of columns
+   */
+  public int getColumns()
+  {
+    return columns;
+  }
+
+  public void setColumns(int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+
+    this.columns = columns;
+    invalidate();
+    repaint();
+  }
+
+  public int getHorizontalAlignment()
+  {
+    return align;
+  }
+
+  public void setHorizontalAlignment(int newAlign)
+  {
+    int oldAlign = align;
+    align = newAlign;
+    invalidate();
+    repaint();
+    firePropertyChange("horizontalAlignment", oldAlign, newAlign);
+  }
+
+  public void setFont(Font newFont)
+  {
+    super.setFont(newFont);
+    revalidate();
+  }
+
+  public Dimension getPreferredSize()
+  {
+    Dimension size;
+    FontMetrics fm = getFontMetrics(getFont());
+    int fontHeight = fm.getMaxAscent() + fm.getMaxDescent();
+    int columnWidth = fm.charWidth('m');
+    
+    if (columns != 0)
+      {
+	size = new Dimension(columns * columnWidth + 4, fontHeight + 4);
+      }
+    else
+      {
+	size = new Dimension(10, 10);
+      }
+
+    return size;
+  }
 }
Index: javax/swing/JToggleButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JToggleButton.java,v
retrieving revision 1.2
diff -u -r1.2 JToggleButton.java
--- javax/swing/JToggleButton.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JToggleButton.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
 /* JToggleButton.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -44,66 +44,102 @@
 
 public class JToggleButton extends AbstractButton implements Accessible
 {
-    public JToggleButton()
-    {
-	this(null, null);
-    }
-    public JToggleButton(Action a)
-    {
-	this();
-	setAction(a);
-    }
 
-    public JToggleButton(Icon icon)
-    { 
-	this(null, icon);
-    }    
+  public static class ToggleButtonModel extends DefaultButtonModel
+  {
+    private static final long serialVersionUID = -1589950750899943974L;
   
-    public JToggleButton(String text)
+    public void setPressed(boolean b)  
     {
-	this(text, null);
-    }
+      if (! isEnabled())
+        return;
       
-    public JToggleButton(String text, Icon icon)
-    {
-	this(text, icon, false);
-    }
-
-    public JToggleButton (String text, Icon icon, boolean selected) 
-    {
-	super(text, icon);
-
-        // Create the model
-        setModel(new ToggleButtonModel(this));
-	
-        model.setSelected(selected);
+      super.setPressed(b);
+      
+      // setPressed(false) == mouse release on us,
+      // if we were armed, we flip the selected state.
+      if (!b && isArmed())
+        setSelected(! isSelected());
     }
+  }
 
 
+  private static final long serialVersionUID = -3128248873429850443L;
     
-    public AccessibleContext getAccessibleContext()
-    {
-	//Gets the AccessibleContext associated with this JToggleButton. 
-	return null;
-    }
+  public JToggleButton()
+  {
+    this(null, null);
+  }
+  public JToggleButton(Action a)
+  {
+    this();
+    setAction(a);
+  }
+
+  public JToggleButton(Icon icon)
+  { 
+    this(null, icon);
+  }    
   
-    public String getUIClassID()
-    {
-	//Returns a string that specifies the name of the L&F class that renders this component.  
-	return "JToggleButton";
-    }
+  public JToggleButton (Icon icon, boolean selected) 
+  {
+    this(null, icon, selected);
+  }
   
-    protected  String paramString()
-    {
-	return "JToggleButton";
-    }
+  public JToggleButton(String text)
+  {
+    this(text, null);
+  }
+      
+  public JToggleButton(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+
+  public JToggleButton(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+
+  public JToggleButton (String text, Icon icon, boolean selected) 
+  {
+    super(text, icon);
+
+    horizontalAlignment = LEADING;
+    setModel(new ToggleButtonModel());	
+    model.setSelected(selected);
+  }
+
+  /**
+   * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
+   *
+   * @return the associated context
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
   
+  /**
+   * Returns a string that specifies the name of the Look and Feel
+   * class that renders this component.
+   */
+  public String getUIClassID()
+  {
+    return "ToggleButtonUI";
+  }
   
-    public void updateUI()
-    {	
-	ButtonUI b = (ButtonUI)UIManager.getUI(this);
-	setUI(b);
-    }
+  protected  String paramString()
+  {
+    return "JToggleButton";
+  }
+  
+  
+  public void updateUI()
+  {	
+    ButtonUI b = (ButtonUI)UIManager.getUI(this);
+    setUI(b);
+  }
 }
 
 
Index: javax/swing/JToolBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JToolBar.java,v
retrieving revision 1.3
diff -u -r1.3 JToolBar.java
--- javax/swing/JToolBar.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/JToolBar.java	6 Sep 2004 16:35:59 -0000
@@ -37,11 +37,13 @@
 
 package javax.swing;
 
-import java.awt.Dimension;
 import java.awt.Component;
 import java.awt.Container;
+import java.awt.Dimension;
 import java.awt.Graphics;
+import java.awt.GridLayout;
 import java.awt.Insets;
+import java.awt.LayoutManager;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
@@ -51,424 +53,735 @@
 import javax.accessibility.AccessibleStateSet;
 import javax.swing.plaf.ToolBarUI;
 
+
 /**
- * JToolBar
- * @author	Andrew Selkirk
- * @version	1.0
+ * JToolBar is a component that provides a toolbar to Swing programs. Users
+ * can add buttons (or actions that will be represented by JButtons) as well
+ * as other components to the JToolBar. JToolBars can be dragged in and out
+ * of their parent components. If the JToolBar is dragged out of the parent,
+ * then it will be displayed in its own RootPaneContainer. For dragging to
+ * work properly, JToolBars need to be placed in a Container that has a
+ * BorderLayout. That parent Container cannot have components in the NORTH,
+ * EAST, SOUTH,  or WEST components (that is not the JToolBar).
  */
-public class JToolBar extends JComponent 
-  implements SwingConstants, Accessible
+public class JToolBar extends JComponent implements SwingConstants, Accessible
 {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * AccessibleJToolBar
-	 */
-	protected class AccessibleJToolBar extends AccessibleJComponent {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJToolBar
-		 * @param component TODO
-		 */
-		protected AccessibleJToolBar(JToolBar component) {
-			super(component);
-			// TODO
-		} // AccessibleJToolBar()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return AccessibleRole.TOOL_BAR;
-		} // getAccessibleRole()
-
-
-	} // AccessibleJToolBar
-
-	/**
-	 * Separator
-	 */
-	public static class Separator extends JSeparator {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * separatorSize
-		 */
-		private Dimension size;
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor Separator
-		 */
-		public Separator() {
-			// TODO
-		} // Separator()
-
-		/**
-		 * Constructor Separator
-		 * @param size TODO
-		 */
-		public Separator(Dimension size) {
-			// TODO
-		} // Separator()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getUIClassID
-		 * @returns String
-		 */
-		public String getUIClassID() {
-			return null; // TODO
+  /**
+   * AccessibleJToolBar
+   */
+  protected class AccessibleJToolBar extends AccessibleJComponent
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -5516888265903814215L;
+
+    /**
+     * Constructor AccessibleJToolBar
+     */
+    protected AccessibleJToolBar()
+    {
+    }
+
+    /**
+     * getAccessibleStateSet
+     *
+     * @return AccessibleStateSet
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      return null; // TODO
+    }
+
+    /**
+     * getAccessibleRole
+     *
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.TOOL_BAR;
+    }
+  }
+
+	/**
+   * This is the private JToolBar layout manager.
+   */
+  private class DefaultToolBarLayout implements LayoutManager
+  {
+    /**
+     * This method is called when a new component is added to the container.
+     *
+     * @param name The name of the component added.
+     * @param comp The component that was added.
+	 */
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called to lay out the given container  to position and
+     * size the child components.
+     *
+     * @param c The container to lay out.
+     *
+     * @throws Error DOCUMENT ME!
+     */
+    public void layoutContainer(Container c)
+    {
+      if (! (c instanceof JToolBar))
+	throw new Error("DefaultToolBarLayout can only be used on JToolBars.");
+      Insets insets = getInsets();
+      Insets margin = getMargin();
+      int middle;
+      if (margin != null)
+        {
+	  insets.left += margin.left;
+	  insets.top += margin.top;
+	  insets.bottom += margin.bottom;
+	  insets.right += margin.right;
+        }
+      Component[] components = c.getComponents();
+      Dimension tdims = c.getSize();
+      int start = 0;
+      Dimension pref;
+    
+      if (getOrientation() == SwingUtilities.HORIZONTAL)
+        {
+	  start += insets.left;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] != null && components[i].isVisible())
+	        {
+		  pref = components[i].getPreferredSize();
+		  if (pref != null)
+		    {
+		      middle = (tdims.height - pref.height) / 2;
+		      components[i].setBounds(start, middle, pref.width,
+		                              pref.height);
+		      start += pref.width;
+		    }
+	        }
+	    }
+        }
+      else
+        {
+	  start += insets.top;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] != null && components[i].isVisible())
+	        {
+		  pref = components[i].getPreferredSize();
+		  if (pref != null)
+		    {
+		      middle = (tdims.width - pref.width) / 2;
+		      components[i].setBounds(middle, start, pref.width,
+		                              pref.height);
+		      start += pref.height;
+		    }
+	        }
+	    }
+        }
+    }
+
+    /**
+     * This method returns the minimum size of the given container given the
+     * child components.
+     *
+     * @param parent The container to measure.
+     *
+     * @return The minimum size of the given container.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return preferredLayoutSize(parent);
+    }
+
+		/**
+     * This method returns the preferred size of the given container given the
+     * child components.
+     *
+     * @param parent The container to measure.
+     *
+     * @return The preferred size of the given container.
+		 */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      int orientation = getOrientation();
+      Component[] components = getComponents();
+
+      int limit = 0;
+      int total = 0;
+      Dimension dims;
+
+      int w = 0;
+      int h = 0;
+
+      if (orientation == SwingConstants.HORIZONTAL)
+        {
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  if (dims.height > limit)
+		    limit = dims.height;
+		  total += dims.width;
+	        }
+	    }
+	  w = total;
+	  h = limit;
+        }
+      else
+        {
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  if (dims.width > limit)
+		    limit = dims.width;
+		  total += dims.height;
+	        }
+	    }
+	  w = limit;
+	  h = total;
+        }
+
+      Insets insets = getInsets();
+      w += insets.left + insets.right;
+      h += insets.top + insets.bottom;
+
+      Insets margin = getMargin();
+      if (margin != null)
+        {
+	  w += margin.left + margin.right;
+	  h += margin.top + margin.bottom;
+        }
+
+      return new Dimension(w, h);
+    }
+
+		/**
+     * This method is called when the given component  is removed from the
+     * container.
+     *
+     * @param comp The component removed.
+		 */
+    public void removeLayoutComponent(Component comp)
+    {
+      // Do nothing.
+    }
+  }
+
+		/**
+   * This is an extension of JSeparator used in toolbars. Unlike JSeparator,
+   * nothing is painted for this Separator, it is only blank space that
+   * separates components.
+		 */
+  public static class Separator extends JSeparator
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -1656745644823105219L;
+
+    /**
+     * Creates a new Separator object.
+     */
+    public Separator()
+    {
+      super();
+    } // Separator()
+
+    /**
+     * Creates a new Separator object with the given size.
+     *
+     * @param size The size of the separator.
+     */
+    public Separator(Dimension size)
+    {
+      setPreferredSize(size);
+    } // Separator()
+
+		/**
+     * This method returns the String ID of the UI class of  Separator.
+     *
+     * @return The UI class' String ID.
+		 */
+    public String getUIClassID()
+    {
+      return "ToolBarSeparatorUI";
 		} // getUIClassID()
 
 		/**
-		 * getPreferredSize
-		 * @returns Dimension
-		 */
-		public Dimension getPreferredSize() {
-			return null; // TODO
+     * This method returns the preferred size of the Separator.
+     *
+     * @return The preferred size of the Separator.
+		 */
+    public Dimension getPreferredSize()
+    {
+      return super.getPreferredSize();
 		} // getPreferredSize()
 
 		/**
-		 * getMaximumSize
-		 * @returns Dimension
-		 */
-		public Dimension getMaximumSize() {
-			return null; // TODO
+     * This method returns the maximum size of the Separator.
+     *
+     * @return The maximum size of the Separator.
+		 */
+    public Dimension getMaximumSize()
+    {
+      return super.getPreferredSize();
 		} // getMaximumSize()
 
 		/**
-		 * getMinimumSize
-		 * @returns Dimension
-		 */
-		public Dimension getMinimumSize() {
-			return null; // TODO
+     * This method returns the minimum size of the Separator.
+     *
+     * @return The minimum size of the Separator.
+		 */
+    public Dimension getMinimumSize()
+    {
+      return super.getPreferredSize();
 		} // getMinimumSize()
 
 		/**
-		 * getSeparatorSize
-		 * @returns Dimension
-		 */
-		public Dimension getSeparatorSize() {
-			return null; // TODO
+     * This method returns the size of the Separator.
+     *
+     * @return The size of the Separator.
+		 */
+    public Dimension getSeparatorSize()
+    {
+      return super.getPreferredSize();
 		} // getSeparatorSize()
 
 		/**
-		 * setSeparatorSize
-		 * @param size TODO
-		 */
-		public void setSeparatorSize(Dimension size) {
-			// TODO
+     * This method sets the size of the Separator.
+     *
+     * @param size The new size of the Separator.
+		 */
+    public void setSeparatorSize(Dimension size)
+    {
+      setPreferredSize(size);
 		} // setSeparatorSize()
-
-
 	} // Separator
 
+  /** DOCUMENT ME! */
+    private static final long serialVersionUID = -1269915519555129643L;
+    
+  /** Whether the JToolBar paints its border. */
+  private transient boolean paintBorder = true;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+  /** The extra insets around the JToolBar. */
+  private transient Insets margin;
 
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "ToolBarUI";
+  /** Whether the JToolBar can float (and be dragged around). */
+  private transient boolean floatable = true;
 
-	/**
-	 * paintBorder
-	 */
-	private boolean paintBorder;
+  /** Whether the buttons will have rollover borders. */
+  private transient boolean rollover;
 
-	/**
-	 * margin
-	 */
-	private Insets margin;
+  /** The orientation of the JToolBar. */
+	private int orientation = HORIZONTAL;
 
-	/**
-	 * floatable
-	 */
-	private boolean floatable;
+  /** Fired in a PropertyChangeEvent when the orientation property changes. */
+	public static final String ORIENTATION_CHANGED_PROPERTY = "orientation";
 
-	/**
-	 * orientation
-	 */
-	private int orientation;
+  /** Fired in a PropertyChangeEvent when the floatable property changes. */
+  public static final String FLOATABLE_CHANGED_PROPERTY = "floatable";
 
+  /** Fired in a PropertyChangeEvent when the borderPainted property changes. */
+  public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
 
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
+  /** Fired in a PropertyChangeEvent when the margin property changes. */
+  public static final String MARGIN_CHANGED_PROPERTY = "margin";
 
-	/**
-	 * Constructor JToolBar
-	 */
-	public JToolBar() {
-		// TODO
-	} // JToolBar()
+  /** Fired in a PropertyChangeEvent when the rollover property changes. */
+  public static final String ROLLOVER_CHANGED_PROPERTY = "rollover";
 
 	/**
-	 * Constructor JToolBar
-	 * @param orientation TODO
+   * This method creates a new JToolBar object with horizontal orientation
+   * and no name.
 	 */
-	public JToolBar(int orientation) {
-		// TODO
+  public JToolBar()
+  {
+    this(null, HORIZONTAL);
 	} // JToolBar()
 
 	/**
-	 * Constructor JToolBar
-	 * @param name TODO
-	 */
-	public JToolBar(String name) {
-		// TODO
+   * This method creates a new JToolBar with the given orientation and  no
+   * name.
+   *
+	 * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
+	 */
+  public JToolBar(int orientation)
+  {
+          this(null, orientation);
 	} // JToolBar()
 
 	/**
-	 * Constructor JToolBar
-	 * @param name TODO
-	 * @param orientation TODO
-	 */
-	public JToolBar(String name, int orientation) {
-		// TODO
+   * This method creates a new JToolBar object with the given name and
+   * horizontal orientation.
+   *
+	 * @param name Name assigned to undocked tool bar.
+	 */
+  public JToolBar(String name)
+  {
+          this(name, HORIZONTAL);
 	} // JToolBar()
 
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
+   * This method creates a new JToolBar object with the given name and
+   * orientation.
+   *
+	 * @param name Name assigned to undocked tool bar.
+	 * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
+	 */
+  public JToolBar(String name, int orientation)
+  {
+	        setName(name);
+    setOrientation(orientation);
+    setLayout(new DefaultToolBarLayout());
+    revalidate();
+                updateUI();	
+	} // JToolBar()
 
 	/**
-	 * add
-	 * @param action TODO
-	 * @returns JButton
-	 */
-	public JButton add(Action action) {
-		return null; // TODO
+   * This method adds a new JButton that performs the given Action to the
+   * JToolBar.
+   *
+   * @param action The Action to add to the JToolBar.
+   *
+   * @return The JButton that wraps the Action.
+	 */
+  public JButton add(Action action)
+  {
+    JButton b = createActionComponent(action);
+    add(b);
+    return b;
 	} // add()
 
 	/**
-	 * paintBorder
-	 * @param graphics TODO
-	 */
-	protected void paintBorder(Graphics graphics) {
-		// TODO
+   * This method paints the border if the borderPainted property is true.
+   *
+   * @param graphics The graphics object to paint with.
+	 */
+  protected void paintBorder(Graphics graphics)
+  {
+    if (paintBorder && isFloatable())
+      super.paintBorder(graphics);
 	} // paintBorder()
 
 	/**
-	 * getUI
-	 * @returns ToolBarUI
+   * This method returns the UI class used to paint this JToolBar.
+   *
+   * @return The UI class for this JToolBar.
 	 */
-	public ToolBarUI getUI() {
+  public ToolBarUI getUI()
+  {
 		return (ToolBarUI) ui;
 	} // getUI()
 
 	/**
-	 * setUI
-	 * @param ui TODO
+   * This method sets the UI used with the JToolBar.
+   *
+   * @param ui The UI used with the JToolBar.
 	 */
-	public void setUI(ToolBarUI ui) {
+  public void setUI(ToolBarUI ui)
+  {
 		super.setUI(ui);
 	} // setUI()
 
 	/**
-	 * updateUI
+   * This method resets the UI used to the Look and Feel defaults.
 	 */
-	public void updateUI() {
-		setUI((ToolBarUI) UIManager.get(this));
-		invalidate();
+  public void updateUI()
+  {
+          setUI((ToolBarUI)UIManager.getUI(this));
+    revalidate();
+    repaint();
 	} // updateUI()
 
 	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
+   * This method returns the String identifier for the UI class to the used
+   * with the JToolBar.
+   *
+   * @return The String identifier for the UI class.
+	 */
+  public String getUIClassID()
+  {
+    return "ToolBarUI";
 	} // getUIClassID()
 
 	/**
-	 * getComponentIndex
-	 * @param component TODO
-	 * @returns int
-	 */
-	public int getComponentIndex(Component component) {
-		return 0; // TODO
+   * This method sets the rollover property for the JToolBar. In rollover
+   * mode, JButtons inside the JToolBar will only display their borders when
+   * the mouse is moving over them.
+   *
+   * @param b The new rollover property.
+	 */
+  public void setRollover(boolean b)
+  {
+    if (b != rollover)
+      {
+	rollover = b;
+	firePropertyChange(ROLLOVER_CHANGED_PROPERTY, ! rollover, rollover);
+	revalidate();
+	repaint();
+      }
+  }
+
+  /**
+   * This method returns the rollover property.
+   *
+   * @return The rollover property.
+   */
+  public boolean isRollover()
+  {
+    return rollover;
+  }
+
+  /**
+   * This method returns the index of the given component.
+   *
+   * @param component The component to find.
+   *
+   * @return The index of the given component.
+   */
+  public int getComponentIndex(Component component)
+  {
+    Component[] components = getComponents();
+    if (components == null)
+      return -1;
+
+    for (int i = 0; i < components.length; i++)
+      if (components[i] == component)
+	return i;
+
+    return -1;
 	} // getComponentIndex()
 
 	/**
-	 * getComponentAtIndex
-	 * @param index TODO
-	 * @returns Component
-	 */
-	public Component getComponentAtIndex(int index) {
-		return null; // TODO
+   * This method returns the component at the given index.
+   *
+   * @param index The index of the component.
+   *
+   * @return The component at the given index.
+	 */
+  public Component getComponentAtIndex(int index)
+  {
+    return getComponent(index);
 	} // getComponentAtIndex()
 
 	/**
-	 * getMargin
-	 * @returns Insets
-	 */
-	public Insets getMargin() {
-		return null; // TODO
+   * This method returns the margin property.
+   *
+   * @return The margin property.
+	 */
+  public Insets getMargin()
+  {
+    return margin;
 	} // getMargin()
 
 	/**
-	 * setMargin
-	 * @param margin TODO
-	 */
-	public void setMargin(Insets margin) {
-		// TODO
+   * This method sets the margin property. The margin property determines the
+   * extra space between the children components of the JToolBar and the
+   * border.
+   *
+   * @param margin The margin property.
+	 */
+  public void setMargin(Insets margin)
+  {
+    if ((this.margin != null && margin == null)
+        || (this.margin == null && margin != null)
+        || (margin != null && this.margin != null
+        && (margin.left != this.margin.left
+        || margin.right != this.margin.right || margin.top != this.margin.top
+        || margin.bottom != this.margin.bottom)))
+      {
+	Insets oldMargin = this.margin;
+	this.margin = margin;
+	firePropertyChange(MARGIN_CHANGED_PROPERTY, oldMargin, this.margin);
+	revalidate();
+	repaint();
+      }
 	} // setMargin()
 
 	/**
-	 * isBorderPainted
-	 * @returns boolean
-	 */
-	public boolean isBorderPainted() {
-		return false; // TODO
+   * This method returns the borderPainted property.
+   *
+   * @return The borderPainted property.
+	 */
+  public boolean isBorderPainted()
+  {
+    return paintBorder;
 	} // isBorderPainted()
 
 	/**
-	 * setBorderPainted
-	 * @param painted TODO
-	 */
-	public void setBorderPainted(boolean painted) {
-		// TODO
+   * This method sets the borderPainted property. If set to false, the border
+   * will not be painted.
+   *
+   * @param painted Whether the border will be painted.
+	 */
+  public void setBorderPainted(boolean painted)
+  {
+    if (painted != paintBorder)
+      {
+	paintBorder = painted;
+	firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, ! paintBorder,
+	                   paintBorder);
+	repaint();
+      }
 	} // setBorderPainted()
 
 	/**
-	 * isFloatable
-	 * @returns boolean
-	 */
-	public boolean isFloatable() {
-		return false; // TODO
+   * This method returns the floatable property.
+   *
+   * @return The floatable property.
+	 */
+  public boolean isFloatable()
+  {
+    return floatable;
 	} // isFloatable()
 
 	/**
-	 * setFloatable
-	 * @param floatable TODO
-	 */
-	public void setFloatable(boolean floatable) {
-		// TODO
+   * This method sets the floatable property. If set to false, the JToolBar
+   * cannot be dragged.
+   *
+   * @param floatable Whether the JToolBar can be dragged.
+	 */
+  public void setFloatable(boolean floatable)
+  {
+    if (floatable != this.floatable)
+      {
+	this.floatable = floatable;
+	firePropertyChange(FLOATABLE_CHANGED_PROPERTY, ! floatable, floatable);
+      }
 	} // setFloatable()
 
 	/**
-	 * getOrientation
-	 * @returns int
-	 */
-	public int getOrientation() {
-		return 0; // TODO
+   * This method returns the orientation of the JToolBar.
+   *
+   * @return The orientation of the JToolBar.
+	 */
+  public int getOrientation()
+  {
+    return orientation;
 	} // getOrientation()
 
 	/**
-	 * setOrientation
-	 * @param orientation TODO
-	 */
-	public void setOrientation(int orientation) {
-		// TODO
+   * This method sets the layout manager to be used with the JToolBar.
+   *
+   * @param mgr The Layout Manager used with the JToolBar.
+	 */
+  public void setLayout(LayoutManager mgr)
+  {
+	    super.setLayout(mgr);
+    revalidate();
+    repaint();
+	} // setLayout()
+
+	/**
+   * This method sets the orientation property for JToolBar.
+   *
+   * @param orientation The new orientation for JToolBar.
+   *
+   * @throws IllegalArgumentException If the orientation is not HORIZONTAL or
+   *         VERTICAL.
+	 */
+  public void setOrientation(int orientation)
+  {
+		if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");
+	    if (orientation != this.orientation)
+	    {
+		int oldOrientation = this.orientation;
+		this.orientation = orientation;
+		firePropertyChange(ORIENTATION_CHANGED_PROPERTY, oldOrientation,
+			this.orientation);
+	revalidate();
+	repaint();
+	    }
 	} // setOrientation()
 
 	/**
-	 * addSeparator
+   * This method adds a Separator of default size to the JToolBar.
 	 */
-	public void addSeparator() {
-		// TODO
+  public void addSeparator()
+  {
+    add(new Separator());
 	} // addSeparator()
 
 	/**
-	 * addSeparator
-	 * @param size TODO
-	 */
-	public void addSeparator(Dimension size) {
-		// TODO
+   * This method adds a Separator with the given size to the JToolBar.
+   *
+   * @param size The size of the Separator.
+	 */
+  public void addSeparator(Dimension size)
+  {
+    add(new Separator(size));
 	} // addSeparator()
 
 	/**
-	 * createActionComponent
-	 * @param action TODO
-	 * @returns JButton
-	 */
-	protected JButton createActionComponent(Action action) {
-		return null; // TODO
+   * This method is used to create JButtons which can be added to the JToolBar
+   * for the given action.
+   *
+   * @param action The action to create a JButton for.
+   *
+   * @return The JButton created from the action.
+	 */
+  protected JButton createActionComponent(Action action)
+  {
+    return new JButton(action);
 	} // createActionComponent()
 
 	/**
-	 * createActionChangeListener
-	 * @param button TODO
-	 * @returns PropertyChangeListener
-	 */
-	protected PropertyChangeListener createActionChangeListener(JButton button) {
-		return null; // TODO
+   * This method creates a pre-configured PropertyChangeListener which updates
+   * the control as changes are made to the Action. However, this is no
+   * longer the recommended way of adding Actions to Containers. As such,
+   * this method returns null.
+   *
+   * @param button The JButton to configure a PropertyChangeListener for.
+   *
+   * @return null.
+	 */
+  protected PropertyChangeListener createActionChangeListener(JButton button)
+  {
+    // XXX: As specified, this returns null. But seems kind of strange, usually deprecated methods don't just return null, verify!
+    return null;
 	} // createActionChangeListener()
 
 	/**
-	 * addImpl
-	 * @param component TODO
-	 * @param constraints TODO
-	 * @param index TODO
-	 */
-	protected void addImpl(Component component, Object constraints, int index) {
-		// TODO
-	} // addImpl()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
+   * This method overrides Container's addImpl method. If a JButton is added,
+   * it is disabled.
+   *
+   * @param component The Component to add.
+   * @param constraints The Constraints placed on the component.
+   * @param index The index to place the Component at.
+  */
+  protected void addImpl(Component component, Object constraints, int index)
+  {
+    // XXX: Sun says disable button but test cases show otherwise.
+    super.addImpl(component, constraints, index);
+  } // addImpl()
+
+	/**
+   * This method returns a String description of the JToolBar.
+   *
+   * @return A String description of the JToolBar.
+	 */
+  protected String paramString()
+  {
+    return "JToolBar";
 	} // paramString()
 
-	/**
-	 * getAccessibleContext
-	 * @returns AccessibleContext
-	 */
-	public AccessibleContext getAccessibleContext() {
-		if (accessibleContext == null) {
-			accessibleContext = new AccessibleJToolBar(this);
-		} // if
-		return accessibleContext;
-	} // getAccessibleContext()
-
-
-} // JToolBar
+  /**
+   * getAccessibleContext
+   *
+   * @return AccessibleContext
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJToolBar();
+    
+    return accessibleContext;
+  }
+}
Index: javax/swing/JToolTip.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JToolTip.java,v
retrieving revision 1.2
diff -u -r1.2 JToolTip.java
--- javax/swing/JToolTip.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JToolTip.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
-/* JToolTip.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JToolTip.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,20 +35,160 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.AWTEvent;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.ToolTipUI;
+
 
+/**
+ * This class is used to display ToolTips. ToolTips are small floating windows
+ * that display text when the mouse comes to rest over a Component. ToolTips
+ * are set for JComponents using JComponent.setToolTipText(String).
+ */
 public class JToolTip extends JComponent implements Accessible
 {
-    String text;
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = -1138929898906751643L;
 
-    JToolTip(String text)
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJToolTip extends AccessibleJComponent
+  {
+    /**
+     * Creates a new AccessibleJToolTip object.
+     */
+    protected AccessibleJToolTip()
     {
-	this.text = text;
     }
-}
 
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getAccessibleDescription()
+    {
+      return null;
+    }
 
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+  }
+
+  /** The text to display in the JToolTip. */
+  String text;
+
+  /** The JComponent this JToolTip is used for. */
+  JComponent component;
+
+  /**
+   * Creates a new JToolTip object.
+   */
+  public JToolTip()
+  {
+    disableEvents(AWTEvent.MOUSE_EVENT_MASK);
+    updateUI();
+  }
+
+  /**
+   * This method returns the text this JToolTip displays.
+   *
+   * @return The text that this JToolTip displays.
+   */
+  public String getTipText()
+  {
+    return text;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the JComponent this JToolTip displays for.
+   *
+   * @return The JComponent this JToolTip displays for.
+   */
+  public JComponent getComponent()
+  {
+    return component;
+  }
+
+  /**
+   * This method returns the UI responsible for displaying this JToolTip.
+   *
+   * @return The UI responsible for displaying this JToolTip.
+   */
+  public ToolTipUI getUI()
+  {
+    return (ToolTipUI) ui;
+  }
+
+  /**
+   * This method returns the String identifier for the UI class.
+   *
+   * @return The String identifier for the UI class.
+   */
+  public String getUIClassID()
+  {
+    return "ToolTipUI";
+  }
+
+  /**
+   * This method returns a debugging String describing the JToolTip.
+   *
+   * @return A debugging String describing the JToolTip.
+   */
+  protected String paramString()
+  {
+    return "JToolTip";
+  }
+
+  /**
+   * This method sets the JComponent that the JToolTip displays for.
+   *
+   * @param c The JComponent that the JToolTip displays for.
+   */
+  public void setComponent(JComponent c)
+  {
+    component = c;
+  }
+
+  /**
+   * This method sets the text that the JToolTip displays.
+   *
+   * @param tipText The text that the JToolTip displays.
+   */
+  public void setTipText(String tipText)
+  {
+    text = tipText;
+  }
+
+  /**
+   * This method resets the UI used to the Look and Feel default.
+   */
+  public void updateUI()
+  {
+    setUI((ToolTipUI) UIManager.getUI(this));
+    revalidate();
+    repaint();
+  }
+}
Index: javax/swing/JTree.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JTree.java,v
retrieving revision 1.2
diff -u -r1.2 JTree.java
--- javax/swing/JTree.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JTree.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
-/* JTree.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JTree.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,92 +35,439 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Dimension;
 import java.awt.Rectangle;
-import java.io.Serializable;
 import java.util.Hashtable;
 import java.util.Vector;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeExpansionListener;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeWillExpandListener;
 import javax.swing.plaf.TreeUI;
-import javax.swing.tree.DefaultTreeSelectionModel;
-import javax.swing.tree.TreeCellEditor;
+import javax.swing.tree.ExpandVetoException;
 import javax.swing.tree.TreeCellRenderer;
 import javax.swing.tree.TreeModel;
 import javax.swing.tree.TreeNode;
 import javax.swing.tree.TreePath;
-import javax.swing.tree.TreeSelectionModel;
-
-public class JTree extends JComponent implements Scrollable, Accessible
-{
-    JTree()
-    {
-	updateUI();
-    }
-    
-    public TreeUI getUI()
-    {
-        return (TreeUI) ui;
-    }
-
-    public void setUI(TreeUI ui)
-    {
-        super.setUI(ui);
-    }
-
-    public void updateUI()
-    {
-        setUI((TreeUI)UIManager.getUI(this));
-    }
-
-    
-    public String getUIClassID()
-    {
-	return "JTree";
-    }
-
-
-    public AccessibleContext getAccessibleContext()
-    {
-      return null;
-    }
-
-    public Dimension getPreferredScrollableViewportSize()
-    {
-	return null;
-    }
-
-    public int getScrollableUnitIncrement(Rectangle visibleRect,
-					  int orientation,
-					  int direction)
-    {
-	return 1;
-    }
-
-    public int getScrollableBlockIncrement(Rectangle visibleRect,
-					   int orientation,
-					   int direction)
-    {
-	return 1;
-    }
-
-    public boolean getScrollableTracksViewportWidth()
-    {
-	return false;
-    }
-
-    public boolean getScrollableTracksViewportHeight()
-    {
-	return false;
-    }
-}
 
 
+public class JTree extends JComponent
+  implements Scrollable, Accessible
+{
+  private static final long serialVersionUID = 7559816092864483649L;
 
+  protected TreeCellRenderer cellRenderer;
+  protected boolean editable;
+  protected boolean rootVisible;
+  protected boolean showsRootHandles;
+  protected TreeModel treeModel;
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   */
+  public JTree()
+  {
+    treeModel = createTreeModel(null);
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param value the initial nodes in the tree
+   */
+  public JTree(Hashtable value)
+  {
+    treeModel = createTreeModel(value);
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param value the initial nodes in the tree
+   */
+  public JTree(Object[] value)
+  {
+    treeModel = createTreeModel(value);
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param model the model to use
+   */
+  public JTree(TreeModel model)
+  {
+    treeModel = model;
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param root the root node
+   */
+  public JTree(TreeNode root)
+  {
+    this(root, false);
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param root the root node
+   * @param asksAllowChildren if false, all nodes without children are leaf nodes.
+   * If true, only nodes that do not allow children are leaf nodes.
+   */
+  public JTree(TreeNode root, boolean asksAllowChildren)
+  {
+  }
+
+  /**
+   * Creates a new <code>JTree</code> object.
+   *
+   * @param value the initial nodes in the tree
+   */
+  public JTree(Vector value)
+  {
+    treeModel = createTreeModel(value);
+  }
+
+  /**
+   * Creates a new <code>TreeModel</code> object.
+   *
+   * @param value the values stored in the model
+   */
+  protected static TreeModel createTreeModel(Object value)
+  {
+    // FIXME: Implement this.
+    return null;
+  }
+
+  /**
+   * Return the UI associated with this <code>JTree</code> object.
+   *
+   * @return the associated <code>TreeUI</code> object
+   */
+  public TreeUI getUI()
+  {
+    return (TreeUI) ui;
+  }
+
+  /**
+   * Sets the UI associated with this <code>JTree</code> object.
+   *
+   * @param ui the <code>TreeUI</code> to associate
+   */
+  public void setUI(TreeUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method resets the UI used to the Look and Feel defaults..
+   */
+  public void updateUI()
+  {
+    setUI((TreeUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns the String ID of the UI class of  Separator.
+   *
+   * @return The UI class' String ID.
+   */
+  public String getUIClassID()
+  {
+    return "TreeUI";
+  }
+
+  /**
+   * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
+   *
+   * @return the associated context
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+  /**
+   * Returns the preferred viewport size..
+   *
+   * @return the preferred size
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    return null;
+  }
+
+  public int getScrollableUnitIncrement(Rectangle visibleRect,
+                                        int orientation, int direction)
+  {
+    return 1;
+  }
+
+  public int getScrollableBlockIncrement(Rectangle visibleRect,
+                                         int orientation, int direction)
+  {
+    return 1;
+  }
+
+  public boolean getScrollableTracksViewportWidth()
+  {
+    return false;
+  }
+
+  public boolean getScrollableTracksViewportHeight()
+  {
+    return false;
+  }
+
+  /**
+   * Adds a <code>TreeExpansionListener</code> object to the tree.
+   *
+   * @param listener the listener to add
+   */
+  public void addTreeExpansionListener(TreeExpansionListener listener)
+  {
+    listenerList.add(TreeExpansionListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>TreeExpansionListener</code> object from the tree.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeTreeExpansionListener(TreeExpansionListener listener)
+  {
+    listenerList.remove(TreeExpansionListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>TreeExpansionListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public TreeExpansionListener[] getTreeExpansionListeners()
+  {
+    return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
+  }
+
+  /**
+   * Notifies all listeners that the tree was collapsed.
+   *
+   * @param path the path to the node that was collapsed
+   */
+  public void fireTreeCollapsed(TreePath path)
+  {
+    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
+    TreeExpansionListener[] listeners = getTreeExpansionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].treeCollapsed(event);
+  }
+  
+  /**
+   * Notifies all listeners that the tree was expanded.
+   *
+   * @param path the path to the node that was expanded
+   */
+  public void fireTreeExpanded(TreePath path)
+  {
+    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
+    TreeExpansionListener[] listeners = getTreeExpansionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].treeExpanded(event);
+  }
+
+  /**
+   * Adds a <code>TreeSelctionListener</code> object to the tree.
+   *
+   * @param listener the listener to add
+   */
+  public void addTreeSelectionListener(TreeSelectionListener listener)
+  {
+    listenerList.add(TreeSelectionListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>TreeSelectionListener</code> object from the tree.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeTreeSelectionListener(TreeSelectionListener listener)
+  {
+    listenerList.remove(TreeSelectionListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>TreeSelectionListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public TreeSelectionListener[] getTreeSelectionListeners()
+  {
+    return (TreeSelectionListener[]) getListeners(TreeSelectionListener.class);
+  }
+
+  /**
+   * Notifies all listeners when the selection of the tree changed.
+   *
+   * @param event the event to send
+   */
+  protected void fireValueChanged(TreeSelectionEvent event)
+  {
+    TreeSelectionListener[] listeners = getTreeSelectionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].valueChanged(event);
+  }
+
+  /**
+   * Adds a <code>TreeWillExpandListener</code> object to the tree.
+   *
+   * @param listener the listener to add
+   */
+  public void addTreeWillExpandListener(TreeWillExpandListener listener)
+  {
+    listenerList.add(TreeWillExpandListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>TreeWillExpandListener</code> object from the tree.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeTreeWillExpandListener(TreeWillExpandListener listener)
+  {
+    listenerList.remove(TreeWillExpandListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>TreeWillExpandListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public TreeWillExpandListener[] getTreeWillExpandListeners()
+  {
+    return (TreeWillExpandListener[]) getListeners(TreeWillExpandListener.class);
+  }
+
+  /**
+   * Notifies all listeners that the tree will collapse.
+   *
+   * @param path the path to the node that will collapse
+   */
+  public void fireTreeWillCollapse(TreePath path)
+    throws ExpandVetoException
+  {
+    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
+    TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].treeWillCollapse(event);
+  }
+
+  /**
+   * Notifies all listeners that the tree will expand.
+   *
+   * @param path the path to the node that will expand
+   */
+  public void fireTreeWillExpand(TreePath path)
+    throws ExpandVetoException
+  {
+    TreeExpansionEvent event = new TreeExpansionEvent(this, path);
+    TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].treeWillExpand(event);
+  }
+
+  /**
+   * Returns the model of this <code>JTree</code> object.
+   *
+   * @return the associated <code>TreeModel</code>
+   */
+  public TreeModel getModel()
+  {
+    return treeModel;
+  }
+
+  /**
+   * Sets the model to use in <code>JTree</object>.
+   *
+   * @param model the <code>TreeModel</code> to use
+   */
+  public void setModel(TreeModel model)
+  {
+    treeModel = model;
+  }
+
+  /**
+   * Checks if this <code>JTree</code> object is editable.
+   *
+   * @return <code>true</code> if this tree object is editable,
+   * <code>false</code> otherwise
+   */
+  public boolean isEditable()
+  {
+    return editable;
+  }
+
+  /**
+   * Sets the <code>editable</code> property.
+   *
+   * @param flag <code>true</code> to make this tree object editable,
+   * <code>false</code> otherwise
+   */
+  public void setEditable(boolean flag)
+  {
+    if (editable == flag)
+      return;
+
+    boolean oldValue = editable;
+    editable = flag;
+    firePropertyChange("editable", oldValue, editable);
+  }
+
+  /**
+   * Checks if the root element is visible.
+   *
+   * @return <code>true</code> if the root element is visible,
+   * <code>false</code> otherwise
+   */
+  public boolean isRootVisbile()
+  {
+    return rootVisible;
+  }
+
+  public void setRootVisible(boolean flag)
+  {
+    rootVisible = flag;
+  }
+
+  public boolean getShowsRootHandles()
+  {
+    return showsRootHandles;
+  }
+
+  public void setShowRootHandles(boolean flag)
+  {
+    showsRootHandles = flag;
+  }
+
+  public TreeCellRenderer getCellRenderer()
+  {
+    return cellRenderer;
+  }
+  
+  public void setCellRenderer(TreeCellRenderer newRenderer)
+  {
+    cellRenderer = newRenderer;
+  }
+}
Index: javax/swing/JViewport.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JViewport.java,v
retrieving revision 1.2
diff -u -r1.2 JViewport.java
--- javax/swing/JViewport.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/JViewport.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
 /* JViewport.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,104 +39,314 @@
 package javax.swing;
 
 import java.awt.Component;
-import java.awt.Container;
+import java.awt.Dimension;
 import java.awt.Graphics;
-import java.awt.Image;
+import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
+
 import javax.accessibility.Accessible;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ViewportUI;
 
+
+/**
+ *  
+ * <pre>
+ *                                                     _
+ *   +-------------------------------+    ...........Y1 \
+ *   |  view                         |                .  \
+ *   |  (this component's child)     |                .   > VY
+ *   |                               |                .  / = Y2-Y1
+ *   |         +------------------------------+  ....Y2_/
+ *   |         | viewport            |        |       .
+ *   |         | (this component)    |        |       .
+ *   |         |                     |        |       .
+ *   |         |                     |        |       .
+ *   |         |                     |        |       .
+ *   |         |                     |        |       .
+ *   |         +------------------------------+  ....Y3
+ *   |                               |                .
+ *   |         .                     |        .       .
+ *   |         .                     |        .       .
+ *   +---------.---------------------+    ...........Y4
+ *   .         .                     .        .
+ *   .         .                     .        .
+ *   .         .                     .        .
+ *   X1.......X2.....................X3.......X4
+ *   \____  ___/
+ *        \/
+ *        VX = X2-X1
+ *</pre>
+ *  
+ * <p>A viewport is, like all swing components, located at some position in
+ * the swing component tree; that location is exactly the same as any other
+ * components: the viewport's "bounds".</p>
+ *
+ * <p>But in terms of drawing its child, the viewport thinks of itself as
+ * covering a particular position <em>of the view's coordinate space</em>.
+ * For example, the {@link javax.JViewPort.getViewPosition} method returns
+ * the position <code>(VX,VY)</code> shown above, which is an position in
+ * "view space", even though this is <em>implemented</em> by positioning
+ * the underlying child at position <code>(-VX,-VY)</code></p>
+ *
+ */
 public class JViewport extends JComponent
 {
-    Component c;
-
-    JViewport()
-    {
-	setOpaque(true);
-	updateUI();
-    }
-
-    void setView(Component c)
-    {
-	if (this.c != null)
-	    remove(c);
-
-	this.c = c;
-
-	add(c);
-    }
-
-    public String getUIClassID()
-    {
-	return "JViewport";
-    }
-
-    public void updateUI()
-    {
-	ViewportUI vp = (ViewportUI) UIManager.getUI(this);
-	setUI(vp);
-    }
-
-    Container GetHeavy(Container parent)
-    {
-	if (parent == null)
-	    return null;
-
-	while (isLightweightComponent(parent))
-	    {
-		Container p = parent.getParent();
-
-		if (p == null)
-		    {
-			System.out.println("GetHeavy FAILED, no heavy weight component found");
-			return parent;
-		    }
-		
-		parent = p;
-	    }
-	return parent;
-    }
+  private static final long serialVersionUID = -6925142919680527970L;
+  
+  public static final int SIMPLE_SCROLL_MODE = 0;
+  public static final int BLIT_SCROLL_MODE = 1;
+  public static final int BACKINGSTORE_SCROLL_MODE = 2;
+
+  ChangeEvent changeEvent = new ChangeEvent(this);
+
+  int scrollMode;
+
+  protected boolean scrollUnderway;
+  protected boolean isViewSizeSet;
+
+  /** 
+   * The width and height of the Viewport's area in terms of view
+   * coordinates.  Typically this will be the same as the width and height
+   * of the viewport's bounds, unless the viewport transforms units of
+   * width and height, which it may do, for example if it magnifies or
+   * rotates its view.
+   *
+   * @see #toViewCoordinates
+   */
+  Dimension extentSize;
+
+  /**
+   * The width and height of the view in its own coordinate space.
+   */
+
+  Dimension viewSize;
+
+  Point lastPaintPosition;
+
+  public JViewport()
+  {
+    setOpaque(true);
+    updateUI();
+  }
+
+  public Dimension getExtentSize()
+  {
+    if (extentSize == null)
+      return toViewCoordinates(getSize());
+    else
+      return extentSize;
+  }
+
+  public Dimension toViewCoordinates(Dimension size)
+  {
+    return size;
+  }
+
+  public Point toViewCoordinates(Point p)
+  {
+    Point pos = getViewPosition();
+    return new Point(p.x + pos.x,
+                     p.y + pos.y);
+  }
+
+  public void setExtentSize(Dimension newSize)
+  {
+    extentSize = newSize;
+    fireStateChanged();
+  }
+
+  public Dimension getViewSize()
+  {
+    if (isViewSizeSet)
+      return viewSize;
+    else
+      return getView().getSize();
+  }
+
+
+  public void setViewSize(Dimension newSize)
+  {
+    viewSize = newSize;
+    Component view = getView();
+    if (view != null)
+      view.setSize(viewSize);
+    isViewSizeSet = true;
+    fireStateChanged();
+  }
+
+  /**
+   * Get the viewport's position in view space. Despite confusing name,
+   * this really does return the viewport's (0,0) position in view space,
+   * not the view's position.
+   */
+
+  public Point getViewPosition()
+  {
+    Component view = getView();
+    if (view == null)
+      return new Point(0,0);
+    else
+      {
+        Point p = view.getLocation();
+        p.x = -p.x;
+        p.y = -p.y;
+        return p;
+      }
+  }
+
+  public void setViewPosition(Point p)
+  {
+    Component view = getView();
+    if (view != null)
+      {
+        Point q = new Point(-p.x, -p.y);
+        view.setLocation(q);
+        fireStateChanged();
+      }
+  }
+
+  public Rectangle getViewRect()
+  {
+    return new Rectangle(getViewPosition(), 
+                         getExtentSize());
+  }
+
+  public boolean isBackingStoreEnabled()
+  {
+    return scrollMode == BACKINGSTORE_SCROLL_MODE;
+  }
+
+  public void setBackingStoreEnabled(boolean b)
+  {
+    if (b && scrollMode != BACKINGSTORE_SCROLL_MODE)
+      {
+        scrollMode = BACKINGSTORE_SCROLL_MODE;
+        fireStateChanged();
+      }
+  }
+
+  public void setScrollMode(int mode)
+  {
+    scrollMode = mode;
+    fireStateChanged();
+  }
+
+  public int getScrollMode()
+  {
+    return scrollMode;
+  }
+
+  public Component getView()
+  {
+    if (getComponentCount() == 0)
+      return null;
+  
+    return getComponents()[0];
+  }
+
+  public void setView(Component v)
+  {
+    while (getComponentCount() > 0)
+      remove(0);
+    if (v != null)
+      {
+        add(v);
+        fireStateChanged();
+      }
+  }
+
+  public void revalidate()
+  {
+    fireStateChanged();
+    super.revalidate();
+  }
+
+  public void reshape(int x, int y, int w, int h)
+  {
+    boolean changed = 
+      (x != getX()) 
+      || (y != getY()) 
+      || (w != getWidth())
+      || (h != getHeight());
+    super.reshape(x, y, w, h);
+    if (changed)
+      fireStateChanged();
+  }
     
+  public void addImpl(Component comp, Object constraints, int index)
+  {
+    if (getComponentCount() > 0)
+      remove(getComponents()[0]);
     
-    public void paint(Graphics g)
-    {
-	paintChildren(g);
-
-	System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX   JViewport -----> paint()");
-
-	Container parent = GetHeavy(getParent());
-	
-	System.out.println("parent = " + parent + ", " + getParent());
-
-	//parent.paint();
-
-	Graphics wg = parent.getGraphics();
-	
-	int x = 0;
-	int y = 0;
-	int w = getWidth();
-	int h = getHeight();
-
-	Rectangle r = new Rectangle(x, y, w, h);
-
-	int ox = 0;
-	int oy = 0;
-
-	wg.copyArea(r.x,
-		    r.y,
-		    r.width,
-		    r.height,
-		    ox,
-		    oy);
+    super.addImpl(comp, constraints, index);
+  }
 
-	wg.dispose();
-    }
+  public final Insets getInsets() 
+  {
+    return new Insets(0,0,0,0);
+  }
+
+  public final Insets getInsets(Insets insets)
+  {
+    if (insets == null)
+      return getInsets();
+    insets.top = 0;
+    insets.bottom = 0;
+    insets.left = 0;
+    insets.right = 0;
+    return insets;
+  }
+    
+  public boolean isOptimizedDrawingEnabled()
+  {
+    return false;
+  }
+
+  public ChangeListener[] getChangeListeners() 
+  {
+    return (ChangeListener[]) getListeners(ChangeListener.class);
+  }
+
+  public void paint(Graphics g)
+  {
+    paintComponent(g);
+  }
+
+  void fireStateChanged()
+  {
+    ChangeListener[] listeners = getChangeListeners();
+    for (int i = 0; i < listeners.length; ++i)
+      listeners[i].stateChanged(changeEvent);
+  }
+
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * This method returns the String ID of the UI class of  Separator.
+   *
+   * @return The UI class' String ID.
+   */
+  public String getUIClassID()
+  {
+    return "ViewportUI";
+  }
+
+  /**
+   * This method resets the UI used to the Look and Feel defaults..
+   */
+  public void updateUI()
+  {
+    setUI((ViewportUI) UIManager.getUI(this));
+  }            
 }
-
-
-
-
-
-
-
Index: javax/swing/JWindow.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JWindow.java,v
retrieving revision 1.3
diff -u -r1.3 JWindow.java
--- javax/swing/JWindow.java	27 Jun 2003 12:41:52 -0000	1.3
+++ javax/swing/JWindow.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
 /* JWindow.java --
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -44,11 +44,11 @@
 import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
 import java.awt.LayoutManager;
 import java.awt.Window;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowEvent;
+
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 
@@ -58,8 +58,10 @@
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
-public class JWindow extends Window implements Accessible
+public class JWindow extends Window implements Accessible, RootPaneContainer
 {
+  private static final long serialVersionUID = 5420698392125238833L;
+  
     public final static int HIDE_ON_CLOSE        = 0;
     public final static int EXIT_ON_CLOSE        = 1;
     public final static int DISPOSE_ON_CLOSE     = 2;
@@ -79,8 +81,8 @@
      *************/
 
     public JWindow()
-    {
-      this(null);
+    {      
+      super(SwingUtilities.getOwnerFrame());
     }
 
     // huuu ?
@@ -114,30 +116,23 @@
     return d;
   }
 
-    JMenuBar getJMenuBar()
-    {    return getRootPane().getJMenuBar();   }
-    
-    void setJMenuBar(JMenuBar menubar)
-    {    getRootPane().setJMenuBar(menubar); }
-    
-
   public  void setLayout(LayoutManager manager)
   {    super.setLayout(manager);  }
 
-    void setLayeredPane(JLayeredPane layeredPane) 
+    public void setLayeredPane(JLayeredPane layeredPane) 
     {   getRootPane().setLayeredPane(layeredPane);   }
   
-    JLayeredPane getLayeredPane()
+    public JLayeredPane getLayeredPane()
     {   return getRootPane().getLayeredPane();     }
   
-    JRootPane getRootPane()
+    public JRootPane getRootPane()
     {
 	if (rootPane == null)
 	    setRootPane(createRootPane());
 	return rootPane;          
     }
 
-    void setRootPane(JRootPane root)
+    public void setRootPane(JRootPane root)
     {
 	if (rootPane != null)
 	    remove(rootPane);
@@ -146,19 +141,19 @@
 	add(rootPane, BorderLayout.CENTER);
     }
 
-    JRootPane createRootPane()
+    public JRootPane createRootPane()
     {   return new JRootPane();    }
 
-    Container getContentPane()
+    public Container getContentPane()
     {    return getRootPane().getContentPane();     }
 
-    void setContentPane(Container contentPane)
+    public void setContentPane(Container contentPane)
     {    getRootPane().setContentPane(contentPane);    }
   
-    Component getGlassPane()
+    public Component getGlassPane()
     {    return getRootPane().getGlassPane();   }
   
-    void setGlassPane(Component glassPane)
+    public void setGlassPane(Component glassPane)
     {   getRootPane().setGlassPane(glassPane);   }
 
     
Index: javax/swing/KeyStroke.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/KeyStroke.java,v
retrieving revision 1.3
diff -u -r1.3 KeyStroke.java
--- javax/swing/KeyStroke.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/KeyStroke.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
 /* KeyStroke.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -41,231 +41,65 @@
 import java.awt.event.KeyEvent;
 import java.io.Serializable;
 
-/**
- * KeyStroke
- * @author	Andrew Selkirk
- * @version	1.0
- */
-public class KeyStroke implements Serializable
+public class KeyStroke 
+  extends AWTKeyStroke
+  implements Serializable
 {
   static final long serialVersionUID = -9060180771037902530L;
+  private KeyStroke() {
+  }
+  
+  protected KeyStroke(char keyChar, int keyCode, int modifiers,
+                      boolean onKeyRelease)
+  {
+    super(keyChar, keyCode, modifiers, onKeyRelease);
+  }
+
+  static
+  {
+    AWTKeyStroke.registerSubclass(KeyStroke.class);
+  }
+
+  public static KeyStroke getKeyStroke(char keyChar) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyChar);
+  }
+
+  /** 
+   * @deprecated Use {@link #getKeyStroke(char)}
+   *
+   * This method, unlike all the other factory methods on this object,
+   * returns a non-cached, non-shared object. New code should not use it.
+   */
+  public static KeyStroke getKeyStroke(char keyChar, boolean onKeyRelease) 
+  {
+    return new KeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, onKeyRelease);
+  }
+
+  public static KeyStroke getKeyStroke(Character keyChar, int modifiers) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyChar, modifiers);
+  }
+
+  public static KeyStroke getKeyStroke(int keyCode, int modifiers, 
+                                       boolean onKeyRelease) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyCode, modifiers, onKeyRelease);
+  }
+
+  public static KeyStroke getKeyStroke(int keyCode, int modifiers) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyCode, modifiers);
+  }
+
+  public static KeyStroke getKeyStroke(String str) 
+  {
+    return (KeyStroke) getAWTKeyStroke(str);
+  }
+
+  public static KeyStroke getKeyStrokeForEvent(KeyEvent event) 
+  {
+    return (KeyStroke) getAWTKeyStrokeForEvent(event);
+  }
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * keyChar
-	 */
-	private	char	keyChar			= 0;
-
-	/**
-	 * keyCode
-	 */
-	private	int		keyCode			= 0;
-
-	/**
-	 * modifiers
-	 */
-	private	int		modifiers		= 0;
-
-	/**
-	 * onKeyRelease
-	 */
-	private	boolean	onKeyRelease	= false;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor KeyStroke
-	 */
-	private KeyStroke() {
-	} // KeyStroke()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * hashCode
-	 * @returns int
-	 */
-	public int hashCode() {
-		return 0; // TODO
-	} // hashCode()
-
-	/**
-	 * equals
-	 * @param object TODO
-	 * @returns boolean
-	 */
-	public boolean equals(Object object) {
-
-		// Variables
-		KeyStroke	key;
-
-		if (object instanceof KeyStroke) {
-			key = (KeyStroke) object;
-			if (key.keyChar == keyChar &&
-				key.keyCode == keyCode &&
-				key.modifiers == modifiers &&
-				key.onKeyRelease == onKeyRelease) {
-				return true;
-			} // if
-		} // if
-		return false;
-
-	} // equals()
-
-	/**
-	 * toString
-	 * @returns String
-	 */
-	public String toString() {
-		return null; // TODO
-	} // toString()
-
-	/**
-	 * getKeyStroke
-	 * @param keyChar TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(char keyChar) {
-
-		// Variables
-		KeyStroke	key;
-
-		key = new KeyStroke();
-		key.keyChar = keyChar;
-		return key;
-
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStroke - deprecated
-	 * @param keyChar TODO
-	 * @param onKeyRelease TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(char keyChar, boolean onKeyRelease) {
-		KeyStroke key = getKeyStroke(keyChar);
-		key.onKeyRelease = onKeyRelease;
-		return key;
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStroke
-	 * @param keyChar TODO
-	 * @param modifiers TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(Character keyChar, int modifiers) {
-		KeyStroke key = getKeyStroke(keyChar.charValue());
-		key.modifiers = modifiers;
-		return key;
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStroke
-	 * @param keyCode TODO
-	 * @param modifiers TODO
-	 * @param onKeyRelease TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(int keyCode, int modifiers, 
-				boolean onKeyRelease) {
-
-		// Variables
-		KeyStroke	key;
-
-		key = new KeyStroke();
-		key.keyCode = keyCode;
-		key.modifiers = modifiers;
-		key.onKeyRelease = onKeyRelease;
-		return key;
-
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStroke
-	 * @param keyCode TODO
-	 * @param modifiers TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(int keyCode, int modifiers) {
-		return getKeyStroke(keyCode, modifiers, false);
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStroke
-	 * @param string TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStroke(String string) {
-		return null; // TODO
-	} // getKeyStroke()
-
-	/**
-	 * getKeyStrokeForEvent
-	 * @param event TODO
-	 * @returns KeyStroke
-	 */
-	public static KeyStroke getKeyStrokeForEvent(KeyEvent event) {
-
-		// Variables
-		int	eventID;
-		int	eventMod;
-
-		// Get Event ID
-		eventID = event.getID();
-		eventMod = event.getModifiers();
-
-		// Check for KEY_TYPED event
-		if (eventID == KeyEvent.KEY_TYPED) {
-			return getKeyStroke(event.getKeyChar(), eventMod);
-
-		// KEY_PRESSED or KEY_RELEASED event
-		} else {
-			return getKeyStroke(event.getKeyCode(), eventMod);
-		} // if
-
-	} // getKeyStrokeForEvent()
-
-	/**
-	 * getKeyChar
-	 * @returns char
-	 */
-	public char getKeyChar() {
-		return keyChar;
-	} // getKeyChar()
-
-	/**
-	 * getKeyCode
-	 * @returns int
-	 */
-	public int getKeyCode() {
-		return keyCode;
-	} // getKeyCode()
-
-	/**
-	 * getModifiers
-	 * @returns int
-	 */
-	public int getModifiers() {
-		return modifiers; // TODO
-	} // getModifiers()
-
-	/**
-	 * isOnKeyRelease
-	 * @returns boolean
-	 */
-	public boolean isOnKeyRelease() {
-		return onKeyRelease;
-	} // isOnKeyRelease()
-
-
-} // KeyStroke
+}
Index: javax/swing/ListModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ListModel.java,v
retrieving revision 1.2
diff -u -r1.2 ListModel.java
--- javax/swing/ListModel.java	10 Jan 2004 21:07:43 -0000	1.2
+++ javax/swing/ListModel.java	6 Sep 2004 16:35:59 -0000
@@ -1,4 +1,4 @@
-/* ListModel.java -- 
+/* ListModel.java --
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -36,13 +36,45 @@
 exception statement from your version. */
 
 package javax.swing;
-
 import javax.swing.event.ListDataListener;
 
+/**
+ * This is an interface to general list-like data, typically used as the
+ * model object of a {@link JList} component.
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
 public interface ListModel
-{    
+{
+  /**
+   * Return the number of data elements in the list.
+   *
+   * @return The number of data elements in the list
+   */
   int getSize();
+
+  /**
+   * Retrieves a data element at a specified index.
+   *
+   * @param index The index of the element to retrieve
+   *
+   * @return The data element at the specified index
+   */
   Object getElementAt(int index);
+
+  /**
+   * Add a listener object to this model. The listener will be called
+   * any time the set of elements in the model is changed.
+   *
+   * @param l The listener to add
+   */
   void addListDataListener(ListDataListener l);
+
+  /**
+   * Add a listener object to this model. The listener will no longer be
+   * called when the set of elements in the model is changed.
+   *
+   * @param l The listener to remove
+   */
   void removeListDataListener(ListDataListener l);
 }
Index: javax/swing/ListSelectionModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ListSelectionModel.java,v
retrieving revision 1.3
diff -u -r1.3 ListSelectionModel.java
--- javax/swing/ListSelectionModel.java	12 Oct 2003 13:20:49 -0000	1.3
+++ javax/swing/ListSelectionModel.java	6 Sep 2004 16:35:59 -0000
@@ -42,24 +42,41 @@
 
 public interface ListSelectionModel
 {
-    int SINGLE_SELECTION = 0;
-    int SINGLE_INTERVAL_SELECTION = 1;
-    int MULTIPLE_INTERVAL_SELECTION = 1;
-
-    void setSelectionMode(int a);
-    int getSelectionMode();
-
-    void clearSelection();
+  int SINGLE_SELECTION = 0;
+  int SINGLE_INTERVAL_SELECTION = 1;
+  int MULTIPLE_INTERVAL_SELECTION = 2;
+
+  void setSelectionMode(int a);
+  int getSelectionMode();
+  
+  void clearSelection();
     
-    int getMinSelectionIndex();
-    int getMaxSelectionIndex();
-    boolean isSelectedIndex(int a);
+  int getMinSelectionIndex();
+  int getMaxSelectionIndex();
 
-    void setSelectionInterval(int index0, int index1);
+  boolean isSelectedIndex(int a);
 
-    
+  boolean isSelectionEmpty();
+  void setSelectionInterval(int index0, int index1);
+  void addSelectionInterval(int index0,
+                            int index1);
+  void removeSelectionInterval(int index0,
+                               int index1);
+  void insertIndexInterval(int index,
+                           int length,
+                           boolean before);
+  void removeIndexInterval(int index0,
+                           int index1);
+
+  int getAnchorSelectionIndex();
+  void setAnchorSelectionIndex(int index);
+  int getLeadSelectionIndex();
+  void setLeadSelectionIndex(int index);
+
+  void setValueIsAdjusting(boolean valueIsAdjusting);
+  boolean getValueIsAdjusting();
 
-    void addListSelectionListener(ListSelectionListener listener);
-    void removeListSelectionListener(ListSelectionListener listener);    
+  void addListSelectionListener(ListSelectionListener listener);
+  void removeListSelectionListener(ListSelectionListener listener);    
 
 }
Index: javax/swing/LookAndFeel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/LookAndFeel.java,v
retrieving revision 1.2
diff -u -r1.2 LookAndFeel.java
--- javax/swing/LookAndFeel.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/LookAndFeel.java	6 Sep 2004 16:35:59 -0000
@@ -1,5 +1,5 @@
-/* LookAndFeel.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* LookAndFeel.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,93 +35,162 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Component;
+import java.awt.Toolkit;
 import javax.swing.text.JTextComponent;
 
+
 public abstract class LookAndFeel
 {
-    public UIDefaults getDefaults()
-    {
-	//This method is called once by UIManager.setLookAndFeel to create the look and feel specific defaults table.
-	return null;
-    }
-
-    public abstract  String getDescription();  
-    public abstract  String getID();
-    public abstract  String getName();
-
-    public void initialize()
-    {
-	//UIManager.setLookAndFeel calls this method before the first call (and typically the only call) to getDefaults(). 
-    }
-
-    static void installBorder(JComponent c, String defaultBorderName)
-    {
-	//Convenience method for installing a component's default Border object on the specified component if either the border is currently null or already an instance of UIResource. 
-    }
-
-    public static void installColors(JComponent c, String defaultBgName, String defaultFgName)
-    {
-	//Convenience method for initializing a component's foreground and background color properties with values from the current defaults table. 
-    }
-
-    public static void installColorsAndFont(JComponent c, String defaultBgName, String defaultFgName, String defaultFontName)
-    {
-	//Convenience method for initializing a components foreground background and font properties with values from the current defaults table. 
-    }
-  
-    public abstract  boolean isNativeLookAndFeel();
-    public abstract  boolean isSupportedLookAndFeel();
-
-    public static void loadKeyBindings(InputMap retMap, Object[] keys)
-    {
-	//Loads the bindings in keys into retMap. 
-    }
-
-    public static ComponentInputMap makeComponentInputMap(JComponent c, Object[] keys)
-    {
-	//    Creates a ComponentInputMap from keys. 
-	return null;
-    }  
-
-    public static Object makeIcon(Class baseClass, String gifFile)
-    {
-	//Utility method that creates a UIDefaults.LazyValue that creates an ImageIcon UIResource for the specified gifFile filename. 
-	return null;
-    }
-  
-    public static InputMap makeInputMap(Object[] keys)
-    {
-	//Creates a InputMap from keys. 
-	return null;
-    }
-
-    public static JTextComponent.KeyBinding[] makeKeyBindings(Object[] keyBindingList)
-    {
-	//        Convenience method for building lists of KeyBindings.  
-	return null;
-    }
-
+  /**
+   * This method is called once by UIManager.setLookAndFeel to create
+   * the look and feel specific defaults table.
+   *
+   * @return the UI defaults
+   */
+  public UIDefaults getDefaults()
+  {
+    return null;
+  }
+
+  public abstract String getDescription();
+
+  public abstract String getID();
+
+  public abstract String getName();
+
+  /**
+   * Returns true when the Look and Feel supports window decorations,
+   * false others. This method returns always false and needs to be overwritten
+   * when the derived Look and Feel supports this.
+   *
+   * @return false
+   *
+   * @since 1.4
+   */
+  public boolean getSupportsWindowDecorations()
+  {
+    return false;
+  }
   
-    public String toString()
-    {
-	//Returns a string that displays and identifies this object's properties. 
-	return "LookAndFeel";
-    }
-  
-    public void uninitialize()
-    {
-	//UIManager.setLookAndFeel calls this method just before we're replaced by a new default look and feel. 
-    }
-
-  
-    public static void uninstallBorder(JComponent c)
-    {
-	//Convenience method for un-installing a component's default border on the specified component if the border is currently an instance of UIResource.
-    }
-
+  /**
+   * UIManager.setLookAndFeel calls this method before the first call
+   * (and typically the only call) to getDefaults(). 
+   */
+  public void initialize()
+  {
+  }
+
+  /**
+   * Convenience method for installing a component's default Border object
+   * on the specified component if either the border is currently null
+   * or already an instance of UIResource. 
+   */
+  public static void installBorder(JComponent c, String defaultBorderName)
+  {
+  }
+
+  /**
+   * Convenience method for initializing a component's foreground and
+   * background color properties with values from the current defaults table.
+   */
+  public static void installColors(JComponent c, String defaultBgName, String defaultFgName)
+  {
+  }
+
+  /**
+   * Convenience method for initializing a components foreground background
+   * and font properties with values from the current defaults table. 
+   */
+  public static void installColorsAndFont(JComponent component,
+					  String defaultBgName,
+					  String defaultFgName,
+					  String defaultFontName)
+  {
+  }
+
+  public abstract boolean isNativeLookAndFeel();
+
+  public abstract boolean isSupportedLookAndFeel();
+
+  /**
+   * Loads the bindings in keys into retMap. 
+   */
+  public static void loadKeyBindings(InputMap retMap, Object[] keys)
+  {
+  }
+
+  /**
+   * Creates a ComponentInputMap from keys. 
+   */
+  public static ComponentInputMap makeComponentInputMap(JComponent c,
+							Object[] keys)
+  {
+    return null;
+  }
+
+  /**
+   * Utility method that creates a UIDefaults.LazyValue that creates an
+   * ImageIcon UIResource for the specified gifFile filename. 
+   */
+  public static Object makeIcon(Class baseClass, String gifFile)
+  {
+    return null;
+  }
+
+  /**
+   * Creates a InputMap from keys. 
+   */
+  public static InputMap makeInputMap(Object[] keys)
+  {
+    return null;
+  }
+
+  /**
+   * Convenience method for building lists of KeyBindings.  
+   */
+  public static JTextComponent.KeyBinding[] makeKeyBindings(Object[] keyBindingList)
+  {
+    return null;
+  }
+
+  /**
+   * Invoked when the user attempts an invalid operation. The default implement
+   * just beeps. Subclasses that wish to change this need to override this
+   * method.
+   *
+   * @param component the component the error occured in
+   */
+  public void provideErrorFeedback(Component component)
+  {
+    Toolkit.getDefaultToolkit().beep();
+  }
+
+  /**
+   * Returns a string that displays and identifies this object's properties.
+   *
+   * @return the string "LookAndFeel"
+   */
+  public String toString()
+  {
+    return "LookAndFeel";
+  }
+
+  /**
+   * UIManager.setLookAndFeel calls this method just before we're replaced by
+   * a new default look and feel. 
+   */
+  public void uninitialize()
+  {
+  }
+
+  /**
+   * Convenience method for un-installing a component's default border on the
+   * specified component if the border is currently an instance of UIResource.
+   */
+  public static void uninstallBorder(JComponent c)
+  {
+  }
 }
-
Index: javax/swing/MenuSelectionManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/MenuSelectionManager.java,v
retrieving revision 1.2
diff -u -r1.2 MenuSelectionManager.java
--- javax/swing/MenuSelectionManager.java	19 Jun 2003 16:30:09 -0000	1.2
+++ javax/swing/MenuSelectionManager.java	6 Sep 2004 16:36:00 -0000
@@ -1,5 +1,5 @@
-/* MenuSelectionManager.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* MenuSelectionManager.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,42 +35,349 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Vector;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.event.EventListenerList;
 
+
+/**
+ * This class manages current menu selectection. It provides
+ * methods to clear and set current selected menu path.
+ * It also fires StateChange event to its registered
+ * listeners whenever selected path of the current menu hierarchy
+ * changes.
+ *
+ */
 public class MenuSelectionManager
 {
-  protected ChangeEvent changeEvent;
-  
-  protected EventListenerList listenerList = new EventListenerList ();
+  /** ChangeEvent fired when selected path changes*/
+  protected ChangeEvent changeEvent = new ChangeEvent(this);
+
+  /** List of listeners for this MenuSelectionManager */
+  protected EventListenerList listenerList = new EventListenerList();
 
-  protected void fireStateChanged ()
+  /** Default manager for the current menu hierarchy*/
+  private static final MenuSelectionManager manager = new MenuSelectionManager();
+
+  /** Path to the currently selected menu */
+  private Vector selectedPath = new Vector();
+
+  /**
+   * Fires StateChange event to registered listeners
+   */
+  protected void fireStateChanged()
   {
-    ChangeListener[] listeners = getChangeListeners ();
+    ChangeListener[] listeners = getChangeListeners();
 
     for (int i = 0; i < listeners.length; i++)
+      listeners[i].stateChanged(changeEvent);
+  }
+
+  /**
+   * Adds ChangeListener to this MenuSelectionManager
+   *
+   * @param listener ChangeListener to add
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Removes ChangeListener from the list of registered listeners
+   * for this MenuSelectionManager.
+   *
+   * @param listener ChangeListner to remove
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * Returns list of registered listeners with MenuSelectionManager
+   *
+   * @since 1.4
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Unselects all the menu elements on the selection path
+   */
+  public void clearSelectedPath()
+  {
+    // Send events from the bottom most item in the menu - hierarchy to the
+    // top most
+    for (int i = selectedPath.size() - 1; i >= 0; i--)
+      ((MenuElement) selectedPath.get(i)).menuSelectionChanged(false);
+
+    // clear selected path
+    selectedPath.clear();
+
+    // notify all listeners that the selected path was changed    
+    fireStateChanged();
+  }
+
+  /**
+   * This method returns menu element on the selected path that contains
+   * given source point. If no menu element on the selected path contains this
+   * point, then null is returned.
+   *
+   * @param source Component relative to which sourcePoint is given
+   * @param sourcePoint point for which we want to find menu element that contains it
+   *
+   * @return Returns menu element that contains given source point and belongs
+   * to the currently selected path. Null is return if no such menu element found.
+   */
+  public Component componentForPoint(Component source, Point sourcePoint)
+  {
+    // Convert sourcePoint to screen coordinates.
+    Point sourcePointOnScreen = sourcePoint;
+    SwingUtilities.convertPointToScreen(sourcePointOnScreen, source);
+
+    Point compPointOnScreen;
+    Component resultComp = null;
+
+    // For each menu element on the selected path, express its location 
+    // in terms of screen coordinates and check if there is any 
+    // menu element on the selected path that contains given source point.
+    for (int i = 0; i < selectedPath.size(); i++)
       {
-        listeners [i].stateChanged (new ChangeEvent (this));
+	Component comp = ((Component) selectedPath.get(i));
+        Dimension size = comp.getSize();
+
+	// convert location of this menu item to screen coordinates
+	compPointOnScreen = comp.getLocationOnScreen();
+
+	if (compPointOnScreen.x <= sourcePointOnScreen.x
+	    && sourcePointOnScreen.x < compPointOnScreen.x + size.width
+	    && compPointOnScreen.y <= sourcePointOnScreen.y
+	    && sourcePointOnScreen.y < compPointOnScreen.y + size.height)
+	  {
+	    Point p = sourcePointOnScreen;
+	    SwingUtilities.convertPointFromScreen(p, comp);
+	    resultComp = SwingUtilities.getDeepestComponentAt(comp, p.x, p.y);
+	    break;
+	  }
       }
+    return resultComp;
   }
 
-  public void addChangeListener (ChangeListener listener)
+  /**
+   * Returns shared instance of MenuSelection Manager
+   *
+   * @return default Manager
+   */
+  public static MenuSelectionManager defaultManager()
   {
-    listenerList.add (ChangeListener.class, listener);
+    return manager;
   }
 
-  public void removeChangeListener (ChangeListener listener)
+  /**
+   * Returns path representing current menu selection
+   *
+   * @return Current selection path
+   */
+  public MenuElement[] getSelectedPath()
   {
-    listenerList.remove (ChangeListener.class, listener);
+    MenuElement[] path = new MenuElement[selectedPath.size()];
+
+    for (int i = 0; i < path.length; i++)
+      path[i] = (MenuElement) selectedPath.get(i);
+
+    return path;
   }
 
-  /** @since 1.4 */
-  public ChangeListener[] getChangeListeners ()
+  /**
+   * Returns true if specified component is part of current menu
+   * heirarchy and false otherwise
+   *
+   * @param c Component for which to check
+   * @return True if specified component is part of current menu
+   */
+  public boolean isComponentPartOfCurrentMenu(Component c)
   {
-    return (ChangeListener[]) listenerList.getListeners (ChangeListener.class);
+    MenuElement[] subElements;
+    for (int i = 0; i < selectedPath.size(); i++)
+      {
+	subElements = ((MenuElement) selectedPath.get(i)).getSubElements();
+	for (int j = 0; j < subElements.length; j++)
+	  {
+	    if ((subElements[j].getComponent()).equals(c))
+	      return true;
+	  }
+      }
+
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   */
+  public void processKeyEvent(KeyEvent e)
+  {
+    throw new UnsupportedOperationException("not implemented");
+  }
+
+  /**
+   * Forwards given mouse event to all of the source subcomponents.
+   *
+   * @param event Mouse event
+   */
+  public void processMouseEvent(MouseEvent event)
+  {
+    Component source = ((Component) event.getSource());
+
+    // In the case of drag event, event.getSource() returns component
+    // where drag event originated. However menu element processing this 
+    // event should be the one over which mouse is currently located, 
+    // which is not necessary the source of the drag event.     
+    Component mouseOverMenuComp;
+
+    // find over which menu element the mouse is currently located
+    if (event.getID() == MouseEvent.MOUSE_DRAGGED
+        || event.getID() == MouseEvent.MOUSE_RELEASED)
+      mouseOverMenuComp = componentForPoint(source, event.getPoint());
+    else
+      mouseOverMenuComp = source;
+
+    // Process this event only if mouse is located over some menu element
+    if (mouseOverMenuComp != null && (mouseOverMenuComp instanceof MenuElement))
+      {
+	MenuElement[] path = getPath(mouseOverMenuComp);
+	((MenuElement) mouseOverMenuComp).processMouseEvent(event, path,
+	                                                    manager);
+
+	// FIXME: Java specification says that mouse events should be
+	// forwarded to subcomponents. The code below does it, but
+	// menu's work fine without it. This code is commented for now.	  
+
+	/*
+	MenuElement[] subComponents = ((MenuElement) mouseOverMenuComp)
+	                              .getSubElements();
+
+    for (int i = 0; i < subComponents.length; i++)
+      {
+	  subComponents[i].processMouseEvent(event, path, manager);
+      }
+	*/
+      }
+  }
+
+  /**
+   * Sets menu selection to the specified path
+   *
+   * @param path new selection path
+   */
+  public void setSelectedPath(MenuElement[] path)
+  {
+    if (path == null)
+      {
+	clearSelectedPath();
+	return;
+      }
+
+    int i;
+    int minSize = path.length; // size of the smaller path. 
+
+    if (path.length > selectedPath.size())
+      {
+	minSize = selectedPath.size();
+
+	// if new selected path contains more elements then current
+	// selection then first add all elements at 
+	// the indexes > selectedPath.size 
+	for (i = selectedPath.size(); i < path.length; i++)
+	  {
+	    selectedPath.add(path[i]);
+	    path[i].menuSelectionChanged(true);
+	  }
+      }
+
+    else if (path.length < selectedPath.size())
+      {
+	// if new selected path contains less elements then current 
+	// selection then first remove all elements from the selection
+	// at the indexes > path.length
+	for (i = selectedPath.size() - 1; i >= path.length; i--)
+	  {
+	    ((MenuElement) selectedPath.get(i)).menuSelectionChanged(false);
+	    selectedPath.remove(i);
+	  }
+
+	minSize = path.length;
+      }
+
+    // Now compare elements in new and current selection path at the 
+    // same location and adjust selection until 
+    // same menu elements will be encountered at the
+    // same index in both current and new selection path.
+    MenuElement oldSelectedItem;
+
+    for (i = minSize - 1; i >= 0; i--)
+      {
+	oldSelectedItem = (MenuElement) selectedPath.get(i);
+
+	if (path[i].equals(oldSelectedItem))
+	  break;
+
+	oldSelectedItem.menuSelectionChanged(false);
+	path[i].menuSelectionChanged(true);
+	selectedPath.setElementAt(path[i], i);
+      }
+
+    fireStateChanged();
+  }
+
+  /**
+   * Returns path to the specified component
+   *
+   * @param c component for which to find path for
+   *
+   * @return path to the specified component
+   */
+  private MenuElement[] getPath(Component c)
+  {
+    // FIXME: There is the same method in BasicMenuItemUI. However I
+    // cannot use it here instead of this method, since I cannot assume that 
+    // all the menu elements on the selected path are JMenuItem or JMenu.
+    // For now I've just duplicated it here. Please 
+    // fix me or delete me if another better approach will be found, and 
+    // this method will not be necessary.
+    ArrayList path = new ArrayList();
+
+    // if given component is JMenu, we also need to include 
+    // it's popup menu in the path 
+    if (c instanceof JMenu)
+      path.add(((JMenu) c).getPopupMenu());
+    while (c instanceof MenuElement)
+      {
+	path.add(0, (MenuElement) c);
+
+	if (c instanceof JPopupMenu)
+	  c = ((JPopupMenu) c).getInvoker();
+	else
+	  c = c.getParent();
+      }
+
+    MenuElement[] pathArray = new MenuElement[path.size()];
+    path.toArray(pathArray);
+    return pathArray;
   }
-} // class MenuSelectionManager
+}
Index: javax/swing/MutableComboBoxModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/MutableComboBoxModel.java,v
retrieving revision 1.2
diff -u -r1.2 MutableComboBoxModel.java
--- javax/swing/MutableComboBoxModel.java	12 Oct 2003 13:20:49 -0000	1.2
+++ javax/swing/MutableComboBoxModel.java	6 Sep 2004 16:36:00 -0000
@@ -38,40 +38,46 @@
 package javax.swing;
 
 /**
- * MutableComboBoxModel
- * @author	Andrew Selkirk
- * @version	1.0
+ * MutableComboBoxModel is interface for data model that keeps track of the
+ * components data and provides methods to insert and remove elements from
+ * it. The Classes implementing this interface should  fire appropriate
+ * events indicating the undergoing change in the data model.
+ *
+ * @author Andrew Selkirk
+ * @author Olga Rodimina
+ * @version 1.0
  */
-public interface MutableComboBoxModel extends ComboBoxModel {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * addElement
-	 * @param object TODO
-	 */
-	void addElement(Object object);
-
-	/**
-	 * removeElementAt
-	 * @param index TODO
-	 */
-	void removeElementAt(int index);
-
-	/**
-	 * insertElementAt
-	 * @param object TODO
-	 * @param index TODO
-	 */
-	void insertElementAt(Object object, int index);
-
-	/**
-	 * removeElement
-	 * @param object TODO
-	 */
-	void removeElement(Object object);
-
-
+public interface MutableComboBoxModel extends ComboBoxModel
+{
+  /**
+   * This method adds given object to its data model.
+   *
+   * @param object element to add to the data model.
+   */
+  void addElement(Object object);
+
+  /**
+   * This method removes elements located at the given index in the data
+   * model.
+   *
+   * @param index index specifying location of the element to remove.
+   */
+  void removeElementAt(int index);
+
+  /**
+   * This method inserts givent element to the data model, at the specified
+   * index.
+   *
+   * @param object element to insert
+   * @param index index specifying the position in the data model where the
+   *        given element should be inserted.
+   */
+  void insertElementAt(Object object, int index);
+
+  /**
+   * This method removes given element from the data model
+   *
+   * @param element to remove.
+   */
+  void removeElement(Object object);
 } // MutableComboBoxModel
Index: javax/swing/Popup.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/Popup.java,v
retrieving revision 1.1
diff -u -r1.1 Popup.java
--- javax/swing/Popup.java	27 Jun 2003 12:41:52 -0000	1.1
+++ javax/swing/Popup.java	6 Sep 2004 16:36:00 -0000
@@ -163,7 +163,7 @@
 
 
     /**
-     * Displays the popup&#x2019;s <code>JWindow</code> on the screen.
+     * Displays the popup's <code>JWindow</code> on the screen.
      * Nothing happens if it is already visible.
      */
     public void show()
@@ -173,7 +173,7 @@
     
     
     /**
-     * Removes the popup&#x2019;s <code>JWindow</code> from the
+     * Removes the popup's <code>JWindow</code> from the
      * screen.  Nothing happens if it is currently not visible.
      */
     public void hide()
Index: javax/swing/RepaintManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/RepaintManager.java,v
retrieving revision 1.2
diff -u -r1.2 RepaintManager.java
--- javax/swing/RepaintManager.java	11 Jun 2003 13:20:39 -0000	1.2
+++ javax/swing/RepaintManager.java	6 Sep 2004 16:36:00 -0000
@@ -35,248 +35,505 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Image;
 import java.awt.Rectangle;
+import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Vector;
 
+
 /**
- * RepaintManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * <p>The repaint manager holds a set of dirty regions, invalid components,
+ * and a double buffer surface.  The dirty regions and invalid components
+ * are used to coalesce multiple revalidate() and repaint() calls in the
+ * component tree into larger groups to be refreshed "all at once"; the
+ * double buffer surface is used by root components to paint
+ * themselves.</p>
+ *
+ * <p>In general, painting is very confusing in swing. see <a
+ * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
+ * document</a> for more details.</p>
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
  */
-public class RepaintManager {
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * dirtyComponents
-	 */
-	Hashtable dirtyComponents;
-
-	/**
-	 * tmpDirtyComponents
-	 */
-	Hashtable tmpDirtyComponents;
-
-	/**
-	 * invalidComponents
-	 */
-	Vector invalidComponents;
-
-	/**
-	 * doubleBufferingEnabled
-	 */
-	boolean doubleBufferingEnabled;
-
-	/**
-	 * doubleBuffer
-	 */
-	Image doubleBuffer;
-
-	/**
-	 * doubleBufferSize
-	 */
-	Dimension doubleBufferSize;
-
-	/**
-	 * doubleBufferMaxSize
-	 */
-	private Dimension doubleBufferMaxSize;
-
-	/**
-	 * resetDoubleBuffer
-	 */
-	private boolean resetDoubleBuffer;
-
-	/**
-	 * repaintManagerKey
-	 */
-	private static final Object repaintManagerKey = null; // TODO
-
-	/**
-	 * tmp
-	 */
-	Rectangle tmp;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor RepaintManager
-	 */
-	public RepaintManager() {
-		// TODO
-	} // RepaintManager()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * toString
-	 * @returns String
-	 */
-	public synchronized String toString() {
-		return null; // TODO
-	} // toString()
-
-	/**
-	 * currentManager
-	 * @param component TODO
-	 * @returns RepaintManager
-	 */
-	public static RepaintManager currentManager(Component component) {
-		return null; // TODO
-	} // currentManager()
-
-	/**
-	 * currentManager
-	 * @param component TODO
-	 * @returns RepaintManager
-	 */
-	public static RepaintManager currentManager(JComponent component) {
-		return null; // TODO
-	} // currentManager()
-
-	/**
-	 * setCurrentManager
-	 * @param manager TODO
-	 */
-	public static void setCurrentManager(RepaintManager manager) {
-		// TODO
-	} // setCurrentManager()
-
-	/**
-	 * addInvalidComponent
-	 * @param component TODO
-	 */
-	public synchronized void addInvalidComponent(JComponent component) {
-		// TODO
-	} // addInvalidComponent()
-
-	/**
-	 * removeInvalidComponent
-	 * @param component TODO
-	 */
-	public synchronized void removeInvalidComponent(JComponent component) {
-		// TODO
-	} // removeInvalidComponent()
-
-	/**
-	 * addDirtyRegion
-	 * @param component TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param w TODO
-	 * @param h TODO
-	 */
-	public synchronized void addDirtyRegion(JComponent component, int x,
-			int y, int w, int h) {
-		// TODO
-	} // addDirtyRegion()
-
-	/**
-	 * getDirtyRegion
-	 * @param component TODO
-	 * @returns Rectangle
-	 */
-	public Rectangle getDirtyRegion(JComponent component) {
-		return null; // TODO
-	} // getDirtyRegion()
-
-	/**
-	 * markCompletelyDirty
-	 * @param component TODO
-	 */
-	public void markCompletelyDirty(JComponent component) {
-		// TODO
-	} // markCompletelyDirty()
-
-	/**
-	 * markCompletelyClean
-	 * @param component TODO
-	 */
-	public void markCompletelyClean(JComponent component) {
-		// TODO
-	} // markCompletelyClean()
-
-	/**
-	 * isCompletelyDirty
-	 * @param component TODO
-	 * @returns boolean
-	 */
-	public boolean isCompletelyDirty(JComponent component) {
-		return false; // TODO
-	} // isCompletelyDirty()
-
-	/**
-	 * validateInvalidComponents
-	 */
-	public void validateInvalidComponents() {
-		// TODO
-	} // validateInvalidComponents()
-
-	/**
-	 * paintDirtyRegions
-	 */
-	public void paintDirtyRegions() {
-		// TODO
-	} // paintDirtyRegions()
-
-	/**
-	 * getOffscreenBuffer
-	 * @param component TODO
-	 * @param proposedWidth TODO
-	 * @param proposedHeight TODO
-	 * @returns Image
-	 */
-	public Image getOffscreenBuffer(Component component,
-			int proposedWidth, int proposedHeight) {
-		return null; // TODO
-	} // getOffscreenBuffer()
-
-	/**
-	 * getDoubleBufferMaximumSize
-	 * @returns Dimension
-	 */
-	public Dimension getDoubleBufferMaximumSize() {
-		return null; // TODO
-	} // getDoubleBufferMaximumSize()
-
-	/**
-	 * setDoubleBufferMaximumSize
-	 * @param size TODO
-	 */
-	public void setDoubleBufferMaximumSize(Dimension size) {
-		// TODO
-	} // setDoubleBufferMaximumSize()
-
-	/**
-	 * setDoubleBufferingEnabled
-	 * @param buffer TODO
-	 */
-	public void setDoubleBufferingEnabled(boolean buffer) {
-		// TODO
-	} // setDoubleBufferingEnabled()
-
-	/**
-	 * isDoubleBufferingEnabled
-	 * @returns boolean
-	 */
-	public boolean isDoubleBufferingEnabled() {
-		return false; // TODO
-	} // isDoubleBufferingEnabled()
-
+public class RepaintManager
+{
 
-} // RepaintManager
+  /**
+   * <p>A helper class which is placed into the system event queue at
+   * various times in order to facilitate repainting and layout. There is
+   * typically only one of these objects active at any time. When the
+   * {@link RepaintManager} is told to queue a repaint, it checks to see if
+   * a {@link RepaintWorker} is "live" in the system event queue, and if
+   * not it inserts one using {@link SwingUtilities.invokeLater}.</p>
+   *
+   * <p>When the {@link RepaintWorker} comes to the head of the system
+   * event queue, its {@link RepaintWorker#run} method is executed by the
+   * swing paint thread, which revalidates all invalid components and
+   * repaints any damage in the swing scene.</p>
+   */
+
+  protected class RepaintWorker
+    implements Runnable
+  {
+    boolean live;
+    public RepaintWorker()
+    {
+      live = false;
+    }
+    public synchronized void setLive(boolean b) 
+    {
+      live = b;
+    }
+    public synchronized boolean isLive()
+    {
+      return live;
+    }
+    public void run()
+    {
+      RepaintManager rm = RepaintManager.globalManager;
+      setLive(false);
+      rm.validateInvalidComponents();
+      rm.paintDirtyRegions();
+    }
+  }
+
+  
+  /** 
+   * A table storing the dirty regions of components.  The keys of this
+   * table are components, the values are rectangles. Each component maps
+   * to exactly one rectangle.  When more regions are marked as dirty on a
+   * component, they are union'ed with the existing rectangle.
+   *
+   * @see #addDirtyRegion
+   * @see #getDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyClean
+   * @see #markCompletelyDirty
+   */
+  Hashtable dirtyComponents;
+
+  /**
+   * A single, shared instance of the helper class. Any methods which mark
+   * components as invalid or dirty eventually activate this instance. It
+   * is added to the event queue if it is not already active, otherwise
+   * reused.
+   *
+   * @see #addDirtyRegion
+   * @see #addInvalidComponent
+   */
+  RepaintWorker repaintWorker;
+
+  /** 
+   * The set of components which need revalidation, in the "layout" sense.
+   * There is no additional information about "what kind of layout" they
+   * need (as there is with dirty regions), so it is just a vector rather
+   * than a table.
+   *
+   * @see #addInvalidComponent
+   * @see #removeInvalidComponent
+   * @see #validateInvalidComponents
+   */
+  Vector invalidComponents;
+
+  /** 
+   * Whether or not double buffering is enabled on this repaint
+   * manager. This is merely a hint to clients; the RepaintManager will
+   * always return an offscreen buffer when one is requested.
+   * 
+   * @see #getDoubleBufferingEnabled
+   * @see #setDoubleBufferingEnabled
+   */
+  boolean doubleBufferingEnabled;
+
+  /** 
+   * The current offscreen buffer. This is reused for all requests for
+   * offscreen drawing buffers. It grows as necessary, up to {@link
+   * #doubleBufferMaximumSize}, but there is only one shared instance.
+   *
+   * @see #getOffscreenBuffer
+   * @see #doubleBufferMaximumSize
+   */
+  Image doubleBuffer;
+
+  /**
+   * The maximum width and height to allocate as a double buffer. Requests
+   * beyond this size are ignored.
+   *
+   * @see #paintDirtyRegions
+   * @see #getDoubleBufferMaximumSize
+   * @see #setDoubleBufferMaximumSize
+   */
+  Dimension doubleBufferMaximumSize;
+
+
+  /**
+   * The global, shared RepaintManager instance. This is reused for all
+   * components in all windows.
+   *
+   * @see #currentManager
+   * @see #setCurrentManager
+   */
+  private static RepaintManager globalManager;
+
+  /**
+   * Create a new RepaintManager object.
+   */
+  public RepaintManager()
+  {
+    dirtyComponents = new Hashtable();
+    invalidComponents = new Vector();
+    repaintWorker = new RepaintWorker();
+    doubleBufferMaximumSize = new Dimension(2000,2000);
+    doubleBufferingEnabled = true;
+  }
+
+  /**
+   * Get the value of the shared {@link #globalManager} instance, possibly
+   * returning a special manager associated with the specified
+   * component. The default implementaiton ignores the component parameter.
+   *
+   * @param component A component to look up the manager of
+   *
+   * @return The current repaint manager
+   *
+   * @see #setCurrentManager
+   */
+  public static RepaintManager currentManager(Component component)
+  {
+    if (globalManager == null)
+      globalManager = new RepaintManager();
+    return globalManager;
+  }
+
+  /**
+   * Get the value of the shared {@link #globalManager} instance, possibly
+   * returning a special manager associated with the specified
+   * component. The default implementaiton ignores the component parameter.
+   *
+   * @param component A component to look up the manager of
+   *
+   * @return The current repaint manager
+   *
+   * @see #setCurrentManager
+   */
+  public static RepaintManager currentManager(JComponent component)
+  {
+    return currentManager((Component)component);
+  }
+
+  /**
+   * Set the value of the shared {@link #globalManager} instance.
+   *
+   * @param manager The new value of the shared instance
+   *
+   * @see #currentManager
+   */
+  public static void setCurrentManager(RepaintManager manager)
+  {
+    globalManager = manager;
+  }
+
+  /**
+   * Add a component to the {@link #invalidComponents} vector. If the
+   * {@link #repaintWorker} class is not active, insert it in the system
+   * event queue.
+   *
+   * @param component The component to add
+   *
+   * @see #removeInvalidComponent
+   */
+  public synchronized void addInvalidComponent(JComponent component)
+  {
+    Component ancestor = component.getParent();
+
+    while (ancestor != null
+           && (! (ancestor instanceof JComponent)
+               || ! ((JComponent) ancestor).isValidateRoot() ))
+      ancestor = ancestor.getParent();
+
+    if (ancestor != null
+        && ancestor instanceof JComponent
+        && ((JComponent) ancestor).isValidateRoot())
+      component = (JComponent) ancestor;
+    
+    if (invalidComponents.contains(component))
+      return;
+
+    invalidComponents.add(component);
+    
+    if (! repaintWorker.isLive())
+      {
+        repaintWorker.setLive(true);
+        SwingUtilities.invokeLater(repaintWorker);
+      }
+  }
+
+  /**
+   * Remove a component from the {@link #invalidComponents} vector.
+   *
+   * @param component The component to remove
+   *
+   * @see #addInvalidComponent
+   */
+  public synchronized void removeInvalidComponent(JComponent component)
+  {
+    invalidComponents.removeElement(component);
+  }
+
+  /**
+   * Add a region to the set of dirty regions for a specified component.
+   * This involves union'ing the new region with any existing dirty region
+   * associated with the component. If the {@link #repaintWorker} class
+   * is not active, insert it in the system event queue.
+   *
+   * @param component The component to add a dirty region for
+   * @param x The left x coordinate of the new dirty region
+   * @param y The top y coordinate of the new dirty region
+   * @param w The width of the new dirty region
+   * @param h The height of the new dirty region
+   *
+   * @see #addDirtyRegion
+   * @see #getDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyClean
+   * @see #markCompletelyDirty
+   */
+  public synchronized void addDirtyRegion(JComponent component, int x, int y,
+                                          int w, int h)
+  {
+    Rectangle r = new Rectangle(x, y, w, h);
+    if (dirtyComponents.containsKey(component))
+      r = r.union((Rectangle)dirtyComponents.get(component));
+    dirtyComponents.put(component, r);
+    if (! repaintWorker.isLive())
+      {
+        repaintWorker.setLive(true);
+        SwingUtilities.invokeLater(repaintWorker);
+      }
+  }
+  
+  /**
+   * Get the dirty region associated with a component, or <code>null</code>
+   * if the component has no dirty region.
+   *
+   * @param component The component to get the dirty region of
+   *
+   * @return The dirty region of the component
+   *
+   * @see #dirtyComponents
+   * @see #addDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyClean
+   * @see #markCompletelyDirty
+   */
+  public Rectangle getDirtyRegion(JComponent component)
+  {
+    return (Rectangle) dirtyComponents.get(component);
+  }
+  
+  /**
+   * Mark a component as dirty over its entire bounds.
+   *
+   * @param component The component to mark as dirty
+   *
+   * @see #dirtyComponents
+   * @see #addDirtyRegion
+   * @see #getDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyClean
+   */
+  public void markCompletelyDirty(JComponent component)
+  {
+    Rectangle r = component.getBounds();
+    addDirtyRegion(component, r.x, r.y, r.width, r.height);
+  }
+
+  /**
+   * Remove all dirty regions for a specified component
+   *
+   * @param component The component to mark as clean
+   *
+   * @see #dirtyComponents
+   * @see #addDirtyRegion
+   * @see #getDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyDirty
+   */
+  public void markCompletelyClean(JComponent component)
+  {
+    dirtyComponents.remove(component);
+  }
+
+  /**
+   * Return <code>true</code> if the specified component is completely
+   * contained within its dirty region, otherwise <code>false</code>
+   *
+   * @param component The component to check for complete dirtyness
+   *
+   * @return Whether the component is completely dirty
+   *
+   * @see #dirtyComponents
+   * @see #addDirtyRegion
+   * @see #getDirtyRegion
+   * @see #isCompletelyDirty
+   * @see #markCompletelyClean
+   */
+  public boolean isCompletelyDirty(JComponent component)
+  {
+    Rectangle dirty = (Rectangle) dirtyComponents.get(component);
+    if (dirty == null)
+      return false;
+    Rectangle r = component.getBounds();
+    if (r == null)
+      return true;
+    return dirty.contains(r);
+  }
+
+  /**
+   * Validate all components which have been marked invalid in the {@link
+   * #invalidComponents} vector.
+   */
+  public void validateInvalidComponents()
+  {
+    for (Enumeration e = invalidComponents.elements(); e.hasMoreElements(); )
+      {
+        JComponent comp = (JComponent) e.nextElement();
+        if (! (comp.isVisible() && comp.isShowing()))
+          continue;
+        comp.validate();
+      }
+    invalidComponents.clear();
+  }
+
+  /**
+   * Repaint all regions of all components which have been marked dirty in
+   * the {@link #dirtyComponents} table.
+   */
+  public void paintDirtyRegions()
+  {
+    // step 1: pull out roots and calculate spanning damage
+
+    HashMap roots = new HashMap();
+    for (Enumeration e = dirtyComponents.keys(); e.hasMoreElements(); )
+      {
+        JComponent comp = (JComponent) e.nextElement();
+        if (! (comp.isVisible() && comp.isShowing()))
+          continue;
+        Rectangle damaged = getDirtyRegion(comp);
+        if (damaged.width == 0 || damaged.height == 0)
+          continue;
+        JRootPane root = comp.getRootPane();
+        // If the component has no root, no repainting will occur.
+        if (root == null)
+          continue;
+        Rectangle rootDamage = SwingUtilities.convertRectangle(comp, damaged, root);
+        if (! roots.containsKey(root))
+          {
+            roots.put(root, rootDamage);
+          }
+        else
+          {
+            roots.put(root, ((Rectangle)roots.get(root)).union(rootDamage));
+          }
+      }
+    dirtyComponents.clear();
+
+    // step 2: paint those roots
+    Iterator i = roots.entrySet().iterator();
+    while(i.hasNext())
+      {
+        Map.Entry ent = (Map.Entry) i.next();
+        JRootPane root = (JRootPane) ent.getKey();
+        Rectangle rect = (Rectangle) ent.getValue();
+        root.paintImmediately(rect);                	
+      }
+  }
+
+  /**
+   * Get an offscreen buffer for painting a component's image. This image
+   * may be smaller than the proposed dimensions, depending on the value of
+   * the {@link #doubleBufferMaximumSize} property.
+   *
+   * @param component The component to return an offscreen buffer for
+   * @param proposedWidth The proposed width of the offscreen buffer
+   * @param proposedHeight The proposed height of the offscreen buffer
+   *
+   * @return A shared offscreen buffer for painting
+   *
+   * @see #doubleBuffer
+   */
+  public Image getOffscreenBuffer(Component component, int proposedWidth,
+                                  int proposedHeight)
+  {
+    if (doubleBuffer == null 
+        || (((doubleBuffer.getWidth(null) < proposedWidth) 
+             || (doubleBuffer.getHeight(null) < proposedHeight))
+            && (proposedWidth < doubleBufferMaximumSize.width)
+            && (proposedHeight < doubleBufferMaximumSize.height)))
+      {
+        doubleBuffer = component.createImage(proposedWidth, proposedHeight);
+      }
+    return doubleBuffer;
+  }
+
+  /**
+   * Get the value of the {@link #doubleBufferMaximumSize} property.
+   *
+   * @return The current value of the property
+   *
+   * @see #setDoubleBufferMaximumSize
+   */
+  public Dimension getDoubleBufferMaximumSize()
+  {
+    return doubleBufferMaximumSize;
+  }
+
+  /**
+   * Set the value of the {@link #doubleBufferMaximumSize} property.
+   *
+   * @param size The new value of the property
+   *
+   * @see #getDoubleBufferMaximumSize
+   */
+  public void setDoubleBufferMaximumSize(Dimension size)
+  {
+    doubleBufferMaximumSize = size;
+  }
+
+  /**
+   * Set the value of the {@link #doubleBufferingEnabled} property.
+   *
+   * @param buffer The new value of the property
+   *
+   * @see #getDoubleBufferingEnabled
+   */
+  public void setDoubleBufferingEnabled(boolean buffer)
+  {
+    doubleBufferingEnabled = buffer;
+  }
+
+  /**
+   * Get the value of the {@link #doubleBufferingEnabled} property.
+   *
+   * @return The current value of the property
+   *
+   * @see #setDoubleBufferingEnabled
+   */
+  public boolean isDoubleBufferingEnabled()
+  {
+    return doubleBufferingEnabled;
+  }
+  
+  public String toString()
+  {
+    return "RepaintManager";
+  }
+}
Index: javax/swing/ScrollPaneConstants.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ScrollPaneConstants.java,v
retrieving revision 1.2
diff -u -r1.2 ScrollPaneConstants.java
--- javax/swing/ScrollPaneConstants.java	12 Oct 2003 13:20:49 -0000	1.2
+++ javax/swing/ScrollPaneConstants.java	6 Sep 2004 16:36:00 -0000
@@ -1,5 +1,5 @@
 /* ScrollPaneConstants.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,116 +42,110 @@
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public interface ScrollPaneConstants {
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * VIEWPORT
-	 */
-	String VIEWPORT = "VIEWPORT";
-
-	/**
-	 * VERTICAL_SCROLLBAR
-	 */
-	String VERTICAL_SCROLLBAR = "VERTICAL_SCROLLBAR";
-
-	/**
-	 * HORIZONTAL_SCROLLBAR
-	 */
-	String HORIZONTAL_SCROLLBAR = "HORIZONTAL_SCROLLBAR";
-
-	/**
-	 * ROW_HEADER
-	 */
-	String ROW_HEADER = "ROW_HEADER";
-
-	/**
-	 * COLUMN_HEADER
-	 */
-	String COLUMN_HEADER = "COLUMN_HEADER";
-
-	/**
-	 * LOWER_LEFT_CORNER
-	 */
-	String LOWER_LEFT_CORNER = "LOWER_LEFT_CORNER";
-
-	/**
-	 * LOWER_RIGHT_CORNER
-	 */
-	String LOWER_RIGHT_CORNER = "LOWER_RIGHT_CORNER";
-
-	/**
-	 * UPPER_LEFT_CORNER
-	 */
-	String UPPER_LEFT_CORNER = "UPPER_LEFT_CORNER";
-
-	/**
-	 * UPPER_RIGHT_CORNER
-	 */
-	String UPPER_RIGHT_CORNER = "UPPER_RIGHT_CORNER";
-
-	/**
-	 * LOWER_LEADING_CORNER
-	 */
-	String LOWER_LEADING_CORNER = "LOWER_LEADING_CORNER";
-
-	/**
-	 * LOWER_TRAILING_CORNER
-	 */
-	String LOWER_TRAILING_CORNER = "LOWER_TRAILING_CORNER";
-
-	/**
-	 * UPPER_LEADING_CORNER
-	 */
-	String UPPER_LEADING_CORNER = "UPPER_LEADING_CORNER";
-
-	/**
-	 * UPPER_TRAILING_CORNER
-	 */
-	String UPPER_TRAILING_CORNER = "UPPER_TRAILING_CORNER";
-
-	/**
-	 * VERTICAL_SCROLLBAR_POLICY
-	 */
-	String VERTICAL_SCROLLBAR_POLICY = "VERTICAL_SCROLLBAR_POLICY";
-
-	/**
-	 * HORIZONTAL_SCROLLBAR_POLICY
-	 */
-	String HORIZONTAL_SCROLLBAR_POLICY = "HORIZONTAL_SCROLLBAR_POLICY";
-
-	/**
-	 * VERTICAL_SCROLLBAR_AS_NEEDED
-	 */
-	int VERTICAL_SCROLLBAR_AS_NEEDED = 20;
-
-	/**
-	 * VERTICAL_SCROLLBAR_NEVER
-	 */
-	int VERTICAL_SCROLLBAR_NEVER = 21;
-
-	/**
-	 * VERTICAL_SCROLLBAR_ALWAYS
-	 */
-	int VERTICAL_SCROLLBAR_ALWAYS = 22;
-
-	/**
-	 * HORIZONTAL_SCROLLBAR_AS_NEEDED
-	 */
-	int HORIZONTAL_SCROLLBAR_AS_NEEDED = 30;
-
-	/**
-	 * HORIZONTAL_SCROLLBAR_NEVER
-	 */
-	int HORIZONTAL_SCROLLBAR_NEVER = 31;
-
-	/**
-	 * HORIZONTAL_SCROLLBAR_ALWAYS
-	 */
-	int HORIZONTAL_SCROLLBAR_ALWAYS = 32;
-
-
-} // ScrollPaneConstants
+public interface ScrollPaneConstants
+{
+  /**
+   * VIEWPORT
+   */
+  String VIEWPORT = "VIEWPORT";
+
+  /**
+   * VERTICAL_SCROLLBAR
+   */
+  String VERTICAL_SCROLLBAR = "VERTICAL_SCROLLBAR";
+
+  /**
+   * HORIZONTAL_SCROLLBAR
+   */
+  String HORIZONTAL_SCROLLBAR = "HORIZONTAL_SCROLLBAR";
+
+  /**
+   * ROW_HEADER
+   */
+  String ROW_HEADER = "ROW_HEADER";
+
+  /**
+   * COLUMN_HEADER
+   */
+  String COLUMN_HEADER = "COLUMN_HEADER";
+
+  /**
+   * LOWER_LEFT_CORNER
+   */
+  String LOWER_LEFT_CORNER = "LOWER_LEFT_CORNER";
+
+  /**
+   * LOWER_RIGHT_CORNER
+   */
+  String LOWER_RIGHT_CORNER = "LOWER_RIGHT_CORNER";
+
+  /**
+   * UPPER_LEFT_CORNER
+   */
+  String UPPER_LEFT_CORNER = "UPPER_LEFT_CORNER";
+
+  /**
+   * UPPER_RIGHT_CORNER
+   */
+  String UPPER_RIGHT_CORNER = "UPPER_RIGHT_CORNER";
+
+  /**
+   * LOWER_LEADING_CORNER
+   */
+  String LOWER_LEADING_CORNER = "LOWER_LEADING_CORNER";
+
+  /**
+   * LOWER_TRAILING_CORNER
+   */
+  String LOWER_TRAILING_CORNER = "LOWER_TRAILING_CORNER";
+
+  /**
+   * UPPER_LEADING_CORNER
+   */
+  String UPPER_LEADING_CORNER = "UPPER_LEADING_CORNER";
+
+  /**
+   * UPPER_TRAILING_CORNER
+   */
+  String UPPER_TRAILING_CORNER = "UPPER_TRAILING_CORNER";
+
+  /**
+   * VERTICAL_SCROLLBAR_POLICY
+   */
+  String VERTICAL_SCROLLBAR_POLICY = "VERTICAL_SCROLLBAR_POLICY";
+
+  /**
+   * HORIZONTAL_SCROLLBAR_POLICY
+   */
+  String HORIZONTAL_SCROLLBAR_POLICY = "HORIZONTAL_SCROLLBAR_POLICY";
+
+  /**
+   * VERTICAL_SCROLLBAR_AS_NEEDED
+   */
+  int VERTICAL_SCROLLBAR_AS_NEEDED = 20;
+
+  /**
+   * VERTICAL_SCROLLBAR_NEVER
+   */
+  int VERTICAL_SCROLLBAR_NEVER = 21;
+
+  /**
+   * VERTICAL_SCROLLBAR_ALWAYS
+   */
+  int VERTICAL_SCROLLBAR_ALWAYS = 22;
+
+  /**
+   * HORIZONTAL_SCROLLBAR_AS_NEEDED
+   */
+  int HORIZONTAL_SCROLLBAR_AS_NEEDED = 30;
+
+  /**
+   * HORIZONTAL_SCROLLBAR_NEVER
+   */
+  int HORIZONTAL_SCROLLBAR_NEVER = 31;
+
+  /**
+   * HORIZONTAL_SCROLLBAR_ALWAYS
+   */
+  int HORIZONTAL_SCROLLBAR_ALWAYS = 32;
+}
Index: javax/swing/ScrollPaneLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ScrollPaneLayout.java,v
retrieving revision 1.3
diff -u -r1.3 ScrollPaneLayout.java
--- javax/swing/ScrollPaneLayout.java	11 Jun 2003 13:20:39 -0000	1.3
+++ javax/swing/ScrollPaneLayout.java	6 Sep 2004 16:36:00 -0000
@@ -1,5 +1,5 @@
 /* ScrollPaneLayout.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -41,9 +41,12 @@
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Dimension;
+import java.awt.Insets;
 import java.awt.LayoutManager;
 import java.awt.Rectangle;
+import java.awt.Point;
 import java.io.Serializable;
+import javax.swing.border.Border;
 
 /**
  * ScrollPaneLayout
@@ -55,258 +58,418 @@
 {
   static final long serialVersionUID = -4480022884523193743L;
 
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * UIResource
-	 */
-	public static class UIResource extends ScrollPaneLayout 
-			implements javax.swing.plaf.UIResource {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor UIResource
-		 */
-		public UIResource() {
-			// TODO
-		} // UIResource()
-
-
-	} // UIResource
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * viewport
-	 */
-	protected JViewport viewport;
-
-	/**
-	 * vsb
-	 */
-	protected JScrollBar vsb;
-
-	/**
-	 * hsb
-	 */
-	protected JScrollBar hsb;
-
-	/**
-	 * rowHead
-	 */
-	protected JViewport rowHead;
-
-	/**
-	 * colHead
-	 */
-	protected JViewport colHead;
-
-	/**
-	 * lowerLeft
-	 */
-	protected Component lowerLeft;
-
-	/**
-	 * lowerRight
-	 */
-	protected Component lowerRight;
-
-	/**
-	 * upperLeft
-	 */
-	protected Component upperLeft;
-
-	/**
-	 * upperRight
-	 */
-	protected Component upperRight;
-
-	/**
-	 * vsbPolicy
-	 */
-	protected int vsbPolicy;
-
-	/**
-	 * hsbPolicy
-	 */
-	protected int hsbPolicy;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor ScrollPaneLayout
-	 */
-	public ScrollPaneLayout() {
-		// TODO
-	} // ScrollPaneLayout()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * syncWithScrollPane
-	 * @param scrollPane TODO
-	 */
-	public void syncWithScrollPane(JScrollPane scrollPane) {
-		// TODO
-	} // syncWithScrollPane()
-
-	/**
-	 * addSingletonComponent
-	 * @param oldComponent TODO
-	 * @param newComponent TODO
-	 * @returns Component
-	 */
-	protected Component addSingletonComponent(Component oldComponent,
-			Component newComponent) {
-		return null; // TODO
-	} // addSingletonComponent()
-
-	/**
-	 * addLayoutComponent
-	 * @param string TODO
-	 * @param component TODO
-	 */
-	public void addLayoutComponent(String string, Component component) {
-		// TODO
-	} // addLayoutComponent()
-
-	/**
-	 * removeLayoutComponent
-	 * @param component TODO
-	 */
-	public void removeLayoutComponent(Component component) {
-		// TODO
-	} // removeLayoutComponent()
-
-	/**
-	 * getVerticalScrollBarPolicy
-	 * @returns int
-	 */
-	public int getVerticalScrollBarPolicy() {
-		return 0; // TODO
-	} // getVerticalScrollBarPolicy()
-
-	/**
-	 * setVerticalScrollBarPolicy
-	 * @param policy TODO
-	 */
-	public void setVerticalScrollBarPolicy(int policy) {
-		// TODO
-	} // setVerticalScrollBarPolicy()
-
-	/**
-	 * getHorizontalScrollBarPolicy
-	 * @returns int
-	 */
-	public int getHorizontalScrollBarPolicy() {
-		return 0; // TODO
-	} // getHorizontalScrollBarPolicy()
-
-	/**
-	 * setHorizontalScrollBarPolicy
-	 * @param policy TODO
-	 */
-	public void setHorizontalScrollBarPolicy(int policy) {
-		// TODO
-	} // setHorizontalScrollBarPolicy()
-
-	/**
-	 * getViewport
-	 * @returns JViewport
-	 */
-	public JViewport getViewport() {
-		return null; // TODO
-	} // getViewport()
-
-	/**
-	 * getHorizontalScrollBar
-	 * @returns JScrollBar
-	 */
-	public JScrollBar getHorizontalScrollBar() {
-		return null; // TODO
-	} // getHorizontalScrollBar()
-
-	/**
-	 * getVerticalScrollBar
-	 * @returns JScrollBar
-	 */
-	public JScrollBar getVerticalScrollBar() {
-		return null; // TODO
-	} // getVerticalScrollBar()
-
-	/**
-	 * getRowHeader
-	 * @returns JViewport
-	 */
-	public JViewport getRowHeader() {
-		return null; // TODO
-	} // getRowHeader()
-
-	/**
-	 * getColumnHeader
-	 * @returns JViewport
-	 */
-	public JViewport getColumnHeader() {
-		return null; // TODO
-	} // getColumnHeader()
-
-	/**
-	 * getCorner
-	 * @param key TODO
-	 * @returns Component
-	 */
-	public Component getCorner(String key) {
-		return null; // TODO
-	} // getCorner()
-
-	/**
-	 * preferredLayoutSize
-	 * @param parent TODO
-	 * @returns Dimension
-	 */
-	public Dimension preferredLayoutSize(Container parent) {
-		return null; // TODO
-	} // preferredLayoutSize()
-
-	/**
-	 * minimumLayoutSize
-	 * @param parent TODO
-	 * @returns Dimension
-	 */
-	public Dimension minimumLayoutSize(Container parent) {
-		return null; // TODO
-	} // minimumLayoutSize()
-
-	/**
-	 * layoutContainer
-	 * @param parent TODO
-	 */
-	public void layoutContainer(Container parent) {
-		// TODO
-	} // layoutContainer()
-
-	/**
-	 * getViewportBorderBounds
-	 * @param value0 TODO
-	 * @returns Rectangle
-	 */
-	public Rectangle getViewportBorderBounds(JScrollPane scrollPane) {
-		return null; // TODO
-	} // getViewportBorderBounds()
+  public static class UIResource extends ScrollPaneLayout 
+    implements javax.swing.plaf.UIResource {
+    public UIResource() {
+    }
+  }
+
+  protected JViewport viewport;
+  protected JScrollBar vsb;
+  protected JScrollBar hsb;
+  protected JViewport rowHead;
+  protected JViewport colHead;
+  protected Component lowerLeft;
+  protected Component lowerRight;
+  protected Component upperLeft;
+  protected Component upperRight;
+  protected int vsbPolicy;
+  protected int hsbPolicy;
+
+  public ScrollPaneLayout() {
+		
+  }
+
+  public void syncWithScrollPane(JScrollPane scrollPane) {
+    viewport = scrollPane.getViewport();
+    rowHead = scrollPane.getRowHeader();
+    colHead = scrollPane.getColumnHeader();
+    vsb = scrollPane.getVerticalScrollBar();
+    hsb = scrollPane.getHorizontalScrollBar();
+    vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
+    hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
+    lowerLeft = scrollPane.getCorner(LOWER_LEFT_CORNER);
+    lowerRight = scrollPane.getCorner(LOWER_RIGHT_CORNER);
+    upperLeft = scrollPane.getCorner(UPPER_LEFT_CORNER);
+    upperRight = scrollPane.getCorner(UPPER_RIGHT_CORNER);    
+  }
+
+  protected Component addSingletonComponent(Component oldComponent,
+                                            Component newComponent) {
+    return null;
+  }
+
+  public void addLayoutComponent(String key, Component component) 
+  {
+    if (key == VIEWPORT)
+      viewport = (JViewport) component;
+    else if (key == VERTICAL_SCROLLBAR)
+      vsb = (JScrollBar) component;
+    else if (key == HORIZONTAL_SCROLLBAR)
+      hsb = (JScrollBar) component;
+    else if (key == ROW_HEADER)
+      rowHead = (JViewport) component;
+    else if (key == COLUMN_HEADER)
+      colHead = (JViewport) component;
+    else if (key == LOWER_RIGHT_CORNER)
+      lowerRight = component;
+    else if (key == UPPER_RIGHT_CORNER)
+      upperRight = component;
+    else if (key == LOWER_LEFT_CORNER)
+      lowerLeft = component;
+    else if (key == UPPER_LEFT_CORNER)
+      upperLeft = component;
+  }
+
+  public void removeLayoutComponent(Component component) {
+    if (component == viewport)
+      viewport = null;
+    else if (component == vsb)
+      vsb = null;
+    else if (component == hsb)
+      hsb = null;
+    else if (component == rowHead)
+      rowHead = null;
+    else if (component == colHead)
+      colHead = null;
+    else if (component == lowerRight)
+      lowerRight = null;
+    else if (component == upperRight)
+      upperRight = null;
+    else if (component == lowerLeft)
+      lowerLeft = null;
+    else if (component == upperLeft)
+      upperLeft = null;
+  }
+
+  public int getVerticalScrollBarPolicy()
+  {
+    return vsbPolicy;
+  }
+
+  public void setVerticalScrollBarPolicy(int policy)
+  {
+    vsbPolicy = policy;
+  }
+
+  public int getHorizontalScrollBarPolicy()
+  {
+    return hsbPolicy;
+  }
+
+  public void setHorizontalScrollBarPolicy(int policy)
+  {
+    hsbPolicy = policy;
+  }
+
+  public JViewport getViewport()
+  {
+    return viewport;
+  }
+
+  public JScrollBar getHorizontalScrollBar()
+  {
+    return hsb;
+  }
+
+  public JScrollBar getVerticalScrollBar()
+  {
+    return vsb;
+  }
+
+  public JViewport getRowHeader()
+  {
+    return rowHead;
+  }
+
+  public JViewport getColumnHeader()
+  {
+    return colHead;
+  }
+
+  public Component getCorner(String key)
+  {
+    if (key == LOWER_RIGHT_CORNER)
+      return lowerRight;
+    else if (key == UPPER_RIGHT_CORNER)
+      return upperRight;
+    else if (key == LOWER_LEFT_CORNER)
+      return lowerLeft;
+    else if (key == UPPER_LEFT_CORNER)
+      return upperLeft;
+    return null;
+  }
+
+  private static void maybeSetPreferredSize(JComponent src, Dimension dim)
+  {
+    Dimension tmp = null;
+    if (src != null)
+      tmp = src.getPreferredSize();
+    if (tmp != null)
+      dim.setSize(tmp);        
+  }
+
+  private static void maybeSetMinimumSize(JComponent src, Dimension dim)
+  {
+    Dimension tmp = null;
+    if (src != null)
+      tmp = src.getMinimumSize();
+    if (tmp != null)
+      dim.setSize(tmp);
+  }
+
+  public Dimension preferredLayoutSize(Container parent) 
+  {
+    if (parent != null && parent instanceof JScrollPane)
+      {
+        JScrollPane sc = (JScrollPane) parent;
+        synchronized (sc.getTreeLock ())
+          {
+            Dimension insetsSize = new Dimension(0,0); 
+            Dimension viewportSize = new Dimension(0,0); 
+            Dimension viewportInsetsSize = new Dimension(0,0); 
+            Dimension columnHeaderSize = new Dimension(0,0); 
+            Dimension rowHeaderSize = new Dimension(0,0); 
+            Dimension verticalScrollBarSize = new Dimension(0,0); 
+            Dimension horizontalScrollBarSize = new Dimension(0,0); 
+
+            Insets insets = sc.getInsets();
+            Border viewportBorder = sc.getViewportBorder();
+            Insets viewportInsets = null;
+
+            if (viewportBorder != null)
+              {
+              viewportInsets = viewportBorder.getBorderInsets(parent);
+                if (viewportInsets != null)
+                  viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
+                                             viewportInsets.top + viewportInsets.bottom);
+              }
+
+            if (insets != null)
+              insetsSize.setSize(insets.left + insets.right,
+                                 insets.top + insets.bottom);
+
+            if (viewport != null)
+              {
+                Component view = null;
+                Scrollable scr = null;
+                Dimension pref = null;
+                
+                view = viewport.getView();
+                if (view != null && view instanceof Scrollable)
+                  scr = (Scrollable) view;
+                if (scr != null)
+                  pref = scr.getPreferredScrollableViewportSize();
+                if (pref == null)
+                  pref = viewport.getPreferredSize();
+                if (pref != null)
+                  viewportSize.setSize(pref);
+              }
+                       
+            maybeSetPreferredSize(colHead, columnHeaderSize);
+            maybeSetPreferredSize(rowHead, rowHeaderSize);
+            maybeSetPreferredSize(vsb, verticalScrollBarSize);
+            maybeSetPreferredSize(hsb, horizontalScrollBarSize);
+
+            return new Dimension(insetsSize.width 
+                                 + viewportSize.width
+                                 + viewportInsetsSize.width
+                                 + rowHeaderSize.width
+                                 + verticalScrollBarSize.width,
+                                 insetsSize.height
+                                 + viewportSize.height
+                                 + viewportInsetsSize.height
+                                 + columnHeaderSize.height
+                                 + horizontalScrollBarSize.height);
+          }
+      }
+    else
+      {
+        return new Dimension(0,0);
+      }
+  }
+
+  public Dimension minimumLayoutSize(Container parent)
+  {
+    if (parent instanceof JScrollPane)
+      {
+        JScrollPane sc = (JScrollPane) parent;
+        synchronized (sc.getTreeLock ())
+          {
+            Dimension insetsSize = new Dimension(0,0); 
+            Dimension viewportSize = new Dimension(0,0); 
+            Dimension viewportInsetsSize = new Dimension(0,0); 
+            Dimension columnHeaderSize = new Dimension(0,0); 
+            Dimension rowHeaderSize = new Dimension(0,0); 
+            Dimension verticalScrollBarSize = new Dimension(0,0); 
+            Dimension horizontalScrollBarSize = new Dimension(0,0); 
+
+            Insets insets = sc.getInsets();
+            Border viewportBorder = sc.getViewportBorder();
+            Insets viewportInsets = null;
+
+            if (viewportBorder != null)
+              {
+              viewportInsets = viewportBorder.getBorderInsets(parent);
+                if (viewportInsets != null)
+                  viewportInsetsSize.setSize(viewportInsets.left + viewportInsets.right,
+                                             viewportInsets.top + viewportInsets.bottom);
+              }
+
+            if (insets != null)
+              insetsSize.setSize(insets.left + insets.right,
+                                 insets.top + insets.bottom);
+
+            maybeSetMinimumSize(viewport, viewportSize);
+            maybeSetMinimumSize(colHead, columnHeaderSize);
+            maybeSetMinimumSize(rowHead, rowHeaderSize);
+
+            if (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)
+              maybeSetMinimumSize(vsb, verticalScrollBarSize);
+
+            if (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)
+              maybeSetMinimumSize(hsb, horizontalScrollBarSize);
+            
+            return new Dimension(insetsSize.width 
+                                 + viewportSize.width
+                                 + viewportInsetsSize.width
+                                 + rowHeaderSize.width
+                                 + verticalScrollBarSize.width,
+                                 insetsSize.height
+                                 + viewportSize.height
+                                 + viewportInsetsSize.height
+                                 + columnHeaderSize.height
+                                 + horizontalScrollBarSize.height);
+          }
+      }
+    else
+      {
+        return new Dimension(0,0);
+      }
+  }
+
+  /**
+   *
+   *     +----+--------------------+----+ y1
+   *     | c1 |   column header    | c2 |
+   *     +----+--------------------+----+ y2
+   *     | r  |                    | v  |
+   *     | o  |                    |    |
+   *     | w  |                    | s  |
+   *     |    |                    | r  |
+   *     | h  |                    | o  |
+   *     | e  |      viewport      | l  |
+   *     | a  |                    | l  |
+   *     | d  |                    | b  |
+   *     | e  |                    | a  |
+   *     | r  |                    | r  |
+   *     +----+--------------------+----+ y3
+   *     | c3 |    h scrollbar     | c4 |
+   *     +----+--------------------+----+ y4
+   *    x1   x2                   x3   x4
+   *   
+   */
+  public void layoutContainer(Container parent)
+  {
+    if (parent instanceof JScrollPane)
+      {
+        JScrollPane sc = (JScrollPane) parent;
+        synchronized (sc.getTreeLock ())
+          {
+            JViewport viewport = sc.getViewport();
+            Dimension viewSize = viewport.getViewSize(); 
+            Point viewPos = viewport.getViewPosition(); 
+
+            int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
+            int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
+
+            Rectangle scrollPaneBounds = SwingUtilities.calculateInnerArea(sc, null);
+
+            x1 = scrollPaneBounds.x;
+            y1 = scrollPaneBounds.y;
+            x4 = scrollPaneBounds.x + scrollPaneBounds.width;
+            y4 = scrollPaneBounds.y + scrollPaneBounds.height;
+            
+            if (colHead != null)
+              y2 = y1 + colHead.getPreferredSize().height;
+            else
+              y2 = y1;
+
+            if (rowHead != null)
+              x2 = x1 + rowHead.getPreferredSize().width;
+            else
+              x2 = x1;
+
+            int vsbPolicy = sc.getVerticalScrollBarPolicy();
+            int hsbPolicy = sc.getHorizontalScrollBarPolicy();
+
+            x3 = x4 - vsb.getPreferredSize().width;
+            y3 = y4 - hsb.getPreferredSize().height;
+
+            boolean showVsb = 
+              (vsb != null)
+              && ((vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS)
+                  || (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED 
+                      && viewSize.height > (y3 - y2)));
+
+            boolean showHsb = 
+              (hsb != null)
+              && ((hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS)
+                  || (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED 
+                      && viewSize.width > (x3 - x2)));
+            
+            if (!showVsb)
+              x3 = x4;
+
+            if (!showHsb)
+              y3 = y4;
+
+            // now set the layout
+
+            if (viewport != null)
+              viewport.setBounds(new Rectangle(x2, y2, x3-x2, y3-y2));
+
+            if (colHead != null)
+              colHead.setBounds(new Rectangle(x2, y1, x3-x2, y2-y1));
+
+            if (rowHead != null)
+              rowHead.setBounds(new Rectangle(x1, y2, x2-x1, y3-y2));
+
+            if (showVsb)
+              {
+                vsb.setVisible(true);
+	      vsb.setBounds(new Rectangle(x3, y2, x4-x3, y3-y2));
+              }
+            else if (vsb != null)
+              vsb.setVisible(false);
+
+            if (showHsb)
+              {
+                hsb.setVisible(true);
+              hsb.setBounds(new Rectangle(x2, y3, x3-x2, y4-y3));
+              }
+            else if (hsb != null)
+              hsb.setVisible(false);
+
+            if (upperLeft != null)
+              upperLeft.setBounds(new Rectangle(x1, y1, x2-x1, y2-y1));
+
+            if (upperRight != null)
+              upperRight.setBounds(new Rectangle(x3, y1, x4-x3, y2-y1));
+
+            if (lowerLeft != null)
+              lowerLeft.setBounds(new Rectangle(x1, y3, x2-x1, y4-y3));
+
+            if (lowerRight != null)
+              lowerRight.setBounds(new Rectangle(x3, y3, x4-x3, y4-y3));
+
+          }
+      }
+  }
+
+  public Rectangle getViewportBorderBounds(JScrollPane scrollPane) {
+    return null;
+  }
 
 
-} // ScrollPaneLayout
+}
Index: javax/swing/SpinnerNumberModel.java
===================================================================
RCS file: javax/swing/SpinnerNumberModel.java
diff -N javax/swing/SpinnerNumberModel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/SpinnerNumberModel.java	6 Sep 2004 16:36:00 -0000
@@ -0,0 +1,241 @@
+/* SpinnerNumberModel.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+/**
+ * SpinnerNumberModel
+ *
+ * @author Ka-Hing Cheung
+ * @version 1.0
+ */
+public class SpinnerNumberModel extends AbstractSpinnerModel
+{
+  /** DOCUMENT ME! */
+  private Number value;
+
+  /** DOCUMENT ME! */
+  private Comparable minimum;
+
+  /** DOCUMENT ME! */
+  private Comparable maximum;
+
+  /** DOCUMENT ME! */
+  private Number stepSize;
+
+  /**
+   * Creates a <code>SpinnerNumberModel</code> with initial value 0, step 1,
+   * and no maximum nor minimum.
+   */
+  public SpinnerNumberModel()
+  {
+    this(new Integer(0), null, null, new Integer(1));
+  }
+
+  /**
+   * Creates a <code>SpinnerNumberModel</code> with double precision
+   *
+   * @param value the initial value
+   * @param minimum the minimum value
+   * @param maximum the maximum value
+   * @param stepSize the step size
+   */
+  public SpinnerNumberModel(double value, double minimum, double maximum,
+                            double stepSize)
+  {
+    this(new Double(value), new Double(minimum), new Double(maximum),
+         new Double(stepSize));
+  }
+
+  /**
+   * Creates a <code>SpinnerNumberModel</code> with integer precision
+   *
+   * @param value the initial value
+   * @param minimum the minimum value
+   * @param maximum the maximum value
+   * @param stepSize the step size
+   */
+  public SpinnerNumberModel(int value, int minimum, int maximum, int stepSize)
+  {
+    this(new Integer(value), new Integer(minimum), new Integer(maximum),
+         new Integer(stepSize));
+  }
+
+  /**
+   * Creates a <code>SpinnerNumberModel</code> with <code>Number</code>s and
+   * <code>Comparable</code>s.
+   *
+   * @param value the initial value
+   * @param minimum the minimum value, if null there's no minimum
+   * @param maximum the maximum value, if null there's no maximum
+   * @param stepSize the step size
+   *
+   * @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
+   *         does not hold
+   */
+  public SpinnerNumberModel(Number value, Comparable minimum,
+                            Comparable maximum, Number stepSize)
+  {
+    if (stepSize == null)
+      throw new IllegalArgumentException("stepSize may not be null");
+    if (value == null)
+      throw new IllegalArgumentException("value may not be null");
+    if (minimum != null)
+      {
+	if (minimum.compareTo(value) > 0)
+	  throw new IllegalArgumentException("minimum is not <= value");
+      }
+    else
+      minimum = new Comparable()
+	  {
+	    public int compareTo(Object obj)
+	    {
+	      return -1;
+	    }
+	  };
+
+
+    if (maximum != null)
+      {
+	if (maximum.compareTo(value) < 0)
+	  throw new IllegalArgumentException("maximum is not >= value");
+      }
+    else
+      maximum = new Comparable()
+	  {
+	    public int compareTo(Object obj)
+	    {
+	      return 1;
+	    }
+	  };
+
+
+    this.value = value;
+    this.stepSize = stepSize;
+    this.minimum = minimum;
+    this.maximum = maximum;
+  }
+
+  /**
+   * Sets the new value and fire a change event
+   *
+   * @param value the new value
+   *
+   * @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
+   *         does not hold
+   */
+  public void setValue(Object value)
+  {
+    if (! (value instanceof Number))
+      throw new IllegalArgumentException("value must be a Number");
+
+    this.value = (Number) value;
+    fireStateChanged();
+  }
+
+  /**
+   * Gets the current value
+   *
+   * @return the current value
+   */
+  public Object getValue()
+  {
+    return value;
+  }
+
+  /**
+   * Gets the next value without changing the current value, or null if the
+   * current value is maximum.
+   *
+   * @return the next value
+   */
+  public Object getNextValue()
+  {
+    Number num;
+
+    if (value instanceof Double)
+      num = new Double(value.doubleValue() + stepSize.doubleValue());
+    else if (value instanceof Float)
+      num = new Double(value.floatValue() + stepSize.floatValue());
+    else if (value instanceof Long)
+      num = new Long(value.longValue() + stepSize.longValue());
+    else if (value instanceof Integer)
+      num = new Integer(value.intValue() + stepSize.intValue());
+    else if (value instanceof Short)
+      num = new Short((short) (value.shortValue() + stepSize.shortValue()));
+    else
+      num = new Byte((byte) (value.byteValue() + stepSize.byteValue()));
+
+    return maximum.compareTo(num) >= 0 ? num : null;
+  }
+
+  /**
+   * Gets the previous value without changing the current value, or null if
+   * the current value is minimum.
+   *
+   * @return the previous value
+   */
+  public Object getPreviousValue()
+  {
+    Number num;
+
+    if (value instanceof Double)
+      num = new Double(value.doubleValue() - stepSize.doubleValue());
+    else if (value instanceof Float)
+      num = new Double(value.floatValue() - stepSize.floatValue());
+    else if (value instanceof Long)
+      num = new Long(value.longValue() - stepSize.longValue());
+    else if (value instanceof Integer)
+      num = new Integer(value.intValue() - stepSize.intValue());
+    else if (value instanceof Short)
+      num = new Short((short) (value.shortValue() - stepSize.shortValue()));
+    else
+      num = new Byte((byte) (value.byteValue() - stepSize.byteValue()));
+
+    return minimum.compareTo(num) <= 0 ? num : null;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Number getNumber()
+  {
+    return value;
+  }
+}
Index: javax/swing/Spring.java
===================================================================
RCS file: javax/swing/Spring.java
diff -N javax/swing/Spring.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/Spring.java	6 Sep 2004 16:36:00 -0000
@@ -0,0 +1,580 @@
+/* Spring.java -- 
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+/**
+ * Calculates the space between component edges, that are layed out by
+ * {@link SpringLayout}.
+ * <p>
+ * A Spring defines a minimum, preferred and maximum distance for each edge
+ * (north, east, south, west) of a component.
+ * </p>
+ * However, springs are not static, their actual values are computed at
+ * runtime. That means, if a Spring C is defined as the sum of Spring A and
+ * Spring B, then the values (min, pref and max) are not calculated at
+ * creation of Spring C, but instead always when {@link #getValue} is
+ * called. So, when Spring A or Spring B changes, this is reflected in
+ * Spring C.
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+public abstract class Spring
+{
+
+  /** Indicates a not-set value. **/
+  public static final int UNSET = -2147483648;
+
+  /**
+   * Creates a new Spring object. This constructor is used by the static
+   * methods which create Springs.
+   */
+  protected Spring()
+  {
+  }
+
+  /**
+   * Creates a Spring which min, pref and max values are all the same.
+   * These kind of Springs are 'struts'.
+   *
+   * @param val the constant for min, pref and max values.
+   * @return a Spring object with constant values for min, pref and max.
+   */
+  public static Spring constant(int val)
+  {
+    return new SimpleSpring(val, val, val);
+  }
+
+  /** Creates a Spring which min, pref and max values are constants.
+   * @param min the constant for the minimum value.
+   * @param pref the constant for the preferred value.
+   * @param max the constant for the maximum value.
+   * @return a Spring object with constant values for min, pref and max.
+   */
+  public static Spring constant(int min, int pref, int max)
+  {
+    return new SimpleSpring(min, pref, max);
+  }
+
+  /**
+   * Returns the maximum value of the Spring.
+   *
+   * @return the maximum value.
+   */
+  public abstract int getMaximumValue();
+
+  /**
+   * Returns the minimum value of this Spring.
+   *
+   * @return the minimum value.
+   */
+  public abstract int getMinimumValue();
+
+  /**
+   * Return the preferred value of this Spring.
+   *
+   * @return the preferred value.
+   */
+  public abstract int getPreferredValue();
+
+  /**
+   * Return the actual value of this Spring.
+   *
+   * @return the actual value of this Spring.
+   */
+  public abstract int getValue();
+
+  /**
+   * Creates and returns a Spring, which always has the maximum values
+   * min = max(min_s1, min_s2), pref = max(pref_s1, pref_s2), max =
+   * max(max_s1, max_s2).
+   *
+   * @param s1 the first summand of the max Spring.
+   * @param s2 the second summand of the max Spring.
+   * @return a Spring which is max(s1, s2).
+   */
+  public static Spring max(Spring s1, Spring s2)
+  {
+    return new MaxSpring(s1, s2);
+  }
+
+  /**
+   * Creates and returns a Spring, which is always the negation of s.
+   * min = -min_s, pref = -pref_s, max = -max_pref.
+   *
+   * @param s the Spring to be negated.
+   * @return the negative of <code>s</code>.
+   */
+  public static Spring minus(Spring s)
+  {
+    return new MinusSpring(s);
+  }
+
+  /**
+   * Sets the actual value. If <code>value</code> is out of the (min, max)
+   * bounds, then the value is adjusted, so that is inside these bounds.
+   *
+   * @param value the value to be set.
+   */
+  public abstract void setValue(int value);
+
+  /**
+   * Creates and returns a Spring, which is always the sum of s1 and s2.
+   * min_sum = min_s1 + min_s2, pref_sum = pref_s1 + pref_s2, max_sum =
+   * max_s1 + max_s2.
+   *
+   * @param s1 the 1st summand of the sum Spring.
+   * @param s2 the 2nd summand of the sum Spring.
+   * @return a sum which is <code>s1 + s2</code>.
+   */
+  public static Spring sum(Spring s1, Spring s2)
+  {
+    return new AddSpring(s1, s2);
+  }
+
+  /**
+   * A simple Spring, that holds constant values for min, pref and max.
+   *
+   * @author Roman Kennke (roman@ontographics.com)
+   */
+  private static final class SimpleSpring extends Spring
+  {
+
+    /** The constant value for min. */
+    private final int min;
+
+    /** The constant value for pref. */
+    private final int pref;
+
+    /** The constant value for max. */
+    private final int max;
+
+    /** The actual value of the spring. */
+    private int value;
+
+    /**
+     * Creates a new SimpleSpring object.
+     *
+     * @param min the constant minimum value.
+     * @param pref the constant preferred value.
+     * @param max the constant maximum value.
+     */
+    public SimpleSpring(int newMin, int newPref, int newMax)
+    {
+      min = newMin;
+      pref = newPref;
+      max = newMax;
+      value = Spring.UNSET;
+    }
+
+    /**
+     * Returns the maximum value of this Spring.
+     *
+     * @return the maximum value.
+     */
+    public int getMaximumValue()
+    {
+      return max;
+    }
+
+    /**
+     * Returns the minimum value of this Spring.
+     *
+     * @return the minimum value.
+     */
+    public int getMinimumValue()
+    {
+      return min;
+    }
+
+    /**
+     * Returns the preferred value of this Spring.
+     *
+     * @return the preferred value.
+     */
+    public int getPreferredValue()
+    {
+      return pref;
+    }
+
+    /**
+     * Return the actual current value of this Spring.
+     *
+     * @return the current value.
+     */
+    public int getValue()
+    {
+
+      if (value == Spring.UNSET)
+        {
+          value = pref;
+        }
+	    
+      return value;
+    }
+	
+    /**
+     * Sets the current value.
+     *
+     * @param val the value to be set.
+     */
+    public void setValue(int val)
+    {
+
+      if (val > max)
+        {
+          value = max;
+	}
+      else if (val < min)
+        {
+          value = min;
+	}
+      else
+        {
+          value = val;
+        }
+    }
+
+  }
+
+
+  /**
+   * A Spring, that is the sum of two other Springs.
+   *
+   * @author Roman Kennke (roman@ontographics.com)
+   */
+  private static final class AddSpring extends Spring
+  {
+
+    /** The springs, that are the 'operands' of this Spring. */
+    private final Spring s1;
+    private final Spring s2;
+
+    /** The current value for this Spring. */
+    private int value;
+
+    /**
+     * Creates a new AddSpring object.
+     *
+     * @param s1 the first operand.
+     * @param s2 the second operand.
+     */
+    protected AddSpring(Spring s1, Spring s2)
+    {
+      super();
+      this.s1 = s1;
+      this.s2 = s2;
+      value = Spring.UNSET;
+    }
+
+    /**
+     * Returns the maximum value of this Spring.
+     *
+     * @return the maximum value.
+     */
+    public int getMaximumValue()
+    {
+      int max1 = s1.getMaximumValue();
+      int max2 = s2.getMaximumValue();
+      return max1 + max2;
+    }
+
+    /**
+     * Return the minimum value of this Spring.
+     *
+     * @return the minimum value.
+     */
+    public int getMinimumValue()
+    {
+      int min1 = s1.getMinimumValue();
+      int min2 = s2.getMinimumValue();
+      return min1 + min2;
+    }
+
+    /**
+     * Returns the preferred value of this Spring.
+     *
+     * @return the preferred value.
+     */
+    public int getPreferredValue()
+    {
+      int pref1 = s1.getPreferredValue();
+      int pref2 = s2.getPreferredValue();
+      return pref1 + pref2;
+    }
+
+    /**
+     * Returns the actual current value of this Spring.
+     *
+     * @return the current value of this Spring.
+     */
+    public int getValue()
+    {
+      if (value == Spring.UNSET)
+        {
+          int val1 = s1.getValue();
+          int val2 = s2.getValue();
+          value = val1 + val2;
+        }
+      return value;
+    }
+
+    /**
+     * Sets the current value.
+     *
+     * @param val the value to be set.
+     */
+    public void setValue(int val)
+    {
+
+      if (val > getMaximumValue())
+        {
+          value = getMaximumValue();
+        }
+      else if (val < getMinimumValue())
+        {
+          value = getMinimumValue();
+        }
+      else
+        {
+          value = val;
+        }
+
+    }
+	
+  }
+
+
+  /**
+   * A Spring that is calculated as the negation of another Spring.
+   *
+   * @author Roman Kennke (roman@ontographics.com)
+   */
+  private static final class MinusSpring extends Spring
+  {
+
+    /** The Spring from which to calculate the negation. */
+    private final Spring s;
+
+    /** The current value of this Spring. */
+    private int value;
+
+    /**
+     * Creates a new MinusSpring object.
+     * @param s the Spring from which to calculate the negation.
+     */
+    protected MinusSpring(Spring s)
+    {
+      super();
+      this.s = s;
+      value = Spring.UNSET;
+    }
+
+    /** Returns the maximum value of this Spring.
+     *
+     * @return the maximum value.
+     */
+    public int getMaximumValue()
+    {
+      return -s.getMinimumValue();
+    }
+
+    /**
+     * Returns the minimum value of this Spring.
+     *
+     * @return the minimum value.
+     */
+    public int getMinimumValue()
+    {
+      return -s.getMaximumValue();
+    }
+
+    /**
+     * Returns the preferred value of this Spring.
+     *
+     * @return the preferred value.
+     */
+    public int getPreferredValue()
+    {
+      return -s.getPreferredValue();
+    }
+
+    /**
+     * Returns the current value of this Spring.
+     *
+     * @return the current value.
+     */
+    public int getValue()
+    {
+      if (value == Spring.UNSET)
+        {
+	  value = -s.getValue();
+	}
+      return value;
+    }
+
+    /**
+     * Sets the current value.
+     *
+     * @param val the value to be set.
+     */
+    public void setValue(int val)
+    {
+    
+      if (val > getMaximumValue())
+        {
+          value = getMaximumValue();
+	}
+      else if (val < getMinimumValue())
+	{
+          value = getMinimumValue();
+        }
+      else
+	{
+	  value = val;
+        }
+
+    }
+
+  }
+
+
+  /**
+   * A Spring, that is calculated as the maximum of two Springs.
+   *
+   * @author Roman Kennke (roman@ontographics.com)
+   */
+  private static final class MaxSpring extends Spring
+  {
+
+    /** The two other Springs from which to calculate the maximum. */
+    private final Spring s1;
+    private final Spring s2;
+
+    /** The current value of this Spring. */
+    private int value;
+
+    /**
+     * Creates a new MaxSpring object.
+     *
+     * @param s1 the 1st operand.
+     * @param s2 the 2nd operand.
+     */
+    protected MaxSpring(Spring s1, Spring s2)
+    {
+      super();
+      this.s1 = s1;
+      this.s2 = s2;
+      value = Spring.UNSET;
+    }
+
+
+    /**
+     * Returns the maximum value of this Spring.
+     *
+     * @return the maximum value.
+     */
+    public int getMaximumValue()
+    {
+      int max1 = s1.getMaximumValue();
+      int max2 = s2.getMaximumValue();
+      return Math.max(max1, max2);
+    }
+
+    /**
+     * Returns the minimum value of this Spring.
+     *
+     * @return the minimum value.
+     */
+    public int getMinimumValue()
+    {
+      int min1 = s1.getMinimumValue();
+      int min2 = s2.getMinimumValue();
+      return Math.max(min1, min2);
+    }
+
+    /**
+     * Returns the preferred value of this Spring.
+     *
+     * @return the preferred value.
+     */
+    public int getPreferredValue()
+    {
+      int pref1 = s1.getPreferredValue();
+      int pref2 = s2.getPreferredValue();
+      return Math.max(pref1, pref2);
+    }
+
+    /**
+     * Returns the actual value of this Spring.
+     *
+     * @return the current value.
+     */
+    public int getValue()
+    {
+      if (value == Spring.UNSET)
+        {
+          int val1 = s1.getValue();
+          int val2 = s2.getValue();
+          value = Math.max(val1, val2);
+      }
+      return value;
+    }
+
+    /**
+     * Sets the current value.
+     *
+     * @param val the value to be set.
+     */
+    public void setValue(int val)
+    {
+
+      if (val > getMaximumValue())
+        {
+          value = getMaximumValue();
+	}
+      else if (val < getMinimumValue())
+        {
+          value = getMinimumValue();
+        }
+      else
+        {
+          value = val;
+        }
+    }
+  }
+}
Index: javax/swing/SpringLayout.java
===================================================================
RCS file: javax/swing/SpringLayout.java
diff -N javax/swing/SpringLayout.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/SpringLayout.java	6 Sep 2004 16:36:00 -0000
@@ -0,0 +1,660 @@
+/* SpringLayout.java -- 
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.LayoutManager2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.Spring;
+
+/**
+ * A very flexible layout manager. Components are laid out by defining the
+ * relationships between them. The relationships are expressed as
+ * {@link Spring}s. You can attach a Spring for each edge of a component and
+ * link it to an edge of a different component. For example, you can say,
+ * the northern edge of component A should be attached to the southern edge
+ * of component B, and the space between them should be something between
+ * x and y pixels, and preferably z pixels.
+ * <p>While quite simple, this layout manager can be used to emulate most other
+ * layout managers, and can also be used to solve some layout problems, which
+ * would be hard to solve with other layout managers.</p>
+ *
+ * @author Roman Kennke (roman@ontographics.com)
+ */
+public class SpringLayout implements LayoutManager2
+{
+
+  /** The right edge of a component. */
+  public static final String EAST = "East";
+
+  /** The top edge of a component. */
+  public static final String NORTH = "North";
+
+  /** The bottom edge of a component. */
+  public static final String SOUTH = "South";
+
+  /** The left edge of a component. */
+  public static final String WEST = "West";
+
+  /** maps components to their constraints. */
+  private Map constraintsMap;
+
+  /**
+   * The constraints that define the relationships between components.
+   * Each Constraints object can hold 4 Springs: one for each edge of the
+   * component. Additionally it can hold Springs for the components width
+   * and the components height. Since the height and width constraints are
+   * dependend on the other constraints, a component can be over-constraint.
+   * In this case (like when all of NORTH, SOUTH and HEIGHT are constraint),
+   * the values are adjusted, so that the mathematics still hold true.
+   *
+   * @author Roman Kennke (roman@ontographics.com)
+   */
+  public final static class Constraints
+  {
+
+    // The constraints for each edge, and width and height.
+    /** The Spring for the left edge. */
+    private Spring x;
+
+    /** The Spring for the upper edge. */
+    private Spring y;
+
+    /** The Spring for the height. */
+    private Spring height;
+
+    /** The Spring for the width. */
+    private Spring width;
+
+    /** The Spring for the right edge. */
+    private Spring east;
+
+    /** The Spring for the bottom edge. */
+    private Spring south;
+
+    /**
+     * Creates a new Constraints object.
+     * There is no constraint set.
+     */
+    public Constraints()
+    {
+      x = y = height = width = east = south = null;
+    }
+
+    /**
+     * Creates a new Constraints object.
+     *
+     * @param x the constraint for the left edge of the component.
+     * @param y the constraint for the upper edge of the component.
+     */
+    public Constraints(Spring x, Spring y)
+    {
+      this.x = x;
+      this.y = y;
+      width = height = east = south = null;
+    }
+
+    /**
+     * Creates a new Constraints object.
+     *
+     * @param x the constraint for the left edge of the component.
+     * @param y the constraint for the upper edge of the component.
+     * @param width the constraint for the width of the component.
+     * @param height the constraint for the height of the component.
+     */
+    public Constraints(Spring x, Spring y, Spring width, Spring height)
+    {
+      this.x = x;
+      this.y = y;
+      this.width = width;
+      this.height = height;
+      east = south = null;
+    }
+
+    /**
+     * Returns the constraint for the edge with the <code>edgeName</code>.
+     * This is expected to be one of
+     * {@link #EAST}, {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+     *
+     * @param edgeName the name of the edge.
+     * @return the constraint for the specified edge.
+     */
+    public Spring getConstraint(String edgeName)
+    {
+      Spring retVal = null;
+      if (edgeName.equals(SpringLayout.NORTH))
+	retVal = y;
+      else if (edgeName.equals(SpringLayout.WEST))
+        retVal = x;
+      else if (edgeName.equals(SpringLayout.SOUTH))
+        {
+          retVal = south;
+	  if ((retVal == null) && (y != null) && (height != null))
+            retVal = Spring.sum(y, height);
+        }
+      else if (edgeName.equals(SpringLayout.EAST))
+        {
+          retVal = east;
+          if ((retVal == null) && (x != null) && (width != null))
+            retVal = Spring.sum(x, width);
+	}
+
+      return retVal;
+    }
+
+    /**
+     * Returns the constraint for the height of the component.
+     *
+     * @return the height constraint. 
+     */
+    public Spring getHeight()
+    {
+      Spring retVal = height;
+      if ((retVal == null) && (y != null) && (south != null))
+        {
+          retVal = Spring.sum(south, Spring.minus(y));
+        }
+      return retVal;
+    }
+
+    /**
+     * Returns the constraint for the width of the component.
+     *
+     * @return the width constraint.
+     */
+    public Spring getWidth()
+    {
+      Spring retVal = width;
+      if ((retVal == null) && (x != null) && (east != null))
+        {
+          retVal = Spring.sum(east, Spring.minus(x));
+	}
+      return retVal;
+    }
+
+    /**
+     * Returns the constraint for the left edge of the component.
+     *
+     * @return the left-edge constraint (== WEST).
+     */
+    public Spring getX()
+    {
+      Spring retVal = x;
+      if ((retVal == null) && (width != null) && (east != null))
+        {
+          retVal = Spring.sum(east, Spring.minus(width));
+        }
+      return retVal;
+    }
+
+    /**
+     * Returns the constraint for the upper edge of the component.
+     *
+     * @return the upper-edge constraint (== NORTH).
+     */
+    public Spring getY()
+    {
+      Spring retVal = y;
+      if ((retVal == null) && (height != null) && (south != null))
+        {
+          retVal = Spring.sum(south, Spring.minus(height));
+        }
+      return retVal;
+    }
+
+    /**
+     * Sets a constraint for the specified edge. If this leads to an
+     * over-constrained situation, the constraints get adjusted, so that
+     * the mathematics still hold true.
+     *
+     * @param edgeName the name of the edge, one of {@link #EAST},
+     *     {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+     * @param s the constraint to be set.
+     */
+    public void setConstraint(String edgeName, Spring s)
+    {
+    
+      if (edgeName.equals(SpringLayout.WEST))
+        {
+          x = s;
+	  if ((width != null) && (east != null))
+            width = Spring.sum(east, Spring.minus(x));
+        }
+      else if (edgeName.equals(SpringLayout.NORTH))
+        {
+          y = s;
+          if ((height != null) && (south != null))
+          height = Spring.sum(south, Spring.minus(y));
+        }
+      else if (edgeName.equals(SpringLayout.EAST))
+        {
+          east = s;
+          if ((x != null) && (width != null))
+            x = Spring.sum(east, Spring.minus(width));
+        }
+      else if (edgeName.equals(SpringLayout.SOUTH))
+        {
+          south = s;
+          if ((height != null) && (y != null))
+	    y = Spring.sum(south, Spring.minus(height));
+        }
+
+    }
+
+    /**
+     * Sets the height-constraint.
+     *
+     * @param s the constraint to be set.
+     */
+    public void setHeight(Spring s)
+    {
+      height = s;
+      if ((south != null) && (y != null))
+        south = Spring.sum(y, height);
+
+    }
+
+    /**
+     * Sets the width-constraint.
+     *
+     * @param s the constraint to be set.
+     */
+    public void setWidth(Spring s)
+    {
+      width = s;
+      if ((east != null) && (x != null))
+        east = Spring.sum(x, width);
+
+    }
+
+    /**
+     * Sets the WEST-constraint.
+     *
+     * @param s the constraint to be set.
+     */
+    public void setX(Spring s)
+    {
+      x = s;
+      if ((width != null) && (east != null))
+        width = Spring.sum(east, Spring.minus(x));
+
+    }
+
+    /**
+     * Sets the NORTH-constraint.
+     *
+     * @param s the constraint to be set.
+     */
+    public void setY(Spring s)
+    {
+      y = s;
+      if ((height != null) && (south != null))
+        height = Spring.sum(south, Spring.minus(y));
+
+    }
+  }
+
+  /**
+   * Creates a new SpringLayout.
+   */
+  public SpringLayout()
+  {
+
+    constraintsMap = new HashMap();
+  }
+
+  /**
+   * Adds a layout component and a constraint object to this layout.
+   * This method is usually only called by a {@java.awt.Container}s add
+   * Method.
+   *
+   * @param component the component to be added.
+   * @param constraint the constraint to be set.
+   */
+  public void addLayoutComponent(Component component, Object constraint)
+  {
+    constraintsMap.put(component, constraint);
+  }
+
+
+  /**
+   * Adds a layout component and a constraint object to this layout.
+   * This method is usually only called by a {@java.awt.Container}s add
+   * Method. This method does nothing, since SpringLayout does not manage
+   * String-indexed components.
+   *
+   * @param component the component to be added.
+   * @param constraint the constraint to be set.
+   */
+  public void addLayoutComponent(String name, Component c)
+  {
+    // do nothing here.
+  }
+
+  /**
+   * Returns the constraint of the edge named by <code>edgeName</code>.
+   *
+   * @param c the component from which to get the constraint.
+   * @param edgeName the name of the edge, one of {@link #EAST},
+   *     {@link #WEST}, {@link NORTH} or {@link SOUTH}.
+   * @return the constraint of the edge <code>edgeName</code> of the
+   * component c.
+   */
+  public Spring getConstraint(String edgeName, Component c)
+  {
+    Constraints constraints = getConstraints(c);
+    return constraints.getConstraint(edgeName);
+  }
+
+  /**
+   * Returns the {@link Constraints} object associated with the specified
+   * component.
+   *
+   * @param c the component for which to determine the constraint.
+   * @return the {@link Constraints} object associated with the specified
+   *      component.
+   */
+  public SpringLayout.Constraints getConstraints(Component c)
+  {
+    Constraints constraints = (Constraints) constraintsMap.get(c);
+    if (constraints == null)
+      {
+        Container parent = c.getParent();
+        constraints = new Constraints();
+        if (parent != null)
+          {
+            constraints.setX
+              (Spring.constant(parent.getInsets().left));
+            constraints.setY
+              (Spring.constant(parent.getInsets().top));
+          }
+        else
+          {
+            constraints.setX
+              (Spring.constant(0));
+            constraints.setY
+              (Spring.constant(0));
+
+          }
+        constraints.setWidth
+          (Spring.constant(c.getMinimumSize().width,
+                           c.getPreferredSize().width,
+                           c.getMaximumSize().width));
+        constraints.setHeight
+          (Spring.constant(c.getMinimumSize().height,
+                           c.getPreferredSize().height,
+                           c.getMaximumSize().height));
+
+        constraintsMap.put(c, constraints);
+
+      }
+
+    return constraints;
+  }
+
+  /**
+   * Returns the X alignment of the Container <code>p</code>.
+   *
+   * @param p the {@link java.awt.Container} for which to determine the X
+   *     alignment.
+   * @return always 0.0
+   */
+  public float getLayoutAlignmentX(Container p)
+  {
+    return 0.0F;
+  }
+
+  /**
+   * Returns the Y alignment of the Container <code>p</code>.
+   *
+   * @param p the {@link java.awt.Container} for which to determine the Y
+   *     alignment.
+   * @return always 0.0
+   */
+  public float getLayoutAlignmentY(Container p)
+  {
+    return 0.0F;
+  }
+
+  /**
+   * Recalculate a possibly cached layout.
+   */
+  public void invalidateLayout(Container p)
+  {
+    // nothing to do here yet
+  }
+
+  /**
+   * Lays out the container <code>p</code>.
+   *
+   * @param p the container to be laid out.
+   */
+  public void layoutContainer(Container p)
+  {
+
+    addLayoutComponent(p, new Constraints(Spring.constant(0),
+                                          Spring.constant(0)));
+
+    int offsetX = p.getInsets().left;
+    int offsetY = p.getInsets().right;
+
+    Component[] components = p.getComponents();
+    for (int index = 0; index < components.length; index++)
+      {
+        Component c = components[index];
+        Constraints constraints = getConstraints(c);
+        int x = constraints.getX().getValue();
+        int y = constraints.getY().getValue();
+        int width = constraints.getWidth().getValue();
+        int height = constraints.getHeight().getValue();
+
+        c.setLocation(x + offsetX, y + offsetY);
+        c.setSize(width, height);
+      }
+
+  }
+
+  /**
+   * Calculates the maximum size of the layed out container. This
+   * respects the maximum sizes of all contained components.
+   *
+   * @param p the container to be laid out.
+   * @return the maximum size of the container.
+   */
+  public Dimension maximumLayoutSize(Container p)
+  {
+    int maxX = 0;
+    int maxY = 0;
+
+    int offsetX = p.getInsets().left;
+    int offsetY = p.getInsets().right;
+
+    Component[] components = p.getComponents();
+    for (int index = 0; index < components.length; index++)
+      {
+        Component c = components[index];
+        Constraints constraints = getConstraints(c);
+        int x = constraints.getX().getMaximumValue();
+        int y = constraints.getY().getMaximumValue();
+        int width = constraints.getWidth().getMaximumValue();
+        int height = constraints.getHeight().getMaximumValue();
+
+        int rightEdge = offsetX + x + width;
+        if (rightEdge > maxX)
+          maxX = rightEdge;
+        int bottomEdge = offsetY + y + height;
+        if (bottomEdge > maxY)
+          maxY = bottomEdge;
+      }
+
+    return new Dimension(maxX, maxY);
+  }
+
+
+  /**
+   * Calculates the minimum size of the layed out container. This
+   * respects the minimum sizes of all contained components.
+   *
+   * @param p the container to be laid out.
+   * @return the minimum size of the container.
+   */
+  public Dimension minimumLayoutSize(Container p)
+  {
+    int maxX = 0;
+    int maxY = 0;
+
+    int offsetX = p.getInsets().left;
+    int offsetY = p.getInsets().right;
+
+    Component[] components = p.getComponents();
+    for (int index = 0; index < components.length; index++)
+      {
+        Component c = components[index];
+        Constraints constraints = getConstraints(c);
+        int x = constraints.getX().getMinimumValue();
+        int y = constraints.getY().getMinimumValue();
+        int width = constraints.getWidth().getMinimumValue();
+        int height = constraints.getHeight().getMinimumValue();
+
+        int rightEdge = offsetX + x + width;
+        if (rightEdge > maxX)
+          maxX = rightEdge;
+        int bottomEdge = offsetY + y + height;
+        if (bottomEdge > maxY)
+          maxY = bottomEdge;
+      }
+
+    return new Dimension(maxX, maxY);
+  }
+
+  /**
+   * Calculates the preferred size of the layed out container. This
+   * respects the preferred sizes of all contained components.
+   *
+   * @param p the container to be laid out.
+   * @return the preferred size of the container.
+   */
+  public Dimension preferredLayoutSize(Container p)
+  {
+    int maxX = 0;
+    int maxY = 0;
+
+    int offsetX = p.getInsets().left;
+    int offsetY = p.getInsets().right;
+
+    Component[] components = p.getComponents();
+    for (int index = 0; index < components.length; index++)
+      {
+        Component c = components[index];
+        Constraints constraints = getConstraints(c);
+        int x = constraints.getX().getPreferredValue();
+        int y = constraints.getY().getPreferredValue();
+        int width = constraints.getWidth().getPreferredValue();
+        int height = constraints.getHeight().getPreferredValue();
+
+        int rightEdge = offsetX + x + width;
+        if (rightEdge > maxX)
+          maxX = rightEdge;
+        int bottomEdge = offsetY + y + height;
+        if (bottomEdge > maxY)
+          maxY = bottomEdge;
+      }
+
+    return new Dimension(maxX, maxY);
+  }
+
+  /**
+   * Attaches the edge <code>e1</code> of component <code>c1</code> to
+   * the edge <code>e2</code> of component <code>c2</code> width the
+   * fixed strut <code>pad</code>.
+   *
+   * @param e1 the edge of component 1.
+   * @param c1 the component 1.
+   * @param pad the space between the components in pixels.
+   * @param e2 the edge of component 2.
+   * @param c2 the component 2.
+   */
+  public void putConstraint(String e1, Component c1, int pad, String e2, 
+                            Component c2)
+  {
+    Constraints constraints1 = getConstraints(c1);
+    Constraints constraints2 = getConstraints(c2);
+
+    Spring strut = Spring.constant(pad);
+    Spring otherEdge = constraints2.getConstraint(e2);
+    constraints1.setConstraint(e1, Spring.sum(strut, otherEdge));
+
+  }
+
+  /**
+   * Attaches the edge <code>e1</code> of component <code>c1</code> to
+   * the edge <code>e2</code> of component <code>c2</code> width the
+   * {@link Spring} <code>s</code>.
+   *
+   * @param e1 the edge of component 1.
+   * @param c1 the component 1.
+   * @param s the space between the components as a {@link Spring} object.
+   * @param e2 the edge of component 2.
+   * @param c2 the component 2.
+   */
+  public void putConstraint(String e1, Component c1, Spring s, String e2, 
+                            Component c2)
+  {
+    Constraints constraints1 = getConstraints(c1);
+    Constraints constraints2 = getConstraints(c2);
+
+    Spring otherEdge = constraints2.getConstraint(e2);
+    constraints1.setConstraint(e1, Spring.sum(s, otherEdge));
+
+  }
+
+  /**
+   * Removes a layout component.
+   * @param c the layout component to remove.
+   */
+  public void removeLayoutComponent(Component c)
+  {
+    // do nothing here
+  }
+}
Index: javax/swing/SwingConstants.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/SwingConstants.java,v
retrieving revision 1.3
diff -u -r1.3 SwingConstants.java
--- javax/swing/SwingConstants.java	12 Oct 2003 13:20:49 -0000	1.3
+++ javax/swing/SwingConstants.java	6 Sep 2004 16:36:00 -0000
@@ -60,5 +60,15 @@
     
   int LEADING      = 10;
   int TRAILING     = 11;
+
+  /**
+   * @since 1.4
+   */
+  int NEXT         = 12;
+
+  /**
+   * @since 1.4
+   */
+  int PREVIOUS     = 13;
 }
 
Index: javax/swing/SwingUtilities.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/SwingUtilities.java,v
retrieving revision 1.3
diff -u -r1.3 SwingUtilities.java
--- javax/swing/SwingUtilities.java	14 Jul 2003 05:33:30 -0000	1.3
+++ javax/swing/SwingUtilities.java	6 Sep 2004 16:36:01 -0000
@@ -1,5 +1,5 @@
-/* SwingUtilities.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* SwingUtilities.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,101 +35,983 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.applet.Applet;
 import java.awt.Component;
+import java.awt.ComponentOrientation;
 import java.awt.Container;
-import java.awt.EventQueue;
 import java.awt.Font;
 import java.awt.FontMetrics;
+import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.Shape;
 import java.awt.Toolkit;
 import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.lang.reflect.InvocationTargetException;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleStateSet;
+import javax.swing.plaf.ActionMapUIResource;
+import javax.swing.plaf.InputMapUIResource;
+
 
+/**
+ * This class contains a number of static utility functions which are
+ * useful when drawing swing components, dispatching events, or calculating
+ * regions which need painting.
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
 public class SwingUtilities implements SwingConstants
 {
-  public static FontMetrics getFontMetrics (Font font)
+  /** 
+   * This frame should be used as parent for JWindow or JDialog 
+   * that doesn't an owner
+   */
+  private static OwnerFrame ownerFrame;
+
+  /**
+   * Calculates the portion of the base rectangle which is inside the
+   * insets.
+   *
+   * @param base The rectangle to apply the insets to
+   * @param insets The insets to apply to the base rectangle
+   * @param ret A rectangle to use for storing the return value, or
+   * <code>null</code>
+   *
+   * @return The calculated area inside the base rectangle and its insets,
+   * either stored in ret or a new Rectangle if ret is <code>null</code>
+   *
+   * @see #calculateInnerArea
+   */
+  public static Rectangle calculateInsetArea(Rectangle base, Insets insets,
+                                             Rectangle ret)
+  {
+    if (ret == null)
+      ret = new Rectangle();
+    ret.setBounds(base.x + insets.left, base.y + insets.top,
+                  base.width - (insets.left + insets.right),
+                  base.height - (insets.top + insets.bottom));
+    return ret;
+  }
+
+  /**
+   * Calculates the portion of the component's bounds which is inside the
+   * component's border insets. This area is usually the area a component
+   * should confine its painting to. The coordinates are returned in terms
+   * of the <em>component's</em> coordinate system, where (0,0) is the
+   * upper left corner of the component's bounds.
+   *
+   * @param c The component to measure the bounds of
+   * @param r A Rectangle to store the return value in, or
+   * <code>null</code>
+   *
+   * @return The calculated area inside the component and its border
+   * insets
+   *
+   * @see #calculateInsetArea
+   */
+  public static Rectangle calculateInnerArea(JComponent c, Rectangle r)
+  {
+    Rectangle b = getLocalBounds(c);
+    return calculateInsetArea(b, c.getInsets(), r);
+  }
+
+  /**
+   * Calculates the bounds of a component in the component's own coordinate
+   * space. The result has the same height and width as the component's
+   * bounds, but its location is set to (0,0).
+   *
+   * @param aComponent The component to measure
+   *
+   * @return The component's bounds in its local coordinate space
+   */
+  public static Rectangle getLocalBounds(Component aComponent)
+  {
+    Rectangle bounds = aComponent.getBounds();
+    return new Rectangle(0, 0, bounds.width, bounds.height);
+  }
+
+  /**
+   * Returns the font metrics object for a given font. The metrics can be
+   * used to calculate crude bounding boxes and positioning information,
+   * for laying out components with textual elements.
+   *
+   * @param font The font to get metrics for
+   *
+   * @return The font's metrics
+   *
+   * @see java.awt.font.GlyphMetrics
+   */
+  public static FontMetrics getFontMetrics(Font font)
+  {
+    return Toolkit.getDefaultToolkit().getFontMetrics(font);
+  }
+
+  /**
+   * If <code>comp</code> is a RootPaneContainer, return its JRootPane.
+   * Otherwise call <code>getAncestorOfClass(JRootPane.class, a)</code>.
+   *
+   * @param comp The component to get the JRootPane of
+   *
+   * @return a suitable JRootPane for <code>comp</code>, or <code>null</code>
+   * 
+   * @see javax.swing.RootPaneContainer#getRootPane
+   * @see #getAncestorOfClass
+   */
+  public static JRootPane getRootPane(Component comp)
+  {
+    if (comp instanceof RootPaneContainer)
+      return ((RootPaneContainer)comp).getRootPane();
+    else
+      return (JRootPane) getAncestorOfClass(JRootPane.class, comp);
+  }
+
+  /**
+   * Returns the least ancestor of <code>comp</code> which has the
+   * specified name.
+   *
+   * @param name The name to search for
+   * @param comp The component to search the ancestors of
+   *
+   * @return The nearest ancestor of <code>comp</code> with the given
+   * name, or <code>null</code> if no such ancestor exists
+   *
+   * @see java.awt.Component#getName
+   * @see #getAncestorOfClass
+   */
+  public static Container getAncestorNamed(String name, Component comp)
+  {
+    while (comp != null && (comp.getName() != name))
+      comp = comp.getParent();
+    return (Container) comp;
+  }
+
+  /**
+   * Returns the least ancestor of <code>comp</code> which is an instance
+   * of the specified class.
+   *
+   * @param c The class to search for
+   * @param comp The component to search the ancestors of
+   *
+   * @return The nearest ancestor of <code>comp</code> which is an instance
+   * of the given class, or <code>null</code> if no such ancestor exists
+   *
+   * @see #getAncestorOfClass
+   * @see #windowForComponent
+   */
+  public static Container getAncestorOfClass(Class c, Component comp)
+  {
+    while (comp != null && (! c.isInstance(comp)))
+      comp = comp.getParent();
+    return (Container) comp;
+  }
+
+  /**
+   * Equivalent to calling <code>getAncestorOfClass(Window, comp)</code>.
+   *
+   * @param comp The component to search for an ancestor window 
+   *
+   * @return An ancestral window, or <code>null</code> if none exists
+   */
+  public static Window windowForComponent(Component comp)
   {
-    return Toolkit.getDefaultToolkit ().getFontMetrics (font);
+    return (Window) getAncestorOfClass(Window.class, comp);
   }
 
-  public static JRootPane getRootPane (Component a)
+  /**
+   * Returns the "root" of the component tree containint <code>comp</code>
+   * The root is defined as either the <em>least</em> ancestor of
+   * <code>comp</code> which is a {@link Window}, or the <em>greatest</em>
+   * ancestor of <code>comp</code> which is a {@link Applet} if no {@link
+   * Window} ancestors are found.
+   *
+   * @param comp The component to search for a root
+   *
+   * @return The root of the component's tree, or <code>null</code>
+   */
+  public static Component getRoot(Component comp)
   {
-    if (a instanceof JRootPane)
-      return (JRootPane) a;
-	
-    a = a.getParent();
+    Applet app = null;
+    Window win = null;
 
-    if (a != null)
+    while (comp != null)
       {
-        return getRootPane(a);
+        if (win == null && comp instanceof Window)
+          win = (Window) comp;
+        else if (comp instanceof Applet)
+          app = (Applet) comp;
+        comp = comp.getParent();
+      }
+
+    if (win != null)
+      return win;
+    else
+      return app;
+  }
+
+  /**
+   * Return true if a descends from b, in other words if b is an
+   * ancestor of a.
+   *
+   * @param a The child to search the ancestry of
+   * @param b The potential ancestor to search for
+   *
+   * @return true if a is a descendent of b, false otherwise
+   */
+  public static boolean isDescendingFrom(Component a, Component b)
+  {
+    while (true)
+      {
+        if (a == null || b == null)
+          return false;
+        if (a == b)
+          return true;
+        a = a.getParent();
       }
-    
-    return null;
   }
 
-  public static void updateComponentTreeUI(JFrame comp)
+  /**
+   * Returns the deepest descendent of parent which is both visible and
+   * contains the point <code>(x,y)</code>. Returns parent when either
+   * parent is not a container, or has no children which contain
+   * <code>(x,y)</code>. Returns <code>null</code> when either
+   * <code>(x,y)</code> is outside the bounds of parent, or parent is
+   * <code>null</code>.
+   * 
+   * @param parent The component to search the descendents of
+   * @param x Horizontal coordinate to search for
+   * @param y Vertical coordinate to search for
+   *
+   * @return A component containing <code>(x,y)</code>, or
+   * <code>null</code>
+   *
+   * @see java.awt.Container#findComponentAt
+   */
+  public static Component getDeepestComponentAt(Component parent, int x, int y)
   {
+    if (parent == null || (! parent.contains(x, y)))
+      return null;
+
+    if (! (parent instanceof Container))
+      return parent;
+
+    Container c = (Container) parent;
+    return c.findComponentAt(x, y);
   }
 
+  /**
+   * Converts a point from a component's local coordinate space to "screen"
+   * coordinates (such as the coordinate space mouse events are delivered
+   * in). This operation is equivalent to translating the point by the
+   * location of the component (which is the origin of its coordinate
+   * space).
+   *
+   * @param p The point to convert
+   * @param c The component which the point is expressed in terms of
+   *
+   * @see convertPointFromScreen
+   */
+  public static void convertPointToScreen(Point p, Component c)
+  {
+    Point c0 = c.getLocationOnScreen();
+    p.translate(c0.x, c0.y);
+  }
+
+  /**
+   * Converts a point from "screen" coordinates (such as the coordinate
+   * space mouse events are delivered in) to a component's local coordinate
+   * space. This operation is equivalent to translating the point by the
+   * negation of the component's location (which is the origin of its
+   * coordinate space).
+   *
+   * @param p The point to convert
+   * @param c The component which the point should be expressed in terms of
+   */
+  public static void convertPointFromScreen(Point p, Component c)
+  {
+    Point c0 = c.getLocationOnScreen();
+    p.translate(-c0.x, -c0.y);
+  }
+
+  /**
+   * Converts a point <code>(x,y)</code> from the coordinate space of one
+   * component to another. This is equivalent to converting the point from
+   * <code>source</code> space to screen space, then back from screen space
+   * to <code>destination</code> space. If exactly one of the two
+   * Components is <code>null</code>, it is taken to refer to the root
+   * ancestor of the other component. If both are <code>null</code>, no
+   * transformation is done.
+   *
+   * @param source The component which the point is expressed in terms of
+   * @param x Horizontal coordinate of point to transform
+   * @param y Vertical coordinate of point to transform
+   * @param destination The component which the return value will be
+   * expressed in terms of
+   *
+   * @return The point <code>(x,y)</code> converted from the coordinate space of the
+   * source component to the coordinate space of the destination component
+   *
+   * @see #convertPointToScreen
+   * @see #convertPointFromScreen
+   * @see #convertRectangle
+   * @see #getRoot
+   */
+  public static Point convertPoint(Component source, int x, int y,
+                                   Component destination)
+  {
+    Point pt = new Point(x, y);
+
+    if (source == null && destination == null)
+      return pt;
+
+    if (source == null)
+      source = getRoot(destination);
+
+    if (destination == null)
+      destination = getRoot(source);
+
+    convertPointToScreen(pt, source);
+    convertPointFromScreen(pt, destination);
+
+    return pt;
+  }
+  
+  public static Point convertPoint(Component source, Point aPoint, Component destination)
+  {
+    return convertPoint(source, aPoint.x, aPoint.y, destination);
+  }
+
+  /**
+   * Converts a rectangle from the coordinate space of one component to
+   * another. This is equivalent to converting the rectangle from
+   * <code>source</code> space to screen space, then back from screen space
+   * to <code>destination</code> space. If exactly one of the two
+   * Components is <code>null</code>, it is taken to refer to the root
+   * ancestor of the other component. If both are <code>null</code>, no
+   * transformation is done.
+   *
+   * @param source The component which the rectangle is expressed in terms of
+   * @param rect The rectangle to convert
+   * @param destination The component which the return value will be
+   * expressed in terms of
+   *
+   * @return A new rectangle, equal in size to the input rectangle, but
+   * with its position converted from the coordinate space of the source
+   * component to the coordinate space of the destination component
+   *
+   * @see #convertPointToScreen
+   * @see #convertPointFromScreen
+   * @see #convertPoint
+   * @see #getRoot
+   */
+  public static Rectangle convertRectangle(Component source,
+                                           Rectangle rect,
+                                           Component destination)
+  {
+    Point pt = convertPoint(source, rect.x, rect.y, destination);
+    return new Rectangle(pt.x, pt.y, rect.width, rect.height);
+  }
+
+  /**
+   * Convert a mouse event which refrers to one component to another.  This
+   * includes changing the mouse event's coordinate space, as well as the
+   * source property of the event. If <code>source</code> is
+   * <code>null</code>, it is taken to refer to <code>destination</code>'s
+   * root component. If <code>destination</code> is <code>null</code>, the
+   * new event will remain expressed in <code>source</code>'s coordinate
+   * system.
+   *
+   * @param source The component the mouse event currently refers to
+   * @param sourceEvent The mouse event to convert
+   * @param destination The component the new mouse event should refer to
+   *
+   * @return A new mouse event expressed in terms of the destination
+   * component's coordinate space, and with the destination component as
+   * its source
+   *
+   * @see #convertPoint
+   */
+  public static MouseEvent convertMouseEvent(Component source,
+                                             MouseEvent sourceEvent,
+                                             Component destination)
+  {
+    Point newpt = convertPoint(source, sourceEvent.getX(), sourceEvent.getY(),
+                               destination);
+
+    return new MouseEvent(destination, sourceEvent.getID(),
+                          sourceEvent.getWhen(), sourceEvent.getModifiersEx(),
+                          newpt.x, newpt.y, sourceEvent.getClickCount(),
+                          sourceEvent.isPopupTrigger(), sourceEvent.getButton());
+  }
+
+  /**
+   * Recursively walk the component tree under <code>comp</code> calling
+   * <code>updateUI</code> on each {@link JComponent} found. This causes
+   * the entire tree to re-initialize its UI delegates.
+   *
+   * @param comp The component to walk the children of, calling <code>updateUI</code>
+   */
+  public static void updateComponentTreeUI(Component comp)
+  {
+    if (comp == null)
+      return;
+    
+    if (comp instanceof Container)
+      {
+        Component[] children = ((Container)comp).getComponents();
+        for (int i = 0; i < children.length; ++i)
+          updateComponentTreeUI(children[i]);
+      }
+
+    if (comp instanceof JComponent)
+      ((JComponent)comp).updateUI();
+  }
+
+
+  /**
+   * <p>Layout a "compound label" consisting of a text string and an icon
+   * which is to be placed near the rendered text. Once the text and icon
+   * are laid out, the text rectangle and icon rectangle parameters are
+   * altered to store the calculated positions.</p>
+   *
+   * <p>The size of the text is calculated from the provided font metrics
+   * object.  This object should be the metrics of the font you intend to
+   * paint the label with.</p>
+   *
+   * <p>The position values control where the text is placed relative to
+   * the icon. The horizontal position value should be one of the constants
+   * <code>LEADING</code>, <code>TRAILING</code>, <code>LEFT</code>,
+   * <code>RIGHT</code> or <code>CENTER</code>. The vertical position value
+   * should be one fo the constants <code>TOP</code>, <code>BOTTOM</code>
+   * or <code>CENTER</code>.</p>
+   *
+   * <p>The text-icon gap value controls the number of pixels between the
+   * icon and the text.</p>
+   *
+   * <p>The alignment values control where the text and icon are placed, as
+   * a combined unit, within the view rectangle. The horizontal alignment
+   * value should be one of the constants <code>LEADING</code>,
+   * <code>TRAILING</code>, <code>LEFT</code>, <code>RIGHT</code> or
+   * <code>CENTER</code>. The vertical alignment valus should be one of the
+   * constants <code>TOP</code>, <code>BOTTOM</code> or
+   * <code>CENTER</code>.</p>
+   *
+   * <p>If the <code>LEADING</code> or <code>TRAILING</code> constants are
+   * given for horizontal alignment or horizontal text position, they are
+   * interpreted relative to the provided component's orientation property,
+   * a constant in the {@link java.awt.ComponentOrientation} class. For
+   * example, if the component's orientation is <code>LEFT_TO_RIGHT</code>,
+   * then the <code>LEADING</code> value is a synonym for <code>LEFT</code>
+   * and the <code>TRAILING</code> value is a synonym for
+   * <code>RIGHT</code></p>
+   *
+   * <p>If the text and icon are equal to or larger than the view
+   * rectangle, the horizontal and vertical alignment values have no
+   * affect.</p>
+   *
+   * @param c A component used for its orientation value
+   * @param fm The font metrics used to measure the text
+   * @param text The text to place in the compound label
+   * @param icon The icon to place next to the text
+   * @param verticalAlignment The vertical alignment of the label relative
+   * to its component
+   * @param horizontalAlignment The horizontal alignment of the label
+   * relative to its component
+   * @param verticalTextPosition The vertical position of the label's text
+   * relative to its icon
+   * @param horizontalTextPosition The horizontal position of the label's
+   * text relative to its icon
+   * @param viewR The view rectangle, specifying the area which layout is
+   * constrained to
+   * @param iconR A rectangle which is modified to hold the laid-out
+   * position of the icon
+   * @param textR A rectangle which is modified to hold the laid-out
+   * position of the text
+   * @param textIconGap The distance between text and icon
+   *
+   * @return The string of characters, possibly truncated with an elipsis,
+   * which is laid out in this label
+   */
+
   public static String layoutCompoundLabel(JComponent c, 
                                            FontMetrics fm,
+                                           String text, 
+                                           Icon icon, 
+                                           int verticalAlignment,
+                                           int horizontalAlignment, 
+                                           int verticalTextPosition,
+                                           int horizontalTextPosition, 
+                                           Rectangle viewR,
+                                           Rectangle iconR, 
+                                           Rectangle textR, 
+                                           int textIconGap)
+  {
+
+    // Fix up the orientation-based horizontal positions.
+
+    if (horizontalTextPosition == LEADING)
+      {
+        if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
+          horizontalTextPosition = RIGHT;
+        else
+          horizontalTextPosition = LEFT;
+      }
+    else if (horizontalTextPosition == TRAILING)
+      {
+        if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
+          horizontalTextPosition = LEFT;
+        else
+          horizontalTextPosition = RIGHT;
+      }
+
+    // Fix up the orientation-based alignments.
+
+    if (horizontalAlignment == LEADING)
+      {
+        if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
+          horizontalAlignment = RIGHT;
+        else
+          horizontalAlignment = LEFT;
+      }
+    else if (horizontalAlignment == TRAILING)
+      {
+        if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
+          horizontalAlignment = LEFT;
+        else
+          horizontalAlignment = RIGHT;
+      }
+    
+    return layoutCompoundLabel(fm, text, icon,
+                               verticalAlignment,
+                               horizontalAlignment,
+                               verticalTextPosition,
+                               horizontalTextPosition,
+                               viewR, iconR, textR, textIconGap);
+  }
+
+  /**
+   * <p>Layout a "compound label" consisting of a text string and an icon
+   * which is to be placed near the rendered text. Once the text and icon
+   * are laid out, the text rectangle and icon rectangle parameters are
+   * altered to store the calculated positions.</p>
+   *
+   * <p>The size of the text is calculated from the provided font metrics
+   * object.  This object should be the metrics of the font you intend to
+   * paint the label with.</p>
+   *
+   * <p>The position values control where the text is placed relative to
+   * the icon. The horizontal position value should be one of the constants
+   * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>. The
+   * vertical position value should be one fo the constants
+   * <code>TOP</code>, <code>BOTTOM</code> or <code>CENTER</code>.</p>
+   *
+   * <p>The text-icon gap value controls the number of pixels between the
+   * icon and the text.</p>
+   *
+   * <p>The alignment values control where the text and icon are placed, as
+   * a combined unit, within the view rectangle. The horizontal alignment
+   * value should be one of the constants <code>LEFT</code>, <code>RIGHT</code> or
+   * <code>CENTER</code>. The vertical alignment valus should be one of the
+   * constants <code>TOP</code>, <code>BOTTOM</code> or
+   * <code>CENTER</code>.</p>
+   *
+   * <p>If the text and icon are equal to or larger than the view
+   * rectangle, the horizontal and vertical alignment values have no
+   * affect.</p>
+   *
+   * <p>Note that this method does <em>not</em> know how to deal with
+   * horizontal alignments or positions given as <code>LEADING</code> or
+   * <code>TRAILING</code> values. Use the other overloaded variant of this
+   * method if you wish to use such values.
+   *
+   * @param fm The font metrics used to measure the text
+   * @param text The text to place in the compound label
+   * @param icon The icon to place next to the text
+   * @param verticalAlignment The vertical alignment of the label relative
+   * to its component
+   * @param horizontalAlignment The horizontal alignment of the label
+   * relative to its component
+   * @param verticalTextPosition The vertical position of the label's text
+   * relative to its icon
+   * @param horizontalTextPosition The horizontal position of the label's
+   * text relative to its icon
+   * @param viewR The view rectangle, specifying the area which layout is
+   * constrained to
+   * @param iconR A rectangle which is modified to hold the laid-out
+   * position of the icon
+   * @param textR A rectangle which is modified to hold the laid-out
+   * position of the text
+   * @param textIconGap The distance between text and icon
+   *
+   * @return The string of characters, possibly truncated with an elipsis,
+   * which is laid out in this label
+   */
+
+  public static String layoutCompoundLabel(FontMetrics fm,
                                            String text,
-                                           Icon i,
-                                           int vert_a, 
-                                           int hor_i, 
-                                           int vert_text_pos,
-                                           int hor_text_pos, 
-                                           Rectangle vr,
-                                           Rectangle ir, 
-                                           Rectangle tr,
-                                           int gap)
-  {
-    // view rect 'vr' already ok, 
-    // we need to compute ir (icon rect) and tr (text-rect)
-	
-    int next_x = 0;//vr.x;
-    int next_y = 0;//vr.y;
-	
-    ir.height = ir.width = ir.y = ir.x = 0;
-
-    if (i != null)
-      {
-        ir.x = vr.x;
-        ir.y = vr.y;
-        ir.width = i.getIconWidth();
-        ir.height = i.getIconWidth();
-
-
-        next_x += gap + i.getIconWidth();
-        next_y += gap + i.getIconHeight();
-      }
-	
-    tr.x = next_x;
-    tr.y = vr.y + (vr.height/2);
+                                           Icon icon,
+                                           int verticalAlignment,
+                                           int horizontalAlignment,
+                                           int verticalTextPosition,
+                                           int horizontalTextPosition,
+                                           Rectangle viewR,
+                                           Rectangle iconR,
+                                           Rectangle textR,
+                                           int textIconGap)
+  {
+
+    // Work out basic height and width.
+
+    if (icon == null)
+      {
+        textIconGap = 0;
+        iconR.width = 0;
+        iconR.height = 0;
+      }
+    else
+      {
+        iconR.width = icon.getIconWidth();
+        iconR.height = icon.getIconHeight();
+      }
+    if (text == null)
+      {
+        textIconGap = 0;
+	textR.width = 0;
+	textR.height = 0;
+      }
+    else
+      {
+        textR.width = fm.stringWidth(text);
+        textR.height = fm.getHeight(); 
+      }
+
+    // Work out the position of text and icon, assuming the top-left coord
+    // starts at (0,0). We will fix that up momentarily, after these
+    // "position" decisions are made and we look at alignment.
+
+    switch (horizontalTextPosition)
+      {
+      case LEFT:
+        textR.x = 0;
+        iconR.x = textR.width + textIconGap;
+        break;
+      case RIGHT:
+        iconR.x = 0;
+        textR.x = iconR.width + textIconGap;
+        break;
+      case CENTER:
+        int centerLine = Math.max(textR.width, iconR.width) / 2;
+        textR.x = centerLine - textR.width/2;
+        iconR.x = centerLine - iconR.width/2;
+        break;
+      }
+
+    switch (verticalTextPosition)
+      {
+      case TOP:
+        textR.y = 0;
+        iconR.y = (horizontalTextPosition == CENTER 
+                   ? textR.height + textIconGap : 0);
+        break;
+      case BOTTOM:
+        iconR.y = 0;
+        textR.y = (horizontalTextPosition == CENTER
+                   ? iconR.height + textIconGap 
+                   : iconR.height - textR.height);
+        break;
+      case CENTER:
+        int centerLine = Math.max(textR.height, iconR.height) / 2;
+        textR.y = centerLine - textR.height/2;
+        iconR.y = centerLine - iconR.height/2;
+        break;
+      }
+    // The two rectangles are laid out correctly now, but only assuming
+    // that their upper left corner is at (0,0). If we have any alignment other
+    // than TOP and LEFT, we need to adjust them.
+
+    Rectangle u = textR.union(iconR);
+    int horizontalAdjustment = viewR.x;
+    int verticalAdjustment = viewR.y;
+    switch (verticalAlignment)
+      {
+      case TOP:
+        break;
+      case BOTTOM:
+        verticalAdjustment += (viewR.height - u.height);
+        break;
+      case CENTER:
+        verticalAdjustment += ((viewR.height/2) - (u.height/2));
+        break;
+      }
+    switch (horizontalAlignment)
+      {
+      case LEFT:
+        break;
+      case RIGHT:
+        horizontalAdjustment += (viewR.width - u.width);
+        break;
+      case CENTER:
+        horizontalAdjustment += ((viewR.width/2) - (u.width/2));
+        break;
+      }
 
-    tr.width  = fm.stringWidth(text);
-    tr.height = fm.getHeight() +  fm.getAscent()/2;
+    iconR.x += horizontalAdjustment;
+    iconR.y += verticalAdjustment;
+
+    textR.x += horizontalAdjustment;
+    textR.y += verticalAdjustment;
 
     return text;
   }
 
-}
+  /** 
+   * Calls {@link java.awt.EventQueue.invokeLater} with the
+   * specified {@link Runnable}. 
+   */
+  public static void invokeLater(Runnable doRun)
+  {
+    java.awt.EventQueue.invokeLater(doRun);
+  }
 
+  /** 
+   * Calls {@link java.awt.EventQueue.invokeAndWait} with the
+   * specified {@link Runnable}. 
+   */
+  public static void invokeAndWait(Runnable doRun)
+    throws InterruptedException,
+    InvocationTargetException
+  {
+    java.awt.EventQueue.invokeAndWait(doRun);
+  }
 
+  /** 
+   * Calls {@link java.awt.EventQueue.isEventDispatchThread}.
+   */
+  public static boolean isEventDispatchThread()
+  {
+    return java.awt.EventQueue.isDispatchThread();
+  }
+  
+  /**
+   * This method paints the given component at the given position and size.
+   * The component will be reparented to the container given.
+   * 
+   * @param g The Graphics object to draw with.
+   * @param c The Component to draw
+   * @param p The Container to reparent to.
+   * @param x The x coordinate to draw at.
+   * @param y The y coordinate to draw at.
+   * @param w The width of the drawing area.
+   * @param h The height of the drawing area.
+   */
+  public static void paintComponent(Graphics g, Component c, Container p, 
+                                    int x, int y, int w, int h)
+  {       
+    Container parent = c.getParent();
+    if (parent != null)
+      parent.remove(c);
+    if (p != null)
+      p.add(c);
+    
+    Shape savedClip = g.getClip();
+    
+    g.setClip(x, y, w, h);
+    g.translate(x, y);
 
+    c.paint(g);
+    
+    g.translate(-x, -y);
+    g.setClip(savedClip);
+  }
 
+  /**
+   * This method paints the given component in the given rectangle.
+   * The component will be reparented to the container given.
+   * 
+   * @param g The Graphics object to draw with.
+   * @param c The Component to draw
+   * @param p The Container to reparent to.
+   * @param r The rectangle that describes the drawing area.
+   */  
+  public static void paintComponent(Graphics g, Component c, 
+                                    Container p, Rectangle r)
+  {
+    paintComponent(g, c, p, r.x, r.y, r.width, r.height);
+  }
+  
+  /**
+   * This method returns the common Frame owner used in JDialogs or
+   * JWindow when no owner is provided.
+   *
+   * @return The common Frame 
+   */
+  static Frame getOwnerFrame()
+  {
+    if (ownerFrame == null)
+      ownerFrame = new OwnerFrame();
+    return ownerFrame;
+  }
 
+  /**
+   * Checks if left mouse button was clicked.
+   *
+   * @param event the event to check
+   *
+   * @return true if left mouse was clicked, false otherwise.
+   */
+  public static boolean isLeftMouseButton(MouseEvent event)
+  {
+    return ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK)
+	     == InputEvent.BUTTON1_DOWN_MASK);
+  }
 
+  /**
+   * Checks if middle mouse button was clicked.
+   *
+   * @param event the event to check
+   *
+   * @return true if middle mouse was clicked, false otherwise.
+   */
+  public static boolean isMiddleMouseButton(MouseEvent event)
+  {
+    return ((event.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK)
+	     == InputEvent.BUTTON2_DOWN_MASK);
+  }
 
+  /**
+   * Checks if right mouse button was clicked.
+   *
+   * @param event the event to check
+   *
+   * @return true if right mouse was clicked, false otherwise.
+   */
+  public static boolean isRightMouseButton(MouseEvent event)
+  {
+    return ((event.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK)
+	     == InputEvent.BUTTON3_DOWN_MASK);
+  }
+  
+  /**
+   * This frame should be used when constructing a Window/JDialog without
+   * a parent. In this case, we are forced to use this frame as a window's
+   * parent, because we simply cannot pass null instead of parent to Window
+   * constructor, since doing it will result in NullPointerException.
+   */
+  private static class OwnerFrame extends Frame
+  {
+    public void setVisible(boolean b)
+    {
+      // Do nothing here. 
+    }
+    
+    public boolean isShowing()
+    {
+      return true;
+    }
+  }
 
+  public static boolean notifyAction(Action action,
+                                     KeyStroke ks,
+                                     KeyEvent event,
+                                     Object sender,
+                                     int modifiers)
+  {
+    if (action != null && action.isEnabled())
+      {
+        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
+        if (name == null
+            && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED)
+          name = new String(new char[] {event.getKeyChar()});
+        action.actionPerformed(new ActionEvent(sender,
+                                               ActionEvent.ACTION_PERFORMED,
+                                               name, modifiers));
+        return true;
+      }
+    return false;
+  }
 
+  /**
+   * <p>Change the shared, UI-managed {@link ActionMap} for a given
+   * component. ActionMaps are arranged in a hierarchy, in order to
+   * encourage sharing of common actions between components. The hierarchy
+   * unfortunately places UI-managed ActionMaps at the <em>end</em> of the
+   * parent-pointer chain, as illustrated:</p>
+   *
+   * <pre>
+   *  [{@link javax.swing.JComponent#getActionMap()}] 
+   *          --&gt; [{@link javax.swing.ActionMap}] 
+   *     parent --&gt; [{@link javax.swing.text.KeymapActionMap}] 
+   *       parent --&gt; [{@link javax.swing.plaf.ActionMapUIResource}]
+   * </pre>
+   *
+   * <p>Our goal with this method is to replace the first ActionMap along
+   * this chain which is an instance of {@link ActionMapUIResource}, since
+   * these are the ActionMaps which are supposed to be shared between
+   * components.</p>
+   *
+   * <p>If the provided ActionMap is <code>null</code>, we interpret the
+   * call as a request to remove the UI-managed ActionMap from the
+   * component's ActionMap parent chain.</p>
+   */
+  public static void replaceUIActionMap(JComponent component, 
+                                        ActionMap uiActionMap)
+  {
+    ActionMap child = component.getActionMap();
+    if (child == null)
+      component.setActionMap(uiActionMap);
+    else
+      {
+        while(child.getParent() != null
+              && !(child.getParent() instanceof ActionMapUIResource))
+          child = child.getParent();
+        if (child != null)
+          child.setParent(uiActionMap);
+      }
+  }
+
+  /**
+   * <p>Change the shared, UI-managed {@link InputMap} for a given
+   * component. InputMaps are arranged in a hierarchy, in order to
+   * encourage sharing of common input mappings between components. The
+   * hierarchy unfortunately places UI-managed InputMaps at the
+   * <em>end</em> of the parent-pointer chain, as illustrated:</p>
+   *
+   * <pre>
+   *  [{@link javax.swing.JComponent#getInputMap()}] 
+   *          --&gt; [{@link javax.swing.InputMap}] 
+   *     parent --&gt; [{@link javax.swing.text.KeymapWrapper}] 
+   *       parent --&gt; [{@link javax.swing.plaf.InputMapUIResource}]
+   * </pre>
+   *
+   * <p>Our goal with this method is to replace the first InputMap along
+   * this chain which is an instance of {@link InputMapUIResource}, since
+   * these are the InputMaps which are supposed to be shared between
+   * components.</p>
+   *
+   * <p>If the provided InputMap is <code>null</code>, we interpret the
+   * call as a request to remove the UI-managed InputMap from the
+   * component's InputMap parent chain.</p>
+   */
+  public static void replaceUIInputMap(JComponent component, 
+                                       int condition, 
+                                       InputMap uiInputMap)
+  {
+    InputMap child = component.getInputMap(condition);
+    if (child == null)
+      component.setInputMap(condition, uiInputMap);
+    else
+      {
+        while(child.getParent() != null
+              && !(child.getParent() instanceof InputMapUIResource))
+          child = child.getParent();
+        if (child != null)
+          child.setParent(uiInputMap);
+      }
+  }
+}
Index: javax/swing/Timer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/Timer.java,v
retrieving revision 1.3
diff -u -r1.3 Timer.java
--- javax/swing/Timer.java	24 Jun 2003 09:48:40 -0000	1.3
+++ javax/swing/Timer.java	6 Sep 2004 16:36:01 -0000
@@ -1,5 +1,5 @@
-/* Timer.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* Timer.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,146 +35,370 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.Serializable;
 import java.util.EventListener;
-import java.util.Vector;
 import javax.swing.event.EventListenerList;
 
+
+/**
+ * DOCUMENT ME!
+ */
 public class Timer implements Serializable
 {
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = -1116180831621385484L;
+
+  /** DOCUMENT ME! */
   protected EventListenerList listenerList = new EventListenerList();
-  
-  int ticks;
-  static boolean verbose;
+
+  // This object manages a "queue" of virtual actionEvents, maintained as a
+  // simple long counter. When the timer expires, a new event is queued,
+  // and a dispatcher object is pushed into the system event queue. When
+  // the system thread runs the dispatcher, it will fire as many
+  // ActionEvents as have been queued, unless the timer is set to
+  // coalescing mode, in which case it will fire only one ActionEvent.
+
+  /** DOCUMENT ME! */
+  private long queue;
+
+  /** DOCUMENT ME! */
+  private Object queueLock = new Object();
+
+  /** DOCUMENT ME! */
+  private Waker waker;
+
+  /**
+   * DOCUMENT ME!
+   */
+  private void queueEvent()
+  {
+    synchronized (queueLock)
+      {
+	queue++;
+	if (queue == 1)
+	  SwingUtilities.invokeLater(new Runnable()
+	      {
+		public void run()
+		{
+		  drainEvents();
+		}
+	      });
+
+      }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  private void drainEvents()
+  {
+    synchronized (queueLock)
+      {
+	if (isCoalesce())
+	  {
+	    if (queue > 0)
+	      fireActionPerformed();
+	  }
+	else
+	  {
+	    while (queue > 0)
+	      {
+		fireActionPerformed();
+		queue--;
+	      }
+	  }
+	queue = 0;
+      }
+  }
+
+  static boolean logTimers;
+
+  /** DOCUMENT ME! */
+  boolean coalesce = true;
+
+  /** DOCUMENT ME! */
+  boolean repeats = true;
+
+  /** DOCUMENT ME! */
   boolean running;
-  boolean repeat_ticks = true;
-  long interval, init_delay;
-    
-  class Waker extends Thread
+
+  /** DOCUMENT ME! */
+  int ticks;
+
+  /** DOCUMENT ME! */
+  int delay;
+
+  /** DOCUMENT ME! */
+  int initialDelay;
+
+  /**
+   * DOCUMENT ME!
+   */
+  private class Waker extends Thread
   {
+    /**
+     * DOCUMENT ME!
+     */
     public void run()
     {
       running = true;
-      try {
-	sleep(init_delay);
-		
-	while (running)
-	  {
-	    sleep(interval);
+      try
+        {
+	  sleep(initialDelay);
+
+	  while (running)
+	    {
+	      try
+	        {
+		  sleep(delay);
+	        }
+	      catch (InterruptedException e)
+	        {
+		  return;
+	        }
+	      queueEvent();
 
-	    if (verbose)
-	      {
+	      if (logTimers)
 		System.out.println("javax.swing.Timer -> clocktick");
-	      }
 
-	    ticks++;
-	    fireActionPerformed();
-  
-	    if (! repeat_ticks)
-	      break;
-	  }
-	running = false;
-      } catch (Exception e) {
-	System.out.println("swing.Timer::" + e);
-      }
+	      if (! repeats)
+		break;
+	    }
+	  running = false;
+        }
+      catch (Exception e)
+        {
+//	  System.out.println("swing.Timer::" + e);
+        }
     }
   }
 
+  /**
+   * Creates a new Timer object.
+   *
+   * @param d DOCUMENT ME!
+   * @param listener DOCUMENT ME!
+   */
+  public Timer(int d, ActionListener listener)
+  {
+    delay = d;
+
+    if (listener != null)
+      addActionListener(listener);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param c DOCUMENT ME!
+   */
+  public void setCoalesce(boolean c)
+  {
+    coalesce = c;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isCoalesce()
+  {
+    return coalesce;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param listener DOCUMENT ME!
+   */
   public void addActionListener(ActionListener listener)
   {
-    listenerList.add (ActionListener.class, listener);
+    listenerList.add(ActionListener.class, listener);
   }
-  
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param listener DOCUMENT ME!
+   */
   public void removeActionListener(ActionListener listener)
   {
-    listenerList.remove (ActionListener.class, listener);
+    listenerList.remove(ActionListener.class, listener);
   }
 
   /**
+   * DOCUMENT ME!
+   *
+   * @param listenerType DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   *
    * @since 1.3
    */
-  public EventListener[] getListeners (Class listenerType)
+  public EventListener[] getListeners(Class listenerType)
   {
-    return listenerList.getListeners (listenerType);
+    return listenerList.getListeners(listenerType);
   }
-  
+
   /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   *
    * @since 1.4
    */
-  public ActionListener[] getActionListeners ()
+  public ActionListener[] getActionListeners()
   {
-    return (ActionListener[]) listenerList.getListeners (ActionListener.class);
+    return (ActionListener[]) listenerList.getListeners(ActionListener.class);
   }
 
-  protected void fireActionPerformed (ActionEvent event)
+  /**
+   * DOCUMENT ME!
+   *
+   * @param event DOCUMENT ME!
+   */
+  protected void fireActionPerformed(ActionEvent event)
   {
     ActionListener[] listeners = getActionListeners();
-    
+
     for (int i = 0; i < listeners.length; i++)
-      {
-	listeners [i].actionPerformed (event);
-      }
+      listeners[i].actionPerformed(event);
   }
 
-  void fireActionPerformed ()
+  /**
+   * DOCUMENT ME!
+   */
+  void fireActionPerformed()
   {
-    fireActionPerformed (new ActionEvent (this, ticks, "Timer"));
+    fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
   }
 
-  public static void setLogTimers(boolean flag)
+  /**
+   * DOCUMENT ME!
+   *
+   * @param lt DOCUMENT ME!
+   */
+  public static void setLogTimers(boolean lt)
   {
-    verbose = flag;
+    logTimers = lt;
   }
 
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
   public static boolean getLogTimers()
   {
-    return verbose;
+    return logTimers;
   }
-    
 
-  public void setDelay(int delay)
+  /**
+   * DOCUMENT ME!
+   *
+   * @param d DOCUMENT ME!
+   */
+  public void setDelay(int d)
   {
-    interval = delay;
+    delay = d;
   }
 
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
   public int getDelay()
   {
-    return (int)interval;
+    return delay;
   }
 
+  /**
+   * DOCUMENT ME!
+   *
+   * @param i DOCUMENT ME!
+   */
+  public void setInitialDelay(int i)
+  {
+    initialDelay = i;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public int getInitialDelay()
+  {
+    return initialDelay;
+  }
 
-  public void setInitialDelay(int initialDelay)
+  /**
+   * DOCUMENT ME!
+   *
+   * @param r DOCUMENT ME!
+   */
+  public void setRepeats(boolean r)
   {
-    init_delay = initialDelay;
+    repeats = r;
   }
 
-  public void setRepeats(boolean flag)
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isRepeats()
   {
-    repeat_ticks = flag;
+    return repeats;
   }
 
-  boolean isRunning()
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isRunning()
   {
     return running;
   }
 
-  void start()
+  /**
+   * DOCUMENT ME!
+   */
+  public void start()
   {
     if (isRunning())
-      {
-	System.err.println("attempt to start a running timer");
-	return;
-      }
-    new Waker().start();
+      return;
+    waker = new Waker();
+    waker.start();
   }
 
-  void stop()
+  /**
+   * DOCUMENT ME!
+   */
+  public void restart()
+  {
+    stop();
+    start();
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void stop()
   {
     running = false;
+    if (waker != null)
+      waker.interrupt();
+    synchronized (queueLock)
+      {
+	queue = 0;
+      }
   }
 }
Index: javax/swing/ToggleButtonModel.java
===================================================================
RCS file: javax/swing/ToggleButtonModel.java
diff -N javax/swing/ToggleButtonModel.java
--- javax/swing/ToggleButtonModel.java	19 Jun 2003 16:30:09 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,60 +0,0 @@
-/* ToggleButtonModel.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package javax.swing;
-
-public class ToggleButtonModel extends DefaultButtonModel
-{
-    ToggleButtonModel(JComponent c)
-    {
-	super(c);
-    }
-
-    public void setPressed(boolean b)  
-    {
-	if (! isEnabled())
-	    return;
-	
-	if (! b)
-	    {
-		return;
-	    }
-	
-	setSelected(b);
-    }
-}
Index: javax/swing/ToolTipManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ToolTipManager.java,v
retrieving revision 1.2
diff -u -r1.2 ToolTipManager.java
--- javax/swing/ToolTipManager.java	10 Jan 2004 21:07:43 -0000	1.2
+++ javax/swing/ToolTipManager.java	6 Sep 2004 16:36:01 -0000
@@ -37,358 +37,608 @@
 
 package javax.swing;
 
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Panel;
+import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.event.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseMotionListener;
+import javax.swing.JComponent;
+import javax.swing.Popup;
+import javax.swing.PopupFactory;
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+
 
 /**
- * ToolTipManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * This class is responsible for the registration of JToolTips to Components
+ * and for displaying them when appropriate.
  */
-public class ToolTipManager extends MouseAdapter implements MouseMotionListener {
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * stillInsideTimerAction
-	 */
-	protected class stillInsideTimerAction implements ActionListener {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor stillInsideTimerAction
-		 * @param manager TODO
-		 */
-		protected stillInsideTimerAction(ToolTipManager manager) {
-			// TODO
-		} // stillInsideTimerAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * actionPerformed
-		 * @param event TODO
-		 */
-		public void actionPerformed(ActionEvent event) {
-			// TODO
-		} // actionPerformed()
-
-
-	} // stillInsideTimerAction
-
-	/**
-	 * outsideTimerAction
-	 */
-	protected class outsideTimerAction implements ActionListener {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor outsideTimerAction
-		 * @param manager TODO
-		 */
-		protected outsideTimerAction(ToolTipManager manager) {
-			// TODO
-		} // outsideTimerAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * actionPerformed
-		 * @param value0 TODO
-		 */
-		public void actionPerformed(ActionEvent event) {
-			// TODO
-		} // actionPerformed()
-
-
-	} // outsideTimerAction
-
-	/**
-	 * insideTimerAction
-	 */
-	protected class insideTimerAction implements ActionListener {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor insideTimerAction
-		 * @param manager TODO
-		 */
-		protected insideTimerAction(ToolTipManager manager) {
-			// TODO
-		} // insideTimerAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * actionPerformed
-		 * @param event TODO
-		 */
-		public void actionPerformed(ActionEvent event) {
-			// TODO
-		} // actionPerformed()
-
-
-	} // insideTimerAction
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * enterTimer
-	 */
-	Timer enterTimer;
-
-	/**
-	 * exitTimer
-	 */
-	Timer exitTimer;
-
-	/**
-	 * insideTimer
-	 */
-	Timer insideTimer;
-
-	/**
-	 * toolTipText
-	 */
-	String toolTipText;
-
-	/**
-	 * mouseEvent
-	 */
-	MouseEvent mouseEvent;
-
-	/**
-	 * showImmediately
-	 */
-	boolean showImmediately;
-
-	/**
-	 * tip
-	 */
-	JToolTip tip;
-
-	/**
-	 * enabled
-	 */
-	boolean enabled;
-
-	/**
-	 * timerEnter
-	 */
-	private long timerEnter;
-
-	/**
-	 * lightWeightPopupEnabled
-	 */
-	protected boolean lightWeightPopupEnabled;
-
-	/**
-	 * heavyWeightPopupEnabled
-	 */
-	protected boolean heavyWeightPopupEnabled;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor ToolTipManager
-	 */
-	ToolTipManager() {
-		// TODO
-	} // ToolTipManager()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * sharedInstance
-	 * @returns ToolTipManager
-	 */
-	public static ToolTipManager sharedInstance() {
-		return null; // TODO
-	} // sharedInstance()
-
-	/**
-	 * setEnabled
-	 * @param enabled TODO
-	 */
-	public void setEnabled(boolean enabled) {
-		// TODO
-	} // setEnabled()
-
-	/**
-	 * isEnabled
-	 * @returns boolean
-	 */
-	public boolean isEnabled() {
-		return false; // TODO
-	} // isEnabled()
-
-	/**
-	 * isLightWeightPopupEnabled
-	 * @returns boolean
-	 */
-	public boolean isLightWeightPopupEnabled() {
-		return false; // TODO
-	} // isLightWeightPopupEnabled()
-
-	/**
-	 * setLightWeightPopupEnabled
-	 * @param enabled TODO
-	 */
-	public void setLightWeightPopupEnabled(boolean enabled) {
-		// TODO
-	} // setLightWeightPopupEnabled()
-
-	/**
-	 * getInitialDelay
-	 * @returns int
-	 */
-	public int getInitialDelay() {
-		return 0; // TODO
-	} // getInitialDelay()
-
-	/**
-	 * setInitialDelay
-	 * @param delay TODO
-	 */
-	public void setInitialDelay(int delay) {
-		// TODO
-	} // setInitialDelay()
-
-	/**
-	 * getDismissDelay
-	 * @returns int
-	 */
-	public int getDismissDelay() {
-		return 0; // TODO
-	} // getDismissDelay()
-
-	/**
-	 * setDismissDelay
-	 * @param delay TODO
-	 */
-	public void setDismissDelay(int delay) {
-		// TODO
-	} // setDismissDelay()
-
-	/**
-	 * getReshowDelay
-	 * @returns int
-	 */
-	public int getReshowDelay() {
-		return 0; // TODO
-	} // getReshowDelay()
-
-	/**
-	 * setReshowDelay
-	 * @param delay TODO
-	 */
-	public void setReshowDelay(int delay) {
-		// TODO
-	} // setReshowDelay()
-
-	/**
-	 * registerComponent
-	 * @param component TODO
-	 */
-	public void registerComponent(JComponent component) {
-		// TODO
-	} // registerComponent()
-
-	/**
-	 * unregisterComponent
-	 * @param component TODO
-	 */
-	public void unregisterComponent(JComponent component) {
-		// TODO
-	} // unregisterComponent()
-
-	/**
-	 * mouseEntered
-	 * @param event TODO
-	 */
-	public void mouseEntered(MouseEvent event) {
-		// TODO
-	} // mouseEntered()
-
-	/**
-	 * mouseExited
-	 * @param event TODO
-	 */
-	public void mouseExited(MouseEvent event) {
-		// TODO
-	} // mouseExited()
-
-	/**
-	 * mousePressed
-	 * @param event TODO
-	 */
-	public void mousePressed(MouseEvent event) {
-		// TODO
-	} // mousePressed()
-
-	/**
-	 * mouseDragged
-	 * @param event TODO
-	 */
-	public void mouseDragged(MouseEvent event) {
-		// TODO
-	} // mouseDragged()
-
-	/**
-	 * mouseMoved
-	 * @param event TODO
-	 */
-	public void mouseMoved(MouseEvent event) {
-		// TODO
-	} // mouseMoved()
-
-
-} // ToolTipManager
+public class ToolTipManager extends MouseAdapter implements MouseMotionListener
+{
+  /**
+   * This ActionListener is associated with the Timer that listens to whether
+   * the JToolTip can be hidden after four seconds.
+   */
+  protected class stillInsideTimerAction implements ActionListener
+  {
+    /**
+     * This method creates a new stillInsideTimerAction object.
+     */
+    protected stillInsideTimerAction()
+    {
+    }
+
+    /**
+     * This method hides the JToolTip when the Timer has finished.
+     *
+     * @param event The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent event)
+    {
+      hideTip();
+    }
+  }
+
+  /**
+   * This Actionlistener is associated with the Timer that listens to whether
+   * the mouse cursor has re-entered the JComponent in time for an immediate
+   * redisplay of the JToolTip.
+   */
+  protected class outsideTimerAction implements ActionListener
+  {
+    /**
+     * This method creates a new outsideTimerAction object.
+     */
+    protected outsideTimerAction()
+    {
+    }
+
+    /**
+     * This method is called when the Timer that listens to whether the mouse
+     * cursor has re-entered the JComponent has run out.
+     *
+     * @param event The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  /**
+   * This ActionListener is associated with the Timer that listens to whether
+   * it is time for the JToolTip to be displayed after the mouse has entered
+   * the JComponent.
+   */
+  protected class insideTimerAction implements ActionListener
+  {
+    /**
+     * This method creates a new insideTimerAction object.
+     */
+    protected insideTimerAction()
+    {
+    }
+
+    /**
+     * This method displays the JToolTip when the Mouse has been still for the
+     * delay.
+     *
+     * @param event The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent event)
+    {
+      showTip();
+      if (insideTimer != null)
+	insideTimer.start();
+    }
+  }
+
+  /**
+   * The Timer that determines whether the Mouse has been still long enough
+   * for the JToolTip to be displayed.
+   */
+  Timer enterTimer;
+
+  /**
+   * The Timer that determines whether the Mouse has re-entered the JComponent
+   * quickly enough for the JToolTip to be displayed immediately.
+   */
+  Timer exitTimer;
+
+  /**
+   * The Timer that determines whether the JToolTip has been displayed long
+   * enough for it to be hidden.
+   */
+  Timer insideTimer;
+
+  /** A global enabled setting for the ToolTipManager. */
+  private transient boolean enabled = true;
+
+  /** lightWeightPopupEnabled */
+  protected boolean lightWeightPopupEnabled = true;
+
+  /** heavyWeightPopupEnabled */
+  protected boolean heavyWeightPopupEnabled = false;
+
+  /** The shared instance of the ToolTipManager. */
+  private static ToolTipManager shared;
+
+  /** The current component the tooltip is being displayed for. */
+  private static Component currentComponent;
+
+  /** The current tooltip. */
+  private static JToolTip currentTip;
+
+  /** The last known position of the mouse cursor. */
+  private static Point currentPoint;
+
+  /**
+   * The panel that holds the tooltip when the tooltip is displayed fully
+   * inside the current container.
+   */
+  private static Container containerPanel;
+
+  /**
+   * The window used when the tooltip doesn't fit inside the current
+   * container.
+   */
+  private static JWindow tooltipWindow;
+
+  /**
+   * Creates a new ToolTipManager and sets up the timers.
+   */
+  ToolTipManager()
+  {
+    enterTimer = new Timer(750, new insideTimerAction());
+    enterTimer.setRepeats(false);
+
+    insideTimer = new Timer(4000, new stillInsideTimerAction());
+    insideTimer.setRepeats(false);
+
+    exitTimer = new Timer(500, new outsideTimerAction());
+    exitTimer.setRepeats(false);
+  }
+
+  /**
+   * This method returns the shared instance of ToolTipManager used by all
+   * JComponents.
+   *
+   * @return The shared instance of ToolTipManager.
+   */
+  public static ToolTipManager sharedInstance()
+  {
+    if (shared == null)
+      shared = new ToolTipManager();
+
+    return shared;
+  }
+
+  /**
+   * This method sets whether ToolTips are enabled or disabled for all
+   * JComponents.
+   *
+   * @param enabled Whether ToolTips are enabled or disabled for all
+   *        JComponents.
+   */
+  public void setEnabled(boolean enabled)
+  {
+    if (! enabled)
+      {
+	enterTimer.stop();
+	exitTimer.stop();
+	insideTimer.stop();
+      }
+
+    this.enabled = enabled;
+  }
+
+  /**
+   * This method returns whether ToolTips are enabled.
+   *
+   * @return Whether ToolTips are enabled.
+   */
+  public boolean isEnabled()
+  {
+    return enabled;
+  }
+
+  /**
+   * This method returns whether LightweightToolTips are enabled.
+   *
+   * @return Whether LighweightToolTips are enabled.
+   */
+  public boolean isLightWeightPopupEnabled()
+  {
+    return lightWeightPopupEnabled;
+  }
+
+  /**
+   * This method sets whether LightweightToolTips are enabled. If you mix
+   * Lightweight and Heavyweight components, you must set this to false to
+   * ensure that the ToolTips popup above all other components.
+   *
+   * @param enabled Whether LightweightToolTips will be enabled.
+   */
+  public void setLightWeightPopupEnabled(boolean enabled)
+  {
+    lightWeightPopupEnabled = enabled;
+    heavyWeightPopupEnabled = ! enabled;
+  }
+
+  /**
+   * This method returns the initial delay before the ToolTip is shown when
+   * the mouse enters a Component.
+   *
+   * @return The initial delay before the ToolTip is shown.
+   */
+  public int getInitialDelay()
+  {
+    return enterTimer.getDelay();
+  }
+
+  /**
+   * This method sets the initial delay before the ToolTip is shown when the
+   * mouse enters a Component.
+   *
+   * @param delay The initial delay before the ToolTip is shown.
+   */
+  public void setInitialDelay(int delay)
+  {
+    enterTimer.setDelay(delay);
+  }
+
+  /**
+   * This method returns the time the ToolTip will be shown before being
+   * hidden.
+   *
+   * @return The time the ToolTip will be shown before being hidden.
+   */
+  public int getDismissDelay()
+  {
+    return insideTimer.getDelay();
+  }
+
+  /**
+   * This method sets the time the ToolTip will be shown before being hidden.
+   *
+   * @param delay The time the ToolTip will be shown before being hidden.
+   */
+  public void setDismissDelay(int delay)
+  {
+    insideTimer.setDelay(delay);
+  }
+
+  /**
+   * This method returns the amount of delay where if the mouse re-enters a
+   * Component, the tooltip will be shown immediately.
+   *
+   * @return The reshow delay.
+   */
+  public int getReshowDelay()
+  {
+    return exitTimer.getDelay();
+  }
+
+  /**
+   * This method sets the amount of delay where if the mouse re-enters a
+   * Component, the tooltip will be shown immediately.
+   *
+   * @param delay The reshow delay.
+   */
+  public void setReshowDelay(int delay)
+  {
+    exitTimer.setDelay(delay);
+  }
+
+  /**
+   * This method registers a JComponent with the ToolTipManager.
+   *
+   * @param component The JComponent to register with the ToolTipManager.
+   */
+  public void registerComponent(JComponent component)
+  {
+    component.addMouseListener(this);
+    component.addMouseMotionListener(this);
+  }
+
+  /**
+   * This method unregisters a JComponent with the ToolTipManager.
+   *
+   * @param component The JComponent to unregister with the ToolTipManager.
+   */
+  public void unregisterComponent(JComponent component)
+  {
+    component.removeMouseMotionListener(this);
+    component.removeMouseListener(this);
+  }
+
+  /**
+   * This method is called whenever the mouse enters a JComponent registered
+   * with the ToolTipManager. When the mouse enters within the period of time
+   * specified by the reshow delay, the tooltip will be displayed
+   * immediately. Otherwise, it must wait for the initial delay before
+   * displaying the tooltip.
+   *
+   * @param event The MouseEvent.
+   */
+  public void mouseEntered(MouseEvent event)
+  {
+    if (currentComponent != null
+        && getContentPaneDeepestComponent(event) == currentComponent)
+      return;
+    currentPoint = event.getPoint();
+    currentComponent = (Component) event.getSource();
+
+    if (exitTimer.isRunning())
+      {
+	exitTimer.stop();
+	showTip();
+	insideTimer.start();
+	return;
+      }
+
+    // This should always be stopped unless we have just fake-exited.
+    if (! enterTimer.isRunning())
+      enterTimer.start();
+  }
+
+  /**
+   * This method is called when the mouse exits a JComponent registered with
+   * the ToolTipManager. When the mouse exits, the tooltip should be hidden
+   * immediately.
+   *
+   * @param event The MouseEvent.
+   */
+  public void mouseExited(MouseEvent event)
+  {
+    if (getContentPaneDeepestComponent(event) == currentComponent)
+      return;
+
+    currentPoint = event.getPoint();
+    currentComponent = null;
+    hideTip();
+
+    if (! enterTimer.isRunning() && insideTimer.isRunning())
+      exitTimer.start();
+    if (enterTimer.isRunning())
+      enterTimer.stop();
+    if (insideTimer.isRunning())
+      insideTimer.stop();
+  }
+
+  /**
+   * This method is called when the mouse is pressed on a JComponent
+   * registered with the ToolTipManager. When the mouse is pressed, the
+   * tooltip (if it is shown) must be hidden immediately.
+   *
+   * @param event The MouseEvent.
+   */
+  public void mousePressed(MouseEvent event)
+  {
+    currentPoint = event.getPoint();
+    if (enterTimer.isRunning())
+      enterTimer.restart();
+    else if (insideTimer.isRunning())
+      {
+	insideTimer.stop();
+	hideTip();
+      }
+    currentComponent.invalidate();
+    currentComponent.validate();
+    currentComponent.repaint();
+  }
+
+  /**
+   * This method is called when the mouse is dragged in a JComponent
+   * registered with the ToolTipManager.
+   *
+   * @param event The MouseEvent.
+   */
+  public void mouseDragged(MouseEvent event)
+  {
+    currentPoint = event.getPoint();
+    if (enterTimer.isRunning())
+      enterTimer.restart();
+  }
+
+  /**
+   * This method is called when the mouse is moved in a JComponent registered
+   * with the ToolTipManager.
+   *
+   * @param event The MouseEvent.
+   */
+  public void mouseMoved(MouseEvent event)
+  {
+    currentPoint = event.getPoint();
+    if (currentTip != null)
+      currentTip.setTipText(((JComponent) currentComponent).getToolTipText(event));
+    if (enterTimer.isRunning())
+      enterTimer.restart();
+  }
+
+  /**
+   * This method displays the ToolTip. It can figure out the method needed to
+   * show it as well (whether to display it in heavyweight/lightweight panel
+   * or a window.)
+   */
+  private void showTip()
+  {
+    if (! enabled)
+      return;
+
+    if (currentTip == null
+        || currentTip.getComponent() != currentComponent
+        && currentComponent instanceof JComponent)
+      currentTip = ((JComponent) currentComponent).createToolTip();
+    Point p = currentPoint;
+    Dimension dims = currentTip.getPreferredSize();
+    if (canToolTipFit(currentTip))
+      {
+	JLayeredPane pane = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
+	                                                                   currentComponent))
+	                    .getLayeredPane();
+
+	// This should never happen, but just in case.
+	if (pane == null)
+	  return;
+
+	if (containerPanel != null)
+	  hideTip();
+	if (isLightWeightPopupEnabled())
+	  {
+	    containerPanel = new Panel();
+	    JRootPane root = new JRootPane();
+	    root.getContentPane().add(currentTip);
+	    containerPanel.add(root);
+	  }
+	else
+	  {
+	    containerPanel = new JPanel();
+	    containerPanel.add(currentTip);
+	  }
+	LayoutManager lm = containerPanel.getLayout();
+	if (lm instanceof FlowLayout)
+	  {
+	    FlowLayout fm = (FlowLayout) lm;
+	    fm.setVgap(0);
+	    fm.setHgap(0);
+	  }
+
+	p = getGoodPoint(p, pane, currentTip, dims);
+
+	pane.add(containerPanel);
+	containerPanel.setBounds(p.x, p.y, dims.width, dims.height);
+	currentTip.setBounds(0, 0, dims.width, dims.height);
+
+	pane.revalidate();
+	pane.repaint();
+      }
+    else
+      {
+	SwingUtilities.convertPointToScreen(p, currentComponent);
+	tooltipWindow = new JWindow();
+	tooltipWindow.getContentPane().add(currentTip);
+	tooltipWindow.setFocusable(false);
+	tooltipWindow.pack();
+	tooltipWindow.setBounds(p.x, p.y, dims.width, dims.height);
+	tooltipWindow.show();
+      }
+    currentTip.setVisible(true);
+  }
+
+  /**
+   * This method hides the ToolTip.
+   */
+  private void hideTip()
+  {
+    if (currentTip == null || ! currentTip.isVisible() || ! enabled)
+      return;
+    currentTip.setVisible(false);
+    if (containerPanel != null)
+      {
+	Container parent = containerPanel.getParent();
+	if (parent == null)
+	  return;
+	parent.remove(containerPanel);
+	parent.invalidate();
+	parent.validate();
+	parent.repaint();
+
+	parent = currentTip.getParent();
+	if (parent == null)
+	  return;
+	parent.remove(currentTip);
+
+	containerPanel = null;
+      }
+    if (tooltipWindow != null)
+      {
+	tooltipWindow.hide();
+	tooltipWindow.dispose();
+	tooltipWindow = null;
+      }
+  }
+
+  /**
+   * This method returns a point in the LayeredPane where the ToolTip can be
+   * shown. The point returned (if the ToolTip is to be displayed at the
+   * preferred dimensions) will always place the ToolTip inside the
+   * currentComponent if possible.
+   *
+   * @param p The last known good point for the mouse.
+   * @param c The JLayeredPane in the first RootPaneContainer up from the
+   *        currentComponent.
+   * @param tip The ToolTip to display.
+   * @param dims The ToolTip preferred dimensions (can be null).
+   *
+   * @return A good point to place the ToolTip.
+   */
+  private Point getGoodPoint(Point p, JLayeredPane c, JToolTip tip,
+                             Dimension dims)
+  {
+    if (dims == null)
+      dims = tip.getPreferredSize();
+    Rectangle bounds = currentComponent.getBounds();
+    if (p.x + dims.width > bounds.width)
+      p.x = bounds.width - dims.width;
+    if (p.y + dims.height > bounds.height)
+      p.y = bounds.height - dims.height;
+
+    p = SwingUtilities.convertPoint(currentComponent, p, c);
+    return p;
+  }
+
+  /**
+   * This method returns the deepest component in the content pane for the
+   * first RootPaneContainer up from the currentComponent. This method is
+   * used in conjunction with one of the mouseXXX methods.
+   *
+   * @param e The MouseEvent.
+   *
+   * @return The deepest component in the content pane.
+   */
+  private Component getContentPaneDeepestComponent(MouseEvent e)
+  {
+    Component source = (Component) e.getSource();
+    Container parent = (Container) SwingUtilities.getAncestorOfClass(JRootPane.class,
+                                                                     currentComponent);
+    if (parent == null)
+      return null;
+    parent = ((JRootPane) parent).getContentPane();
+    Point p = e.getPoint();
+    p = SwingUtilities.convertPoint(source, p, parent);
+    Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
+    return target;
+  }
+
+  /**
+   * This method returns whether the ToolTip can fit in the first
+   * RootPaneContainer up from the currentComponent.
+   *
+   * @param tip The ToolTip.
+   *
+   * @return Whether the ToolTip can fit.
+   */
+  private boolean canToolTipFit(JToolTip tip)
+  {
+    JRootPane root = (JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class,
+                                                                   currentComponent);
+    if (root == null)
+      return false;
+    Dimension pref = tip.getPreferredSize();
+    Dimension rootSize = root.getSize();
+    if (rootSize.width > pref.width && rootSize.height > pref.height)
+      return true;
+    return false;
+  }
+}
Index: javax/swing/TransferHandler.java
===================================================================
RCS file: javax/swing/TransferHandler.java
diff -N javax/swing/TransferHandler.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/TransferHandler.java	6 Sep 2004 16:36:01 -0000
@@ -0,0 +1,55 @@
+/* TransferHandler.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.io.Serializable;
+
+public class TransferHandler implements Serializable
+{
+  private static final long serialVersionUID = -7908749299918704233L;
+
+  public static final int NONE = 0;
+  public static final int COPY = 1;
+  public static final int MOVE = 2;
+  public static final int COPY_OR_MOVE = 3;
+
+  protected TransferHandler()
+  {
+    // Do nothing here.
+  }
+}
Index: javax/swing/UIDefaults.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/UIDefaults.java,v
retrieving revision 1.6
diff -u -r1.6 UIDefaults.java
--- javax/swing/UIDefaults.java	27 Nov 2003 09:04:01 -0000	1.6
+++ javax/swing/UIDefaults.java	6 Sep 2004 16:36:01 -0000
@@ -1,5 +1,5 @@
 /* UIDefaults.java -- database for all settings and interface bindings.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -43,39 +43,36 @@
 import java.awt.Insets;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
 import java.lang.reflect.Method;
-import java.lang.reflect.Constructor;
 import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
 import java.util.LinkedList;
+import java.util.ListIterator;
 import java.util.Locale;
-import java.util.Set;
-import java.util.HashSet;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
+import java.util.Set;
+
 import javax.swing.border.Border;
 import javax.swing.plaf.ComponentUI;
 
 /**
  * UIDefaults is a database where all settings and interface bindings are
  * stored into. An PLAF implementation fills one of these (see for example
- * plaf/basic/BasicDefaults.java) with "JButton" -> new BasicButtonUI().
+ * plaf/basic/BasicLookAndFeel.java) with "ButtonUI" -> new BasicButtonUI().
  *
  * @author Ronald Veldema (rveldema@cs.vu.nl)
  */
 public class UIDefaults extends Hashtable
 {
+  private LinkedList bundles;
+  private Locale defaultLocale;
+  private PropertyChangeSupport propertyChangeSupport;
 
-  LinkedList bundles;
-  Set listeners;
-  Locale defaultLocale;
-
-  interface ActiveValue
+  public interface ActiveValue
   {
     Object createValue(UIDefaults table);
-  } // interface ActiveValue
+  }
 
   public static class LazyInputMap implements LazyValue
   {
@@ -94,12 +91,12 @@
         }
       return im;
     }
-  } // class LazyInputMap
+  }
 
-  interface LazyValue
+  public interface LazyValue
   {
     Object createValue(UIDefaults table);
-  } // interface LazyValue
+  }
 
   public static class ProxyLazyValue implements LazyValue
   {
@@ -210,28 +207,24 @@
     {
       return inner.createValue (table);
     }
-  } // class ProxyLazyValue
+  }
 
   private static final long serialVersionUID = 7341222528856548117L;
 
   public UIDefaults()
   {
     bundles = new LinkedList ();
-    listeners = new HashSet ();
     defaultLocale = Locale.getDefault ();
+    propertyChangeSupport = new PropertyChangeSupport(this);
   }
 
   public UIDefaults(Object[] entries)
   {
-    bundles = new LinkedList ();
-    listeners = new HashSet ();
-    defaultLocale = Locale.getDefault ();
+    this();
 
     for (int i = 0; (2*i+1) < entries.length; ++i)
-      {
         put (entries[2*i], entries[2*i+1]);
       }
-  }
 
   public Object get(Object key)
   {
@@ -369,13 +362,13 @@
     return o instanceof String ? (String) o : null;
   }
 
-  int getInt(Object key)
+  public int getInt(Object key)
   {
     Object o = get(key);
     return o instanceof Integer ? ((Integer) o).intValue() : 0;
   }
 
-  int getInt(Object key, Locale l)
+  public int getInt(Object key, Locale l)
   {
     Object o = get(key, l);
     return o instanceof Integer ? ((Integer) o).intValue() : 0;
@@ -473,7 +466,6 @@
         getUIError ("InvocationTargetException ("+ ite.getTargetException() 
 		    +") calling createUI(...) on " + cls.toString ());
         return null;        
-
 	}
     catch (Exception e)
   {
@@ -482,43 +474,38 @@
       }
   }
 
-  void addPropertyChangeListener(PropertyChangeListener listener)
+  public void addPropertyChangeListener(PropertyChangeListener listener)
   {
-    listeners.add (listener);
+    propertyChangeSupport.addPropertyChangeListener(listener);
   }
 
   void removePropertyChangeListener(PropertyChangeListener listener)
   {
-    listeners.remove (listener);
+    propertyChangeSupport.removePropertyChangeListener(listener);
   }
 
   public PropertyChangeListener[] getPropertyChangeListeners()
   {
-    return (PropertyChangeListener[]) listeners.toArray ();
+    return propertyChangeSupport.getPropertyChangeListeners();
   }
 
-  protected void firePropertyChange(String property, Object o, Object n)
+  protected void firePropertyChange(String property,
+				    Object oldValue, Object newValue)
   {
-    Iterator i = listeners.iterator ();
-    PropertyChangeEvent pce = new PropertyChangeEvent (this, property, o, n);
-    while (i.hasNext ())
-      {
-        PropertyChangeListener pcl = (PropertyChangeListener) i.next ();
-        pcl.propertyChange (pce);
-      }
+    propertyChangeSupport.firePropertyChange(property, oldValue, newValue);
   }
 
-  void addResourceBundle(String name)
+  public void addResourceBundle(String name)
   {
     bundles.addFirst (name);
   }
 
-  void removeResourceBundle(String name)
+  public void removeResourceBundle(String name)
   {
     bundles.remove (name);
   }
 
-  void setDefaultLocale(Locale loc)
+  public void setDefaultLocale(Locale loc)
   {
     defaultLocale = loc;
   }
@@ -527,4 +514,4 @@
   {
     return defaultLocale;
   }
-} // class UIDefaults
+}
Index: javax/swing/UIManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/UIManager.java,v
retrieving revision 1.6
diff -u -r1.6 UIManager.java
--- javax/swing/UIManager.java	27 Nov 2003 08:53:42 -0000	1.6
+++ javax/swing/UIManager.java	6 Sep 2004 16:36:01 -0000
@@ -1,5 +1,5 @@
 /* UIManager.java -- 
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -54,15 +54,22 @@
   {
     String name, clazz;
 	
-    LookAndFeelInfo(String name, 
-                    String clazz)
+    public LookAndFeelInfo(String name, 
+			   String clazz)
     {
       this.name  = name;
       this.clazz = clazz;
     }
 
-    String getName()      { return name;  }
-    String getClassName() { return clazz; }
+    public String getName()
+    {
+      return name;
+    }
+    
+    public String getClassName()
+    {
+      return clazz;
+    }
   }
 
   private static final long serialVersionUID = -5547433830339189365L;
@@ -80,18 +87,31 @@
     // Do nothing here.
   }
 
+  /**
+   * Add a <code>PropertyChangeListener</code> to the listener list.
+   *
+   * @param listener the listener to add
+   */
   public static void addPropertyChangeListener (PropertyChangeListener listener)
   {
     // FIXME
   }
 
+  /**
+   * Remove a <code>PropertyChangeListener</code> from the listener list.
+   *
+   * @param listener the listener to remove
+   */
   public static void removePropertyChangeListener (PropertyChangeListener listener)
-    // Remove a PropertyChangeListener from the listener list. 
   {
     // FIXME
   }
 
   /**
+   * Returns an array of all added <code>PropertyChangeListener</code> objects.
+   *
+   * @return an array of listeners
+   *
    * @since 1.4
    */
   public static PropertyChangeListener[] getPropertyChangeListeners ()
@@ -100,9 +120,11 @@
     throw new Error ("Not implemented");
   }
 
+  /**
+   * Add a LookAndFeel to the list of auxiliary look and feels.
+   */
   public static void addAuxiliaryLookAndFeel (LookAndFeel l)
   {
-    // Add a LookAndFeel to the list of auxiliary look and feels. 
     if (aux_installed == null)
       {
         aux_installed = new LookAndFeel[1];
@@ -178,8 +200,7 @@
    */
   public static Dimension getDimension(Object key)
   {
-    System.out.println("UIManager.getDim");
-    return new Dimension(200,100);
+    return (Dimension) getLookAndFeel().getDefaults().get(key);
   }
 
   /**
@@ -188,21 +209,25 @@
    *
    * @param key an Object that specifies the font. Typically,
    *        this is a String such as
-   *        <code>&quot;TitledBorder.font&quot;</code>.
+   *        <code>TitledBorder.font</code>.
    */
   public static Font getFont(Object key)
   {
     return (Font) getLookAndFeel().getDefaults().get(key);
   }
 
+  /**
+   * Returns an Icon from the defaults table.
+   */
   public static Icon getIcon(Object key)
-    // Returns an Icon from the defaults table. 
   {
     return (Icon) getLookAndFeel().getDefaults().get(key);
   }
   
+  /**
+   * Returns an Insets object from the defaults table.
+   */
   public static Insets getInsets(Object key)
-    // Returns an Insets object from the defaults table. 
   {
     return (Insets) getLookAndFeel().getDefaults().getInsets(key);
   }
@@ -234,49 +259,71 @@
     return getLookAndFeel().getDefaults();
   }
 
+  /**
+   * Returns a string from the defaults table.
+   */
   public static String getString(Object key)
-    // Returns a string from the defaults table. 
   {
     return (String) getLookAndFeel().getDefaults().get(key);
   }
   
+  /**
+   * Returns the name of the LookAndFeel class that implements the
+   * native systems look and feel if there is one, otherwise the name
+   * of the default cross platform LookAndFeel class.
+   */
   public static String getSystemLookAndFeelClassName()
-    // Returns the name of the LookAndFeel class that implements the native systems look and feel if there is one, otherwise the name of the default cross platform LookAndFeel class. 
   {
     return getCrossPlatformLookAndFeelClassName();
   }
 
+  /**
+   * Returns the Look and Feel object that renders the target component.
+   */
   public static ComponentUI getUI(JComponent target)
-    // Returns the L&F object that renders the target component. 
   {
-    ComponentUI ui = getDefaults().getUI(target);
-    //System.out.println("GET-UI-> " + ui + ", for " + target);
-    return ui;
+    return getDefaults().getUI(target);
   }
 
+  /**
+   * Creates a new look and feel and adds it to the current array.
+   */
   public static void installLookAndFeel(String name, String className)
-    // Creates a new look and feel and adds it to the current array. 
   {
   }
 
+  /**
+   * Adds the specified look and feel to the current array and then calls
+   * setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]).
+   */
   public static void installLookAndFeel(LookAndFeelInfo info)
-    // Adds the specified look and feel to the current array and then calls setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]). 
   {
   }
 
+  /**
+   * Stores an object in the defaults table.
+   */
   public static Object put(Object key, Object value)
-    // Stores an object in the defaults table. 
   {
     return getLookAndFeel().getDefaults().put(key,value);
   }
 
+  /**
+   * Replaces the current array of installed LookAndFeelInfos.
+   */
   public static void setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
-    // Replaces the current array of installed LookAndFeelInfos. 
   {
   }
   
+  /**
+   * Set the current default look.
+   */
   public static void setLookAndFeel(LookAndFeel newLookAndFeel)
+    throws UnsupportedLookAndFeelException
   {
+    if (! newLookAndFeel.isSupportedLookAndFeel())
+      throw new UnsupportedLookAndFeelException(newLookAndFeel.getName());
+    
     if (look_and_feel != null)
       look_and_feel.uninitialize();
 
@@ -288,11 +335,13 @@
     //repaint();
   }
 
+  /**
+   * Set the current default look and feel using a class name.
+   */
   public static void setLookAndFeel (String className)
     throws ClassNotFoundException, InstantiationException, IllegalAccessException,
     UnsupportedLookAndFeelException
   {
-    //          Set the current default look and feel using a class name.
     Class c = Class.forName(className);
     LookAndFeel a = (LookAndFeel) c.newInstance(); // throws class-cast-exception
     setLookAndFeel(a);
Index: javax/swing/ViewportLayout.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/ViewportLayout.java,v
retrieving revision 1.3
diff -u -r1.3 ViewportLayout.java
--- javax/swing/ViewportLayout.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/ViewportLayout.java	6 Sep 2004 16:36:01 -0000
@@ -41,75 +41,118 @@
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Rectangle;
 import java.io.Serializable;
 
 /**
  * ViewportLayout
  * @author	Andrew Selkirk
- * @version	1.0
+ * @author	Graydon Hoare
  */
 public class ViewportLayout implements LayoutManager, Serializable
 {
   static final long serialVersionUID = -788225906076097229L;
 
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor ViewportLayout
-	 */
-	public ViewportLayout() {
-		// TODO
-	} // ViewportLayout()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * addLayoutComponent
-	 * @param name TODO
-	 * @param c TODO
-	 */
-	public void addLayoutComponent(String name, Component c) {
-		// TODO
-	} // addLayoutComponent()
-
-	/**
-	 * removeLayoutComponent
-	 * @param c TODO
-	 */
-	public void removeLayoutComponent(Component c) {
-		// TODO
-	} // removeLayoutComponent()
-
-	/**
-	 * preferredLayoutSize
-	 * @param parent TODO
-	 * @returns Dimension
-	 */
-	public Dimension preferredLayoutSize(Container parent) {
-		return null; // TODO
-	} // preferredLayoutSize()
-
-	/**
-	 * minimumLayoutSize
-	 * @param parent TODO
-	 * @returns Dimension
-	 */
-	public Dimension minimumLayoutSize(Container parent) {
-		return null; // TODO
-	} // minimumLayoutSize()
-
-	/**
-	 * layoutContainer
-	 * @param parent TODO
-	 */
-	public void layoutContainer(Container parent) {
-		// TODO
-	} // layoutContainer()
-
-
-} // ViewportLayout
+  public ViewportLayout() 
+  {
+  }
+  public void addLayoutComponent(String name, Component c) 
+  {
+  }
+  public void removeLayoutComponent(Component c) 
+  {
+  }
+  public Dimension preferredLayoutSize(Container parent) 
+  {
+    JViewport vp = (JViewport)parent;
+    Component view = vp.getView();
+      return view.getPreferredSize();
+  }
+  public Dimension minimumLayoutSize(Container parent) 
+  {
+    JViewport vp = (JViewport)parent;
+    Component view = vp.getView();
+    return view.getMinimumSize();
+  }
+
+  /**
+   * Layout the view and viewport to respect the following rules. These are
+   * not precisely the rules described in sun's javadocs, but they are the
+   * rules which sun's swing implementation follows, if you watch its
+   * behavior:
+   *
+   * <ol> 
+   * 
+   * <li>If the port is larger than the view's minimum size, put the port
+   * at view position <code>(0,0)</code> and make the view's size equal to
+   * the port's.</li>
+   *
+   * <li>If the port is smaller than the view, leave the view at its
+   * minimum size. also, do not move the port, <em>unless</em> the port
+   * extends into space <em>past</em> the edge of the view. If so, move the
+   * port up or to the left, in view space, by the amount of empty space
+   * (keep the lower and right edges lined up)</li>
+   *
+   * </ol>
+   *
+   * @see JViewport#getViewSize
+   * @see JViewport#setViewSize
+   * @see JViewport#getViewPosition
+   * @see JViewport#setViewPosition
+   */
+
+  public void layoutContainer(Container parent) 
+  {
+    // The way to interpret this function is basically to ignore the names
+    // of methods it calls, and focus on the variable names here. getViewRect
+    // doesn't, for example, return the view; it returns the port bounds in
+    // view space. Likwise setViewPosition doesn't reposition the view; it 
+    // positions the port, in view coordinates.
+
+    JViewport port = (JViewport) parent;    
+    Component view = port.getView();
+
+    // These dimensions and positions are in *view space*.  Do not mix
+    // variables in here from port space (eg. parent.getBounds()). This
+    // function should be entirely in view space, because the methods on
+    // the viewport require inputs in view space.
+
+    Rectangle portBounds = port.getViewRect();
+    Dimension viewPref = view.getPreferredSize();
+    Dimension viewMinimum = view.getMinimumSize();
+    Point portLowerRight = new Point(portBounds.x + portBounds.width,
+                                     portBounds.y + portBounds.height);
+        
+    // vertical implementation of the above rules
+    if (portBounds.height >= viewMinimum.height)
+      {
+        portBounds.y = 0;
+        viewPref.height = portBounds.height;
+      }
+    else
+      {
+        viewPref.height = viewMinimum.height;
+        int overextension = portLowerRight.y - viewPref.height;
+        if (overextension > 0)
+            portBounds.y -= overextension;
+      }
+
+    // horizontal implementation of the above rules
+    if (portBounds.width >= viewMinimum.width)
+      {
+        portBounds.x = 0;
+        viewPref.width = portBounds.width;
+      }
+    else
+      {
+        viewPref.width = viewMinimum.width;
+        int overextension = portLowerRight.x - viewPref.width;
+        if (overextension > 0)
+            portBounds.x -= overextension;
+      }
+
+    port.setViewPosition(portBounds.getLocation());
+    port.setViewSize(viewPref);
+  }
+}
Index: javax/swing/border/TitledBorder.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/border/TitledBorder.java,v
retrieving revision 1.4
diff -u -r1.4 TitledBorder.java
--- javax/swing/border/TitledBorder.java	19 Jun 2003 10:48:45 -0000	1.4
+++ javax/swing/border/TitledBorder.java	6 Sep 2004 16:36:01 -0000
@@ -1,5 +1,5 @@
 /* TitledBorder.java -- 
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -45,8 +45,8 @@
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Insets;
-import java.awt.Rectangle;
 import java.awt.Shape;
+
 import javax.swing.UIManager;
 
 
@@ -252,7 +252,7 @@
    * The border underneath the title. If this value is
    * <code>null</code>, the border will be retrieved from the {@link
    * javax.swing.UIManager}&#x2019;s defaults table using the key
-   * <code>&quot;TitledBorder.border&quot;</code>.
+   * <code>TitledBorder.border</code>.
    */
   protected Border border;
 
@@ -279,7 +279,7 @@
    * The font for displaying the title text. If this value is
    * <code>null</code>, the font will be retrieved from the {@link
    * javax.swing.UIManager}&#x2019;s defaults table using the key
-   * <code>&quot;TitledBorder.font&quot;</code>.
+   * <code>TitledBorder.font</code>.
    */
   protected Font titleFont;
 
@@ -288,7 +288,7 @@
    * The color for displaying the title text. If this value is
    * <code>null</code>, the color will be retrieved from the {@link
    * javax.swing.UIManager}&#x2019;s defaults table using the key
-   * <code>&quot;TitledBorder.titleColor&quot;</code>.
+   * <code>TitledBorder.titleColor</code>.
    */
   protected Color titleColor;
 
@@ -717,11 +717,11 @@
    * Retrieves the border underneath the title. If no border has been
    * set, or if it has been set to<code>null</code>, the current
    * {@link javax.swing.LookAndFeel} will be asked for a border
-   * using the key <code>&quot;TitledBorder.border&quot;</code>.
+   * using the key <code>TitledBorder.border</code>.
    *
    * @return a border, or <code>null</code> if the current LookAndFeel
    *         does not provide a border for the key
-   *         <code>&quot;TitledBorder.border&quot;</code>.
+   *         <code>TitledBorder.border</code>.
    *
    * @see javax.swing.UIManager#getBorder(Object)
    */
@@ -766,11 +766,11 @@
    * Retrieves the font for displaying the title text. If no font has
    * been set, or if it has been set to<code>null</code>, the current
    * {@link javax.swing.LookAndFeel} will be asked for a font
-   * using the key <code>&quot;TitledBorder.font&quot;</code>.
+   * using the key <code>TitledBorder.font</code>.
    *
    * @return a font, or <code>null</code> if the current LookAndFeel
    *         does not provide a font for the key
-   *         <code>&quot;TitledBorder.font&quot;</code>.
+   *         <code>TitledBorder.font</code>.
    *
    * @see javax.swing.UIManager#getFont(Object)
    */
@@ -787,11 +787,11 @@
    * Retrieves the color for displaying the title text. If no color has
    * been set, or if it has been set to<code>null</code>, the current
    * {@link javax.swing.LookAndFeel} will be asked for a color
-   * using the key <code>&quot;TitledBorder.titleColor&quot;</code>.
+   * using the key <code>TitledBorder.titleColor</code>.
    *
    * @return a color, or <code>null</code> if the current LookAndFeel
    *         does not provide a color for the key
-   *         <code>&quot;TitledBorder.titleColor&quot;</code>.
+   *         <code>TitledBorder.titleColor</code>.
    *
    * @see javax.swing.UIManager#getColor(Object)
    */
@@ -1088,7 +1088,7 @@
 
 
     /**
-     * The border that constitues the &quot;interior&quot; border
+     * The border that constitues the interior border
      * underneath the title text.
      */
     Border border;
Index: javax/swing/colorchooser/AbstractColorChooserPanel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/colorchooser/AbstractColorChooserPanel.java,v
retrieving revision 1.2
diff -u -r1.2 AbstractColorChooserPanel.java
--- javax/swing/colorchooser/AbstractColorChooserPanel.java	11 Jun 2003 13:20:40 -0000	1.2
+++ javax/swing/colorchooser/AbstractColorChooserPanel.java	6 Sep 2004 16:36:02 -0000
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.colorchooser;
 
 import java.awt.Color;
@@ -44,106 +43,119 @@
 import javax.swing.JColorChooser;
 import javax.swing.JPanel;
 
+
 /**
  * AbstractColorChooserPanel
- * @author	Andrew Selkirk
- * @version	1.0
+ *
+ * @author Andrew Selkirk
+ * @version 1.0
  */
-public abstract class AbstractColorChooserPanel extends JPanel {
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * chooser
-	 */
-	private JColorChooser chooser;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor AbstractColorChooserPanel
-	 */
-	public AbstractColorChooserPanel() {
-		// TODO
-	} // AbstractColorChooserPanel()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getDisplayName
-	 * @returns String
-	 */
-	public abstract String getDisplayName();
-
-	/**
-	 * updateChooser
-	 */
-	public abstract void updateChooser();
-
-	/**
-	 * buildChooser
-	 */
-	protected abstract void buildChooser();
-
-	/**
-	 * getSmallDisplayIcon
-	 * @returns Icon
-	 */
-	public abstract Icon getSmallDisplayIcon();
-
-	/**
-	 * getLargeDisplayIcon
-	 * @returns Icon
-	 */
-	public abstract Icon getLargeDisplayIcon();
-
-	/**
-	 * installChooserPanel
-	 * @param chooser TODO
-	 */
-	public void installChooserPanel(JColorChooser chooser) {
-		// TODO
-	} // installChooserPanel()
-
-	/**
-	 * uninstallChooserPanel
-	 * @param chooser TODO
-	 */
-	public void uninstallChooserPanel(JColorChooser chooser) {
-		// TODO
-	} // uninstallChooserPanel()
-
-	/**
-	 * getColorSelectionModel
-	 * @returns ColorSelectionModel
-	 */
-	public ColorSelectionModel getColorSelectionModel() {
-		return null; // TODO
-	} // getColorSelectionModel()
-
-	/**
-	 * getColorFromModel
-	 * @returns Color
-	 */
-	protected Color getColorFromModel() {
-		return null; // TODO
-	} // getColorFromModel()
-
-	/**
-	 * paint
-	 * @param graphics TODO
-	 */
-	public void paint(Graphics graphics) {
-		// TODO
-	} // paint()
-
-
+public abstract class AbstractColorChooserPanel extends JPanel
+{
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = -977469671210173863L;
+
+  /** The chooser associated with this panel. */
+  private JColorChooser chooser;
+
+  /**
+   * This is the constructor for the AbstractColorChooserPanel.
+   */
+  public AbstractColorChooserPanel()
+  {
+  } // AbstractColorChooserPanel()
+
+  /**
+   * This method returns the name displayed in the tab for this chooser panel.
+   *
+   * @return The name displayed in the JTabbedPane's tabs.
+   */
+  public abstract String getDisplayName();
+
+  /**
+   * This method updates the chooser panel when the JColorChooser's color has
+   * changed.
+   */
+  public abstract void updateChooser();
+
+  /**
+   * This method constructs and does any initialization necessary for the
+   * chooser panel.
+   */
+  protected abstract void buildChooser();
+
+  /**
+   * This method sets the small icon used in the JTabbedPane for this chooser
+   * panel.
+   *
+   * @return The small icon used in the JTabbedPane.
+   */
+  public abstract Icon getSmallDisplayIcon();
+
+  /**
+   * This method sets the large icon useed in the jTabbedPane for this chooser
+   * panel.
+   *
+   * @return The large icon.
+   */
+  public abstract Icon getLargeDisplayIcon();
+
+  /**
+   * This method installs the chooser panel for the given JColorChooser.
+   *
+   * @param chooser The JColorChooser that will have this panel installed.
+   */
+  public void installChooserPanel(JColorChooser chooser)
+  {
+    this.chooser = chooser;
+    buildChooser();
+  } // installChooserPanel()
+
+  /**
+   * This method removes the chooser panel from the given JColorChooser and
+   * does any necessary clean up for the chooser panel.
+   *
+   * @param chooser The JColorChooser that is having this panel removed.
+   */
+  public void uninstallChooserPanel(JColorChooser chooser)
+  {
+    this.chooser = null;
+  } // uninstallChooserPanel()
+
+  /**
+   * This method returns the ColorSelectionModel for the JColorChooser
+   * associated with this chooser panel.
+   *
+   * @return The ColorSelectionModel for the JColorChooser associated with
+   *         this chooser panel.
+   */
+  public ColorSelectionModel getColorSelectionModel()
+  {
+    if (chooser != null)
+      return chooser.getSelectionModel();
+    return null;
+  } // getColorSelectionModel()
+
+  /**
+   * This method returns the current color stored in the model for this
+   * chooser panel.
+   *
+   * @return The current color.
+   */
+  protected Color getColorFromModel()
+  {
+    if (chooser != null)
+      return chooser.getColor();
+    return null;
+  } // getColorFromModel()
+
+  /**
+   * This method paints the chooser panel.
+   *
+   * @param graphics The Graphics object to paint with.
+   */
+  public void paint(Graphics graphics)
+  {
+    super.paint(graphics);
+  } // paint()
 } // AbstractColorChooserPanel
Index: javax/swing/colorchooser/ColorChooserComponentFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/colorchooser/ColorChooserComponentFactory.java,v
retrieving revision 1.2
diff -u -r1.2 ColorChooserComponentFactory.java
--- javax/swing/colorchooser/ColorChooserComponentFactory.java	11 Jun 2003 13:20:40 -0000	1.2
+++ javax/swing/colorchooser/ColorChooserComponentFactory.java	6 Sep 2004 16:36:02 -0000
@@ -35,49 +35,51 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.colorchooser;
 
 import javax.swing.JComponent;
 
+
 /**
  * ColorChooserComponentFactory
- * @author	Andrew Selkirk
- * @version	1.0
+ *
+ * @author Andrew Selkirk
+ * @version 1.0
  */
-public class ColorChooserComponentFactory {
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor ColorChooserComponentFactory
-	 */
-	private ColorChooserComponentFactory() {
-		// TODO
-	} // ColorChooserComponentFactory()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getDefaultChooserPanels
-	 * @returns AbstractColorChooserPanel[]
-	 */
-	public static AbstractColorChooserPanel[] getDefaultChooserPanels() {
-		return null; // TODO
-	} // getDefaultChooserPanels()
-
-	/**
-	 * getPreviewPanel
-	 * @returns JComponent
-	 */
-	public static JComponent getPreviewPanel() {
-		return null; // TODO
-	} // getPreviewPanel()
-
-
+public class ColorChooserComponentFactory
+{
+  /**
+   * Constructor ColorChooserComponentFactory
+   */
+  private ColorChooserComponentFactory()
+  {
+  } // ColorChooserComponentFactory()
+
+  /**
+   * This method returns the three default chooser panels to be used in
+   * JColorChooser.
+   *
+   * @return The default chooser panels.
+   */
+  public static AbstractColorChooserPanel[] getDefaultChooserPanels()
+  {
+    AbstractColorChooserPanel[] values = 
+                                         {
+                                           new DefaultSwatchChooserPanel(),
+                                           new DefaultHSBChooserPanel(),
+                                           new DefaultRGBChooserPanel()
+                                         };
+    return values;
+  }
+
+  /**
+   * This method returns the default preview panel to be used with
+   * JColorChoosers.
+   *
+   * @return The default preview panel.
+   */
+  public static JComponent getPreviewPanel()
+  {
+    return new DefaultPreviewPanel();
+  } // getPreviewPanel()
 } // ColorChooserComponentFactory
Index: javax/swing/colorchooser/DefaultColorSelectionModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/colorchooser/DefaultColorSelectionModel.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultColorSelectionModel.java
--- javax/swing/colorchooser/DefaultColorSelectionModel.java	14 Jul 2003 05:33:30 -0000	1.4
+++ javax/swing/colorchooser/DefaultColorSelectionModel.java	6 Sep 2004 16:36:02 -0000
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.colorchooser;
 
 import java.awt.Color;
@@ -44,43 +43,55 @@
 import javax.swing.event.ChangeListener;
 import javax.swing.event.EventListenerList;
 
+
 /**
- * DefaultColorSelectionModel
- * @author	Andrew Selkirk
- * @version	1.0
+ * This is the default implementation of the ColorSelectionModel interface
+ * that JColorChoosers use.
+ *
+ * @author Andrew Selkirk
+ * @version 1.0
  */
-public class DefaultColorSelectionModel 
-  implements ColorSelectionModel, Serializable
+public class DefaultColorSelectionModel implements ColorSelectionModel,
+                                                   Serializable
 {
+  /** DOCUMENT ME! */
   private static final long serialVersionUID = -8117143602864778804L;
 
+  /** The currently selected color. */
   private Color selectedColor;
 
-  protected transient ChangeEvent changeEvent = new ChangeEvent (this);
-  protected EventListenerList listenerList = new EventListenerList ();
+  /** The ChangeEvent fired to all ChangeListeners. */
+  protected transient ChangeEvent changeEvent = new ChangeEvent(this);
+
+  /** The list of listeners. */
+  protected EventListenerList listenerList = new EventListenerList();
 
   /**
-   * Creates a new color selection model.
+   * Creates a new color selection model with the default white color.
    */
   public DefaultColorSelectionModel()
   {
-    this (Color.white);
+    this(Color.white);
   }
 
   /**
    * Creates a new color selection model with a given selected color.
-   * 
-   * @param color The selected color.
+   *
+   * @param color The initial color.
+   *
+   * @throws Error If the color is null.
    */
-  public DefaultColorSelectionModel (Color color)
+  public DefaultColorSelectionModel(Color color)
   {
     super();
+    if (color == null)
+      throw new Error("ColorSelectionModel cannot be set to have null color.");
     this.selectedColor = color;
   }
 
   /**
    * Returns the selected color.
-   * 
+   *
    * @return The selected color.
    */
   public Color getSelectedColor()
@@ -89,31 +100,41 @@
   }
 
   /**
+   * This method sets the color.
+   *
    * @param color The color to set.
+   *
+   * @throws Error If the color is set.
    */
-  public void setSelectedColor (Color color)
+  public void setSelectedColor(Color color)
   {
-    this.selectedColor = color;
+    if (color == null)
+      throw new Error("ColorSelectionModel cannot be set to have null color.");
+    if (color != selectedColor)
+      {
+	this.selectedColor = color;
+	fireStateChanged();
+      }
   }
 
   /**
    * Adds a listener to this model.
-   * 
+   *
    * @param listener The listener to add.
    */
-  public void addChangeListener (ChangeListener listener)
+  public void addChangeListener(ChangeListener listener)
   {
-    listenerList.add (ChangeListener.class, listener);
+    listenerList.add(ChangeListener.class, listener);
   }
 
   /**
    * Removes a listener from this model.
-   * 
+   *
    * @param listener The listener to remove.
    */
-  public void removeChangeListener (ChangeListener listener)
+  public void removeChangeListener(ChangeListener listener)
   {
-    listenerList.remove (ChangeListener.class, listener);
+    listenerList.remove(ChangeListener.class, listener);
   }
 
   /**
@@ -123,19 +144,19 @@
    */
   public ChangeListener[] getChangeListeners()
   {
-    return (ChangeListener[]) listenerList.getListeners (ChangeListener.class);
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
   }
 
   /**
    * Calls all the <code>stateChanged()</code> method of all added
-   * <code>ChangeListener</code> objects with <code>changeEvent</code>
-   * as argument.
+   * <code>ChangeListener</code> objects with <code>changeEvent</code> as
+   * argument.
    */
   protected void fireStateChanged()
   {
     ChangeListener[] listeners = getChangeListeners();
 
     for (int i = 0; i < listeners.length; i++)
-      listeners [i].stateChanged (changeEvent);
+      listeners[i].stateChanged(changeEvent);
   }
 }
Index: javax/swing/colorchooser/DefaultHSBChooserPanel.java
===================================================================
RCS file: javax/swing/colorchooser/DefaultHSBChooserPanel.java
diff -N javax/swing/colorchooser/DefaultHSBChooserPanel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/colorchooser/DefaultHSBChooserPanel.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,860 @@
+/* DefaultHSBChooserPanel.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.colorchooser;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Image;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.awt.image.MemoryImageSource;
+import javax.swing.AbstractButton;
+import javax.swing.ButtonGroup;
+import javax.swing.Icon;
+import javax.swing.JColorChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.SwingConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+
+/**
+ * This is the Default HSB Panel displayed in the JColorChooser.
+ */
+class DefaultHSBChooserPanel extends AbstractColorChooserPanel
+{
+  /** The gradient image displayed. */
+  private transient Image gradientImage;
+
+  /** The Panel that holds the gradient image. */
+  private transient JPanel gradientPanel;
+
+  /** The track gradient image. */
+  private transient Image trackImage;
+
+  /** The panel that holds the track. */
+  private transient JPanel trackPanel;
+
+  /** The slider for the locked HSB value. */
+  private transient JSlider slider;
+
+  /** The RadioButton that controls the Hue. */
+  private transient JRadioButton hRadio;
+
+  /** The RadioButton that controls the Saturation. */
+  private transient JRadioButton sRadio;
+
+  /** The RadioButton that controls the Brightness. */
+  private transient JRadioButton bRadio;
+
+  /** The JSpinner that controls the Hue. */
+  private transient JSpinner hSpinner;
+
+  /** The JSpinner that controls the Saturation. */
+  private transient JSpinner sSpinner;
+
+  /** The JSpinner that controls the Brightness. */
+  private transient JSpinner bSpinner;
+
+  /** The default width of the gradient image. */
+  private static final int imgWidth = 200;
+
+  /** The default height of the gradient image. */
+  private static final int imgHeight = 200;
+
+  /** The default width of the track gradient. */
+  private static final int trackWidth = 30;
+
+  /** The JLabel for Red. */
+  private static final JLabel R = new JLabel("R");
+
+  /** The JLabel for Green. */
+  private static final JLabel G = new JLabel("G");
+
+  /** The JLabel for Blue. */
+  private static final JLabel B = new JLabel("B");
+
+  // FIXME: Should be textfields.
+
+  /** The JLabel that displays the value of Red. */
+  private transient JLabel rFull;
+
+  /** The JLabel that displays the value of Green. */
+  private transient JLabel gFull;
+
+  /** The JLabel that displays the value of Blue. */
+  private transient JLabel bFull;
+
+  /** The point that is displayed in the gradient image. */
+  private transient Point gradientPoint = new Point();
+
+  /**
+   * This indicates that the change to the slider or point is triggered
+   * internally.
+   */
+  private transient boolean internalChange = false;
+
+  /** This indicates that the change to the spinner is triggered internally. */
+  private transient boolean spinnerTrigger = false;
+
+  /** This int identifies which spinner is currently locked. */
+  private transient int locked = -1;
+
+  /** This value indicates that the Hue spinner is locked. */
+  static final int HLOCKED = 0;
+
+  /** This value indicates that the Saturation spinner is locked. */
+  static final int SLOCKED = 1;
+
+  /** This value indicates that the Brightness spinner is locked. */
+  static final int BLOCKED = 2;
+
+  /**
+   * This method indicates that the mouse event is in the process of being
+   * handled.
+   */
+  private transient boolean handlingMouse;
+
+  /**
+   * This helper class handles mouse events on the gradient image.
+   */
+  class MainGradientMouseListener extends MouseAdapter
+    implements MouseMotionListener
+  {
+    /**
+     * This method is called when the mouse is pressed over the gradient
+     * image. The JColorChooser is then updated with new HSB values.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      gradientPoint = e.getPoint();
+      update(e.getPoint());
+    }
+
+    /**
+     * This method is called when the mouse is dragged over the gradient
+     * image. The JColorChooser is then updated with the new HSB values.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      Point p = e.getPoint();
+      if (p.x < 0 || p.y < 0 || p.y > imgHeight || p.x > imgWidth)
+	return;
+
+      gradientPoint = p;
+      update(p);
+    }
+
+    /**
+     * This method is called when the mouse is moved over the gradient image.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method updates the JColorChooser with the new values.
+     *
+     * @param p The Point where the MouseEvent occurred.
+     */
+    private void update(Point p)
+    {
+      handlingMouse = true;
+      if (hSpinner.isEnabled())
+	updateH(p);
+      else if (sSpinner.isEnabled())
+	updateS(p);
+      else
+	updateB(p);
+      handlingMouse = false;
+    }
+
+    /**
+     * This method updates the SB values if Hue is locked.
+     *
+     * @param p The point where the MouseEvent occurred.
+     */
+    private void updateH(Point p)
+    {
+      float s = (imgWidth - p.x * 1f) / imgWidth;
+      float b = (imgHeight - p.y * 1f) / imgHeight;
+
+      // Avoid two changes to the model by changing internalChange to true.
+      internalChange = true;
+      sSpinner.setValue(new Integer((int) (s * 100)));
+      internalChange = false;
+      bSpinner.setValue(new Integer((int) (b * 100)));
+
+      revalidate();
+    }
+
+    /**
+     * This method updates the HB values if Saturation is locked.
+     *
+     * @param p The point where the MouseEvent occurred.
+     */
+    private void updateS(Point p)
+    {
+      float h = p.x * 1f / imgWidth;
+      float b = (imgHeight - p.y * 1f) / imgHeight;
+
+      internalChange = true;
+      hSpinner.setValue(new Integer((int) (h * 365)));
+      internalChange = false;
+      bSpinner.setValue(new Integer((int) (b * 100)));
+
+      revalidate();
+    }
+
+    /**
+     * This method updates the HS values if Brightness is locked.
+     *
+     * @param p The point where the MouseEvent occurred.
+     */
+    private void updateB(Point p)
+    {
+      float h = p.x * 1f / imgWidth;
+      float s = (imgHeight - p.y * 1f) / imgHeight;
+
+      internalChange = true;
+      hSpinner.setValue(new Integer((int) (h * 365)));
+      internalChange = false;
+      sSpinner.setValue(new Integer((int) (s * 100)));
+
+      revalidate();
+    }
+  }
+
+  /**
+   * This method listens for slider value changes.
+   */
+  class SliderChangeListener implements ChangeListener
+  {
+    /**
+     * This method is called when the slider value changes. It should change
+     * the color of the JColorChooser.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      if (internalChange)
+	return;
+
+      Integer value = new Integer(slider.getValue());
+
+      switch (locked)
+        {
+	case HLOCKED:
+	  hSpinner.setValue(value);
+	  break;
+	case SLOCKED:
+	  sSpinner.setValue(value);
+	  break;
+	case BLOCKED:
+	  bSpinner.setValue(value);
+	  break;
+        }
+    }
+  }
+
+  /**
+   * This helper class determines the active JSpinner.
+   */
+  class RadioStateListener implements ChangeListener
+  {
+    /**
+     * This method is called when there is a new JRadioButton that was
+     * selected. As a result, it should activate the associated JSpinner.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      JSpinner change;
+      if (e.getSource() == hRadio)
+        {
+	  locked = HLOCKED;
+	  change = hSpinner;
+        }
+      else if (e.getSource() == sRadio)
+        {
+	  locked = SLOCKED;
+	  change = sSpinner;
+        }
+      else
+        {
+	  locked = BLOCKED;
+	  change = bSpinner;
+        }
+
+      change.setEnabled(((AbstractButton) e.getSource()).isSelected());
+      updateSlider();
+      updateTrack();
+      updateImage();
+      repaint();
+    }
+  }
+
+  /**
+   * This class listens to the JSpinners for changes.
+   */
+  class ImageScrollListener implements ChangeListener
+  {
+    /**
+     * This method is called whenever one of the JSpinner values change. The
+     * JColorChooser should be updated with the new HSB values.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      if (internalChange)
+	return;
+
+      float h = ((Number) hSpinner.getValue()).intValue() / 360f;
+      float s = ((Number) sSpinner.getValue()).intValue() / 100f;
+      float b = ((Number) bSpinner.getValue()).intValue() / 100f;
+
+      spinnerTrigger = true;
+      getColorSelectionModel().setSelectedColor(new Color(Color.HSBtoRGB(h, s,
+                                                                         b)));
+      spinnerTrigger = false;
+
+      if (! handlingMouse)
+        {
+	  updateImage();
+	  updateTrack();
+        }
+      repaint();
+    }
+  }
+
+  /**
+   * Creates a new DefaultHSBChooserPanel object.
+   */
+  DefaultHSBChooserPanel()
+  {
+    super();
+  }
+
+  /**
+   * This method returns the name displayed by the JColorChooser tab that
+   * holds this panel.
+   *
+   * @return The name displayed in the JColorChooser tab.
+   */
+  public String getDisplayName()
+  {
+    return "HSB";
+  }
+
+  /**
+   * This method updates the various components inside the HSBPanel (the
+   * JSpinners, the JSlider, and the gradient image point) with updated
+   * values when the JColorChooser color value changes.
+   */
+  public void updateChooser()
+  {
+    Color c = getColorSelectionModel().getSelectedColor();
+
+    float[] hsbVals = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(),
+                                     null);
+
+    internalChange = true;
+
+    // spinnerTrigger, internalChange, and handlingMouse are used because of the
+    // we don't want things like: change spinner -> update chooser -> change spinner
+    // That's because the value from before and after the update can differ
+    // slightly because of the conversion.
+    // FIXME: Think of better way to deal with this.
+    if (! spinnerTrigger)
+      {
+	hSpinner.setValue(new Integer((int) (hsbVals[0] * 360)));
+	sSpinner.setValue(new Integer((int) (hsbVals[1] * 100)));
+	bSpinner.setValue(new Integer((int) (hsbVals[2] * 100)));
+      }
+
+    switch (locked)
+      {
+      case HLOCKED:
+	if (slider != null)
+	  slider.setValue(((Number) hSpinner.getValue()).intValue());
+	if (! handlingMouse)
+	  {
+	    gradientPoint.x = (int) ((1 - hsbVals[1]) * imgWidth);
+	    gradientPoint.y = (int) ((1 - hsbVals[2]) * imgHeight);
+	  }
+	break;
+      case SLOCKED:
+	if (slider != null)
+	  slider.setValue(((Number) sSpinner.getValue()).intValue());
+	if (! handlingMouse)
+	  {
+	    gradientPoint.x = (int) (hsbVals[0] * imgWidth);
+	    gradientPoint.y = (int) ((1 - hsbVals[2]) * imgHeight);
+	  }
+	break;
+      case BLOCKED:
+	if (slider != null)
+	  slider.setValue(((Number) bSpinner.getValue()).intValue());
+	if (! handlingMouse)
+	  {
+	    gradientPoint.x = (int) (hsbVals[0] * imgWidth);
+	    gradientPoint.y = (int) ((1 - hsbVals[1]) * imgHeight);
+	  }
+	break;
+      }
+    internalChange = false;
+
+    updateImage();
+    updateTrack();
+    updateTextFields();
+  }
+
+  /**
+   * This method builds the DefaultHSBChooserPanel.
+   */
+  protected void buildChooser()
+  {
+    setLayout(new BorderLayout());
+
+    add(buildRightPanel(), BorderLayout.EAST);
+
+    JPanel container = new JPanel();
+    container.setLayout(new BorderLayout());
+
+    gradientPanel = new JPanel()
+        {
+	  public Dimension getPreferredSize()
+	  {
+	    return new Dimension(imgWidth, imgHeight);
+	  }
+
+	  public void paint(Graphics g)
+	  {
+	    if (gradientImage != null)
+	      g.drawImage(gradientImage, 0, 0, this);
+
+	    Color saved = g.getColor();
+	    g.setColor(Color.WHITE);
+	    g.drawOval(gradientPoint.x - 3, gradientPoint.y - 3, 6, 6);
+	    g.setColor(saved);
+	  }
+        };
+
+    MouseAdapter ml = new MainGradientMouseListener();
+    gradientPanel.addMouseListener(ml);
+    gradientPanel.addMouseMotionListener((MouseMotionListener) ml);
+
+    trackPanel = new JPanel()
+        {
+	  public Dimension getPreferredSize()
+	  {
+	    return new Dimension(trackWidth, imgHeight);
+	  }
+
+	  public void paint(Graphics g)
+	  {
+	    if (trackImage != null)
+	      g.drawImage(trackImage, 0, 0, this);
+	  }
+        };
+
+    slider = new JSlider();
+    slider.setPaintTrack(false);
+    slider.setPaintTicks(false);
+
+    slider.setOrientation(SwingConstants.VERTICAL);
+
+    updateSlider();
+
+    container.add(gradientPanel, BorderLayout.WEST);
+    container.add(slider, BorderLayout.CENTER);
+    container.add(trackPanel, BorderLayout.EAST);
+
+    add(container, BorderLayout.WEST);
+    slider.addChangeListener(new SliderChangeListener());
+    repaint();
+  }
+
+  /**
+   * This method uninstalls the DefaultHSBPanel.
+   *
+   * @param chooser The JColorChooser to remove this panel from.
+   */
+  public void uninstallChooserPanel(JColorChooser chooser)
+  {
+    trackImage = null;
+    gradientImage = null;
+    gradientPanel = null;
+    slider = null;
+
+    hSpinner = null;
+    sSpinner = null;
+    bSpinner = null;
+
+    hRadio = null;
+    sRadio = null;
+    bRadio = null;
+
+    removeAll();
+    super.uninstallChooserPanel(chooser);
+  }
+
+  /**
+   * This helper method creates the right side panel (the panel with the
+   * Spinners and TextFields).
+   *
+   * @return The right side panel.
+   */
+  private Container buildRightPanel()
+  {
+    JPanel container = new JPanel();
+    container.setLayout(new GridLayout(6, 2));
+
+    hRadio = new JRadioButton("H");
+    sRadio = new JRadioButton("S");
+    bRadio = new JRadioButton("B");
+
+    ButtonGroup group = new ButtonGroup();
+    group.add(hRadio);
+    group.add(sRadio);
+    group.add(bRadio);
+
+    hSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 359, 1));
+    sSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
+    bSpinner = new JSpinner(new SpinnerNumberModel(100, 0, 100, 1));
+
+    hSpinner.setEnabled(false);
+    sSpinner.setEnabled(false);
+    bSpinner.setEnabled(false);
+
+    ChangeListener cl = new RadioStateListener();
+    ChangeListener scroll = new ImageScrollListener();
+
+    hRadio.addChangeListener(cl);
+    sRadio.addChangeListener(cl);
+    bRadio.addChangeListener(cl);
+
+    hSpinner.addChangeListener(scroll);
+    sSpinner.addChangeListener(scroll);
+    bSpinner.addChangeListener(scroll);
+
+    hRadio.setSelected(true);
+
+    container.add(hRadio);
+    container.add(hSpinner);
+
+    container.add(sRadio);
+    container.add(sSpinner);
+
+    container.add(bRadio);
+    container.add(bSpinner);
+
+    rFull = new JLabel("red full");
+    gFull = new JLabel("green full");
+    bFull = new JLabel("blue full");
+
+    container.add(R);
+    container.add(rFull);
+
+    container.add(G);
+    container.add(gFull);
+
+    container.add(B);
+    container.add(bFull);
+
+    return container;
+  }
+
+  /**
+   * This method returns the small display icon.
+   *
+   * @return The small display icon.
+   */
+  public Icon getSmallDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the large display icon.
+   *
+   * @return The large display icon.
+   */
+  public Icon getLargeDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method paints the chooser panel.
+   *
+   * @param g The graphics object to paint with.
+   */
+  public void paint(Graphics g)
+  {
+    super.paint(g);
+  }
+
+  /**
+   * This method updates the gradient image with a new one taking the Hue
+   * value as the constant.
+   */
+  private void updateHLockImage()
+  {
+    int index = 0;
+    int[] pix = new int[imgWidth * imgHeight];
+    float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
+
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < imgWidth; i++)
+	pix[index++] = Color.HSBtoRGB(hValue, (imgWidth - i * 1f) / imgWidth,
+	                              (imgHeight - j * 1f) / imgHeight)
+	               | (255 << 24);
+
+    gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
+                                                      pix, 0, imgWidth));
+  }
+
+  /**
+   * This method updates the gradient image with a new one taking the
+   * Brightness value as the constant.
+   */
+  private void updateBLockImage()
+  {
+    int[] pix = new int[imgWidth * imgHeight];
+    float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
+
+    int index = 0;
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < imgWidth; i++)
+	pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth,
+	                              (imgHeight - j * 1f) / imgHeight, bValue)
+	               | (255 << 24);
+
+    gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
+                                                      pix, 0, imgWidth));
+  }
+
+  /**
+   * This method updates the gradient image with a new one taking the
+   * Saturation value as the constant.
+   */
+  private void updateSLockImage()
+  {
+    int[] pix = new int[imgWidth * imgHeight];
+    float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
+
+    int index = 0;
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < imgWidth; i++)
+	pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth, sValue,
+	                              (imgHeight - j * 1f) / imgHeight)
+	               | (255 << 24);
+    gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
+                                                      pix, 0, imgWidth));
+  }
+
+  /**
+   * This method calls the appropriate method to update the gradient image
+   * depending on which HSB value is constant.
+   */
+  private void updateImage()
+  {
+    switch (locked)
+      {
+      case HLOCKED:
+	updateHLockImage();
+	break;
+      case SLOCKED:
+	updateSLockImage();
+	break;
+      case BLOCKED:
+	updateBLockImage();
+	break;
+      }
+  }
+
+  /**
+   * This method updates the TextFields with the correct RGB values.
+   */
+  private void updateTextFields()
+  {
+    int c = getColorSelectionModel().getSelectedColor().getRGB();
+
+    rFull.setText("" + (c >> 16 & 0xff));
+    gFull.setText("" + (c >> 8 & 0xff));
+    bFull.setText("" + (c & 0xff));
+
+    repaint();
+  }
+
+  /**
+   * This method updates the slider in response to making a different HSB
+   * property the constant.
+   */
+  private void updateSlider()
+  {
+    if (slider == null)
+      return;
+
+    slider.setMinimum(0);
+    if (locked == HLOCKED)
+      {
+	slider.setMaximum(359);
+	;
+	slider.setValue(((Number) hSpinner.getValue()).intValue());
+	slider.setInverted(true);
+      }
+    else
+      {
+	slider.setMaximum(100);
+	slider.setInverted(false);
+	if (sRadio.isSelected())
+	  slider.setValue(((Number) sSpinner.getValue()).intValue());
+	else
+	  slider.setValue(((Number) bSpinner.getValue()).intValue());
+      }
+    repaint();
+  }
+
+  /**
+   * This method updates the track gradient image depending on which HSB
+   * property is constant.
+   */
+  private void updateTrack()
+  {
+    switch (locked)
+      {
+      case HLOCKED:
+	updateHTrack();
+	break;
+      case SLOCKED:
+	updateSTrack();
+	break;
+      case BLOCKED:
+	updateBTrack();
+	break;
+      }
+  }
+
+  /**
+   * This method updates the track gradient image if the Hue value is allowed
+   * to change (according to the JRadioButtons).
+   */
+  private void updateHTrack()
+  {
+    int trackIndex = 0;
+    int[] trackPix = new int[trackWidth * imgHeight];
+
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < trackWidth; i++)
+	trackPix[trackIndex++] = Color.HSBtoRGB(j * 1f / imgHeight, 1f, 1f)
+	                         | (255 << 24);
+
+    trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
+                                                   trackPix, 0, trackWidth));
+  }
+
+  /**
+   * This method updates the track gradient image if the Saturation value is
+   * allowed to change (according to the JRadioButtons).
+   */
+  private void updateSTrack()
+  {
+    int[] trackPix = new int[trackWidth * imgHeight];
+
+    float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
+    float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
+
+    int trackIndex = 0;
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < trackWidth; i++)
+	trackPix[trackIndex++] = Color.HSBtoRGB(hValue,
+	                                        (imgHeight - j * 1f) / imgHeight,
+	                                        bValue) | (255 << 24);
+
+    trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
+                                                   trackPix, 0, trackWidth));
+  }
+
+  /**
+   * This method updates the track gradient image if the Brightness value is
+   * allowed to change (according to the JRadioButtons).
+   */
+  private void updateBTrack()
+  {
+    int[] trackPix = new int[trackWidth * imgHeight];
+
+    float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
+    float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
+
+    int trackIndex = 0;
+    for (int j = 0; j < imgHeight; j++)
+      for (int i = 0; i < trackWidth; i++)
+	trackPix[trackIndex++] = Color.HSBtoRGB(hValue, sValue,
+	                                        (imgHeight - j * 1f) / imgHeight)
+	                         | (255 << 24);
+
+    trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
+                                                   trackPix, 0, trackWidth));
+  }
+}
Index: javax/swing/colorchooser/DefaultPreviewPanel.java
===================================================================
RCS file: javax/swing/colorchooser/DefaultPreviewPanel.java
diff -N javax/swing/colorchooser/DefaultPreviewPanel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/colorchooser/DefaultPreviewPanel.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,317 @@
+/* DefaultPreviewPanel.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.colorchooser;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import javax.swing.JColorChooser;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.border.Border;
+
+
+/**
+ * This is the default preview panel for the JColorChooser. The default
+ * preview panel is responsible for displaying the currently selected color
+ * of the JColorChooser.
+ */
+class DefaultPreviewPanel extends JPanel
+{
+  /**
+   * This is the border around the preview panel.
+   */
+  class PreviewBorder implements Border
+  {
+    /** This is the value of the top, bottom, top, and right inset. */
+    private static final int edge = 20;
+
+    /**
+     * This is the distance from the top left corner of the border to the
+     * text.
+     */
+    private static final int lead = 5;
+
+    /** This is the horizontal gap between the text and the border. */
+    private static final int gap = 3;
+
+    /**
+     * This method returns the border insets for the given Component.
+     *
+     * @param c The Component to retrieve insets for.
+     *
+     * @return The insets for the given Component.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(edge, edge, edge, edge);
+    }
+
+    /**
+     * This method returns whether the border is responsible for painting its
+     * own background.
+     *
+     * @return Whether the border is responsible for painting its own
+     *         background.
+     */
+    public boolean isBorderOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method paints the border for the given component with the graphics
+     * object using the given properties.
+     *
+     * @param c The Component to paint the border for.
+     * @param g The Graphics object to paint with.
+     * @param x The x location to paint at.
+     * @param y The y location to paint at.
+     * @param width The width of the component.
+     * @param height The height of the component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      Color saved = g.getColor();
+      FontMetrics fm = g.getFontMetrics();
+
+      g.setColor(Color.BLACK);
+      g.drawLine(x + edge / 2, y + edge / 2, x + edge / 2,
+                 y + height - edge / 2);
+      g.drawLine(x + edge / 2, y + height - edge / 2, x + width - edge / 2,
+                 y + height - edge / 2);
+      g.drawLine(x + width - edge / 2, y + edge / 2, x + width - edge / 2,
+                 y + height - edge / 2);
+      g.drawLine(x + edge / 2, y + edge / 2, x + edge / 2 + lead, y + edge / 2);
+
+      int strwidth = fm.stringWidth("Preview");
+
+      g.drawString("Preview", x + edge / 2 + lead + gap,
+                   y + edge / 2 + fm.getAscent() / 2);
+
+      g.drawLine(x + lead + edge / 2 + strwidth + gap * 2, y + edge / 2,
+                 x + width - edge / 2, y + edge / 2);
+
+      g.setColor(saved);
+    }
+  }
+
+  /** A standard large gap size. */
+  private static int largeGap = 6;
+
+  /** A standard small gap size. */
+  private static int smallGap = 2;
+
+  /** The size of each side of the square. */
+  private static int squareSize = 36;
+
+  /** This padding between the text and the edge of its box. */
+  private static int textPadding = 4;
+
+  /** The width of the right most rectangles. */
+  private static int rightSideRectWidth = 60;
+
+  /** The sample text. */
+  private static String sample = "Sample Text   Sample Text";
+
+  /**
+   * Creates a new DefaultPreviewPanel object.
+   */
+  DefaultPreviewPanel()
+  {
+    super();
+    setBorder(new PreviewBorder());
+  }
+
+  /**
+   * This method paints the default preview panel with the given Graphics
+   * object.
+   *
+   * @param g The Graphics object.
+   */
+  public void paint(Graphics g)
+  {
+    super.paint(g);
+    Color currentColor = null;
+    JColorChooser chooser = (JColorChooser) SwingUtilities.getAncestorOfClass(JColorChooser.class,
+                                                                              this);
+    if (chooser != null)
+      currentColor = chooser.getColor();
+
+    Color saved = g.getColor();
+    Insets insets = getInsets();
+
+    int down = insets.top + squareSize + largeGap;
+    int currX = insets.left;
+
+    paintSquare(g, currX, insets.top, Color.WHITE, currentColor, Color.WHITE,
+                -1, -1, -1);
+    paintSquare(g, currX, down, currentColor, null, null, -1, -1, -1);
+
+    currX += squareSize + largeGap;
+
+    paintSquare(g, currX, insets.top, Color.BLACK, currentColor, Color.WHITE,
+                -1, -1, -1);
+    paintSquare(g, currX, down, Color.WHITE, currentColor, null, -1, -1, -1);
+
+    currX += squareSize + largeGap;
+
+    paintSquare(g, currX, insets.top, Color.WHITE, currentColor, Color.BLACK,
+                -1, -1, -1);
+    paintSquare(g, currX, down, Color.BLACK, currentColor, null, -1, -1, -1);
+
+    FontMetrics fm = g.getFontMetrics();
+    int strWidth = fm.stringWidth(sample);
+    int strHeight = fm.getHeight();
+
+    currX += squareSize + largeGap;
+
+    int boxWidth = 2 * textPadding + strWidth;
+    int boxHeight = 2 * textPadding + strHeight;
+
+    int first = insets.top + textPadding;
+    int second = insets.top + boxHeight + smallGap;
+    int third = insets.top + 2 * (boxHeight + smallGap);
+
+    g.setColor(Color.WHITE);
+    g.fillRect(currX, third, boxWidth, boxHeight);
+
+    g.setColor(currentColor);
+    g.drawString(sample, currX + textPadding,
+                 first + textPadding + fm.getAscent());
+
+    g.fillRect(currX, second, boxWidth, boxHeight);
+
+    g.drawString(sample, currX + textPadding,
+                 third + textPadding + fm.getAscent());
+
+    g.setColor(Color.BLACK);
+    g.drawString(sample, currX + textPadding,
+                 second + textPadding + fm.getAscent());
+
+    currX += boxWidth + largeGap;
+
+    g.setColor(Color.WHITE);
+    g.fillRect(currX, insets.top, rightSideRectWidth, squareSize
+               + largeGap / 2);
+
+    g.setColor(currentColor);
+    g.fillRect(currX, insets.top + squareSize + largeGap / 2,
+               rightSideRectWidth, squareSize + largeGap / 2);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method creates and paints a square. The square has two smaller
+   * squares inside of it. Each of the three squares has their sizes
+   * determined by the size arguments. If the size is not given (by passing
+   * in -1), then the size is determined automatically.
+   *
+   * @param g The Graphics object to paint with.
+   * @param x The x location to paint at.
+   * @param y The y location to paint at.
+   * @param first The color of the first square.
+   * @param second The color of the second square.
+   * @param third The color of the third square.
+   * @param firstSize The size of the first square.
+   * @param secondSize The size of the second square.
+   * @param thirdSize The size of the third square.
+   */
+  private void paintSquare(Graphics g, int x, int y, Color first,
+                           Color second, Color third, int firstSize,
+                           int secondSize, int thirdSize)
+  {
+    Color saved = g.getColor();
+    if (firstSize == -1)
+      firstSize = squareSize;
+    if (secondSize == -1)
+      secondSize = squareSize * 2 / 3;
+    if (thirdSize == -1)
+      thirdSize = squareSize / 3;
+    int secondOffset = (firstSize - secondSize) / 2;
+    int thirdOffset = (firstSize - thirdSize) / 2;
+
+    if (first == null)
+      return;
+    g.setColor(first);
+    g.fillRect(x, y, firstSize, firstSize);
+    if (second == null)
+      return;
+    g.setColor(second);
+    g.fillRect(x + secondOffset, y + secondOffset, secondSize, secondSize);
+    if (third == null)
+      return;
+    g.setColor(third);
+    g.fillRect(x + thirdOffset, y + thirdOffset, thirdSize, thirdSize);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method returns the preferred size of the default preview panel.
+   *
+   * @return The preferred size of the default preview panel.
+   */
+  public Dimension getPreferredSize()
+  {
+    Graphics g = getGraphics();
+    FontMetrics fm = g.getFontMetrics();
+    g.dispose();
+
+    int strWidth = fm.stringWidth(sample);
+    int strHeight = fm.getHeight();
+
+    int h1 = (strHeight + 2 * textPadding) * 3 + 2 * smallGap;
+    int h2 = 2 * squareSize + largeGap;
+
+    int height = Math.max(h1, h2);
+
+    int width = 3 * (squareSize + largeGap) + strWidth + 2 * textPadding
+                + largeGap + rightSideRectWidth;
+
+    Insets insets = getInsets();
+
+    return new Dimension(width + insets.right + insets.left,
+                         height + insets.top + insets.bottom);
+  }
+}
Index: javax/swing/colorchooser/DefaultRGBChooserPanel.java
===================================================================
RCS file: javax/swing/colorchooser/DefaultRGBChooserPanel.java
diff -N javax/swing/colorchooser/DefaultRGBChooserPanel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/colorchooser/DefaultRGBChooserPanel.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,377 @@
+/* DefaultRGHChooserPanel.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.colorchooser;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import javax.swing.Icon;
+import javax.swing.JColorChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.SwingConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+
+/**
+ * This is the default RGB panel for the JColorChooser. The color is selected
+ * using three sliders that represent the RGB values.
+ */
+public class DefaultRGBChooserPanel extends AbstractColorChooserPanel
+{
+  /**
+   * This class handles the slider value changes for all three sliders.
+   */
+  class SliderHandler implements ChangeListener
+  {
+    /**
+     * This method is called whenever any of the slider values change.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      if (internalChange)
+	return;
+      int color = R.getValue() << 16 | G.getValue() << 8 | B.getValue();
+
+      getColorSelectionModel().setSelectedColor(new Color(color));
+    }
+  }
+
+  /**
+   * This class handles the Spinner values changing.
+   */
+  class SpinnerHandler implements ChangeListener
+  {
+    /**
+     * This method is called whenever any of the JSpinners change values.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      if (internalChange)
+	return;
+      int red = ((Number) RSpinner.getValue()).intValue();
+      int green = ((Number) GSpinner.getValue()).intValue();
+      int blue = ((Number) BSpinner.getValue()).intValue();
+
+      int color = red << 16 | green << 8 | blue;
+
+      getColorSelectionModel().setSelectedColor(new Color(color));
+    }
+  }
+
+  /**
+   * Whether the color change was initiated from the slider or spinner rather
+   * than externally.
+   */
+  private transient boolean internalChange = false;
+
+  /** The ChangeListener for the sliders. */
+  private transient ChangeListener colorChanger;
+
+  /** The ChangeListener for the spinners. */
+  private transient ChangeListener spinnerHandler;
+
+  /** The slider that handles the red values. */
+  private transient JSlider R;
+
+  /** The slider that handles the green values. */
+  private transient JSlider G;
+
+  /** The slider that handles the blue values. */
+  private transient JSlider B;
+
+  /** The label for the red slider. */
+  private transient JLabel RLabel;
+
+  /** The label for the green slider. */
+  private transient JLabel GLabel;
+
+  /** The label for the blue slider. */
+  private transient JLabel BLabel;
+
+  /** The spinner that handles the red values. */
+  private transient JSpinner RSpinner;
+
+  /** The spinner that handles the green values. */
+  private transient JSpinner GSpinner;
+
+  /** The spinner that handles the blue values. */
+  private transient JSpinner BSpinner;
+
+  /**
+   * Creates a new DefaultRGBChooserPanel object.
+   */
+  public DefaultRGBChooserPanel()
+  {
+    super();
+  }
+
+  /**
+   * This method returns the name displayed in the JTabbedPane.
+   *
+   * @return The name displayed in the JTabbedPane.
+   */
+  public String getDisplayName()
+  {
+    return "RGB";
+  }
+
+  /**
+   * This method updates the chooser panel with the new color chosen in the
+   * JColorChooser.
+   */
+  public void updateChooser()
+  {
+    Color c = getColorFromModel();
+    int rgb = c.getRGB();
+
+    int red = rgb >> 16 & 0xff;
+    int green = rgb >> 8 & 0xff;
+    int blue = rgb & 0xff;
+
+    internalChange = true;
+
+    if (R != null)
+      R.setValue(red);
+    if (RSpinner != null)
+      RSpinner.setValue(new Integer(red));
+    if (G != null)
+      G.setValue(green);
+    if (GSpinner != null)
+      GSpinner.setValue(new Integer(green));
+    if (B != null)
+      B.setValue(blue);
+    if (BSpinner != null)
+      BSpinner.setValue(new Integer(blue));
+
+    internalChange = false;
+
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * This method builds the chooser panel.
+   */
+  protected void buildChooser()
+  {
+    setLayout(new GridBagLayout());
+
+    RLabel = new JLabel("Red");
+    RLabel.setDisplayedMnemonic('d');
+    GLabel = new JLabel("Green");
+    GLabel.setDisplayedMnemonic('n');
+    BLabel = new JLabel("Blue");
+    BLabel.setDisplayedMnemonic('B');
+
+    R = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
+    G = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
+    B = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 255);
+
+    R.setPaintTicks(true);
+    R.setSnapToTicks(false);
+    G.setPaintTicks(true);
+    G.setSnapToTicks(false);
+    B.setPaintTicks(true);
+    B.setSnapToTicks(false);
+
+    R.setLabelTable(R.createStandardLabels(85));
+    R.setPaintLabels(true);
+    G.setLabelTable(G.createStandardLabels(85));
+    G.setPaintLabels(true);
+    B.setLabelTable(B.createStandardLabels(85));
+    B.setPaintLabels(true);
+
+    R.setMajorTickSpacing(85);
+    G.setMajorTickSpacing(85);
+    B.setMajorTickSpacing(85);
+
+    R.setMinorTickSpacing(17);
+    G.setMinorTickSpacing(17);
+    B.setMinorTickSpacing(17);
+
+    RSpinner = new JSpinner(new SpinnerNumberModel(R.getValue(),
+                                                   R.getMinimum(),
+                                                   R.getMaximum(), 1));
+    GSpinner = new JSpinner(new SpinnerNumberModel(G.getValue(),
+                                                   G.getMinimum(),
+                                                   G.getMaximum(), 1));
+    BSpinner = new JSpinner(new SpinnerNumberModel(B.getValue(),
+                                                   B.getMinimum(),
+                                                   B.getMaximum(), 1));
+
+    RLabel.setLabelFor(R);
+    GLabel.setLabelFor(G);
+    BLabel.setLabelFor(B);
+
+    GridBagConstraints bag = new GridBagConstraints();
+    bag.fill = GridBagConstraints.VERTICAL;
+
+    bag.gridx = 0;
+    bag.gridy = 0;
+    add(RLabel, bag);
+
+    bag.gridx = 1;
+    add(R, bag);
+
+    bag.gridx = 2;
+    add(RSpinner, bag);
+
+    bag.gridx = 0;
+    bag.gridy = 1;
+    add(GLabel, bag);
+
+    bag.gridx = 1;
+    add(G, bag);
+
+    bag.gridx = 2;
+    add(GSpinner, bag);
+
+    bag.gridx = 0;
+    bag.gridy = 2;
+    add(BLabel, bag);
+
+    bag.gridx = 1;
+    add(B, bag);
+
+    bag.gridx = 2;
+    add(BSpinner, bag);
+
+    installListeners();
+  }
+
+  /**
+   * This method uninstalls the chooser panel from the JColorChooser.
+   *
+   * @param chooser The JColorChooser to remove this chooser panel from.
+   */
+  public void uninstallChooserPanel(JColorChooser chooser)
+  {
+    uninstallListeners();
+    removeAll();
+
+    R = null;
+    G = null;
+    B = null;
+
+    RSpinner = null;
+    GSpinner = null;
+    BSpinner = null;
+
+    super.uninstallChooserPanel(chooser);
+  }
+
+  /**
+   * This method uninstalls any listeners that were added by the chooser
+   * panel.
+   */
+  private void uninstallListeners()
+  {
+    R.removeChangeListener(colorChanger);
+    G.removeChangeListener(colorChanger);
+    B.removeChangeListener(colorChanger);
+
+    colorChanger = null;
+
+    RSpinner.removeChangeListener(spinnerHandler);
+    GSpinner.removeChangeListener(spinnerHandler);
+    BSpinner.removeChangeListener(spinnerHandler);
+
+    spinnerHandler = null;
+  }
+
+  /**
+   * This method installs any listeners that the chooser panel needs to
+   * operate.
+   */
+  private void installListeners()
+  {
+    colorChanger = new SliderHandler();
+
+    R.addChangeListener(colorChanger);
+    G.addChangeListener(colorChanger);
+    B.addChangeListener(colorChanger);
+
+    spinnerHandler = new SpinnerHandler();
+
+    RSpinner.addChangeListener(spinnerHandler);
+    GSpinner.addChangeListener(spinnerHandler);
+    BSpinner.addChangeListener(spinnerHandler);
+  }
+
+  /**
+   * This method returns the small display icon.
+   *
+   * @return The small display icon.
+   */
+  public Icon getSmallDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the large display icon.
+   *
+   * @return The large display icon.
+   */
+  public Icon getLargeDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method paints the default RGB chooser panel.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  public void paint(Graphics g)
+  {
+    super.paint(g);
+  }
+}
Index: javax/swing/colorchooser/DefaultSwatchChooserPanel.java
===================================================================
RCS file: javax/swing/colorchooser/DefaultSwatchChooserPanel.java
diff -N javax/swing/colorchooser/DefaultSwatchChooserPanel.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/colorchooser/DefaultSwatchChooserPanel.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,891 @@
+/* DefaultSwatchChooserPanel.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.colorchooser;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import javax.swing.Icon;
+import javax.swing.JColorChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+
+/**
+ * This class is the DefaultSwatchChooserPanel. This chooser panel displays a
+ * set of colors that can be picked. Recently picked items will go into a
+ * side panel so the user can see the history of the chosen colors.
+ */
+class DefaultSwatchChooserPanel extends AbstractColorChooserPanel
+{
+  /** The main panel that holds the set of choosable colors. */
+  MainSwatchPanel mainPalette;
+
+  /** A panel that holds the recent colors. */
+  RecentSwatchPanel recentPalette;
+
+  /** The mouse handlers for the panels. */
+  MouseListener mouseHandler;
+
+  /**
+   * This the base class for all swatch panels. Swatch panels are panels that
+   * hold a set of blocks where colors are displayed.
+   */
+  abstract static class SwatchPanel extends JPanel
+  {
+    /** The width of each block. */
+    protected int cellWidth = 10;
+
+    /** The height of each block. */
+    protected int cellHeight = 10;
+
+    /** The gap between blocks. */
+    protected int gap = 1;
+
+    /** The number of rows in the swatch panel. */
+    protected int numRows;
+
+    /** The number of columns in the swatch panel. */
+    protected int numCols;
+
+    /**
+     * Creates a new SwatchPanel object.
+     */
+    SwatchPanel()
+    {
+      super();
+      setBackground(Color.WHITE);
+    }
+
+    /**
+     * This method returns the preferred size of the swatch panel based on the
+     * number of rows and columns and the size of each cell.
+     *
+     * @return The preferred size of the swatch panel.
+     */
+    public Dimension getPreferredSize()
+    {
+      int height = numRows * cellHeight + (numRows - 1) * gap;
+      int width = numCols * cellWidth + (numCols - 1) * gap;
+      Insets insets = getInsets();
+
+      return new Dimension(width + insets.left + insets.right,
+                           height + insets.top + insets.bottom);
+    }
+
+    /**
+     * This method returns the color for the given position.
+     *
+     * @param x The x coordinate of the position.
+     * @param y The y coordinate of the position.
+     *
+     * @return The color at the given position.
+     */
+    public abstract Color getColorForPosition(int x, int y);
+
+    /**
+     * This method initializes the colors for the swatch panel.
+     */
+    protected abstract void initializeColors();
+  }
+
+  /**
+   * This is the main swatch panel. This panel sits in the middle and allows a
+   * set of colors to be picked which will move to the recent swatch panel.
+   */
+  static class MainSwatchPanel extends SwatchPanel
+  {
+    /** The color describing (204, 255, 255) */
+    public static final Color C204255255 = new Color(204, 204, 255);
+
+    /** The color describing (255, 204, 204) */
+    public static final Color C255204204 = new Color(255, 204, 204);
+
+    /** The color describing (204, 255, 204) */
+    public static final Color C204255204 = new Color(204, 255, 204);
+
+    /** The color describing (204, 204, 204) */
+    public static final Color C204204204 = new Color(204, 204, 204);
+
+    /** The color (153, 153, 255). */
+    public static final Color C153153255 = new Color(153, 153, 255);
+
+    /** The color (51, 51, 255). */
+    public static final Color C051051255 = new Color(51, 51, 255);
+
+    /** The color (153, 0, 153). */
+    public static final Color C153000153 = new Color(153, 0, 153);
+
+    /** The color (0, 51, 51). */
+    public static final Color C000051051 = new Color(0, 51, 51);
+
+    /** The color (51, 0, 51). */
+    public static final Color C051000051 = new Color(51, 0, 51);
+
+    /** The color (51, 51, 0). */
+    public static final Color C051051000 = new Color(51, 51, 0);
+
+    /** The color (102, 102, 0). */
+    public static final Color C102102000 = new Color(102, 102, 0);
+
+    /** The color (153, 255, 153). */
+    public static final Color C153255153 = new Color(153, 255, 153);
+
+    /** The color (102, 255, 102). */
+    public static final Color C102255102 = new Color(102, 255, 102);
+
+    /** The color (0, 102, 102). */
+    public static final Color C000102102 = new Color(0, 102, 102);
+
+    /** The color (102, 0, 102). */
+    public static final Color C102000102 = new Color(102, 0, 102);
+
+    /** The color (0, 153, 153). */
+    public static final Color C000153153 = new Color(0, 153, 153);
+
+    /** The color (153, 153, 0). */
+    public static final Color C153153000 = new Color(153, 153, 0);
+
+    /** The color (204, 204, 0). */
+    public static final Color C204204000 = new Color(204, 204, 0);
+
+    /** The color (204, 0, 204). */
+    public static final Color C204000204 = new Color(204, 0, 204);
+
+    /** The color (0, 204, 204). */
+    public static final Color C000204204 = new Color(0, 204, 204);
+
+    /** The color (51, 255, 51). */
+    public static final Color C051255051 = new Color(51, 255, 51);
+
+    /** The color (255, 51, 51). */
+    public static final Color C255051051 = new Color(255, 51, 51);
+
+    /** The color (255, 102, 102). */
+    public static final Color C255102102 = new Color(255, 102, 102);
+
+    /** The color (102, 102, 255). */
+    public static final Color C102102255 = new Color(102, 102, 255);
+
+    /** The color (255, 153, 153). */
+    public static final Color C255153153 = new Color(255, 153, 153);
+    static Color[] colors = 
+                            {
+                              // Row 1
+    Color.WHITE, new Color(204, 255, 255), C204255255, C204255255, C204255255,
+                              C204255255, C204255255, C204255255, C204255255,
+                              C204255255, C204255255, new Color(255, 204, 255),
+                              C255204204, C255204204, C255204204, C255204204,
+                              C255204204, C255204204, C255204204, C255204204,
+                              C255204204, new Color(255, 255, 204), C204255204,
+                              C204255204, C204255204, C204255204, C204255204,
+                              C204255204, C204255204, C204255204, C204255204,
+                              
+    // Row 2
+    C204204204, new Color(153, 255, 255), new Color(153, 204, 255), C153153255,
+                              C153153255, C153153255, C153153255, C153153255,
+                              C153153255, C153153255, new Color(204, 153, 255),
+                              new Color(255, 153, 255),
+                              new Color(255, 153, 204), C255153153, C255153153,
+                              C255153153, C255153153, C255153153, C255153153,
+                              C255153153, new Color(255, 204, 153),
+                              new Color(255, 255, 153),
+                              new Color(204, 255, 153), C153255153, C153255153,
+                              C153255153, C153255153, C153255153, C153255153,
+                              C153255153, new Color(153, 255, 204),
+                              
+    // Row 3
+    C204204204, new Color(102, 255, 255), new Color(102, 204, 255),
+                              new Color(102, 153, 255), C102102255, C102102255,
+                              C102102255, C102102255, C102102255,
+                              new Color(153, 102, 255),
+                              new Color(204, 102, 255),
+                              new Color(255, 102, 255),
+                              new Color(255, 102, 204),
+                              new Color(255, 102, 153), C255102102, C255102102,
+                              C255102102, C255102102, C255102102,
+                              new Color(255, 153, 102),
+                              new Color(255, 204, 102),
+                              new Color(255, 255, 102),
+                              new Color(204, 255, 102),
+                              new Color(153, 255, 102), C102255102, C102255102,
+                              C102255102, C102255102, C102255102,
+                              new Color(102, 255, 153),
+                              new Color(102, 255, 204),
+                              
+    // Row 4
+    new Color(153, 153, 153), new Color(51, 255, 255), new Color(51, 204, 255),
+                              new Color(51, 153, 255), new Color(51, 102, 255),
+                              C051051255, C051051255, C051051255,
+                              new Color(102, 51, 255), new Color(153, 51, 255),
+                              new Color(204, 51, 255), new Color(255, 51, 255),
+                              new Color(255, 51, 204), new Color(255, 51, 153),
+                              new Color(255, 51, 102), C255051051, C255051051,
+                              C255051051, new Color(255, 102, 51),
+                              new Color(255, 153, 51), new Color(255, 204, 51),
+                              new Color(255, 255, 51), new Color(204, 255, 51),
+                              new Color(153, 255, 51), new Color(102, 255, 51),
+                              C051255051, C051255051, C051255051,
+                              new Color(51, 255, 102), new Color(51, 255, 153),
+                              new Color(51, 255, 204),
+                              
+    // Row 5
+    new Color(153, 153, 153), new Color(0, 255, 255), new Color(0, 204, 255),
+                              new Color(0, 153, 255), new Color(0, 102, 255),
+                              new Color(0, 51, 255), new Color(0, 0, 255),
+                              new Color(51, 0, 255), new Color(102, 0, 255),
+                              new Color(153, 0, 255), new Color(204, 0, 255),
+                              new Color(255, 0, 255), new Color(255, 0, 204),
+                              new Color(255, 0, 153), new Color(255, 0, 102),
+                              new Color(255, 0, 51), new Color(255, 0, 0),
+                              new Color(255, 51, 0), new Color(255, 102, 0),
+                              new Color(255, 153, 0), new Color(255, 204, 0),
+                              new Color(255, 255, 0), new Color(204, 255, 0),
+                              new Color(153, 255, 0), new Color(102, 255, 0),
+                              new Color(51, 255, 0), new Color(0, 255, 0),
+                              new Color(0, 255, 51), new Color(0, 255, 102),
+                              new Color(0, 255, 153), new Color(0, 255, 204),
+                              
+    // Row 6
+    new Color(102, 102, 102), C000204204, C000204204, new Color(0, 153, 204),
+                              new Color(0, 102, 204), new Color(0, 51, 204),
+                              new Color(0, 0, 204), new Color(51, 0, 204),
+                              new Color(102, 0, 204), new Color(153, 0, 204),
+                              C204000204, C204000204, C204000204,
+                              new Color(204, 0, 153), new Color(204, 0, 102),
+                              new Color(204, 0, 51), new Color(204, 0, 0),
+                              new Color(204, 51, 0), new Color(204, 102, 0),
+                              new Color(204, 153, 0), C204204000, C204204000,
+                              C204204000, new Color(153, 204, 0),
+                              new Color(102, 204, 0), new Color(51, 204, 0),
+                              new Color(0, 204, 0), new Color(0, 204, 51),
+                              new Color(0, 204, 102), new Color(0, 204, 153),
+                              new Color(0, 204, 204),
+                              
+    // Row 7
+    new Color(102, 102, 102), C000153153, C000153153, C000153153,
+                              new Color(0, 102, 153), new Color(0, 51, 153),
+                              new Color(0, 0, 153), new Color(51, 0, 153),
+                              new Color(102, 0, 153), C153000153, C153000153,
+                              C153000153, C153000153, C153000153,
+                              new Color(153, 0, 102), new Color(153, 0, 51),
+                              new Color(153, 0, 0), new Color(153, 51, 0),
+                              new Color(153, 102, 0), C153153000, C153153000,
+                              C153153000, C153153000, C153153000,
+                              new Color(102, 153, 0), new Color(51, 153, 0),
+                              new Color(0, 153, 0), new Color(0, 153, 51),
+                              new Color(0, 153, 102), C000153153, C000153153,
+                              
+    // Row 8
+    new Color(51, 51, 51), C000102102, C000102102, C000102102, C000102102,
+                              new Color(0, 51, 102), new Color(0, 0, 102),
+                              new Color(51, 0, 102), C102000102, C102000102,
+                              C102000102, C102000102, C102000102, C102000102,
+                              C102000102, new Color(102, 0, 51),
+                              new Color(102, 0, 0), new Color(102, 51, 0),
+                              C102102000, C102102000, C102102000, C102102000,
+                              C102102000, C102102000, C102102000,
+                              new Color(51, 102, 0), new Color(0, 102, 0),
+                              new Color(0, 102, 51), C000102102, C000102102,
+                              C000102102,
+                              
+    // Row 9.
+    Color.BLACK, C000051051, C000051051, C000051051, C000051051, C000051051,
+                              new Color(0, 0, 51), C051000051, C051000051,
+                              C051000051, C051000051, C051000051, C051000051,
+                              C051000051, C051000051, C051000051,
+                              new Color(51, 0, 0), C051051000, C051051000,
+                              C051051000, C051051000, C051051000, C051051000,
+                              C051051000, C051051000, new Color(0, 51, 0),
+                              C000051051, C000051051, C000051051, C000051051,
+                              new Color(51, 51, 51)
+                            };
+
+    /**
+     * Creates a new MainSwatchPanel object.
+     */
+    MainSwatchPanel()
+    {
+      super();
+      numCols = 31;
+      numRows = 9;
+      initializeColors();
+      revalidate();
+    }
+
+    /**
+     * This method returns the color for the given position.
+     *
+     * @param x The x location for the position.
+     * @param y The y location for the position.
+     *
+     * @return The color for the given position.
+     */
+    public Color getColorForPosition(int x, int y)
+    {
+      if (x % (cellWidth + gap) > cellWidth
+          || y % (cellHeight + gap) > cellHeight)
+	// position is located in gap.
+	return null;
+
+      int row = y / (cellHeight + gap);
+      int col = x / (cellWidth + gap);
+      return colors[row * numCols + col];
+    }
+
+    /**
+     * This method initializes the colors for the main swatch panel.
+     */
+    protected void initializeColors()
+    {
+      // Unnecessary
+    }
+
+    /**
+     * This method paints the main graphics panel with the given Graphics
+     * object.
+     *
+     * @param graphics The Graphics object to paint with.
+     */
+    public void paint(Graphics graphics)
+    {
+      int index = 0;
+      Insets insets = getInsets();
+      int currX = insets.left;
+      int currY = insets.top;
+      Color saved = graphics.getColor();
+
+      for (int i = 0; i < numRows; i++)
+        {
+	  for (int j = 0; j < numCols; j++)
+	    {
+	      graphics.setColor(colors[index++]);
+	      graphics.fill3DRect(currX, currY, cellWidth, cellHeight, true);
+	      currX += gap + cellWidth;
+	    }
+	  currX = insets.left;
+	  currY += gap + cellHeight;
+        }
+      graphics.setColor(saved);
+    }
+
+    /**
+     * This method returns the tooltip text for the given MouseEvent.
+     *
+     * @param e The MouseEvent to find tooltip text for.
+     *
+     * @return The tooltip text.
+     */
+    public String getToolTipText(MouseEvent e)
+    {
+      Color c = getColorForPosition(e.getX(), e.getY());
+      if (c == null)
+	return null;
+      return (c.getRed() + "," + c.getGreen() + "," + c.getBlue());
+    }
+  }
+
+  /**
+   * This class is the recent swatch panel. It holds recently selected colors.
+   */
+  public static class RecentSwatchPanel extends SwatchPanel
+  {
+    /** The array for storing recently stored colors. */
+    Color[] colors;
+
+    /** The default color. */
+    public static final Color defaultColor = Color.GRAY;
+
+    /** The index of the array that is the start. */
+    int start = 0;
+
+    /**
+     * Creates a new RecentSwatchPanel object.
+     */
+    RecentSwatchPanel()
+    {
+      super();
+      numCols = 5;
+      numRows = 7;
+      initializeColors();
+      revalidate();
+    }
+
+    /**
+     * This method returns the color for the given position.
+     *
+     * @param x The x coordinate of the position.
+     * @param y The y coordinate of the position.
+     *
+     * @return The color for the given position.
+     */
+    public Color getColorForPosition(int x, int y)
+    {
+      if (x % (cellWidth + gap) > cellWidth
+          || y % (cellHeight + gap) > cellHeight)
+	// position is located in gap.
+	return null;
+
+      int row = y / (cellHeight + gap);
+      int col = x / (cellWidth + gap);
+
+      return colors[getIndexForCell(row, col)];
+    }
+
+    /**
+     * This method initializes the colors for the recent swatch panel.
+     */
+    protected void initializeColors()
+    {
+      colors = new Color[numRows * numCols];
+      for (int i = 0; i < colors.length; i++)
+	colors[i] = defaultColor;
+    }
+
+    /**
+     * This method returns the array index for the given row and column.
+     *
+     * @param row The row.
+     * @param col The column.
+     *
+     * @return The array index for the given row and column.
+     */
+    private int getIndexForCell(int row, int col)
+    {
+      return ((row * numCols) + col + start) % (numRows * numCols);
+    }
+
+    /**
+     * This method adds the given color to the beginning of the swatch panel.
+     *
+     * @param c The color to add.
+     */
+    private void addColorToQueue(Color c)
+    {
+      if (--start == -1)
+	start = numRows * numCols - 1;
+
+      colors[start] = c;
+    }
+
+    /**
+     * This method paints the panel with the given Graphics object.
+     *
+     * @param g The Graphics object to paint with.
+     */
+    public void paint(Graphics g)
+    {
+      Color saved = g.getColor();
+      Insets insets = getInsets();
+      int currX = insets.left;
+      int currY = insets.top;
+
+      for (int i = 0; i < numRows; i++)
+        {
+	  for (int j = 0; j < numCols; j++)
+	    {
+	      g.setColor(colors[getIndexForCell(i, j)]);
+	      g.fill3DRect(currX, currY, cellWidth, cellHeight, true);
+	      currX += cellWidth + gap;
+	    }
+	  currX = insets.left;
+	  currY += cellWidth + gap;
+        }
+    }
+
+    /**
+     * This method returns the tooltip text for the given MouseEvent.
+     *
+     * @param e The MouseEvent.
+     *
+     * @return The tooltip text.
+     */
+    public String getToolTipText(MouseEvent e)
+    {
+      Color c = getColorForPosition(e.getX(), e.getY());
+      if (c == null)
+	return null;
+      return c.getRed() + "," + c.getGreen() + "," + c.getBlue();
+    }
+  }
+
+  /**
+   * This class handles mouse events for the two swatch panels.
+   */
+  class MouseHandler extends MouseAdapter
+  {
+    /**
+     * This method is called whenever the mouse is pressed.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      SwatchPanel panel = (SwatchPanel) e.getSource();
+      Color c = panel.getColorForPosition(e.getX(), e.getY());
+      recentPalette.addColorToQueue(c);
+      DefaultSwatchChooserPanel.this.getColorSelectionModel().setSelectedColor(c);
+      DefaultSwatchChooserPanel.this.repaint();
+    }
+  }
+
+  /**
+   * This is the layout manager for the main panel.
+   */
+  static class MainPanelLayout implements LayoutManager
+  {
+    /**
+     * This method is called when a new component is added to the container.
+     *
+     * @param name The name of the component.
+     * @param comp The added component.
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+    }
+
+    /**
+     * This method is called to set the size and position of the child
+     * components for the given container.
+     *
+     * @param parent The container to lay out.
+     */
+    public void layoutContainer(Container parent)
+    {
+      Component[] comps = parent.getComponents();
+      Insets insets = parent.getInsets();
+      Dimension[] pref = new Dimension[comps.length];
+
+      int xpos = 0;
+      int ypos = 0;
+      int maxHeight = 0;
+      int totalWidth = 0;
+
+      for (int i = 0; i < comps.length; i++)
+        {
+	  pref[i] = comps[i].getPreferredSize();
+	  if (pref[i] == null)
+	    return;
+	  maxHeight = Math.max(maxHeight, pref[i].height);
+	  totalWidth += pref[i].width;
+        }
+
+      ypos = (parent.getSize().height - maxHeight) / 2 + insets.top;
+      xpos = insets.left + (parent.getSize().width - totalWidth) / 2;
+
+      for (int i = 0; i < comps.length; i++)
+        {
+	  if (pref[i] == null)
+	    continue;
+	  comps[i].setBounds(xpos, ypos, pref[i].width, pref[i].height);
+	  xpos += pref[i].width;
+        }
+    }
+
+    /**
+     * This method is called when a component is removed from the container.
+     *
+     * @param comp The component that was removed.
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+    }
+
+    /**
+     * This methods calculates the minimum layout size for the container.
+     *
+     * @param parent The container.
+     *
+     * @return The minimum layout size.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return preferredLayoutSize(parent);
+    }
+
+    /**
+     * This method returns the preferred layout size for the given container.
+     *
+     * @param parent The container.
+     *
+     * @return The preferred layout size.
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      int xmax = 0;
+      int ymax = 0;
+
+      Component[] comps = parent.getComponents();
+      Dimension pref;
+
+      for (int i = 0; i < comps.length; i++)
+        {
+	  pref = comps[i].getPreferredSize();
+	  if (pref == null)
+	    continue;
+	  xmax += pref.width;
+	  ymax = Math.max(ymax, pref.height);
+        }
+
+      Insets insets = parent.getInsets();
+
+      return new Dimension(insets.left + insets.right + xmax,
+                           insets.top + insets.bottom + ymax);
+    }
+  }
+
+  /**
+   * This is the layout manager for the recent swatch panel.
+   */
+  static class RecentPanelLayout implements LayoutManager
+  {
+    /**
+     * This method is called when a component is added to the container.
+     *
+     * @param name The name of the component.
+     * @param comp The added component.
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Nothing needs to be done.
+    }
+
+    /**
+     * This method sets the size and position of the child components of the
+     * given container.
+     *
+     * @param parent The container to lay out.
+     */
+    public void layoutContainer(Container parent)
+    {
+      Component[] comps = parent.getComponents();
+      Dimension parentSize = parent.getSize();
+      Insets insets = parent.getInsets();
+      int currY = insets.top;
+      Dimension pref;
+
+      for (int i = 0; i < comps.length; i++)
+        {
+	  pref = comps[i].getPreferredSize();
+	  if (pref == null)
+	    continue;
+	  comps[i].setBounds(insets.left, currY, pref.width, pref.height);
+	  currY += pref.height;
+        }
+    }
+
+    /**
+     * This method calculates the minimum layout size for the given container.
+     *
+     * @param parent The container.
+     *
+     * @return The minimum layout size.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return preferredLayoutSize(parent);
+    }
+
+    /**
+     * This method calculates the preferred layout size for the given
+     * container.
+     *
+     * @param parent The container.
+     *
+     * @return The preferred layout size.
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      int width = 0;
+      int height = 0;
+      Insets insets = parent.getInsets();
+      Component[] comps = parent.getComponents();
+      Dimension pref;
+      for (int i = 0; i < comps.length; i++)
+        {
+	  pref = comps[i].getPreferredSize();
+	  if (pref != null)
+	    {
+	      width = Math.max(width, pref.width);
+	      height += pref.height;
+	    }
+        }
+
+      return new Dimension(width + insets.left + insets.right,
+                           height + insets.top + insets.bottom);
+    }
+
+    /**
+     * This method is called whenever a component is removed from the
+     * container.
+     *
+     * @param comp The removed component.
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+      // Nothing needs to be done.
+    }
+  }
+
+  /**
+   * Creates a new DefaultSwatchChooserPanel object.
+   */
+  DefaultSwatchChooserPanel()
+  {
+    super();
+  }
+
+  /**
+   * This method updates the chooser panel with the new value from the
+   * JColorChooser.
+   */
+  public void updateChooser()
+  {
+  }
+
+  /**
+   * This method builds the chooser panel.
+   */
+  protected void buildChooser()
+  {
+    // The structure of the swatch panel is:
+    // One large panel (minus the insets).
+    // Inside that panel, there are two panels, one holds the palette.
+    // The other holds the label and the recent colors palette.
+    // The two palettes are two custom swatch panels.
+    setLayout(new MainPanelLayout());
+
+    JPanel mainPaletteHolder = new JPanel();
+    JPanel recentPaletteHolder = new JPanel();
+
+    mainPalette = new MainSwatchPanel();
+    recentPalette = new RecentSwatchPanel();
+    JLabel label = new JLabel("Recent:");
+
+    mouseHandler = new MouseHandler();
+    mainPalette.addMouseListener(mouseHandler);
+    recentPalette.addMouseListener(mouseHandler);
+
+    mainPaletteHolder.setLayout(new BorderLayout());
+    mainPaletteHolder.add(mainPalette, BorderLayout.CENTER);
+
+    recentPaletteHolder.setLayout(new RecentPanelLayout());
+    recentPaletteHolder.add(label);
+    recentPaletteHolder.add(recentPalette);
+
+    JPanel main = new JPanel();
+    main.add(mainPaletteHolder);
+    main.add(recentPaletteHolder);
+
+    this.add(main);
+  }
+
+  /**
+   * This method removes the chooser panel from the JColorChooser.
+   *
+   * @param chooser The JColorChooser this panel is being removed from.
+   */
+  public void uninstallChooserPanel(JColorChooser chooser)
+  {
+    recentPalette = null;
+    mainPalette = null;
+
+    removeAll();
+    super.uninstallChooserPanel(chooser);
+  }
+
+  /**
+   * This method returns the JTabbedPane displayed name.
+   *
+   * @return The name displayed in the JTabbedPane.
+   */
+  public String getDisplayName()
+  {
+    return "Swatches";
+  }
+
+  /**
+   * This method returns the small display icon.
+   *
+   * @return The small display icon.
+   */
+  public Icon getSmallDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the large display icon.
+   *
+   * @return The large display icon.
+   */
+  public Icon getLargeDisplayIcon()
+  {
+    return null;
+  }
+
+  /**
+   * This method paints the chooser panel with the given Graphics object.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  public void paint(Graphics g)
+  {
+    super.paint(g);
+  }
+
+  /**
+   * This method returns the tooltip text for the given MouseEvent.
+   *
+   * @param e The MouseEvent.
+   *
+   * @return The tooltip text.
+   */
+  public String getToolTipText(MouseEvent e)
+  {
+    return null;
+  }
+}
Index: javax/swing/event/DocumentEvent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/event/DocumentEvent.java,v
retrieving revision 1.3
diff -u -r1.3 DocumentEvent.java
--- javax/swing/event/DocumentEvent.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/event/DocumentEvent.java	6 Sep 2004 16:36:02 -0000
@@ -87,68 +87,49 @@
 
 	} // ElementChange
 
-	/**
-	 * EventType
-	 */
-	class EventType {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * INSERT
-		 */
-		EventType INSERT = new EventType("INSERT"); // TODO
-
-		/**
-		 * REMOVE
-		 */
-		EventType REMOVE = new EventType("REMOVE"); // TODO
-
-		/**
-		 * CHANGE
-		 */
-		EventType CHANGE = new EventType("CHANGE"); // TODO
-
-		/**
-		 * typeString
-		 */
-		private String type;
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor EventType
-		 * @param type TODO
-		 */
-		private EventType(String type) {
-			this.type = type;
-		} // EventType()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * toString
-		 * @returns String
-		 */
-		public String toString() {
-			return type; // TODO
-		} // toString()
-
-
-	} // EventType
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  /**
+   * EventType
+   */
+  class EventType
+  {
+    /**
+     * INSERT
+     */
+    public static final EventType INSERT = new EventType("INSERT"); // TODO
+
+    /**
+     * REMOVE
+     */
+    public static final EventType REMOVE = new EventType("REMOVE"); // TODO
+
+    /**
+     * CHANGE
+     */
+    public static final EventType CHANGE = new EventType("CHANGE"); // TODO
+
+    /**
+     * typeString
+     */
+    private String type;
+
+    /**
+     * Constructor EventType
+     * @param type TODO
+     */
+    private EventType(String type)
+    {
+      this.type = type;
+    }
+
+    /**
+     * toString
+     * @returns String
+     */
+    public String toString()
+    {
+      return type;
+    }
+  }
 
 	/**
 	 * getType
Index: javax/swing/event/SwingPropertyChangeSupport.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/event/SwingPropertyChangeSupport.java,v
retrieving revision 1.3
diff -u -r1.3 SwingPropertyChangeSupport.java
--- javax/swing/event/SwingPropertyChangeSupport.java	10 Jan 2004 21:07:43 -0000	1.3
+++ javax/swing/event/SwingPropertyChangeSupport.java	6 Sep 2004 16:36:02 -0000
@@ -210,8 +210,9 @@
 		PropertyChangeListener	listener;
 
 		// Check Values if they are equal
-		if (event.getOldValue() == null || event.getNewValue() == null ||
-			event.getOldValue().equals(event.getNewValue()) == true) {
+		if (event.getOldValue() == null && event.getNewValue() == null ||
+		    (event.getOldValue() != null && event.getNewValue() != null &&
+	            event.getOldValue().equals(event.getNewValue()))) {
 			return;
 		} // if
 
Index: javax/swing/event/UndoableEditListener.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/event/UndoableEditListener.java,v
retrieving revision 1.2
diff -u -r1.2 UndoableEditListener.java
--- javax/swing/event/UndoableEditListener.java	12 Oct 2003 13:25:59 -0000	1.2
+++ javax/swing/event/UndoableEditListener.java	6 Sep 2004 16:36:02 -0000
@@ -1,5 +1,5 @@
 /* UndoableEditListener.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,21 +37,20 @@
 
 package javax.swing.event;
 
-// Imports
 import java.util.EventListener;
 
+
 /**
  * UndoableEditListener public interface
  * @author Andrew Selkirk
  * @author Ronald Veldema
  */
-public interface UndoableEditListener extends EventListener {
-
-	/**
-	 * Undoable edit has happened
-	 * @param event Undoable Edit Event
-	 */
-	void undoableEditHappened(UndoableEditEvent event);
-
-
-} // UndoableEditListener
+public interface UndoableEditListener extends EventListener
+{
+  /**
+   * Undoable edit has happened
+   *
+   * @param event Undoable Edit Event
+   */
+  void undoableEditHappened(UndoableEditEvent event);
+}
Index: javax/swing/filechooser/FileSystemView.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/filechooser/FileSystemView.java,v
retrieving revision 1.2
diff -u -r1.2 FileSystemView.java
--- javax/swing/filechooser/FileSystemView.java	11 Jun 2003 13:20:40 -0000	1.2
+++ javax/swing/filechooser/FileSystemView.java	6 Sep 2004 16:36:02 -0000
@@ -1,5 +1,5 @@
 /* FileSystemView.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,7 +40,6 @@
 
 import java.io.File;
 import java.io.IOException;
-import javax.swing.Icon;
 
 /**
  * FileSystemView
Index: javax/swing/plaf/BorderUIResource.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/BorderUIResource.java,v
retrieving revision 1.8
diff -u -r1.8 BorderUIResource.java
--- javax/swing/plaf/BorderUIResource.java	1 Aug 2003 20:10:21 -0000	1.8
+++ javax/swing/plaf/BorderUIResource.java	6 Sep 2004 16:36:02 -0000
@@ -270,6 +270,8 @@
     extends BevelBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = -1275542891108351642L;
+    
     /**
      * Constructs a BevelBorderUIResource whose colors will be derived
      * from the background of the enclosed component. The background
@@ -279,7 +281,7 @@
      *
      * <p><img src="../border/doc-files/BevelBorder-1.png"
      * width="500" height="150"
-     * alt="[An illustration showing raised and lowered BevelBorders]" />
+     * alt="[An illustration showing raised and lowered BevelBorders]" /></p>
      *
      * @param bevelType the desired appearance of the border. The value
      *        must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -300,7 +302,7 @@
      *
      * <p><img src="../border/doc-files/BevelBorder-2.png" width="500"
      * height="150" alt="[An illustration showing BevelBorders that were
-     * constructed with this method]" />
+     * constructed with this method]" /></p>
      *
      * @param bevelType the desired appearance of the border. The value
      *        must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -340,7 +342,7 @@
      *
      * <p><img src="../border/doc-files/BevelBorder-3.png" width="500"
      * height="150" alt="[An illustration showing BevelBorders that
-     * were constructed with this method]" />
+     * were constructed with this method]" /></p>
      *
      * @param bevelType the desired appearance of the border. The value
      *        must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -399,6 +401,8 @@
     extends CompoundBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = 7550017084975167341L;
+    
     /**
      * Constructs a CompoundBorderUIResource with the specified inside
      * and outside borders.
@@ -432,7 +436,7 @@
    *
    * <p><img src="../border/doc-files/EmptyBorder-1.png"
    * width="290" height="200"
-   * alt="[An illustration of EmptyBorder]" />
+   * alt="[An illustration of EmptyBorder]" /></p>
    *
    * @author Brian Jones (cbj@gnu.org)
    * @author Sascha Brawer (brawer@dandelis.ch)
@@ -441,6 +445,8 @@
     extends EmptyBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = -4914187529340071708L;
+    
     /**
      * Constructs an empty border given the number of pixels required
      * on each side.
@@ -487,7 +493,7 @@
    *
    * <p><img src="../border/doc-files/EtchedBorder-1.png" width="500"
    * height="200" alt="[An illustration of the two EtchedBorder
-   * variants]" />
+   * variants]" /></p>
    *
    * @author Brian Jones (cbj@gnu.org)
    * @author Sascha Brawer (brawer@dandelis.ch)
@@ -496,6 +502,8 @@
     extends EtchedBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = -8186391754165296656L;
+    
     /**
      * Constructs an EtchedBorderUIResource that appears lowered into
      * the surface. The colors will be derived from the background
@@ -514,7 +522,7 @@
      *
      * <p><img src="../border/doc-files/EtchedBorder-1.png"
      * width="500" height="200" alt="[An illustration of the two
-     * EtchedBorder variants]" />
+     * EtchedBorder variants]" /></p>
      *
      * @param etchType the desired appearance of the border. The value
      *        must be either {@link javax.swing.border.EtchedBorder#RAISED}
@@ -555,7 +563,7 @@
      *
      * <p><img src="../border/doc-files/EtchedBorder-2.png" width="500"
      * height="200" alt="[An illustration that shows which pixels get
-     * painted in what color]" />
+     * painted in what color]" /></p>
      *
      * @param etchType the desired appearance of the border. The value
      *        must be either {@link javax.swing.border.EtchedBorder#RAISED}
@@ -588,7 +596,7 @@
    * such as the borders provided by this class.
    *
    * <p><img src="../border/doc-files/LineBorder-1.png" width="500"
-   * height="200" alt="[An illustration of two LineBorders] />
+   * height="200" alt="[An illustration of two LineBorders]" /></p>
    *
    * @author Brian Jones (cbj@gnu.org)
    * @author Sascha Brawer (brawer@dandelis.ch)
@@ -597,6 +605,8 @@
     extends LineBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = -6171232338180172310L;
+    
     /**
      * Constructs a LineBorderUIResource given its color.  The border
      * will be one pixel thick and have plain corners.
@@ -643,7 +653,7 @@
    * such as the borders provided by this class.
    *
    * <p><img src="../border/doc-files/MatteBorder-1.png" width="500"
-   * height="150" alt="[An illustration of two MatteBorders] />
+   * height="150" alt="[An illustration of two MatteBorders]" /></p>
    *
    * @author Brian Jones (cbj@gnu.org)
    * @author Sascha Brawer (brawer@dandelis.ch)
@@ -652,13 +662,15 @@
     extends MatteBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = -8107923147541851122L;
+    
     /**
      * Constructs a MatteBorderUIResource given the width on each side
      * and a fill color.
      *
      * <p><img src="../border/doc-files/MatteBorder-2.png" width="500"
      * height="150" alt="[A picture of a MatteBorder made by this
-     * constructor]" />
+     * constructor]" /></p>
      *
      * @param top the width of the border at its top edge.
      * @param left the width of the border at its left edge.
@@ -680,7 +692,7 @@
      *
      * <p><img src="../border/doc-files/MatteBorder-4.png" width="500"
      * height="150" alt="[A picture of a MatteBorder made by this
-     * constructor]" />
+     * constructor]" /></p>
      *
      * @param top the width of the border at its top edge.
      * @param left the width of the border at its left edge.
@@ -704,7 +716,7 @@
      *
      * <p><img src="../border/doc-files/MatteBorder-6.png" width="500"
      * height="150" alt="[A picture of a MatteBorder made by this
-     * constructor]" />
+     * constructor]" /></p>
      *
      * @param tileIcon an icon for tiling the border area. 
      */
@@ -731,6 +743,8 @@
     extends TitledBorder
     implements UIResource, Serializable
   {
+    private static final long serialVersionUID = 7667113547406407427L;
+    
     /**
      * Constructs a TitledBorderUIResource given the text of its title.
      *
Index: javax/swing/plaf/ComponentUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/ComponentUI.java,v
retrieving revision 1.5
diff -u -r1.5 ComponentUI.java
--- javax/swing/plaf/ComponentUI.java	1 Aug 2003 20:10:21 -0000	1.5
+++ javax/swing/plaf/ComponentUI.java	6 Sep 2004 16:36:02 -0000
@@ -52,7 +52,7 @@
  *
  * <p><img src="doc-files/ComponentUI-1.png" width="700" height="550"
  * alt="[UML diagram illustrating the architecture for pluggable
- * look and feels]" />
+ * look and feels]" /></p>
  *
  * <p>Components such as {@link javax.swing.JSlider} do not directly
  * implement operations related to the look and feel of the user
@@ -68,14 +68,14 @@
  * services. Soon before the end of its lifecycle, the
  * <code>ComponentUI</code> will receive an {@link #uninstallUI}
  * message, at which time the <code>ComponentUI</code> is expected to
- * undo any changes.
+ * undo any changes.</p>
  *
  * <p>Note that the <code>ui</code> of a <code>JComponent</code>
  * changes whenever the user switches between look and feels.  For
  * example, the <code>ui</code> property of a <code>JSlider</code>
  * could change from an instance of <code>MetalSliderUI</code> to an
  * instance of <code>FooSliderUI</code>. This switch can happen at any
- * time, but it will always be performed from inside the Swing thread.
+ * time, but it will always be performed from inside the Swing thread.</p>
  *
  * @author Sascha Brawer (brawer@dandelis.ch)
  */
@@ -96,26 +96,24 @@
    * The delegate object then receives an <code>installUI</code>
    * message.
    *
-   * <p>This method should perform the following tasks:
-   *
-   * <ul><li>Set visual properties such as borders, fonts, colors, or
-   * icons. However, no change should be performed for those
-   * properties whose values have been directly set by the client
-   * application. To allow the distinction, LookAndFeels are expected
-   * to use values that implement the {@link UIResource} marker
-   * interface, such as {@link BorderUIResource} or {@link
-   * ColorUIResource}.</li>
+   * <p>This method should perform the following tasks:</p>
    *
+   * <ul>
+   * <li>Set visual properties such as borders, fonts, colors, or
+   *     icons. However, no change should be performed for those
+   *     properties whose values have been directly set by the client
+   *     application. To allow the distinction, LookAndFeels are expected
+   *     to use values that implement the {@link UIResource} marker
+   *     interface, such as {@link BorderUIResource} or {@link
+   *     ColorUIResource}.</li>
    * <li>If necessary, install a {@link java.awt.LayoutManager}.</li>
-   *
    * <li>Embed custom sub-components. For instance, the UI delegate
-   * for a {@link javax.swing.JSplitPane} might install a special
-   * component for the divider.</li>
-   *
+   *     for a {@link javax.swing.JSplitPane} might install a special
+   *     component for the divider.</li>
    * <li>Register event listeners.</li>
-   *
    * <li>Set up properties related to keyborad navigation, such as
-   * mnemonics or focus traversal policies.</li></ul>
+   *     mnemonics or focus traversal policies.</li>
+   * </ul>
    *
    * @param c the component for which this delegate will provide
    *        services.
Index: javax/swing/plaf/basic/BasicArrowButton.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicArrowButton.java
diff -N javax/swing/plaf/basic/BasicArrowButton.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicArrowButton.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,384 @@
+/* BasicArrowButton.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Graphics;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import javax.swing.border.Border;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.SwingConstants;
+
+
+/**
+ * This class draws simple arrow buttons for the Basic Look and Feel.
+ */
+public class BasicArrowButton extends JButton implements SwingConstants
+{
+  /**
+   * A private helper class that draws icons.
+   */
+  private class arrowIcon implements Icon
+  {
+    /** The polygon that describes the icon. */
+    private Polygon arrow;
+
+    /** The size of the icon. */
+    private int size = 10;
+
+    /**
+     * Creates a new arrowIcon object using the given arrow polygon.
+     *
+     * @param arrow The polygon that describes the arrow.
+     */
+    public arrowIcon(Polygon arrow)
+    {
+      this.arrow = arrow;
+    }
+
+    /**
+     * Returns the height of the icon.
+     *
+     * @return The height of the icon.
+     */
+    public int getIconHeight()
+    {
+      return size;
+    }
+
+    /**
+     * Returns the width of the icon.
+     *
+     * @return The width of the icon.
+     */
+    public int getIconWidth()
+    {
+      return size;
+    }
+
+    /**
+     * Sets the size of the icon.
+     *
+     * @param size The size of the icon.
+     */
+    public void setSize(int size)
+    {
+      this.size = size;
+    }
+
+    /**
+     * Sets the arrow polygon.
+     *
+     * @param arrow The arrow polygon.
+     */
+    public void setArrow(Polygon arrow)
+    {
+      this.arrow = arrow;
+    }
+
+    /**
+     * Paints the icon.
+     *
+     * @param c The Component to paint for.
+     * @param g The Graphics object to draw with.
+     * @param x The X coordinate to draw at.
+     * @param y The Y coordinate to draw at.
+     */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+      Color arrowColor;
+      if (c.isEnabled())
+	arrowColor = darkShadow;
+      else
+	arrowColor = shadow;
+
+      paintIconImpl(g, x, y, arrowColor);
+    }
+
+    /**
+     * This method does the actual painting work.
+     *
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate to paint at.
+     * @param y The y coordinate to paint at.
+     * @param arrowColor The color to paint the arrow with.
+     */
+    public void paintIconImpl(Graphics g, int x, int y, Color arrowColor)
+    {
+      g.translate(x, y);
+
+      Color saved = g.getColor();
+
+      g.setColor(arrowColor);
+
+      g.fillPolygon(arrow);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The direction to point in. */
+  protected int direction;
+
+  /** The color the arrow is painted in if disabled and the bottom and
+   * right edges of the button. */
+  private transient Color shadow = Color.gray;
+
+  /** The color the arrow is painted in if enabled and the bottom and
+   * right edges of the button. */
+  private transient Color darkShadow = Color.BLACK;
+
+  /** The top and left edges of the button. */
+  private transient Color highlight = Color.BLACK;
+
+  /** The border around the ArrowButton. */
+  private transient Border tmpBorder = new Border()
+  {
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(0, 0, 0, 0);
+    }
+    
+    public boolean isBorderOpaque()
+    {
+      return false;
+    }
+    
+    public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
+    {
+      Rectangle bounds = getBounds();
+
+      Color saved = g.getColor();
+      g.setColor(highlight);
+
+      g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height);
+      g.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
+
+      g.setColor(shadow);
+
+      g.drawLine(bounds.x + 1, bounds.y + bounds.height - 1,
+                 bounds.x + bounds.width - 1, bounds.y + bounds.height - 1);
+      g.drawLine(bounds.x + bounds.width - 1, bounds.y + 1,
+                 bounds.x + bounds.width - 1, bounds.y + bounds.height - 1);
+
+      g.setColor(darkShadow);
+
+      g.drawLine(bounds.x, bounds.y + bounds.height, bounds.x + bounds.width,
+                 bounds.y + bounds.height);
+      g.drawLine(bounds.x + bounds.width, bounds.y, bounds.x + bounds.width,
+                 bounds.y + bounds.height);
+
+      g.setColor(saved);
+    }
+  };
+
+  /**
+   * Creates a new BasicArrowButton object.
+   *
+   * @param direction The direction the arrow points in.
+   */
+  public BasicArrowButton(int direction)
+  {
+    super();
+    setDirection(direction);
+    setBorder(tmpBorder);
+  }
+
+  /**
+   * Creates a new BasicArrowButton object with the given colors and 
+   * direction.
+   *
+   * @param direction The direction to point in.
+   * @param background The background color.
+   * @param shadow The shadow color.
+   * @param darkShadow The dark shadow color.
+   * @param highlight The highlight color.
+   */
+  public BasicArrowButton(int direction, Color background, Color shadow,
+                          Color darkShadow, Color highlight)
+  {
+    this(direction);
+    setBackground(background);
+    this.shadow = shadow;
+    this.darkShadow = darkShadow;
+    this.highlight = highlight;
+  }
+
+  /**
+   * This method returns the direction of the arrow.
+   *
+   * @return The direction of the arrow.
+   */
+  public int getDirection()
+  {
+    return direction;
+  }
+
+  /**
+   * This method changes the direction of the arrow.
+   *
+   * @param dir The new direction of the arrow.
+   */
+  public void setDirection(int dir)
+  {
+    Polygon arrow = getArrow(dir, 10);
+    if (getIcon() == null)
+      setIcon(new arrowIcon(arrow));
+    else
+      ((arrowIcon) getIcon()).setArrow(arrow);
+    this.direction = dir;
+  }
+
+  /**
+   * This method paints the arrow button.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  public void paint(Graphics g)
+  {
+    super.paint(g);
+  }
+
+  /**
+   * This method returns the preferred size of the arrow button.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize()
+  {
+    return new Dimension(getIcon().getIconWidth(), getIcon().getIconHeight());
+  }
+
+  /**
+   * This method returns the minimum size of the arrow button.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize()
+  {
+    return getPreferredSize();
+  }
+
+  /**
+   * This method returns the maximum size of the arrow button.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize()
+  {
+    return getPreferredSize();
+  }
+
+  /**
+   * The method paints a triangle with the given size and direction at
+   * the given x and y coordinates.
+   *
+   * @param g The Graphics object to paint with.
+   * @param x The x coordinate to paint at.
+   * @param y The y coordinate to paint at.
+   * @param size The size of the icon.
+   * @param direction The direction of the icon.
+   * @param isEnabled Whether it is enabled.
+   */
+  public void paintTriangle(Graphics g, int x, int y, int size, int direction,
+                            boolean isEnabled)
+  {
+    Polygon arrow = getArrow(direction, size);
+    arrowIcon arrowI = new arrowIcon(arrow);
+    arrowI.setSize(size);
+
+    Color arrowColor;
+    if (isEnabled())
+      arrowColor = darkShadow;
+    else
+      arrowColor = shadow;
+
+    arrowI.paintIconImpl(g, x, y, arrowColor);
+  }
+
+  /**
+   * This is a private helper that creates polygons for a given size 
+   * and direction.
+   *
+   * @param direction The direction of the arrow.
+   * @param size The size of the arrow.
+   *
+   * @return A new arrow polygon.
+   */
+  private Polygon getArrow(int direction, int size)
+  {
+    Polygon arrow;
+    double dsize = (double) size;
+		
+		int one = (int) (dsize * 1 / 10);
+    int two = (int) (dsize * 2 / 10);
+		int five = (int) (dsize * 5 / 10);
+    int eight = (int) (dsize * 8 / 10);
+		
+    switch (direction)
+      {
+      case NORTH:
+	arrow = new Polygon(new int[] { eight, five, one },
+	                    new int[] { eight, one, eight }, 3);
+	break;
+      case SOUTH:
+	arrow = new Polygon(new int[] { eight, five, two },
+	                    new int[] { two, eight, two }, 3);
+	break;
+      case EAST:
+      case RIGHT:
+	arrow = new Polygon(new int[] { two, eight, two },
+	                    new int[] { two, five, eight }, 3);
+	break;
+      case WEST:
+      case LEFT:
+	arrow = new Polygon(new int[] { eight, two, eight },
+	                    new int[] { two, five, eight }, 3);
+	break;
+      default:
+	throw new IllegalArgumentException("Invalid direction given.");
+      }
+    return arrow;
+  }
+}
Index: javax/swing/plaf/basic/BasicButtonListener.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicButtonListener.java
diff -N javax/swing/plaf/basic/BasicButtonListener.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicButtonListener.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,222 @@
+/* BasicButtonListener.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+public class BasicButtonListener
+  implements MouseListener, MouseMotionListener, FocusListener, 
+             ChangeListener, PropertyChangeListener
+{
+  public void propertyChange(PropertyChangeEvent e)
+  {
+  }
+  protected void checkOpacity(AbstractButton b) 
+  {    
+  }
+  public void focusGained(FocusEvent e) 
+  {    
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        if (button.isFocusPainted())
+          button.repaint();   
+      }
+  }
+  
+  public void focusLost(FocusEvent e)
+  {
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        ButtonModel model = button.getModel();
+        model.setArmed(false);
+
+        if (button.isFocusPainted())
+          button.repaint();   
+      }
+  }
+  public void installKeyboardActions(JComponent c)
+  {
+    c.getActionMap().put("pressed", 
+                         new AbstractAction() 
+                         {
+                           public void actionPerformed(ActionEvent e)          
+                           {
+                             AbstractButton button = (AbstractButton) e.getSource();
+                             ButtonModel model = button.getModel();
+                             // It is important that these transitions happen in this order.
+                             model.setArmed(true);
+                             model.setPressed(true);
+                           }
+                         });
+    
+    c.getActionMap().put("released", 
+                         new AbstractAction() 
+                         {
+                           public void actionPerformed(ActionEvent e)          
+                           {
+                             AbstractButton button = (AbstractButton) e.getSource();
+                             ButtonModel model = button.getModel();
+                             // It is important that these transitions happen in this order.
+                             model.setPressed(false);
+                             model.setArmed(false);
+                           }
+                       });    
+  }
+  public void uninstallKeyboardActions(JComponent c)
+  {
+    c.getActionMap().put("pressed", null);
+    c.getActionMap().put("released", null);
+  }
+  public void stateChanged(ChangeEvent e)
+  {
+  }
+  public void mouseMoved(MouseEvent e)
+  {
+  }
+  public void mouseDragged(MouseEvent e)
+  {
+  }
+  public void mouseClicked(MouseEvent e)
+  {
+  }
+
+  /**
+   * Accept a mouse press event and arm the button.
+   *
+   * @param e The mouse press event to accept
+   */
+  public void mousePressed(MouseEvent e)
+  {
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        ButtonModel model = button.getModel();
+        if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
+          {
+            // It is important that these transitions happen in this order.
+            model.setArmed(true);
+            model.setPressed(true);
+          }
+      }
+  }
+
+
+  /**
+   * Accept a mouse release event and set the button's 
+   * "pressed" property to <code>true</code>, if the model
+   * is armed. If the model is not armed, ignore the event.
+   *
+   * @param e The mouse release event to accept
+   */
+  public void mouseReleased(MouseEvent e)
+  {
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        ButtonModel model = button.getModel();
+        if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
+          {
+            // It is important that these transitions happen in this order.
+            model.setPressed(false);
+            model.setArmed(false);
+          }
+      }
+  }
+
+
+  /**
+   * Accept a mouse enter event and set the button's "rollover" property to
+   * <code>true</code>, if the button's "rolloverEnabled" property is
+   * <code>true</code>. If the button is currently armed and the mouse
+   * button is not held down, this enter event will also disarm the model.
+   *
+   * @param e The mouse enter event to accept
+   */
+  public void mouseEntered(MouseEvent e)
+  {
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        ButtonModel model = button.getModel();
+        if (button.isRolloverEnabled())
+          model.setRollover(true);
+        
+        if (model.isPressed() 
+            && (e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
+          model.setArmed(true);
+        else
+          model.setArmed(false);
+      }
+  }
+
+  /**
+   * Accept a mouse exit event and set the button's model's "rollover"
+   * property to <code>false</code>, if it's "rolloverEnabled" property is
+   * <code>true</code>. Also disarm the button.
+   *
+   * @param e The mouse exit event to accept
+   */
+  public void mouseExited(MouseEvent e)
+  {
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        ButtonModel model = button.getModel();
+        if (button.isRolloverEnabled())
+          model.setRollover(false);
+        model.setArmed(false);
+      }
+  }
+}
Index: javax/swing/plaf/basic/BasicButtonUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicButtonUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicButtonUI.java
--- javax/swing/plaf/basic/BasicButtonUI.java	10 Jan 2004 21:59:30 -0000	1.4
+++ javax/swing/plaf/basic/BasicButtonUI.java	6 Sep 2004 16:36:02 -0000
@@ -35,182 +35,379 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
-import java.awt.Insets;
+import java.awt.Graphics2D;
 import java.awt.Rectangle;
+import java.awt.Stroke;
+
 import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ButtonUI;
 import javax.swing.plaf.ComponentUI;
 
 public class BasicButtonUI extends ButtonUI
 {
-    int gap = 3;
-    //    int y_text_space = 2, x_text_space + 5;
-
-    Color textColor, disabledTextColor;
-    Color pressedBackgroundColor;
-    Color normalBackgroundColor;
-
-
-    public static ComponentUI createUI(final JComponent c) 
-    {
-	return new BasicButtonUI();
-    }
-
-    
-    public void installUI(final JComponent c) 
-    {
-	super.installUI(c);
-
-	textColor                = new Color(0,0,0);
-	disabledTextColor        = new Color(130, 130, 130);
-	pressedBackgroundColor   = new Color(150,150,150);
-	pressedBackgroundColor   = new Color(150,150,150);
-	normalBackgroundColor    = new Color(192,192,192);
-    }
+  /**
+   * A constant used to pad out elements in the button's layout and
+   * preferred size calculations.
+   */
+  protected int defaultTextIconGap = 4;
+
+  /**
+   * A constant added to the defaultTextIconGap to adjust the text
+   * within this particular button.
+   */
+  protected int defaultTextShiftOffset = 0;
+
+  private int textShiftOffset;
+
+  private Color focusColor;
+
+  /**
+   * Factory method to create an instance of BasicButtonUI for a given
+   * {@link JComponent}, which should be an {@link AbstractButton}.
+   *
+   * @param c The component to create a UI got
+   *
+   * @return A new UI capable of drawing the component
+   */
+  public static ComponentUI createUI(final JComponent c) 
+  {
+    return new BasicButtonUI();
+  }
+
+  public int getDefaultTextIconGap(AbstractButton b)
+  {
+    return defaultTextIconGap;
+  }
+
+  protected void clearTextShiftOffset()
+  {
+    textShiftOffset = 0;
+  }
+  
+  protected int getTextShiftOffset()
+  {
+    return textShiftOffset;
+  }
+
+  protected void setTextShiftOffset()
+  {
+    textShiftOffset = defaultTextShiftOffset;
+  }
+
+  protected void installDefaults(AbstractButton b)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    focusColor = defaults.getColor("Button.focus");
+    b.setForeground(defaults.getColor("Button.foreground"));
+    b.setBackground(defaults.getColor("Button.background"));
+    b.setMargin(defaults.getInsets("Button.margin"));
+    b.setBorder(defaults.getBorder("Button.border"));
+    b.setIconTextGap(defaults.getInt("Button.textIconGap"));
+    b.setInputMap(JComponent.WHEN_FOCUSED, 
+                  (InputMap) defaults.get("Button.focusInputMap"));
+    b.setOpaque(true);
+  }
+
+  protected void uninstallDefaults(AbstractButton b)
+  {
+    b.setForeground(null);
+    b.setBackground(null);
+    b.setBorder(null);
+    b.setIconTextGap(defaultTextIconGap);
+    b.setMargin(null);
+  }
+
+  protected BasicButtonListener listener;
+
+  protected BasicButtonListener createButtonListener(AbstractButton b)
+  {
+    return new BasicButtonListener();
+  }
+
+  public void installListeners(AbstractButton b)
+  {
+    listener = createButtonListener(b);
+    b.addChangeListener(listener);
+    b.addPropertyChangeListener(listener);
+    b.addFocusListener(listener);    
+    b.addMouseListener(listener);
+    b.addMouseMotionListener(listener);
+  }
+
+  public void uninstallListeners(AbstractButton b)
+  {
+    b.removeChangeListener(listener);
+    b.removePropertyChangeListener(listener);
+    b.removeFocusListener(listener);    
+    b.removeMouseListener(listener);
+    b.removeMouseMotionListener(listener);
+  }
+
+  protected void installKeyboardActions(AbstractButton b)
+  {
+    listener.installKeyboardActions(b);
+  }
+
+  protected void uninstallKeyboardActions(AbstractButton b)
+  {
+    listener.uninstallKeyboardActions(b);
+  }
+
+  /**
+   * Install the BasicButtonUI as the UI for a particular component.
+   * This means registering all the UI's listeners with the component,
+   * and setting any properties of the button which are particular to 
+   * this look and feel.
+   *
+   * @param c The component to install the UI into
+   */
+  public void installUI(final JComponent c) 
+  {
+    super.installUI(c);
+    if (c instanceof AbstractButton)
+      {
+        AbstractButton b = (AbstractButton) c;
+        installDefaults(b);
+        installListeners(b);
+        installKeyboardActions(b);
+      }
+  }
+
+  /**
+   * Calculate the preferred size of this component, by delegating to
+   * {@link BasicGraphicsUtils.getPreferredButtonSize}.
+   *
+   * @param c The component to measure
+   *
+   * @return The preferred dimensions of the component
+   */
+  public Dimension getPreferredSize(JComponent c) 
+  {
+    AbstractButton b = (AbstractButton)c;
+    Dimension d = 
+      BasicGraphicsUtils.getPreferredButtonSize
+      (b, defaultTextIconGap + defaultTextShiftOffset);
+    return d;
+  }
+
+  static private Icon currentIcon(AbstractButton b)
+  {
+    Icon i = b.getIcon();
+    ButtonModel model = b.getModel();
+
+    if (model.isPressed() && b.getPressedIcon() != null)
+      i = b.getPressedIcon();
+
+    else if (model.isRollover())
+      {
+        if (b.isSelected() && b.getRolloverSelectedIcon() != null)
+          i = b.getRolloverSelectedIcon();
+        else if (b.getRolloverIcon() != null)
+          i = b.getRolloverIcon();
+      }    
+
+    else if (b.isSelected())
+      {
+        if (b.isEnabled() && b.getSelectedIcon() != null)
+          i = b.getSelectedIcon();
+        else if (b.getDisabledSelectedIcon() != null)
+          i = b.getDisabledSelectedIcon();
+      }
+
+    else if (! b.isEnabled() && b.getDisabledIcon() != null)
+      i = b.getDisabledIcon();
+
+    return i;
+  }
+
+  /**
+   * Paint the component, which is an {@link AbstractButton}, according to 
+   * its current state.
+   *
+   * @param g The graphics context to paint with
+   * @param c The component to paint the state of
+   */
+  public void paint(Graphics g, JComponent c)
+  {      
+    AbstractButton b = (AbstractButton) c;
+
+    Rectangle tr = new Rectangle();
+    Rectangle ir = new Rectangle();
+    Rectangle vr = new Rectangle();
+    Rectangle br = new Rectangle();
+
+    Font f = c.getFont();
+
+    g.setFont(f);
+
+    SwingUtilities.calculateInnerArea(b, br);
+    SwingUtilities.calculateInsetArea(br, b.getMargin(), vr);    
+    String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f), 
+                                                     b.getText(),
+                                                     currentIcon(b),
+                                                     b.getVerticalAlignment(), 
+                                                     b.getHorizontalAlignment(),
+                                                     b.getVerticalTextPosition(), 
+                                                     b.getHorizontalTextPosition(),
+                                                     vr, ir, tr, 
+                                                     b.getIconTextGap() 
+                                                     + defaultTextShiftOffset);
     
-
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	AbstractButton b = (AbstractButton)c;
-	Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
-	//	System.out.println("^^^^^^^^^^^^^^^^^^^^^^   BASIC-PREF="+d + ",T="+b.text);
-	return d;
-    }
-    
-
-    public void paint(Graphics g, JComponent c)
-    {      
-	AbstractButton b = (AbstractButton) c;
-
-	Rectangle tr = new Rectangle();
-	Rectangle ir = new Rectangle();
-	Rectangle vr = new Rectangle();
-
-        Font f = c.getFont();
-
-        g.setFont(f);
-
-        FontMetrics fm = g.getFontMetrics(f);
-
-        Insets i = c.getInsets();
-
-        vr.x      = i.left;
-        vr.y      = i.top;
-        vr.width  = b.getWidth()  - (i.right  + vr.x);
-        vr.height = b.getHeight() - (i.bottom + vr.y);
-	
-	//System.out.println("             VIEW-RECT-BUTTON="+vr+", insets="+i+", FONTM="+fm);
+    if ((b.getModel().isArmed() && b.getModel().isPressed()) 
+        || b.isSelected())
+      paintButtonPressed(g, b);
+    else
+      paintButtonNormal(g, br, c);
 	
-	String text = SwingUtilities.layoutCompoundLabel(c,
-							 fm, 
-							 b.getText(),
-							 b.getIcon(),
-							 b.getVerticalAlignment(), 
-							 b.getHorizontalAlignment(),
-							 b.getVerticalTextPosition(), 
-							 b.getHorizontalTextPosition(),
-							 vr,
-							 ir,
-							 tr,
-							 gap);
-
-        if (b.getModel().isPressed() ||
-	    b.getModel().isSelected())
-	    {
-	      //System.out.println("paint pressed");
-		paintButtonPressed(g, c);
-	    }
-	else
-	    {
-	      //System.out.println("paint normal");
-		paintButtonNormal(g, c);
-	    }
-	
-	paintIcon(g, c, ir);
-	paintText(g, c, tr, b.getText());
-	paintFocus(g, c, vr, tr, ir);
-    }
-
-
-    protected void paintFocus(Graphics g, 
-			      JComponent c,
-			      Rectangle vr,
-			      Rectangle tr,
-			      Rectangle ir)
-    {
-    }
-
-    protected void paintIcon(Graphics g, 
-			     JComponent c, 
-			     Rectangle iconRect)
-    {
-	AbstractButton b = (AbstractButton) c;
-	if (b.getIcon() != null)
-	    {
-		int x = iconRect.x;
-		int y = iconRect.y;
-
-		System.out.println("WE HAVE AN ICON: " + b.getIcon());
- 
-		b.getIcon().paintIcon(c, g, x, y);
-	    }
-	else
-	    {
-		//System.out.println("NO ICON FOR BUTTON:" + b.text);
-	    }
-    }
-
-    protected void paintButtonPressed(Graphics g,
-				      JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(pressedBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
+    paintIcon(g, c, ir);
+    if (text != null)
+      paintText(g, b, tr, text);
+    paintFocus(g, b, vr, tr, ir);
+  }
+
+  /**
+   * Paint any focus decoration this {@link JComponent} might have.  The
+   * component, which in this case will be an {@link AbstractButton},
+   * should only have focus decoration painted if it has the focus, and its
+   * "focusPainted" property is <code>true</code>.
+   *
+   * @param g Graphics context to paint with
+   * @param b Button to paint the focus of
+   * @param vr Visible rectangle, the area in which to paint
+   * @param tr Text rectangle, contained in visible rectangle
+   * @param ir Icon rectangle, contained in visible rectangle
+   *
+   * @see AbstractButton.isFocusPainted()
+   * @see JComponent.hasFocus()
+   */
+  protected void paintFocus(Graphics g, AbstractButton b, Rectangle vr,
+                            Rectangle tr, Rectangle ir)
+  {
+    if (b.hasFocus() && b.isFocusPainted())
+      {
+        Color saved_color = g.getColor();
+        g.setColor(focusColor);
+        Rectangle focusRect = ir.union(tr);
+        g.drawRect(focusRect.x, focusRect.y,
+                   focusRect.width, focusRect.height);
+        g.setColor(saved_color);
+      }
+  }
+
+  /**
+   * Paint the icon for this component. Depending on the state of the
+   * component and the availability of the button's various icon
+   * properties, this might mean painting one of several different icons.
+   *
+   * @param g Graphics context to paint with
+   * @param c Component to paint the icon of
+   * @param iconRect Rectangle in which the icon should be painted
+   */
+  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
+  {
+    AbstractButton b = (AbstractButton) c;
+    Icon i = currentIcon(b);
+
+    if (i != null)
+      i.paintIcon(c, g, iconRect.x, iconRect.y);
+  }
+
+  /**
+   * Paints the background area of an {@link AbstractButton} in the pressed
+   * state.  This means filling the supplied area with the {@link
+   * pressedBackgroundColor}.
+   *
+   * @param g The graphics context to paint with
+   * @param b The button to paint the state of
+   */
+  protected void paintButtonPressed(Graphics g, AbstractButton b)
+  {
+    if (b.isContentAreaFilled())
+      {
+	Rectangle area = new Rectangle();
+	SwingUtilities.calculateInnerArea(b, area);
+        g.setColor(b.getBackground().darker());
+        g.fillRect(area.x, area.y, area.width, area.height);
+      }
+  }
     
-    protected void paintButtonNormal(Graphics g,
-				     JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(normalBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
+  /**
+   * Paints the background area of an {@link AbstractButton} in the normal,
+   * non-pressed state.  This means filling the supplied area with the
+   * {@link normalBackgroundColor}.
+   *
+   * @param g The graphics context to paint with
+   * @param area The area in which to paint
+   * @param b The component to paint the state of
+   */
+  private void paintButtonNormal(Graphics g, Rectangle area, JComponent b)
+  {
+    if (((AbstractButton)b).isContentAreaFilled() && b.isOpaque())
+      {
+        g.setColor(b.getBackground());
+        g.fillRect(area.x, area.y, area.width, area.height);
+      }
+  }
     
-    protected void paintText(Graphics g,
-			     JComponent c,
-			     Rectangle textRect,
-			     String text) 
-    {	
-	Font f = c.getFont();
-
-        g.setFont(f);
-
-        FontMetrics fm = g.getFontMetrics(f);
-
-	g.setColor(c.isEnabled() ? textColor : disabledTextColor);
-
-	BasicGraphicsUtils.drawString(g,
-				      text, 
-				      0,
-				      textRect.x, 
-				      textRect.y + fm.getAscent()/2);
-    } 
+  /**
+   * Paints the "text" property of an {@link AbstractButton}, using the
+   * {@link textColor} color.
+   *
+   * @param g The graphics context to paint with
+   * @param c The component to paint the state of
+   * @param textRect The area in which to paint the text
+   * @param text The text to paint
+   */
+  protected void paintText(Graphics g, JComponent c, Rectangle textRect,
+                           String text) 
+  {	
+    paintText(g, (AbstractButton) c, textRect, text);
+  }
+
+  /**
+   * Paints the "text" property of an {@link AbstractButton}, using the
+   * {@link textColor} color.
+   *
+   * @param g The graphics context to paint with
+   * @param b The button to paint the state of
+   * @param textRect The area in which to paint the text
+   * @param text The text to paint
+   *
+   * @since 1.4
+   */
+  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
+			   String text)
+  {
+    Font f = b.getFont();
+    g.setFont(f);
+    FontMetrics fm = g.getFontMetrics(f);
+
+    if (b.isEnabled())
+      {
+	g.setColor(b.getForeground());
+	g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+      }
+    else
+      {
+	g.setColor(b.getBackground().brighter());
+	g.drawString(text, textRect.x, textRect.y + fm.getAscent());
+	g.setColor(b.getBackground().darker());
+	g.drawString(text, textRect.x + 1, textRect.y + fm.getAscent() + 1);
+      }
+  } 
 }
-
-
-
-
Index: javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
diff -N javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java	6 Sep 2004 16:36:02 -0000
@@ -0,0 +1,103 @@
+/* BasicCheckBoxMenuItemUI.java
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.MouseEvent;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+
+
+/**
+ * DOCUMENT ME!
+ */
+public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
+{
+  /**
+   * Factory method to create a BasicCheckBoxMenuItemUI for the given {@link
+   * JComponent}, which should be a JCheckBoxMenuItem
+   *
+   * @param c The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicCheckBoxMenuItemUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(final JComponent c)
+  {
+    return new BasicCheckBoxMenuItemUI();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return $returnType$ DOCUMENT ME!
+   */
+  protected String getPropertyPrefix()
+  {
+    return null;
+  }
+
+  /**
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this JRadioButtonMenuItem
+   */
+  protected void installDefaults()
+  {
+    super.installDefaults();
+
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    checkIcon = defaults.getIcon("CheckBoxMenuItem.checkIcon");
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param item DOCUMENT ME!
+   * @param e DOCUMENT ME!
+   * @param path DOCUMENT ME!
+   * @param manager DOCUMENT ME!
+   */
+  public void processMouseEvent(JMenuItem item, MouseEvent e,
+                                MenuElement[] path,
+                         MenuSelectionManager manager)
+  {
+  }
+}
Index: javax/swing/plaf/basic/BasicCheckBoxUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicCheckBoxUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicCheckBoxUI.java
--- javax/swing/plaf/basic/BasicCheckBoxUI.java	10 Jan 2004 21:59:30 -0000	1.4
+++ javax/swing/plaf/basic/BasicCheckBoxUI.java	6 Sep 2004 16:36:02 -0000
@@ -38,82 +38,28 @@
 
 package javax.swing.plaf.basic;
 
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import javax.swing.AbstractButton;
+import javax.swing.Icon;
 import javax.swing.JComponent;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 
 public class BasicCheckBoxUI extends BasicRadioButtonUI
 {  
-    public static ComponentUI createUI(final JComponent c)  {
-	return new BasicCheckBoxUI();
-    }
-
-    
-    public void installUI(final JComponent c)  {
-	super.installUI(c);
-    }
-    
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	AbstractButton b = (AbstractButton)c;
-	Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
-	//System.out.println("^^^^^^^^^^^^^^^^^^^^^^   BASIC-PREF="+d + ",T="+b.text);
-	return d;
-    }
-    
-    protected void paintFocus(Graphics g, 
-			      JComponent c,
-			      Rectangle vr,
-			      Rectangle tr,
-			      Rectangle ir)
-    {
-    }
-
-    protected void paintIcon(Graphics g, 
-			     JComponent c, 
-			     Rectangle iconRect)
-    {
-    }
-
-    protected void paintButtonPressed(Graphics g,
-				      JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(pressedBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
-    
-    protected void paintButtonNormal(Graphics g,
-				     JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(normalBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
-    protected void paintText(Graphics g,
-			     JComponent c,
-			     Rectangle textRect,
-			     String text) 
-    {
-	//        AbstractButton b = (AbstractButton) c;
-	
-	//	System.out.println("drawing string: " + text + ", at:" + textRect);
-	
-	g.setColor(textColor);
-	BasicGraphicsUtils.drawString(g,
-				      text, 
-				      0,
-				      textRect.x, 
-				      textRect.y);
-    } 
+  
+  public static ComponentUI createUI(final JComponent c)  {
+    return new BasicCheckBoxUI();
+  }
+
+  public Icon getDefaultIcon()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    return defaults.getIcon("CheckBox.icon");
+  }
+  
+  public void installUI(final JComponent c)  {
+    super.installUI(c);
+  }  
 }
 
 
Index: javax/swing/plaf/basic/BasicColorChooserUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicColorChooserUI.java
diff -N javax/swing/plaf/basic/BasicColorChooserUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicColorChooserUI.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,338 @@
+/* BasicColorChooserUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JColorChooser;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.colorchooser.AbstractColorChooserPanel;
+import javax.swing.colorchooser.ColorChooserComponentFactory;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ColorChooserUI;
+import javax.swing.plaf.ComponentUI;
+
+
+/**
+ * This is the UI Class for the JColorChooser in the Basic Look and Feel.
+ */
+public class BasicColorChooserUI extends ColorChooserUI
+{
+  /**
+   * This helper class handles property changes from the JColorChooser.
+   */
+  public class PropertyHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called when any of the properties of the JColorChooser
+     * change.
+     *
+     * @param e The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName() == JColorChooser.CHOOSER_PANELS_PROPERTY)
+	makeTabs(chooser.getChooserPanels());
+      else if (e.getPropertyName() == JColorChooser.PREVIEW_PANEL_PROPERTY)
+	updatePreviewPanel(chooser.getPreviewPanel());
+      else if (e.getPropertyName() == JColorChooser.SELECTION_MODEL_PROPERTY)
+	((AbstractColorChooserPanel) pane.getSelectedComponent())
+	.updateChooser();
+
+      chooser.repaint();
+    }
+  }
+
+  /**
+   * This is a helper class that listens to the Model of the JColorChooser for
+   * color change events so it can update the preview panel.
+   */
+  private class PreviewListener implements ChangeListener
+  {
+    /**
+     * This method is called whenever the JColorChooser's color changes.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      if (pane != null)
+        {
+	  AbstractColorChooserPanel panel = (AbstractColorChooserPanel) pane
+	                                    .getSelectedComponent();
+	  if (panel != null)
+	    panel.updateChooser();
+        }
+      chooser.repaint();
+    }
+  }
+
+  /**
+   * This helper class listens to the JTabbedPane that is used for tab
+   * changes.
+   */
+  private class TabPaneListener implements ChangeListener
+  {
+    /**
+     * This method is called whenever a different tab is selected in the
+     * JTabbedPane.
+     *
+     * @param e The ChangeEvent.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      // Need to do this because we don't update all the tabs when they're not
+      // visible, so they are not informed of new colors when they're hidden.
+      AbstractColorChooserPanel comp = (AbstractColorChooserPanel) pane
+                                       .getSelectedComponent();
+      comp.updateChooser();
+    }
+  }
+
+  /** An array of default choosers to use in the JColorChooser. */
+  protected AbstractColorChooserPanel[] defaultChoosers;
+
+  /** The listener for the preview panel. */
+  protected ChangeListener previewListener;
+
+  /** The PropertyChangeListener for the JColorChooser. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The JColorChooser. */
+  private JColorChooser chooser;
+
+  /** The JTabbedPane that is used. */
+  private JTabbedPane pane;
+
+  /** The Container that holds the preview panel. */
+  private Container prevContainer;
+
+  /**
+   * Creates a new BasicColorChooserUI object.
+   */
+  public BasicColorChooserUI()
+  {
+    super();
+  }
+
+  /**
+   * This method creates a new UI Component for the given JComponent.
+   *
+   * @param c The JComponent to create an UI for.
+   *
+   * @return A new BasicColorChooserUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicColorChooserUI();
+  }
+
+  /**
+   * This method creates the default chooser panels for the JColorChooser.
+   *
+   * @return The default chooser panels.
+   */
+  protected AbstractColorChooserPanel[] createDefaultChoosers()
+  {
+    return ColorChooserComponentFactory.getDefaultChooserPanels();
+  }
+
+  /**
+   * This method installs the UI Component for the given JComponent.
+   *
+   * @param c The JComponent to install this UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JColorChooser)
+      {
+	chooser = (JColorChooser) c;
+	chooser.setLayout(new BorderLayout());
+
+	// Do this first, so we avoid doing work for property change events.
+	defaultChoosers = createDefaultChoosers();
+	chooser.setChooserPanels(defaultChoosers);
+	pane = new JTabbedPane();
+
+	pane.addChangeListener(new ChangeListener()
+	    {
+	      public void stateChanged(ChangeEvent e)
+	      {
+		pane.repaint();
+	      }
+	    });
+
+	makeTabs(defaultChoosers);
+
+	chooser.add(pane, BorderLayout.NORTH);
+
+	installPreviewPanel();
+
+	installDefaults();
+	installListeners();
+      }
+  }
+
+  /**
+   * This method adds tabs to the JTabbedPane for the chooserPanels defined in
+   * the JColorChooser.
+   *
+   * @param panels The Panels that need tabs to be made for them.
+   */
+  private void makeTabs(AbstractColorChooserPanel[] panels)
+  {
+    pane.removeAll();
+    for (int i = 0; i < panels.length; i++)
+      pane.addTab(panels[i].getDisplayName(), panels[i].getSmallDisplayIcon(),
+                  panels[i]);
+  }
+
+  /**
+   * This method uninstalls this UI for the given JComponent.
+   *
+   * @param c The JComponent that will have this UI removed.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallListeners();
+    uninstallDefaults();
+
+    pane = null;
+    chooser = null;
+  }
+
+  /**
+   * This method installs the preview panel for the JColorChooser.
+   */
+  protected void installPreviewPanel()
+  {
+    updatePreviewPanel(ColorChooserComponentFactory.getPreviewPanel());
+  }
+
+  /**
+   * This is a helper method that swaps the existing preview panel with the
+   * given panel.
+   *
+   * @param preview The new preview panel.
+   */
+  private void updatePreviewPanel(JComponent preview)
+  {
+    if (prevContainer == null)
+      {
+	prevContainer = new JPanel();
+	prevContainer.setLayout(new BorderLayout());
+	chooser.add(prevContainer, BorderLayout.CENTER);
+      }
+    prevContainer.removeAll();
+    prevContainer.add(preview, BorderLayout.CENTER);
+  }
+
+  /**
+   * This method installs the default properties given by the Basic Look and
+   * Feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    chooser.setFont(defaults.getFont("ColorChooser.font"));
+    chooser.setForeground(defaults.getColor("ColorChooser.foreground"));
+    chooser.setBackground(defaults.getColor("ColorChooser.background"));
+  }
+
+  /**
+   * This method uninstalls the default properties given by the Basic Look and
+   * Feel.
+   */
+  protected void uninstallDefaults()
+  {
+    chooser.setBackground(null);
+    chooser.setForeground(null);
+    chooser.setFont(null);
+  }
+
+  /**
+   * This method installs any listeners required for this UI to function.
+   */
+  protected void installListeners()
+  {
+    propertyChangeListener = createPropertyChangeListener();
+    previewListener = new PreviewListener();
+
+    chooser.addPropertyChangeListener(propertyChangeListener);
+    chooser.getSelectionModel().addChangeListener(previewListener);
+
+    pane.addChangeListener(new TabPaneListener());
+  }
+
+  /**
+   * This method creates the PropertyChangeListener used for listening to the
+   * JColorChooser.
+   *
+   * @return A PropertyChangeListener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyHandler();
+  }
+
+  /**
+   * This method uninstalls any listeners that were previously installed by
+   * the UI.
+   */
+  protected void uninstallListeners()
+  {
+    chooser.removePropertyChangeListener(propertyChangeListener);
+    chooser.getSelectionModel().removeChangeListener(previewListener);
+
+    previewListener = null;
+    propertyChangeListener = null;
+  }
+}
Index: javax/swing/plaf/basic/BasicComboBoxEditor.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicComboBoxEditor.java
diff -N javax/swing/plaf/basic/BasicComboBoxEditor.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicComboBoxEditor.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,170 @@
+/* BasicComboBoxEditor.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Component;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import javax.swing.ComboBoxEditor;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import javax.swing.plaf.UIResource;
+
+
+/**
+ * This is a component that is responsible for displaying/editting  selected
+ * item in comboBox. By default, the  JTextField is returned as
+ * BasicComboBoxEditor.
+ *
+ * @author Olga Rodimina
+ */
+public class BasicComboBoxEditor extends Object implements ComboBoxEditor,
+                                                           FocusListener
+{
+  protected JTextField editor;
+
+  /**
+   * Creates a new BasicComboBoxEditor object.
+   */
+  public BasicComboBoxEditor()
+  {
+    editor = new JTextField();
+    editor.setBorder(new EmptyBorder(1, 1, 1, 1));
+  }
+
+  /**
+   * This method returns textfield that will be used by the combo  box to
+   * display/edit currently selected item in the combo box.
+   *
+   * @return textfield that will be used by the combo box to  display/edit
+   *         currently selected item
+   */
+  public Component getEditorComponent()
+  {
+    return editor;
+  }
+
+  /**
+   * Sets item that should be editted when any editting operation is performed
+   * by the user. The value is always equal to the currently selected value
+   * in the combo box. Thus whenever a different value is selected from the
+   * combo box list then this method should be  called to change editting
+   * item to the new selected item.
+   *
+   * @param selectedItem item that is currently selected in the combo box
+   */
+  public void setItem(Object item)
+  {
+    editor.setText(item.toString());
+  }
+
+  /**
+   * This method returns item that is currently editable.
+   *
+   * @return item in the combo box that is currently editable
+   */
+  public Object getItem()
+  {
+    return editor.getText();
+  }
+
+  public void selectAll()
+  {
+    editor.selectAll();
+  }
+
+  /**
+   * This method is called when textfield gains focus. This will enable
+   * editing of the selected item.
+   *
+   * @param e the FocusEvent describing change in focus.
+   */
+  public void focusGained(FocusEvent e)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method is called when textfield loses focus. If during this time any
+   * editting operation was performed by the user, then it will be cancelled
+   * and selected item will not be changed.
+   *
+   * @param e the FocusEvent describing change in focus
+   */
+  public void focusLost(FocusEvent e)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method adds actionListener to the editor. If the user will edit
+   * currently selected item in the textfield and pressEnter, then action
+   * will be performed. The actionPerformed of this ActionListener should
+   * change the selected item of the comboBox to the newly editted  selected
+   * item.
+   *
+   * @param l the ActionListener responsible for changing selected item of the
+   *        combo box when it is editted by the user.
+   */
+  public void addActionListener(ActionListener l)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method removes actionListener from the textfield.
+   *
+   * @param l the ActionListener to remove from the textfield.
+   */
+  public void removeActionListener(ActionListener l)
+  {
+    // FIXME: Need to implement
+  }
+
+  public static class UIResource extends BasicComboBoxEditor
+    implements javax.swing.plaf.UIResource
+  {
+    /**
+     * Creates a new UIResource object.
+     */
+    public UIResource()
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicComboBoxRenderer.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicComboBoxRenderer.java
diff -N javax/swing/plaf/basic/BasicComboBoxRenderer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicComboBoxRenderer.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,143 @@
+/* BasicComboBoxRenderer.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.io.Serializable;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.SwingConstants;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.plaf.UIResource;
+
+
+/**
+ * This class is renderer for the combo box. 
+ *
+ * @author Olga Rodimina
+ */
+public class BasicComboBoxRenderer extends JLabel implements ListCellRenderer,
+                                                             Serializable
+{
+  /**
+   * This border is used whenever renderer doesn't have a focus.
+   */
+  protected static Border noFocusBorder = new EmptyBorder(0, 0, 0, 0);
+
+  /**
+   * Creates a new BasicComboBoxRenderer object.
+   */
+  public BasicComboBoxRenderer()
+  {
+    setHorizontalAlignment(SwingConstants.LEFT);
+  }
+
+  /**
+   * Returns preferredSize of the renderer
+   *
+   * @return preferredSize of the renderer
+   */
+  public Dimension getPreferredSize()
+  {
+    return super.getPreferredSize();
+  }
+
+  /**
+   * getListCellRendererComponent
+   *
+   * @param list List of items for which to the background and foreground
+   *        colors
+   * @param value object that should be rendered in the cell
+   * @param index index of the cell in the list of items.
+   * @param isSelected draw cell highlighted if isSelected is true
+   * @param cellHasFocus draw focus rectangle around cell if the cell has
+   *        focus
+   *
+   * @return Component that will be used to draw the desired cell.
+   */
+  public Component getListCellRendererComponent(JList list, Object value,
+                                                int index, boolean isSelected,
+                                                boolean cellHasFocus)
+  {
+    String s = value.toString();
+    setText(s);
+    setOpaque(true);
+
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    if (isSelected)
+      {
+	setBackground(list.getSelectionBackground());
+	setForeground(list.getSelectionForeground());
+      }
+    else
+      {
+	setBackground(list.getBackground());
+	setForeground(list.getForeground());
+      }
+
+    setEnabled(list.isEnabled());
+    setFont(list.getFont());
+
+    // Use focusCellHighlightBorder when renderer has focus and 
+    // noFocusBorder otherwise
+    if (cellHasFocus)
+      setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
+    else
+      setBorder(noFocusBorder);
+
+    return this;
+  }
+
+  public static class UIResource extends BasicComboBoxRenderer
+    implements javax.swing.plaf.UIResource
+  {
+    /**
+     * Creates a new UIResource object.
+     */
+    public UIResource()
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicComboBoxUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicComboBoxUI.java
diff -N javax/swing/plaf/basic/BasicComboBoxUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicComboBoxUI.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,1227 @@
+/* BasicComboBoxUI.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.EventListener;
+import javax.accessibility.Accessible;
+import javax.swing.CellRendererPane;
+import javax.swing.ComboBoxEditor;
+import javax.swing.ComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.SwingConstants;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.ComboBoxUI;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicComboPopup;
+import javax.swing.plaf.basic.BasicGraphicsUtils;
+
+
+/**
+ * UI Delegate for JComboBox
+ *
+ * @author Olga Rodimina
+ */
+public class BasicComboBoxUI extends ComboBoxUI
+{
+  /**
+   * This arrow button that is displayed in the rigth side of JComboBox. This
+   * button is used to hide and show combo box's list of items
+   */
+  protected JButton arrowButton;
+
+  /**
+   * The combo box for which this UI delegate is for
+   */
+  protected JComboBox comboBox;
+
+  /**
+   * Component that is responsible for displaying/editting  selected item of
+   * the combo box. By default JTextField is used as an editor for the
+   * JComboBox
+   */
+  protected Component editor;
+
+  /**
+   * Listener listening to focus events occuring in the JComboBox
+   */
+  protected FocusListener focusListener;
+
+  /**
+   * tells whether JComboBox currently has focus
+   */
+  protected boolean hasFocus;
+
+  /**
+   * Listener listening to item events fired by the JComboBox
+   */
+  protected ItemListener itemListener;
+
+  /**
+   * KeyListener listening to key events that occur while JComboBox has focus
+   */
+  protected KeyListener keyListener;
+
+  /**
+   * MouseListener listening to mouse events occuring in the combo box
+   */
+  private MouseListener mouseListener;
+
+  /**
+   * List used when rendering selected item of the combo box. The selection
+   * and foreground colors for combo box renderer  are configured from this
+   * list
+   */
+  protected JList listBox;
+
+  /**
+   * ListDataListener listening to JComboBox model
+   */
+  protected ListDataListener listDataListener;
+
+  /**
+   * Popup list containing combo box's menu items
+   */
+  protected ComboPopup popup;
+  protected KeyListener popupKeyListener;
+  protected MouseListener popupMouseListener;
+  protected MouseMotionListener popupMouseMotionListener;
+
+  /**
+   * Listener listening to changes in the bound properties of JComboBox
+   */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /**
+   * Colors that are used to render selected item in the combo box.
+   */
+  private Color shadow;
+  private Color darkShadow;
+  private Color highlight;
+  private Color lightHighlight;
+
+  /* Size of the largest item in the comboBox */
+  private Dimension largestItemSize;
+
+  // It seems that JComboBox doesn't have a border set explicitely. So we just
+  // paint the border everytime combo box is displayed. 
+
+  /* border insets for this JComboBox*/
+  private static final Insets borderInsets = new Insets(2, 2, 2, 2);
+
+  // Width of the arrow button  
+  private static int arrowButtonWidth = 15;
+
+  // FIXME: This fields aren't used anywhere at this moment.
+  protected Dimension cachedMinimumSize;
+  protected CellRendererPane currentValuePane;
+  protected boolean isMinimumSizeDirty;
+
+  /**
+   * Creates a new BasicComboBoxUI object.
+   */
+  public BasicComboBoxUI()
+  {
+  }
+
+  /**
+   * Factory method to create a BasicComboBoxUI for the given {@link
+   * JComponent}, which should be a {@link JComboBox}.
+   *
+   * @param c The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicComboBoxUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicComboBoxUI();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install a UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+
+    if (c instanceof JComboBox)
+      {
+	comboBox = (JComboBox) c;
+	comboBox.setOpaque(true);
+	comboBox.setLayout(createLayoutManager());
+	installDefaults();
+	installComponents();
+	installListeners();
+	installKeyboardActions();
+      }
+  }
+
+  /**
+   * This method uninstalls the UI.
+   *
+   * @param c The JComponent that is having this UI removed.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallComponents();
+    uninstallDefaults();
+    comboBox = null;
+  }
+
+  /**
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this {@link JComboBox}.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    comboBox.setBackground(defaults.getColor("ComboBox.background"));
+    comboBox.setFont(defaults.getFont("ComboBox.font"));
+    comboBox.setForeground(defaults.getColor("ComboBox.foreground"));
+
+    // Set default color that should be used to to render selected item
+    // of the combo box.
+    shadow = defaults.getColor("Button.shadow");
+    darkShadow = defaults.getColor("Button.darkShadow");
+    lightHighlight = defaults.getColor("Button.light");
+    highlight = defaults.getColor("Button.highlight");
+  }
+
+  /**
+   * This method creates and installs the listeners for this UI.
+   */
+  protected void installListeners()
+  {
+    // install combo box's listeners
+    propertyChangeListener = createPropertyChangeListener();
+    comboBox.addPropertyChangeListener(propertyChangeListener);
+
+    focusListener = createFocusListener();
+    comboBox.addFocusListener(focusListener);
+
+    itemListener = createItemListener();
+    comboBox.addItemListener(itemListener);
+
+    keyListener = createKeyListener();
+    comboBox.addKeyListener(keyListener);
+
+    mouseListener = createMouseListener();
+    comboBox.addMouseListener(mouseListener);
+
+    // install listeners that listen to combo box model
+    listDataListener = createListDataListener();
+    comboBox.getModel().addListDataListener(listDataListener);
+
+    configureArrowButton();
+  }
+
+  /**
+   * This method uninstalls the defaults and sets any objects created during
+   * install to null
+   */
+  protected void uninstallDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    comboBox.setBackground(null);
+    comboBox.setFont(null);
+    comboBox.setForeground(null);
+
+    shadow = null;
+    darkShadow = null;
+    lightHighlight = null;
+    highlight = null;
+  }
+
+  /**
+   * Detaches all the listeners we attached in {@link #installListeners}.
+   */
+  protected void uninstallListeners()
+  {
+    comboBox.removePropertyChangeListener(propertyChangeListener);
+    propertyChangeListener = null;
+
+    comboBox.removeFocusListener(focusListener);
+    focusListener = null;
+
+    comboBox.removeItemListener(itemListener);
+    itemListener = null;
+
+    comboBox.removeKeyListener(keyListener);
+    keyListener = null;
+
+    comboBox.removeMouseListener(mouseListener);
+    mouseListener = null;
+
+    comboBox.getModel().removeListDataListener(listDataListener);
+    listDataListener = null;
+
+    unconfigureArrowButton();
+  }
+
+  /**
+   * This method creates popup that will contain list of combo box's items
+   *
+   * @return popup containing list of combo box's items
+   */
+  protected ComboPopup createPopup()
+  {
+    return new BasicComboPopup(comboBox);
+  }
+
+  /**
+   * Creates KeyListener to listen to key events.
+   *
+   * @return KeyListener that listens to key events.
+   */
+  protected KeyListener createKeyListener()
+  {
+    return new KeyHandler();
+  }
+
+  /**
+   * This method create MouseListener that will listen to mouse event occuring
+   * in combo box.
+   *
+   * @return the MouseListener
+   */
+  private MouseListener createMouseListener()
+  {
+    return new MouseHandler();
+  }
+
+  /**
+   * This method create FocusListener that will listen to changes in this
+   * JComboBox's focus.
+   *
+   * @return theFocusListener
+   */
+  protected FocusListener createFocusListener()
+  {
+    return new FocusHandler();
+  }
+
+  /**
+   * This method create ListDataListener to listen to ComboBox's  data model
+   *
+   * @return ListDataListener
+   */
+  protected ListDataListener createListDataListener()
+  {
+    return new ListDataHandler();
+  }
+
+  /**
+   * This method creates ItemListener that will listen to to the changes in
+   * the JComboBox's selection.
+   *
+   * @return the ItemListener
+   */
+  protected ItemListener createItemListener()
+  {
+    return new ItemHandler();
+  }
+
+  /**
+   * This method creates PropertyChangeListener to listen to  the changes in
+   * the JComboBox's bound properties.
+   *
+   * @return the PropertyChangeListener
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method returns layout manager for the combo box.
+   *
+   * @return layout manager for the combo box
+   */
+  protected LayoutManager createLayoutManager()
+  {
+    return new ComboBoxLayoutManager();
+  }
+
+  /**
+   * This method creates component that will be responsible for rendering the
+   * selected component in the combo box.
+   *
+   * @return render for the combo box
+   */
+  protected ListCellRenderer createRenderer()
+  {
+    return new BasicComboBoxRenderer();
+  }
+
+  /**
+   * Creates component that will be responsible for displaying/editting
+   * selected item in the combo box. This editor is used only when combo box
+   * is editable.
+   *
+   * @return component that will be responsible for  displaying/editting
+   *         selected item in the combo box.
+   */
+  protected ComboBoxEditor createEditor()
+  {
+    return new BasicComboBoxEditor();
+  }
+
+  /**
+   * This method installs components for this JComboBox. ArrowButton, main
+   * part of combo box (upper part) and  popup list of items are created and
+   * configured here.
+   */
+  protected void installComponents()
+  {
+    // create and install arrow button
+    arrowButton = createArrowButton();
+
+    comboBox.add(arrowButton);
+
+    // Set list that will be used by BasicComboBoxRender 
+    // in order to determine the right colors when rendering
+    listBox = new JList();
+
+    Color background = arrowButton.getBackground();
+    listBox.setBackground(background);
+    listBox.setSelectionBackground(background.darker());
+
+    Color foreground = arrowButton.getForeground();
+    listBox.setForeground(foreground);
+    listBox.setSelectionForeground(foreground);
+
+    // set editor and renderer for the combo box. Editor is used
+    // only if combo box becomes editable, otherwise renderer is used
+    // to paint the selected item; combobox is not editable by default. 
+    comboBox.setRenderer(createRenderer());
+
+    comboBox.setEditor(createEditor());
+    editor = comboBox.getEditor().getEditorComponent();
+
+    // create drop down list of items
+    popup = createPopup();
+
+    comboBox.revalidate();
+  }
+
+  /**
+   * This method uninstalls components from this JComboBox
+   */
+  protected void uninstallComponents()
+  {
+    // uninstall arrow button
+    unconfigureArrowButton();
+    comboBox.remove(arrowButton);
+    arrowButton = null;
+
+    listBox = null;
+    popup = null;
+
+    comboBox.setRenderer(null);
+
+    comboBox.setEditor(null);
+    editor = null;
+  }
+
+  /**
+   * This method adds editor to the combo box
+   */
+  public void addEditor()
+  {
+    comboBox.add(editor);
+  }
+
+  /**
+   * This method removes editor from the combo box
+   */
+  public void removeEditor()
+  {
+    comboBox.remove(editor);
+  }
+
+  /**
+   * This method configures editor for this combo box.
+   */
+  protected void configureEditor()
+  {
+    // FIXME: Need to implement. Set font and add listeners.
+  }
+
+  /**
+   * This method removes all the listeners for the editor.
+   */
+  protected void unconfigureEditor()
+  {
+    // FIXME: Need to implement    
+  }
+
+  /**
+   * This method adds listeners to the arrow button part of the combo box.
+   */
+  public void configureArrowButton()
+  {
+    arrowButton.addMouseListener(mouseListener);
+  }
+
+  /**
+   * This method removes listeners from the arrow button part of the combo
+   * box.
+   */
+  public void unconfigureArrowButton()
+  {
+    arrowButton.removeMouseListener(mouseListener);
+  }
+
+  /**
+   * This method create arrow button for this JComboBox. Arrow button is
+   * responsible for displaying / hiding drop down list of items  when it is
+   * clicked.
+   *
+   * @return JButton arrow button for this JComboBox.
+   */
+  protected JButton createArrowButton()
+  {
+    return new BasicArrowButton(BasicArrowButton.SOUTH);
+  }
+
+  /**
+   * This method checks if popup part of the combo box is visible on the
+   * screen
+   *
+   * @param c The JComboBox to check
+   *
+   * @return true if popup part of the JComboBox is visible and false
+   *         otherwise.
+   */
+  public boolean isPopupVisible(JComboBox c)
+  {
+    return popup.isVisible();
+  }
+
+  /**
+   * Displays/Hides JComboBox's list of items on the screen.
+   *
+   * @param c The combo box, for which list of items should be
+   *        displayed/hidden
+   * @param v true if show popup part of the jcomboBox and false to hide.
+   */
+  public void setPopupVisible(JComboBox c, boolean v)
+  {
+    if (v)
+      popup.show();
+    else
+      popup.hide();
+  }
+
+  /**
+   * JComboBox is focus traversable if it is editable and not otherwise.
+   *
+   * @param c combo box for which to check whether it is focus traversable
+   *
+   * @return true if focus tranversable and false otherwise
+   */
+  public boolean isFocusTraversable(JComboBox c)
+  {
+    if (comboBox.isEditable())
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Paints given menu item using specified graphics context
+   *
+   * @param g The graphics context used to paint this combo box
+   * @param c comboBox which needs to be painted.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    if (c instanceof JComboBox)
+      {
+	JComboBox cb = (JComboBox) c;
+
+	paintBorder(g, comboBox.getBounds(), hasFocus);
+
+	Rectangle rect = rectangleForCurrentValue();
+	paintCurrentValueBackground(g, rect, hasFocus);
+	paintCurrentValue(g, rect, hasFocus);
+      }
+  }
+
+  private void paintBorder(Graphics g, Rectangle bounds, boolean hasFocus)
+  {
+    int x = 0;
+    int y = 0;
+    int width = bounds.width;
+    int height = bounds.height;
+
+    Color oldColor = g.getColor();
+
+    if (! arrowButton.getModel().isPressed())
+      BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height, Color.gray,
+                                        Color.white, Color.gray, Color.white);
+    else
+      {
+	g.setColor(darkShadow);
+	g.drawRect(x, y, width, height);
+	g.setColor(shadow);
+	g.drawRect(x + 1, y + 1, width - 3, height - 3);
+      }
+    g.setColor(oldColor);
+  }
+
+  /**
+   * Returns preferred size for the given menu item.
+   *
+   * @param c comboBox for which to get preferred size
+   *
+   * @return $Dimension$ preferred size for the given combo box
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    // return null to indicate that combo box's layout will determin its
+    // preferred size
+    return null;
+  }
+
+  /**
+   * This method returns the minimum size for this {@link JComboBox} for this
+   * look and feel.
+   *
+   * @param c The {@link JComponent} to find the minimum size for.
+   *
+   * @return The dimensions of the minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the maximum size for this {@link JComboBox} for this
+   * look and feel.
+   *
+   * @param c The {@link JComponent} to find the maximum size for
+   *
+   * @return The dimensions of the minimum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return null;
+  }
+
+  public int getAccessibleChildrenCount(JComponent c)
+  {
+    // FIXME: Need to implement
+    return 0;
+  }
+
+  public Accessible getAccessibleChild(JComponent c, int i)
+  {
+    // FIXME: Need to implement
+    return null;
+  }
+
+  /**
+   * Returns true if the specified key is a navigation key and false otherwise
+   *
+   * @param keyCode a key for which to check whether it is navigation key or
+   *        not.
+   *
+   * @return true if the specified key is a navigation key and false otherwis
+   */
+  protected boolean isNavigationKey(int keyCode)
+  {
+    return false;
+  }
+
+  /**
+   * This method selects next possible item relative to the current selection
+   * to be next selected item in the combo box.
+   */
+  protected void selectNextPossibleValue()
+  {
+    int index = comboBox.getSelectedIndex();
+    if (index != comboBox.getItemCount() - 1)
+      comboBox.setSelectedIndex(index + 1);
+  }
+
+  /**
+   * This method selects previous item relative to current selection to be
+   * next selected item.
+   */
+  protected void selectPreviousPossibleValue()
+  {
+    int index = comboBox.getSelectedIndex();
+    if (index != 0)
+      comboBox.setSelectedIndex(index - 1);
+  }
+
+  /**
+   * This method displays combo box popup if the popup is not currently shown
+   * on the screen and hides it if it is  currently shown
+   */
+  protected void toggleOpenClose()
+  {
+    setPopupVisible(comboBox, ! isPopupVisible(comboBox));
+  }
+
+  /**
+   * This method returns bounds in which comboBox's selected Item will be
+   * displayed
+   *
+   * @return rectangle bounds in which comboBox's selected Item will be
+   *         displayed
+   */
+  protected Rectangle rectangleForCurrentValue()
+  {
+    Rectangle cbBounds = comboBox.getBounds();
+
+    // Subtract width or the arrow button and border insets	    
+    Rectangle rectForCurrentValue = new Rectangle(cbBounds.x
+                                                  + borderInsets.left,
+                                                  cbBounds.y
+                                                  + borderInsets.top,
+                                                  cbBounds.width
+                                                  - arrowButtonWidth
+                                                  - borderInsets.left
+                                                  - borderInsets.right,
+                                                  cbBounds.height
+                                                  - borderInsets.top
+                                                  - borderInsets.bottom);
+
+    return rectForCurrentValue;
+  }
+
+  /**
+   * This method returns insets of the current border.
+   *
+   * @return Insets representing space between combo box and its border
+   */
+  protected Insets getInsets()
+  {
+    return new Insets(0, 0, 0, 0);
+  }
+
+  /**
+   * This method paints currently selected value in the main part of the combo
+   * box (part without popup).
+   *
+   * @param g graphics context
+   * @param bounds Rectangle representing the size of the area in which
+   *        selected item should be drawn
+   * @param hasFocus true if combo box has focus and false otherwise
+   */
+  public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus)
+  {
+    if (! comboBox.isEditable())
+      {
+	Object currentValue = comboBox.getSelectedItem();
+	boolean isPressed = arrowButton.getModel().isPressed();
+	if (currentValue != null)
+	  {
+	    Component comp = comboBox.getRenderer()
+	                             .getListCellRendererComponent(listBox,
+	                                                           currentValue,
+	                                                           -1,
+	                                                           isPressed,
+	                                                           isPressed);
+	    if (! comboBox.isEnabled())
+	      comp.setEnabled(false);
+
+	    g.translate(borderInsets.left, borderInsets.top);
+	    comp.setBounds(0, 0, bounds.width, bounds.height);
+	    comp.paint(g);
+	    g.translate(-borderInsets.left, -borderInsets.top);
+	  }
+	comboBox.revalidate();
+      }
+    else
+      comboBox.getEditor().setItem(comboBox.getSelectedItem());
+  }
+
+  /**
+   * This method paints background of part of the combo box, where currently
+   * selected value is displayed. If the combo box has focus this method
+   * should also paint focus rectangle around the combo box.
+   *
+   * @param g graphics context
+   * @param bounds Rectangle representing the size of the largest item  in the
+   *        comboBox
+   * @param hasFocus true if combo box has fox and false otherwise
+   */
+  public void paintCurrentValueBackground(Graphics g, Rectangle bounds,
+                                          boolean hasFocus)
+  {
+    // background is painted by renderer, so it seems that nothing
+    // should be done here.
+  }
+
+  /**
+   * Returns default size for the combo box that doesn't contain any elements
+   * in it
+   *
+   * @return Default size of the combo box with no elements in it.
+   */
+  protected Dimension getDefaultSize()
+  {
+    return new Dimension(6, 17);
+  }
+
+  /**
+   * Returns size of the largest item in the combo box. This size will be the
+   * size of the combo box, not including the arrowButton.
+   *
+   * @return dimensions of the largest item in the combo box.
+   */
+  protected Dimension getLargestItemSize()
+  {
+    ComboBoxModel model = comboBox.getModel();
+    int numItems = model.getSize();
+
+    // if combo box doesn't have any items then simply
+    // return its default size
+    if (numItems == 0)
+      {
+	largestItemSize = getDefaultSize();
+	return largestItemSize;
+      }
+
+    Dimension size = new Dimension(0, 0);
+
+    // ComboBox's display size should be equal to the 
+    // size of the largest item in the combo box. 
+    ListCellRenderer renderer = comboBox.getRenderer();
+
+    for (int i = 0; i < numItems; i++)
+      {
+	Object item = model.getElementAt(i);
+	String s = item.toString();
+	Component comp = renderer.getListCellRendererComponent(listBox, item,
+	                                                       -1, false, false);
+
+	if (comp.getPreferredSize().getWidth() > size.getWidth())
+	  size = comp.getPreferredSize();
+      }
+
+    largestItemSize = size;
+    return largestItemSize;
+  }
+
+  /**
+   * This method installs the keyboard actions for the JComboBox as specified
+   * by the look and feel.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Need to implement.
+  }
+
+  /**
+   * This method uninstalls the keyboard actions for the JComboBox there were
+   * installed by in {@link #installListeners}.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Need to implement.
+  }
+
+  /**
+   * This class is Layout Manager for this combo box.
+   */
+  public class ComboBoxLayoutManager extends Object implements LayoutManager
+  {
+    /**
+     * Creates a new ComboBoxLayoutManager object.
+     */
+    public ComboBoxLayoutManager()
+    {
+    }
+
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Do nothing
+    }
+
+    public void removeLayoutComponent(Component comp)
+    {
+      // Do nothing
+    }
+
+    /**
+     * Returns preferred layout size of the JComboBox.
+     *
+     * @param parent Container for which preferred size should be calculated
+     *
+     * @return preferred size for the given container
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      Dimension d = new Dimension(0, 0);
+
+      if (largestItemSize == null)
+	largestItemSize = getLargestItemSize();
+
+      // add size for the area that will display selected item
+      d.width += largestItemSize.getWidth();
+      d.height += largestItemSize.getHeight();
+
+      // add size of the arrow button
+      d.width += arrowButtonWidth;
+
+      // add width and height of the border
+      d.width += borderInsets.left + borderInsets.right;
+      d.height += borderInsets.left + borderInsets.right;
+
+      // Add combo box's insets 	
+      Insets insets = parent.getInsets();
+      d.width += insets.left + insets.right;
+      d.width += insets.left + insets.right;
+
+      return d;
+    }
+
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return preferredLayoutSize(parent);
+    }
+
+    /**
+     * This method layouts out the components in the container.  It puts arrow
+     * button right end part of the comboBox. If the comboBox is editable
+     * then editor is placed to the left of arrow  button, starting from the
+     * beginning.
+     *
+     * @param parent Container that should be layed out.
+     */
+    public void layoutContainer(Container parent)
+    {
+      // Position editor component to the left of arrow button if combo box is 
+      // editable
+      int editorWidth = comboBox.getBounds().width - arrowButtonWidth - 2;
+
+      if (comboBox.isEditable())
+	editor.setBounds(borderInsets.left, borderInsets.top, editorWidth,
+	                 comboBox.getBounds().height - borderInsets.left
+	                 - borderInsets.top);
+
+      arrowButton.setBounds(editorWidth, 2, arrowButtonWidth,
+                            comboBox.getBounds().height - 4);
+      comboBox.revalidate();
+    }
+  }
+
+  /**
+   * This class handles focus changes occuring in the combo box. This class is
+   * responsible for repainting combo box whenever focus is gained or lost
+   * and also for hiding popup list of items whenever combo box loses its
+   * focus.
+   */
+  public class FocusHandler extends Object implements FocusListener
+  {
+    /**
+     * Creates a new FocusHandler object.
+     */
+    public FocusHandler()
+    {
+    }
+
+    /**
+     * This mehtod is invoked when combo box gains focus. It repaints main
+     * part of combo box  accordingally.
+     *
+     * @param e the FocusEvent
+     */
+    public void focusGained(FocusEvent e)
+    {
+      hasFocus = true;
+      comboBox.repaint();
+    }
+
+    /**
+     * This method is invoked when combo box loses focus It repaint main part
+     * of combo box accordingally and  hides popup list of items.
+     *
+     * @param e the FocusEvent
+     */
+    public void focusLost(FocusEvent e)
+    {
+      hasFocus = false;
+      comboBox.repaint();
+      popup.hide();
+    }
+  }
+
+  /**
+   * This class handles ItemEvent fired by the JComboBox when its selected
+   * item changes.
+   */
+  public class ItemHandler extends Object implements ItemListener
+  {
+    /**
+     * Creates a new ItemHandler object.
+     */
+    public ItemHandler()
+    {
+    }
+
+    /**
+     * This method is invoked when selected item becomes deselected or when
+     * new item becomes selected.
+     *
+     * @param e the ItemEvent representing item's state change.
+     */
+    public void itemStateChanged(ItemEvent e)
+    {
+      comboBox.repaint();
+    }
+  }
+
+  /**
+   * KeyHandler handles key events occuring while JComboBox has focus.
+   */
+  public class KeyHandler extends KeyAdapter
+  {
+    public KeyHandler()
+    {
+    }
+
+    /*
+     * This method is invoked whenever key is pressed while JComboBox is in
+     * focus.
+     */
+    public void keyPressed(KeyEvent e)
+    {
+      // FIXME: This method calls JComboBox.selectWithKeyChar if the key that was 
+      // pressed is not a navigation key. 
+    }
+  }
+
+  /**
+   * This class handles to the changes occuring in the JComboBox's data model
+   */
+  public class ListDataHandler extends Object implements ListDataListener
+  {
+    /**
+     * Creates a new ListDataHandler object.
+     */
+    public ListDataHandler()
+    {
+    }
+
+    /**
+     * This method is invoked content's of JComboBox's data model  are changed
+     *
+     * @param e ListDataEvent describing the change.
+     */
+    public void contentsChanged(ListDataEvent e)
+    {
+      // if the item is selected or deselected
+    }
+
+    /**
+     * This method is invoked when items were added to the JComboBox's data
+     * model.
+     *
+     * @param e ListDataEvent describing the change.
+     */
+    public void intervalAdded(ListDataEvent e)
+    {
+      // must determine if the size of the combo box should change
+      int start = e.getIndex0();
+      int end = e.getIndex1();
+
+      ComboBoxModel model = comboBox.getModel();
+      ListCellRenderer renderer = comboBox.getRenderer();
+
+      if (largestItemSize == null)
+	largestItemSize = new Dimension(0, 0);
+
+      for (int i = start - 1; i < end; i++)
+        {
+	  Object item = model.getElementAt(i);
+	  Component comp = renderer.getListCellRendererComponent(new JList(),
+	                                                         item, -1,
+	                                                         false, false);
+	  if (comp.getPreferredSize().getWidth() > largestItemSize.getWidth())
+	    largestItemSize = comp.getPreferredSize();
+        }
+    }
+
+    /**
+     * This method is invoked when items were removed from the JComboBox's
+     * data model.
+     *
+     * @param e ListDataEvent describing the change.
+     */
+    public void intervalRemoved(ListDataEvent e)
+    {
+      // must determine if the size of the combo box should change
+      // FIXME: need to implement
+    }
+  }
+
+  /**
+   * This class handles PropertyChangeEvents fired by JComboBox.
+   */
+  public class PropertyChangeHandler extends Object
+    implements PropertyChangeListener
+  {
+    public PropertyChangeHandler()
+    {
+    }
+
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JComboBox.ENABLED_CHANGED_PROPERTY))
+        {
+	  // disable arrow button	
+	  arrowButton.setEnabled(comboBox.isEnabled());
+
+	  if (comboBox.isEditable())
+	    comboBox.getEditor().getEditorComponent().setEnabled(comboBox
+	                                                         .isEnabled());
+        }
+      else if (e.getPropertyName().equals(JComboBox.EDITABLE_CHANGED_PROPERTY))
+        {
+	  if (comboBox.isEditable())
+	    {
+	      configureEditor();
+	      addEditor();
+	    }
+	  else
+	    {
+	      unconfigureEditor();
+	      removeEditor();
+	    }
+
+	  comboBox.revalidate();
+	  comboBox.repaint();
+        }
+
+      // FIXME: Need to handle changes in other bound properties.	
+    }
+  }
+
+  /**
+   * MouseHandler listens to mouse events occuring in the combo box. This
+   * class is responsible for repainting this JComboBox whenever the mouse is
+   * being pressed or released over it.
+   */
+  private class MouseHandler extends MouseAdapter
+  {
+    /**
+     * This method is invoked when mouse is pressed over the combo box. It
+     * repaints the combo box accordinglly
+     *
+     * @param e the MouseEvent
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      if (comboBox.isEnabled())
+        {
+	  if (e.getSource() instanceof JComboBox)
+	    {
+	      arrowButton.getModel().setPressed(true);
+	      arrowButton.getModel().setArmed(true);
+	    }
+
+	  comboBox.repaint();
+
+	  if (e.getSource() instanceof BasicArrowButton)
+	    toggleOpenClose();
+        }
+    }
+
+    /**
+     * This method is invoked when mouse is released over the combo box. It
+     * repaints the combo box accordinglly
+     *
+     * @param e the MouseEvent
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      if (comboBox.isEnabled())
+        {
+	  if (e.getSource() instanceof JComboBox)
+	    {
+	      arrowButton.getModel().setPressed(false);
+	      arrowButton.getModel().setArmed(false);
+	    }
+
+	  comboBox.repaint();
+        }
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicComboPopup.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicComboPopup.java
diff -N javax/swing/plaf/basic/BasicComboPopup.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicComboPopup.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,933 @@
+/* BasicComboPopup.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.ComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.Timer;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+
+
+/**
+ * UI Delegate for ComboPopup
+ *
+ * @author Olga Rodimina
+ */
+public class BasicComboPopup extends JPopupMenu implements ComboPopup
+{
+  protected Timer autoscrollTimer;
+
+  /**
+   * ComboBox associated with this popup
+   */
+  protected JComboBox comboBox;
+
+  /*
+   * FIXME: Document fields below
+   */
+  protected boolean hasEntered;
+  protected boolean isAutoScrolling;
+
+  /**
+   * ItemListener listening to the selection changes in the combo box
+   */
+  protected ItemListener itemListener;
+
+  /**
+   * This listener is not used
+   */
+  protected KeyListener keyListener;
+
+  /**
+   * JList which is used to display item is the combo box
+   */
+  protected JList list;
+
+  /**
+   * This listener is not used
+   */
+  protected ListDataListener listDataListener;
+
+  /**
+   * MouseListener listening to mouse events occuring in the  combo box's
+   * list.
+   */
+  protected MouseListener listMouseListener;
+
+  /**
+   * MouseMotionListener listening to mouse motion events occuring  in the
+   * combo box's list
+   */
+  protected MouseMotionListener listMouseMotionListener;
+
+  /**
+   * This listener is not used
+   */
+  protected ListSelectionListener listSelectionListener;
+
+  /**
+   * MouseListener listening to mouse events occuring in the combo box
+   */
+  protected MouseListener mouseListener;
+
+  /**
+   * MouseMotionListener listening to mouse motion events occuring in the
+   * combo box
+   */
+  protected MouseMotionListener mouseMotionListener;
+
+  /**
+   * PropertyChangeListener listening to changes occuring in the bound
+   * properties of the combo box
+   */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /*
+   * FIXME: Document fields below
+   */
+  protected static int SCROLL_DOWN = 1;
+  protected static int SCROLL_UP = 0;
+  protected int scrollDirection;
+
+  /**
+   * JScrollPane that contains list portion of the combo box
+   */
+  protected JScrollPane scroller;
+
+  /**
+   * This field is not used
+   */
+  protected boolean valueIsAdjusting;
+
+  /**
+   * Creates a new BasicComboPopup object.
+   *
+   * @param comboBox the combo box with which this popup should be associated
+   */
+  public BasicComboPopup(JComboBox comboBox)
+  {
+    this.comboBox = comboBox;
+    installComboBoxListeners();
+
+    // initialize list that will be used to display elements of the combo box	
+    this.list = createList();
+    ((JLabel) list.getCellRenderer()).setHorizontalAlignment(SwingConstants.LEFT);
+    configureList();
+
+    // initialize scroller. Add list to the scroller.	
+    scroller = createScroller();
+    configureScroller();
+
+    // add scroller with list inside of it to JPopupMenu
+    super.add(scroller);
+
+    setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
+  }
+
+  /**
+   * This method displays drow down list of combo box items on the screen.
+   */
+  public void show()
+  {
+    Rectangle cbBounds = comboBox.getBounds();
+
+    // popup should have same width as the comboBox and should be hight anough
+    // to display number of rows equal to 'maximumRowCount' property
+    int popupHeight = getPopupHeightForRowCount(comboBox.getMaximumRowCount())
+                      + 4;
+
+    super.setPopupSize(cbBounds.width, popupHeight);
+
+    // location specified is relative to comboBox
+    super.show(comboBox, 0, cbBounds.height);
+  }
+
+  /**
+   * This method hides drop down list of items
+   */
+  public void hide()
+  {
+    super.setVisible(false);
+  }
+
+  /**
+   * Return list cointaining JComboBox's items
+   *
+   * @return list cointaining JComboBox's items
+   */
+  public JList getList()
+  {
+    return list;
+  }
+
+  /**
+   * Returns MouseListener that is listening to mouse events occuring in the
+   * combo box.
+   *
+   * @return MouseListener
+   */
+  public MouseListener getMouseListener()
+  {
+    return mouseListener;
+  }
+
+  /**
+   * Returns MouseMotionListener that is listening to mouse  motion events
+   * occuring in the combo box.
+   *
+   * @return MouseMotionListener
+   */
+  public MouseMotionListener getMouseMotionListener()
+  {
+    return mouseMotionListener;
+  }
+
+  /**
+   * Returns KeyListener listening to key events occuring in the combo box.
+   * This method returns null because KeyHandler is not longer used.
+   *
+   * @return KeyListener
+   */
+  public KeyListener getKeyListener()
+  {
+    return keyListener;
+  }
+
+  /**
+   * This method uninstalls the UI for the  given JComponent.
+   */
+  public void uninstallingUI()
+  {
+    uninstallComboBoxModelListeners(comboBox.getModel());
+
+    uninstallListeners();
+    uninstallKeyboardActions();
+  }
+
+  /**
+   * This method uninstalls listeners that were listening to changes occuring
+   * in the comb box's data model
+   *
+   * @param model data model for the combo box from which to uninstall
+   *        listeners
+   */
+  protected void uninstallComboBoxModelListeners(ComboBoxModel model)
+  {
+    model.removeListDataListener(listDataListener);
+  }
+
+  /**
+   * This method uninstalls keyboard actions installed by the UI.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method fires PopupMenuEvent indicating that combo box's popup list
+   * of items will become visible
+   */
+  protected void firePopupMenuWillBecomeVisible()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method fires PopupMenuEvent indicating that combo box's popup list
+   * of items will become invisible.
+   */
+  protected void firePopupMenuWillBecomeInvisible()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method fires PopupMenuEvent indicating that combo box's popup list
+   * of items was closed without selection.
+   */
+  protected void firePopupMenuCanceled()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * Creates MouseListener to listen to mouse events occuring in the combo
+   * box. Note that this listener doesn't listen to mouse events occuring in
+   * the popup portion of the combo box, it only listens to main combo box
+   * part.
+   *
+   * @return new MouseMotionListener that listens to mouse events occuring in
+   *         the combo box
+   */
+  protected MouseListener createMouseListener()
+  {
+    return new InvocationMouseHandler();
+  }
+
+  /**
+   * Create Mouse listener that listens to mouse dragging events occuring in
+   * the combo box. This listener is responsible for changing the selection
+   * in the combo box list to the component over which mouse is being
+   * currently dragged
+   *
+   * @return new MouseMotionListener that listens to mouse dragging events
+   *         occuring in the combo box
+   */
+  protected MouseMotionListener createMouseMotionListener()
+  {
+    return new InvocationMouseMotionHandler();
+  }
+
+  /**
+   * KeyListener created in this method is not used anymore.
+   *
+   * @return KeyListener that does nothing
+   */
+  protected KeyListener createKeyListener()
+  {
+    return new InvocationKeyHandler();
+  }
+
+  /**
+   * ListSelectionListener created in this method is not used anymore
+   *
+   * @return ListSelectionListener that does nothing
+   */
+  protected ListSelectionListener createListSelectionListener()
+  {
+    return new ListSelectionHandler();
+  }
+
+  /**
+   * Creates ListDataListener. This method returns null, because
+   * ListDataHandler class is obsolete and is no longer used.
+   *
+   * @return null
+   */
+  protected ListDataListener createListDataListener()
+  {
+    return null;
+  }
+
+  /**
+   * This method creates ListMouseListener to listen to mouse events occuring
+   * in the combo box's item list.
+   *
+   * @return MouseListener to listen to mouse events occuring in the combo
+   *         box's items list.
+   */
+  protected MouseListener createListMouseListener()
+  {
+    return new ListMouseHandler();
+  }
+
+  /**
+   * Creates ListMouseMotionlistener to listen to mouse motion events occuring
+   * in the combo box's list. This listener is responsible for highlighting
+   * items in the list when mouse is moved over them.
+   *
+   * @return MouseMotionListener that handles mouse motion events occuring in
+   *         the list of the combo box.
+   */
+  protected MouseMotionListener createListMouseMotionListener()
+  {
+    return new ListMouseMotionHandler();
+  }
+
+  /**
+   * Creates PropertyChangeListener to handle changes in the JComboBox's bound
+   * properties.
+   *
+   * @return PropertyChangeListener to handle changes in the JComboBox's bound
+   *         properties.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * Creates new ItemListener that will listen to ItemEvents occuring in the
+   * combo box.
+   *
+   * @return ItemListener to listen to ItemEvents occuring in the combo box.
+   */
+  protected ItemListener createItemListener()
+  {
+    return new ItemHandler();
+  }
+
+  /**
+   * Creates JList that will be used to display items in the combo box.
+   *
+   * @return JList that will be used to display items in the combo box.
+   */
+  protected JList createList()
+  {
+    JList l = new JList(comboBox.getModel());
+    l.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+    return l;
+  }
+
+  /**
+   * This method configures the list of comboBox's items by setting  default
+   * properties and installing listeners.
+   */
+  protected void configureList()
+  {
+    list.setModel(comboBox.getModel());
+
+    if (comboBox.getItemCount() < comboBox.getMaximumRowCount())
+      list.setVisibleRowCount(comboBox.getItemCount());
+    else
+      list.setVisibleRowCount(comboBox.getMaximumRowCount());
+    installListListeners();
+  }
+
+  /**
+   * This method installs list listeners.
+   */
+  protected void installListListeners()
+  {
+    // mouse listener listening to mouse events occuring in the 
+    // combo box's list of items.
+    listMouseListener = createListMouseListener();
+    list.addMouseListener(listMouseListener);
+
+    // mouse listener listening to mouse motion events occuring in the
+    // combo box's list of items
+    listMouseMotionListener = createListMouseMotionListener();
+    list.addMouseMotionListener(listMouseMotionListener);
+
+    listSelectionListener = createListSelectionListener();
+    list.addListSelectionListener(listSelectionListener);
+  }
+
+  /**
+   * This method creates scroll pane that will contain the list of comboBox's
+   * items inside of it.
+   *
+   * @return JScrollPane
+   */
+  protected JScrollPane createScroller()
+  {
+    return new JScrollPane();
+  }
+
+  /**
+   * This method configures scroll pane to contain list of comboBox's  items
+   */
+  protected void configureScroller()
+  {
+    scroller.getViewport().setView(list);
+    scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+  }
+
+  /**
+   * This method configures popup menu that will be used to display Scrollpane
+   * with list of items inside of it.
+   */
+  protected void configurePopup()
+  {
+    // FIXME: Need to implement
+  }
+
+  /*
+   * This method installs listeners that will listen to changes occuring
+   * in the combo box.
+   */
+  protected void installComboBoxListeners()
+  {
+    // mouse listener that listens to mouse event in combo box
+    mouseListener = createMouseListener();
+    comboBox.addMouseListener(mouseListener);
+
+    // mouse listener that listens to mouse dragging events in the combo box
+    mouseMotionListener = createMouseMotionListener();
+    comboBox.addMouseMotionListener(mouseMotionListener);
+
+    // item listener listenening to selection events in the combo box
+    itemListener = createItemListener();
+    comboBox.addItemListener(itemListener);
+
+    propertyChangeListener = createPropertyChangeListener();
+    comboBox.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * This method installs listeners that will listen to changes occuring in
+   * the comb box's data model
+   *
+   * @param model data model for the combo box for which to install listeners
+   */
+  protected void installComboBoxModelListeners(ComboBoxModel model)
+  {
+    // list data listener to listen for ListDataEvents in combo box.
+    // This listener is now obsolete and nothing is done here
+    listDataListener = createListDataListener();
+    comboBox.getModel().addListDataListener(listDataListener);
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method always returns false to indicate that  items in the combo box
+   * list are not focus traversable.
+   *
+   * @return false
+   */
+  public boolean isFocusTraversable()
+  {
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param direction DOCUMENT ME!
+   */
+  protected void startAutoScrolling(int direction)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void stopAutoScrolling()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void autoScrollUp()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void autoScrollDown()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method helps to delegate focus to the right component in the
+   * JComboBox. If the comboBox is editable then focus is sent to
+   * ComboBoxEditor, otherwise it is delegated to JComboBox.
+   *
+   * @param e MouseEvent
+   */
+  protected void delegateFocus(MouseEvent e)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method displays combo box popup if the popup is  not currently shown
+   * on the screen and hides it if it is  currently visible
+   */
+  protected void togglePopup()
+  {
+    if (BasicComboPopup.this.isVisible())
+      hide();
+    else
+      show();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param e DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected MouseEvent convertMouseEvent(MouseEvent e)
+  {
+    return null;
+  }
+
+  /**
+   * Returns required height of the popup such that number of items visible in
+   * it are equal to the maximum row count.  By default
+   * comboBox.maximumRowCount=8
+   *
+   * @param maxRowCount number of maximum visible rows in the  combo box's
+   *        popup list of items
+   *
+   * @return height of the popup required to fit number of items  equal to
+   *         JComboBox.maximumRowCount.
+   */
+  protected int getPopupHeightForRowCount(int maxRowCount)
+  {
+    int totalHeight = 0;
+    ListCellRenderer rend = list.getCellRenderer();
+
+    if (comboBox.getItemCount() < maxRowCount)
+      maxRowCount = comboBox.getItemCount();
+
+    for (int i = 0; i < maxRowCount; i++)
+      {
+	Component comp = rend.getListCellRendererComponent(list,
+	                                                   list.getModel()
+	                                                       .getElementAt(i),
+	                                                   -1, false, false);
+	Dimension dim = comp.getPreferredSize();
+	totalHeight += dim.height;
+      }
+
+    return totalHeight;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param px DOCUMENT ME!
+   * @param py DOCUMENT ME!
+   * @param pw DOCUMENT ME!
+   * @param ph DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected Rectangle computePopupBounds(int px, int py, int pw, int ph)
+  {
+    return new Rectangle(px, py, pw, ph);
+  }
+
+  /**
+   * This method changes the selection in the list to the item over which  the
+   * mouse is currently located.
+   *
+   * @param anEvent MouseEvent
+   * @param shouldScroll DOCUMENT ME!
+   */
+  protected void updateListBoxSelectionForEvent(MouseEvent anEvent,
+                                                boolean shouldScroll)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * InvocationMouseHandler is a listener that listens to mouse events
+   * occuring in the combo box. Note that this listener doesn't listen to
+   * mouse events occuring in the popup portion of the combo box, it only
+   * listens to main combo box part(area that displays selected item).  This
+   * listener is responsible for showing and hiding popup portion  of the
+   * combo box.
+   */
+  protected class InvocationMouseHandler extends MouseAdapter
+  {
+    /**
+     * Creates a new InvocationMouseHandler object.
+     */
+    protected InvocationMouseHandler()
+    {
+    }
+
+    /**
+     * This method is invoked whenever mouse is being pressed over the main
+     * part of the combo box. This method will show popup if  the popup is
+     * not shown on the screen right now, and it will hide popup otherwise.
+     *
+     * @param e MouseEvent that should be handled
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      if (comboBox.isEnabled())
+	togglePopup();
+    }
+
+    /**
+     * This method is invoked whenever mouse is released
+     *
+     * @param e MouseEvent that should be handled
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      // FIXME: should handle dragging events here, if
+      // mouse was dragged and released over the list of combobox's items,
+      // then item over which it was released should be selected.
+    }
+  }
+
+  /**
+   * InvocationMouseMotionListener is a mouse listener that listens to mouse
+   * dragging events occuring in the combo box.
+   */
+  protected class InvocationMouseMotionHandler extends MouseMotionAdapter
+  {
+    /**
+     * Creates a new InvocationMouseMotionHandler object.
+     */
+    protected InvocationMouseMotionHandler()
+    {
+    }
+
+    public void mouseDragged(MouseEvent e)
+    {
+    }
+  }
+
+  /**
+   * ItemHandler is an item listener that listens to selection event occuring
+   * in the combo box. FIXME: should specify here what it does when item is
+   * selected or deselected in the combo box list.
+   */
+  protected class ItemHandler extends Object implements ItemListener
+  {
+    /**
+     * Creates a new ItemHandler object.
+     */
+    protected ItemHandler()
+    {
+    }
+
+    /**
+     * This method responds to the selection events occuring in the combo box.
+     *
+     * @param e ItemEvent specifying the combo box's selection
+     */
+    public void itemStateChanged(ItemEvent e)
+    {
+    }
+  }
+
+  /**
+   * ListMouseHandler is a listener that listens to mouse events occuring in
+   * the combo box's list of items. This class is responsible for hiding
+   * popup portion of the combo box if the mouse is released inside the combo
+   * box's list.
+   */
+  protected class ListMouseHandler extends MouseAdapter
+  {
+    protected ListMouseHandler()
+    {
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+    }
+
+    public void mouseReleased(MouseEvent anEvent)
+    {
+      int index = list.locationToIndex(anEvent.getPoint());
+      comboBox.setSelectedIndex(index);
+      hide();
+    }
+  }
+
+  /**
+   * ListMouseMotionHandler listens to mouse motion events occuring in the
+   * combo box's list. This class is responsible for highlighting items in
+   * the list when mouse is moved over them
+   */
+  protected class ListMouseMotionHandler extends MouseMotionAdapter
+  {
+    protected ListMouseMotionHandler()
+    {
+    }
+
+    public void mouseMoved(MouseEvent anEvent)
+    {
+      // FIXME: Need to implement
+      // NOTE: the change isn't reflected in data model of the combo box.
+      // The items are only highlited, but not selected
+    }
+  }
+
+  /**
+   * This class listens to changes occuring in the bound properties of the
+   * combo box
+   */
+  protected class PropertyChangeHandler extends Object
+    implements PropertyChangeListener
+  {
+    protected PropertyChangeHandler()
+    {
+    }
+
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JComboBox.RENDERER_CHANGED_PROPERTY))
+        {
+	  list.setCellRenderer((ListCellRenderer) e.getNewValue());
+	  revalidate();
+	  repaint();
+        }
+    }
+  }
+
+  // ------ private helper methods --------------------
+
+  /**
+   * This method uninstalls listeners installed by the UI
+   */
+  private void uninstallListeners()
+  {
+    uninstallListListeners();
+    uninstallComboBoxListeners();
+    uninstallComboBoxModelListeners(comboBox.getModel());
+  }
+
+  /**
+   * This method uninstalls Listeners registered with combo boxes list of
+   * items
+   */
+  private void uninstallListListeners()
+  {
+    list.removeMouseListener(listMouseListener);
+    listMouseListener = null;
+
+    list.removeMouseMotionListener(listMouseMotionListener);
+    listMouseMotionListener = null;
+  }
+
+  /**
+   * This method uninstalls listeners listening to combo box  associated with
+   * this popup menu
+   */
+  private void uninstallComboBoxListeners()
+  {
+    comboBox.removeMouseListener(mouseListener);
+    mouseListener = null;
+
+    comboBox.removeMouseMotionListener(mouseMotionListener);
+    mouseMotionListener = null;
+
+    comboBox.removeItemListener(itemListener);
+    itemListener = null;
+
+    comboBox.removePropertyChangeListener(propertyChangeListener);
+    propertyChangeListener = null;
+  }
+
+  // --------------------------------------------------------------------
+  //  The following classes are here only for backwards API compatibility
+  //  They aren't used.
+  // --------------------------------------------------------------------
+
+  /**
+   * This class is not used any more.
+   */
+  public class ListDataHandler extends Object implements ListDataListener
+  {
+    public ListDataHandler()
+    {
+    }
+
+    public void contentsChanged(ListDataEvent e)
+    {
+    }
+
+    public void intervalAdded(ListDataEvent e)
+    {
+    }
+
+    public void intervalRemoved(ListDataEvent e)
+    {
+    }
+  }
+
+  /**
+   * This class is not used anymore
+   */
+  protected class ListSelectionHandler extends Object
+    implements ListSelectionListener
+  {
+    protected ListSelectionHandler()
+    {
+    }
+
+    public void valueChanged(ListSelectionEvent e)
+    {
+    }
+  }
+
+  /**
+   * This class is not used anymore
+   */
+  public class InvocationKeyHandler extends KeyAdapter
+  {
+    public InvocationKeyHandler()
+    {
+    }
+
+    public void keyReleased(KeyEvent e)
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicDefaults.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicDefaults.java
diff -N javax/swing/plaf/basic/BasicDefaults.java
--- javax/swing/plaf/basic/BasicDefaults.java	27 Nov 2003 09:09:13 -0000	1.6
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,126 +0,0 @@
-/* BasicDefaults.java
-   Copyright (C) 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package javax.swing.plaf.basic;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Insets;
-import javax.swing.UIDefaults;
-import javax.swing.border.MatteBorder;
-
-class BasicBorder extends MatteBorder
-{
-    static Color BtnPointClr = new Color( 180, 180, 180);
-
-	BasicBorder()
-	{
-		super(5,5,5,5, Color.black);
-	}
-	
-	public void paintBorder(Component  c,
-				Graphics  g, 
-				int  x, 
-				int  y, 
-				int  width, 
-				int  height)
-	{
-	    //    System.out.println("PAINT-------------------------------------------BORDER");
-
-	    if (g != null)
-		{
-		    g.setColor( BtnPointClr);
-		    g.draw3DRect( 0, 0, width-1, height-1, true);
-		}
-	}
- }
-
-class PanelBorder extends MatteBorder
-{
-    PanelBorder()
-    {
-	super(5,5,5,5, Color.black);
-	}
-	
-	public void paintBorder(Component  c,
-				Graphics  g, 
-				int  x, 
-				int  y, 
-				int  width, 
-				int  height)
-	{
-	    //    System.out.println("PAINT-------------------------------------------BORDER");
-	    super.paintBorder(c, g, x, y, width, height);
-	}
- }
-
-public class BasicDefaults extends UIDefaults
-{
-    public BasicDefaults()
-    {
-	//	System.out.println("BasicDefaults !!!!!!!!!!!!!!!!!!!!!!!!!");
-	put("JButton", "javax.swing.plaf.basic.BasicButtonUI");
-	put("JLabel",  "javax.swing.plaf.basic.BasicLabelUI");
-	
-	put("JPanel",  "javax.swing.plaf.basic.BasicPanelUI");
-	put("JCheckBox",  "javax.swing.plaf.basic.BasicCheckBoxUI");
-	put("JRadioButton",  "javax.swing.plaf.basic.BasicRadioButtonUI");
-	put("JToggleButton",  "javax.swing.plaf.basic.BasicToggleButtonUI");
-	put("JOptionPane",  "javax.swing.plaf.basic.BasicOptionPaneUI");
-	put("JList",  "javax.swing.plaf.basic.BasicListUI");
-	put("JTree",  "javax.swing.plaf.basic.BasicTreeUI");
-	put("JTextComponent",  "javax.swing.plaf.basic.BasicTextUI");
-	put("JTabbedPane",  "javax.swing.plaf.basic.BasicTabbedPaneUI");
-	put("JScrollPane", "javax.swing.plaf.basic.BasicScrollPaneUI");
-	put("JViewport",   "javax.swing.plaf.basic.BasicViewportUI");
-
-	put("JButton.border",      "javax.swing.plaf.basic.BasicBorder");
-	put("JPanel.border",       "javax.swing.plaf.basic.PanelBorder");
-
-	put("JToggleButton.border", "javax.swing.plaf.basic.PanelBorder");
-	put("JCheckBox.border", "javax.swing.plaf.basic.PanelBorder");
-	put("JRadioButton.border", "javax.swing.plaf.basic.PanelBorder");
-
-	put("AbstractUndoableEdit.undoText", "Undo");
-	put("AbstractUndoableEdit.redoText", "Redo");
-    }
-    
-}
-
-
Index: javax/swing/plaf/basic/BasicDesktopIconUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicDesktopIconUI.java
diff -N javax/swing/plaf/basic/BasicDesktopIconUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicDesktopIconUI.java	6 Sep 2004 16:36:03 -0000
@@ -0,0 +1,589 @@
+/* BasicDesktopIconUI.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.DesktopPaneUI;
+
+
+/**
+ * This class acts as the UI delegate for JDesktopIcons for the Basic look and feel.
+ */
+public class BasicDesktopIconUI extends DesktopIconUI
+{
+  /**
+   * This helper class handles mouse events that occur on the JDesktopIcon.
+   */
+  public class MouseInputHandler extends MouseInputAdapter
+  {
+    /** The x offset from the MouseEvent coordinates to the top left corner. */
+    private transient int xOffset;
+
+    /** The y offset fromt he MouseEvent coordinates to the top left corner. */
+    private transient int yOffset;
+
+    /** A cached value of the JDesktopPane that parents this JDesktopIcon. */
+    private transient JDesktopPane pane;
+
+    /**
+     * This method is called when the mouse is dragged in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      Rectangle b = desktopIcon.getBounds();
+
+      moveAndRepaint(desktopIcon, b.x + e.getX() - xOffset,
+                     b.y + e.getY() - yOffset, b.width, b.height);
+    }
+
+    /**
+     * This method is called when the mouse is moved in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // Nothing to do.
+    }
+
+    /**
+     * This method is called when the mouse is pressed in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      xOffset = e.getX();
+      yOffset = e.getY();
+      pane = frame.getDesktopPane();
+      if (pane != null)
+	pane.getDesktopManager().beginDraggingFrame(desktopIcon);
+    }
+
+    /**
+     * This method is called when the mouse is released in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      if (pane != null)
+	pane.getDesktopManager().endDraggingFrame(desktopIcon);
+      xOffset = 0;
+      yOffset = 0;
+    }
+
+    /**
+     * This method moves and repaints the JDesktopIcon to the given bounds.
+     *
+     * @param f The JComponent to move and repaint.
+     * @param newX The new x coordinate.
+     * @param newY The new y coordinate.
+     * @param newWidth The new width.
+     * @param newHeight The new height.
+     */
+    public void moveAndRepaint(JComponent f, int newX, int newY, int newWidth,
+                               int newHeight)
+    {
+      if (pane != null)
+	pane.getDesktopManager().dragFrame(f, newX, newY);
+      else
+	desktopIcon.setBounds(newX, newY, newWidth, newHeight);
+    }
+  }
+
+  /**
+   * This class acts as the border for the JDesktopIcon.
+   */
+  private class DesktopIconBorder implements Border
+  {
+    /** The left inset value. */
+    int left = 10;
+
+    /** The top inset value. */
+    int top = 4;
+
+    /** The right inset value. */
+    int right = top;
+
+    /** The bottom inset value. */
+    int bottom = top;
+
+    /**
+     * This method returns the insets of the border.
+     *
+     * @param c The Component to find border insets for.
+     *
+     * @return The border insets.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * This method returns whether the border is opaque.
+     *
+     * @return Whether the border is opaque.
+     */
+    public boolean isBorderOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method paints the border.
+     *
+     * @param c The Component the border is in.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate of the Component.
+     * @param y The y coordinate of the Component.
+     * @param width The width of the Component.
+     * @param height The height of the Component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+
+      g.setColor(Color.LIGHT_GRAY);
+
+      g.fillRect(0, 0, left, height);
+      g.fillRect(0, 0, width, top);
+      g.fillRect(0, height - bottom, width, bottom);
+      g.fillRect(width - right, 0, right, height);
+
+      g.setColor(Color.BLACK);
+      g.drawRect(0, 0, width - 1, height - 1);
+
+      int fHeight = height / 4;
+      int hLeft = left / 2;
+
+      g.setColor(Color.BLACK);
+      g.fillRect(hLeft, fHeight, 2, 2);
+      g.fillRect(hLeft, fHeight * 2, 2, 2);
+      g.fillRect(hLeft, fHeight * 3, 2, 2);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The static width and height of the iconSize. */
+  private static final int iconSize = 16;
+
+  /**
+   * This class represents the default frame icon when none
+   * is supplied by the JInternalFrame.
+   */
+  static class InternalFrameDefaultMenuIcon implements Icon
+  {
+    /**
+     * This returns the icon height.
+     *
+     * @return The icon height.
+     */
+    public int getIconHeight()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This returns the icon width.
+     *
+     * @return The icon width.
+     */
+    public int getIconWidth()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This method paints the icon.
+     *
+     * @param c The Component this icon belongs to.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate to paint at.
+     * @param y The y coordinate to paint at.
+     */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+
+      g.setColor(Color.BLUE);
+      g.fillRect(0, 0, iconSize, (int) ((double) iconSize / 3) + 1);
+
+      g.setColor(Color.WHITE);
+      g.fillRect(0, (int) ((double) iconSize / 3), iconSize, iconSize * 5 / 6);
+
+      g.setColor(Color.GRAY);
+      g.drawRect(0, 0, iconSize, iconSize);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The default JDesktopIcon width. */
+  private static final int iconWidth = 160;
+
+  /** The default JDesktopIcon height */
+  private static final int iconHeight = 35;
+
+  /** The JDesktopIcon this UI delegate represents. */
+  protected JDesktopIcon desktopIcon;
+
+  /** The JInternalFrame associated with the JDesktopIcon. */
+  protected JInternalFrame frame;
+
+  /** The MouseListener responsible for reacting to MouseEvents on the JDesktopIcon. */
+  private transient MouseInputListener mouseHandler;
+
+  /** The Button in the JDesktopIcon responsible for deiconifying it. */
+  private transient BoundButton button;
+
+  /** The PropertyChangeListener listening to the JDesktopIcon. */
+  private transient PropertyChangeListener propertyHandler;
+  
+  /** The default icon used when no frame icon is given by the JInternalFrame. */
+  static Icon defaultIcon = new InternalFrameDefaultMenuIcon();
+
+  /**
+   * This is a helper class that is used in JDesktopIcon and gives the Button a predetermined size.
+   */
+  private class BoundButton extends JButton
+  {
+    /**
+     * Creates a new BoundButton object.
+     *
+     * @param title The title of the button.
+     */
+    public BoundButton(String title)
+    {
+      super(title);
+    }
+
+    /**
+     * This method returns a standard size (based on the defaults of the JDesktopIcon) and the insets.
+     *
+     * @return The preferred size of the JDesktopIcon.
+     */
+    public Dimension getPreferredSize()
+    {
+      Insets insets = desktopIcon.getInsets();
+      return new Dimension(iconWidth - insets.left - insets.right,
+                           iconHeight - insets.top - insets.bottom);
+    }
+
+    /**
+     * This method returns the minimum size of the button.
+     *
+     * @return The minimum size of the button.
+     */
+    public Dimension getMinimumSize()
+    {
+      return getPreferredSize();
+    }
+
+    /**
+     * This method returns the maximum size of the button.
+     *
+     * @return The maximum size of the button.
+     */
+    public Dimension getMaximumSize()
+    {
+      return getPreferredSize();
+    }
+  }
+
+  /**
+   * Creates a new BasicDesktopIconUI object.
+   */
+  public BasicDesktopIconUI()
+  {
+  }
+
+  /**
+   * This method creates a new BasicDesktopIconUI for the given JComponent.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicDesktopIconUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicDesktopIconUI();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install this UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JDesktopIcon)
+      {
+	desktopIcon = (JDesktopIcon) c;
+	desktopIcon.setLayout(new BorderLayout());
+	frame = desktopIcon.getInternalFrame();
+
+	installDefaults();
+	installComponents();
+	installListeners();
+
+	desktopIcon.setOpaque(true);
+      }
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    desktopIcon.setOpaque(false);
+    
+    uninstallListeners();
+    uninstallComponents();
+    uninstallDefaults();
+    
+    frame = null;
+    desktopIcon.setLayout(null);
+    desktopIcon = null;
+  }
+
+  /**
+   * This method installs the necessary sub components for the JDesktopIcon.
+   */
+  protected void installComponents()
+  {
+    // Try to create a button based on what the frame's
+    // state is currently
+    button = new BoundButton(frame.getTitle());
+    button.setHorizontalAlignment(SwingConstants.LEFT);
+    button.setHorizontalTextPosition(SwingConstants.TRAILING);
+
+    Icon use = frame.getFrameIcon();
+    if (use == null)
+      use = defaultIcon;
+    button.setIcon(use);
+
+    desktopIcon.add(button, SwingConstants.CENTER);
+  }
+
+  /**
+   * This method uninstalls the sub components for the JDesktopIcon.
+   */
+  protected void uninstallComponents()
+  {
+    desktopIcon.remove(button);
+    
+    button = null;
+  }
+
+  /**
+   * This method installs the listeners needed by this UI.
+   */
+  protected void installListeners()
+  {
+    mouseHandler = createMouseInputListener();
+
+    desktopIcon.addMouseMotionListener(mouseHandler);
+    desktopIcon.addMouseListener(mouseHandler);
+
+    propertyHandler = new PropertyChangeListener()
+        {
+	  public void propertyChange(PropertyChangeEvent e)
+	  {
+	    if (e.getPropertyName().equals(JInternalFrame.TITLE_PROPERTY))
+	      button.setText(desktopIcon.getInternalFrame().getTitle());
+	    else if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY))
+	      {
+		Icon use = desktopIcon.getInternalFrame().getFrameIcon();
+		if (use == null)
+		  use = defaultIcon;
+		button.setIcon(use);
+	      }
+	    desktopIcon.revalidate();
+	    desktopIcon.repaint();
+	  }
+        };
+    frame.addPropertyChangeListener(propertyHandler);
+
+    button.addActionListener(new ActionListener()
+        {
+	  public void actionPerformed(ActionEvent e)
+	  {
+            deiconize();
+	  }
+        });
+  }
+
+  /**
+   * This method uninstalls the listeners needed by the UI.
+   */
+  protected void uninstallListeners()
+  {
+    // button is nulled so no need to remove it.
+    
+    frame.removePropertyChangeListener(propertyHandler);
+    propertyHandler = null;
+    
+    desktopIcon.removeMouseMotionListener(mouseHandler);
+    desktopIcon.removeMouseListener(mouseHandler);
+  }
+
+  /**
+   * This method installs the defaults for the JDesktopIcon.
+   */
+  protected void installDefaults()
+  {
+    // FIXME: Move border to defaults.
+    desktopIcon.setBorder(new DesktopIconBorder());  
+  }
+
+  /**
+   * This method uninstalls the defaults for the JDesktopIcon.
+   */
+  protected void uninstallDefaults()
+  {
+    desktopIcon.setBorder(null);
+  }
+
+  /**
+   * This method creates a new MouseInputListener for the JDesktopIcon.
+   *
+   * @return A new MouseInputListener.
+   */
+  protected MouseInputListener createMouseInputListener()
+  {
+    return new MouseInputHandler();
+  }
+
+  /**
+   * This method returns the preferred size for the given JComponent.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return new Dimension(iconWidth, iconHeight);
+  }
+
+  /**
+   * This method returns the minimum size for the given JComponent.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the maximum size for the given JComponent.
+   *
+   * @param c The JComponent to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the insets of the given JComponent.
+   *
+   * @param c The JComponent to find insets for.
+   *
+   * @return The insets of the given JComponent.
+   */
+  public Insets getInsets(JComponent c)
+  {
+    return c.getInsets();
+  }
+
+  /**
+   * This method deiconizes the JInternalFrame associated with the JDesktopIcon.
+   */
+  public void deiconize() 
+  {
+    try
+    {
+      frame.setIcon(false);
+    }
+    catch (PropertyVetoException pve)
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicDesktopPaneUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicDesktopPaneUI.java
diff -N javax/swing/plaf/basic/BasicDesktopPaneUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicDesktopPaneUI.java	6 Sep 2004 16:36:04 -0000
@@ -0,0 +1,459 @@
+/* BasicDesktopPaneUI.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyVetoException;
+import javax.swing.AbstractAction;
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+import javax.swing.KeyStroke;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.DesktopPaneUI;
+
+
+/**
+ * This class is the UI delegate for JDesktopPane for the Basic look and feel.
+ */
+public class BasicDesktopPaneUI extends DesktopPaneUI
+{
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be closed.
+   */
+  protected class CloseAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setClosed(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isClosable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be maximized.
+   */
+  protected class MaximizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setMaximum(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isMaximizable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be minimized.
+   */
+  protected class MinimizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setIcon(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isIconifiable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that pass the SELECTED
+   * property to the next JInternalFrame in the JDesktopPane's list of
+   * children.
+   */
+  protected class NavigateAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      // This is supposed to set the next selected frame. 
+      JInternalFrame[] frames = desktop.getAllFrames();
+      if (frames.length == 0)
+	return;
+
+      JInternalFrame sFrame = frames[0];
+      if (desktop.getSelectedFrame() != null)
+	sFrame = desktop.getSelectedFrame();
+
+      int i = 0;
+      for (; i < frames.length; i++)
+	if (frames[i] == sFrame)
+	  break;
+
+      // FIXME: Navigate actions go reverse too.	  
+      if (i == frames.length)
+	i = 0;
+
+      desktop.setSelectedFrame(frames[i]);
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether this action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      // Always true.
+      return true;
+    }
+  }
+
+  /**
+   * This helper class is used to restore the JInternalFrame to its original
+   * size before maximizing or iconifying.
+   */
+  protected class OpenAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      JInternalFrame frame = desktop.getSelectedFrame();
+      if (frame != null)
+        {
+	  try
+	    {
+	      if (frame.isIcon())
+		frame.setIcon(false);
+	      else if (frame.isMaximum())
+		frame.setMaximum(false);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether this action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      // JInternalFrames are always restorable.
+      return true;
+    }
+  }
+
+  /** The KeyStroke associated with closing JInternalFrames. */
+  protected KeyStroke closeKey;
+
+  /** The KeyStroke associated with maximizing JInternalFrames. */
+  protected KeyStroke maximizeKey;
+
+  /** The KeyStroke associated with minimizing JInternalFrames. */
+  protected KeyStroke minimizeKey;
+
+  /**
+   * The KeyStroke associated with navigating (forward?) through
+   * JInternalFrames.
+   */
+  protected KeyStroke navigateKey;
+
+  /**
+   * The KeyStroke associated with navigating (backward?) through
+   * JInternalFrames.
+   */
+  protected KeyStroke navigateKey2;
+
+  /** The default desktop manager used with JDesktopPane. */
+  protected DesktopManager desktopManager;
+
+  /** The JDesktopPane this UI is used with. */
+  protected JDesktopPane desktop;
+
+  /**
+   * Creates a new BasicDesktopPaneUI object.
+   */
+  public BasicDesktopPaneUI()
+  {
+  }
+
+  /**
+   * This method creates a BasicDesktopPaneUI for the given JComponent.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicDesktopPaneUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicDesktopPaneUI();
+  }
+
+  /**
+   * This method returns the maximum size for the given JComponent.
+   *
+   * @param c The JComponent to find a maximum size for.
+   *
+   * @return The maximum size for the given JComponent.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the minimum size for the given JComponent.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size for the given JComponent.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the preferred size for the given JComponent.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size for the given JComponent.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    // return null because JDesktopPanes don't have preferred sizes.
+    return null;
+  }
+
+  /**
+   * This method installs the defaults for the JDesktopPane provided by the
+   * current look and feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    desktop.setBackground(defaults.getColor("Desktop.background"));
+  }
+
+  /**
+   * This method installs the desktop manager for the JDesktopPane.
+   */
+  protected void installDesktopManager()
+  {
+    desktopManager = new DefaultDesktopManager();
+    desktop.setDesktopManager(desktopManager);
+  }
+
+  /**
+   * This method installs the keyboard actions for the JDesktopPane.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: create actions and keystrokes.
+    registerKeyboardAction();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install this UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JDesktopPane)
+      {
+	desktop = (JDesktopPane) c;
+
+	installDefaults();
+	installDesktopManager();
+	installKeyboardActions();
+      }
+  }
+
+  /**
+   * This method registers the actions to the appropriate Action and Input
+   * maps.
+   */
+  protected void registerKeyboardAction()
+  {
+    // FIXME: Do the binding.
+    // XXX: the gtk windows tend to intercept a lot of the
+    // key events for themselves. must figure a way past that
+    // before binding
+  }
+
+  /**
+   * This method reverses the work done by the installDefaults method.
+   */
+  protected void uninstallDefaults()
+  {
+    desktop.setBackground(null);
+  }
+
+  /**
+   * This method reverses the work done by the installDesktopManager method.
+   */
+  protected void uninstallDesktopManager()
+  {
+    desktopManager = null;
+    desktop.setDesktopManager(null);
+  }
+
+  /**
+   * This method reverses the work done by the installKeyboardActions method.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    unregisterKeyboardActions();
+    // FIXME: null the actions and keystrokes.
+  }
+
+  /**
+   * This method reverses the work done by the registerKeyboardActions method.
+   */
+  protected void unregisterKeyboardActions()
+  {
+    // FIXME: unmap the keystrokes
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent. It should reverse
+   * all the work done by the installUI method.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallDesktopManager();
+    uninstallDefaults();
+
+    desktop = null;
+  }
+}
Index: javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
diff -N javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicFormattedTextFieldUI.java	6 Sep 2004 16:36:04 -0000
@@ -0,0 +1,62 @@
+/* BasicFormattedTextFieldUI.java
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.plaf.basic;
+
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+
+/**
+ * @since 1.4
+ */
+public class BasicFormattedTextFieldUI extends BasicTextFieldUI
+{
+  public BasicFormattedTextFieldUI()
+  {
+  }
+
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicFormattedTextFieldUI();
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "FormattedTextField";
+  }
+}
\ No newline at end of file
Index: javax/swing/plaf/basic/BasicGraphicsUtils.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java,v
retrieving revision 1.4
diff -u -r1.4 BasicGraphicsUtils.java
--- javax/swing/plaf/basic/BasicGraphicsUtils.java	1 Aug 2003 20:10:22 -0000	1.4
+++ javax/swing/plaf/basic/BasicGraphicsUtils.java	6 Sep 2004 16:36:04 -0000
@@ -45,11 +45,9 @@
 import java.awt.Graphics2D;
 import java.awt.Insets;
 import java.awt.Rectangle;
-
 import java.awt.font.FontRenderContext;
 import java.awt.font.LineMetrics;
 import java.awt.font.TextLayout;
-
 import java.awt.geom.Rectangle2D;
 
 import javax.swing.AbstractButton;
@@ -595,11 +593,9 @@
     Rectangle iconRect = new Rectangle();
     Rectangle textRect = new Rectangle();
     Insets insets = b.getInsets();
+    Insets margin = b.getMargin();
     
-    /* For determining the ideal size, do not assume a size restriction. */
-    viewRect = new Rectangle(0, 0,
-                             /* width */ Integer.MAX_VALUE,
-                             /* height */ Integer.MAX_VALUE);
+    viewRect = new Rectangle();
 
      /* java.awt.Toolkit.getFontMetrics is deprecated. However, it
      * seems not obvious how to get to the correct FontMetrics object
@@ -613,14 +609,13 @@
       b.getToolkit().getFontMetrics(b.getFont()), // see comment above
       b.getText(),
       b.getIcon(),
-      b.getVerticalAlignment(),
+      b.getVerticalAlignment(), 
       b.getHorizontalAlignment(),
       b.getVerticalTextPosition(),
       b.getHorizontalTextPosition(),
       viewRect, iconRect, textRect,
       textIconGap);
 
-
     /*  +------------------------+       +------------------------+
      *  |                        |       |                        |
      *  | ICON                   |       | CONTENTCONTENTCONTENT  |
@@ -628,9 +623,14 @@
      *  |          TEXTTEXTTEXT  |       | CONTENTCONTENTCONTENT  |
      *  +------------------------+       +------------------------+
      */
+
     contentRect = textRect.union(iconRect);
 
-    return new Dimension(insets.left + contentRect.width + insets.right,
-                         insets.top + contentRect.height + insets.bottom);
+    return new Dimension(insets.left + margin.left
+			 + contentRect.width 
+			 + insets.right + margin.right,
+                         insets.top + margin.top
+			 + contentRect.height 
+			 + insets.bottom + margin.bottom);
   }
 }
Index: javax/swing/plaf/basic/BasicIconFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicIconFactory.java,v
retrieving revision 1.2
diff -u -r1.2 BasicIconFactory.java
--- javax/swing/plaf/basic/BasicIconFactory.java	10 May 2003 08:14:36 -0000	1.2
+++ javax/swing/plaf/basic/BasicIconFactory.java	6 Sep 2004 16:36:04 -0000
@@ -39,7 +39,14 @@
 package javax.swing.plaf.basic;
 
 import java.io.Serializable;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Polygon;
+import javax.swing.AbstractButton;
 import javax.swing.Icon;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 /**
  * STUBBED
  */
@@ -47,39 +54,183 @@
 {
   static final long serialVersionUID = 5605588811185324383L;
 
+  static private class DummyIcon 
+    implements Icon
+  {    
+    public int getIconHeight() { return 10; }
+    public int getIconWidth() { return 10; }
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+      Color save = g.getColor();
+      g.setColor(c.getForeground());
+      g.drawRect(x, y, 10, 10);
+      g.setColor(save);
+    }
+  }
+
+
   public BasicIconFactory()
   {
   }
   public static Icon getMenuItemCheckIcon()
   {
-    return null;
+    return new DummyIcon();
   }
   public static Icon getMenuItemArrowIcon()
   {
-    return null;
+    return new DummyIcon();
   }
   public static Icon getMenuArrowIcon()
   {
-    return null;
+    return new Icon()
+      {
+	public int getIconHeight()
+	{
+	  return 12;
+	}
+
+	public int getIconWidth()
+	{
+	  return 12;
+	}
+
+	public void paintIcon(Component c, Graphics g, int x, int y)
+	{
+	  g.translate(x, y);
+
+	  Color saved = g.getColor();
+
+	  g.setColor(Color.BLACK);
+
+	  g.fillPolygon(new Polygon(new int[] { 3, 9, 3 },
+                                  new int[] { 2, 6, 10 },
+                                  3));
+
+	  g.setColor(saved);
+	  g.translate(-x, -y);
+	}
+      };
   }
+
   public static Icon getCheckBoxIcon()
   {
-    return null;
+    return new Icon()
+      {        
+        public int getIconHeight() 
+        { 
+          return 10; 
+        }
+        public int getIconWidth() 
+        { 
+          return 10; 
+        }
+        public void paintIcon(Component c, Graphics g, int x, int y)
+        {
+          if (c instanceof AbstractButton)
+            {
+              UIDefaults defaults;
+              defaults = UIManager.getLookAndFeelDefaults();
+              Color hi = defaults.getColor("CheckBox.highlight");
+              Color low = defaults.getColor("CheckBox.darkShadow");
+              Color sel = defaults.getColor("CheckBox.foreground");
+              Color dim = defaults.getColor("CheckBox.shadow");
+              Polygon check = new Polygon(new int[] {x+3, x+3, x+8},
+                                          new int[] {y+5, y+9, y+3}, 3);
+              AbstractButton b = (AbstractButton) c;
+              Color saved = g.getColor();
+              if (b.isEnabled())
+                {
+                  g.setColor(low);
+                  g.drawRect(x, y, 10, 10);
+                  g.setColor(hi);
+                  g.drawRect(x+1, y+1, 10, 10);
+                  if (b.isSelected())
+                    {
+                      g.setColor(sel);
+                      if (b.isSelected())
+                        {
+                          g.drawLine(x+3, y+5, x+3, y+8);
+                          g.drawLine(x+4, y+5, x+4, y+8);
+                          g.drawLine(x+3, y+8, x+8, y+3);
+                          g.drawLine(x+4, y+8, x+8, y+3);
+                        }
+                    }
+                }
+              else
+                {                  
+                  g.setColor(hi);
+                  g.drawRect(x, y, 10, 10);
+                  if (b.isSelected())
+                    {
+                      g.drawLine(x+3, y+5, x+3, y+9);
+                      g.drawLine(x+3, y+9, x+8, y+3);
+                    }
+                }
+              g.setColor(saved);
+            }
+        }
+      };
   }
+
   public static Icon getRadioButtonIcon()
   {
-    return null;
+    return new Icon()
+      {        
+        public int getIconHeight() 
+        { 
+          return 12; 
+        }
+        public int getIconWidth() 
+        { 
+          return 12; 
+        }
+        public void paintIcon(Component c, Graphics g, int x, int y)
+        {
+          UIDefaults defaults;      
+          defaults = UIManager.getLookAndFeelDefaults();
+          Color hi = defaults.getColor("RadioButton.highlight");
+          Color low = defaults.getColor("RadioButton.darkShadow");
+          Color sel = defaults.getColor("RadioButton.foreground");
+          Color dim = defaults.getColor("RadioButton.shadow");
+
+          if (c instanceof AbstractButton)
+            {
+              AbstractButton b = (AbstractButton) c;
+              Color saved = g.getColor();
+              if (b.isEnabled())
+                {
+                  g.setColor(low);
+                  g.drawOval(x, y, 12, 12);
+                  g.setColor(hi);
+                  g.drawOval(x+1, y+1, 12, 12);
+                  if (b.isSelected())
+                    {
+                      g.setColor(sel);
+                      g.fillOval(x+4, y+4, 6, 6);
+                    }
+                }
+              else
+                {                  
+                  g.setColor(hi);
+                  g.drawOval(x, y, 12, 12);
+                  if (b.isSelected())
+                    g.fillOval(x+4, y+4, 6, 6);
+                }
+              g.setColor(saved);
+            }
+        }
+      };
   }
   public static Icon getCheckBoxMenuItemIcon()
   {
-    return null;
+    return getCheckBoxIcon();
   }
   public static Icon getRadioButtonMenuItemIcon()
   {
-    return null;
+    return getRadioButtonIcon();
   }
   public static Icon createEmptyFrameIcon()
   {
-    return null;
+    return new DummyIcon();
   }
 } // class BasicIconFactory
Index: javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
diff -N javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicInternalFrameTitlePane.java	6 Sep 2004 16:36:04 -0000
@@ -0,0 +1,1004 @@
+/* BasicInternalFrameTitlePane.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.UIManager;
+import javax.swing.UIDefaults;
+
+
+/**
+ * This class acts as a titlebar for JInternalFrames.
+ */
+public class BasicInternalFrameTitlePane extends JComponent
+{
+  /**
+   * The Action responsible for closing the JInternalFrame.
+   */
+  protected class CloseAction extends AbstractAction
+  {
+    /**
+     * This method is called when something closes the JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (frame.isClosable())
+        {
+	  try
+	    {
+	      frame.setClosed(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for iconifying the JInternalFrame.
+   */
+  protected class IconifyAction extends AbstractAction
+  {
+    /**
+     * This method is called when the user wants to iconify the
+     * JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (frame.isIconifiable() && ! frame.isIcon())
+        {
+	  try
+	    {
+	      frame.setIcon(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for maximizing the JInternalFrame.
+   */
+  protected class MaximizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the user wants to maximize the
+     * JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      try
+        {
+	  if (frame.isMaximizable() && ! frame.isMaximum())
+	    frame.setMaximum(true);
+	  else if (frame.isMaximum())
+	    frame.setMaximum(false);
+        }
+      catch (PropertyVetoException pve)
+        {
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for dragging the JInternalFrame.
+   */
+  protected class MoveAction extends AbstractAction
+  {
+    /**
+     * This method is called when the user wants to drag the JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      // FIXME: Implement keyboard driven? move actions.
+    }
+  }
+
+  /**
+   * This Action is responsible for restoring the JInternalFrame. Restoring
+   * the JInternalFrame is the same as setting the maximum property to false.
+   */
+  protected class RestoreAction extends AbstractAction
+  {
+    /**
+     * This method is called when the user wants to restore the
+     * JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (frame.isMaximum())
+        {
+	  try
+	    {
+	      frame.setMaximum(false);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This action is responsible for sizing the JInternalFrame.
+   */
+  protected class SizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the user wants to resize the JInternalFrame.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      // FIXME: Not sure how size actions should be handled.
+    }
+  }
+
+  /**
+   * This class is responsible for handling property change events from the
+   * JInternalFrame and adjusting the Title Pane as necessary.
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called when a PropertyChangeEvent is received by the
+     * Title Pane.
+     *
+     * @param evt The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      // The title and frameIcon are taken care of during painting time.
+      // The only other thing this will care about are the "is----izable"
+      // properties. So we call enable actions to properly handle the 
+      // buttons and menu items for us.
+      enableActions();
+    }
+  }
+
+  /**
+   * This class acts as the MenuBar for the TitlePane. Clicking on the Frame
+   * Icon in the top left corner will activate it.
+   */
+  protected class SystemMenuBar extends JMenuBar
+  {
+    /**
+     * This method returns true if it can receive focus.
+     *
+     * @return True if this Component can receive focus.
+     */
+    public boolean isFocusTransversable()
+    {
+      return true;
+    }
+
+    /**
+     * This method returns true if this Component is expected to paint all of
+     * itself.
+     *
+     * @return True if this Component is expect to paint all of itself.
+     */
+    public boolean isOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method paints this Component.
+     *
+     * @param g The Graphics object to paint with.
+     */
+    public void paint(Graphics g)
+    {
+      Icon frameIcon = frame.getFrameIcon();
+      if (frameIcon == null)
+	frameIcon = BasicDesktopIconUI.defaultIcon;
+      frameIcon.paintIcon(this, g, 0, 0);
+    }
+
+    /**
+     * This method requests that focus be given to this Component.
+     */
+    public void requestFocus()
+    {
+      super.requestFocus();
+    }
+  }
+
+  /**
+   * This class acts as the Layout Manager for the TitlePane.
+   */
+  protected class TitlePaneLayout implements LayoutManager
+  {
+    /**
+     * This method is called when adding a Component to the Container.
+     *
+     * @param name The name to reference the added Component by.
+     * @param c The Component to add.
+     */
+    public void addLayoutComponent(String name, Component c)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called to lay out the children of the Title Pane.
+     *
+     * @param c The Container to lay out.
+     */
+    public void layoutContainer(Container c)
+    {
+      enableActions();
+
+      Insets insets = c.getInsets();
+      int width = c.getBounds().width - insets.left - insets.right;
+      int height = c.getBounds().height - insets.top - insets.bottom;
+
+      // MenuBar is always present and located at the top left corner.
+      Dimension menupref = menuBar.getPreferredSize();
+      menuBar.setBounds(insets.left, insets.top, menupref.width, height);
+
+      int loc = width + insets.left;
+
+      Insets i = closeButton.getInsets();
+      Dimension prefs = new Dimension(iconSize + i.left + i.right,
+                                      iconSize + i.top + i.bottom);
+      int top = insets.top + (height - prefs.height) / 2;
+      if (closeAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  closeButton.setVisible(true);
+	  closeButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	closeButton.setVisible(false);
+
+      if (maximizeAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  maxButton.setVisible(true);
+	  maxButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	maxButton.setVisible(false);
+
+      if (iconifyAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  iconButton.setVisible(true);
+	  iconButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	iconButton.setVisible(false);
+
+      if (title != null)
+	title.setBounds(insets.left + menupref.width, insets.top,
+	                loc - menupref.width - insets.left, height);
+    }
+
+    /**
+     * This method returns the minimum size of the given Container given the
+     * children that it has.
+     *
+     * @param c The Container to get a minimum size for.
+     *
+     * @return The minimum size of the Container.
+     */
+    public Dimension minimumLayoutSize(Container c)
+    {
+      return preferredLayoutSize(c);
+    }
+
+    /**
+     * This method returns the preferred size of the given Container taking
+     * into account the children that it has.
+     *
+     * @param c The Container to lay out.
+     *
+     * @return The preferred size of the Container.
+     */
+    public Dimension preferredLayoutSize(Container c)
+    {
+      Insets frameInsets = frame.getInsets();
+
+      // Height is the max of the preferredHeights of all components
+      // inside the pane
+      int height = 0;
+      int width = 0;
+      Dimension d;
+
+      Component[] components = BasicInternalFrameTitlePane.this.getComponents();
+      for (int i = 0; i < components.length; i++)
+        {
+	  d = components[i].getPreferredSize();
+	  height = Math.max(height, d.height);
+	  width += d.width;
+        }
+
+      Insets insets = BasicInternalFrameTitlePane.this.getInsets();
+      height += insets.top + insets.bottom;
+
+      return new Dimension(width, height);
+    }
+
+    /**
+     * This method is called when removing a Component from the Container.
+     *
+     * @param c The Component to remove.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+    }
+  }
+
+  /**
+   * This helper class is used to create the minimize, maximize and close
+   * buttons in the top right corner of the Title Pane. These buttons are
+   * special since they cannot be given focus and have no border.
+   */
+  private class PaneButton extends JButton
+  {
+    /**
+     * Creates a new PaneButton object with the given Action.
+     *
+     * @param a The Action that the button uses.
+     */
+    public PaneButton(Action a)
+    {
+      super(a);
+      setMargin(new Insets(0, 0, 0, 0));
+      setBorder(null);
+    }
+
+    /**
+     * This method returns true if the Component can be focused.
+     *
+     * @return false.
+     */
+    public boolean isFocusable()
+    {
+      // These buttons cannot be given focus.
+      return false;
+    }
+  }
+
+  /** The action command for the Close action. */
+  protected static String CLOSE_CMD = "Close";
+
+  /** The action command for the Minimize action. */
+  protected static String ICONIFY_CMD = "Minimize";
+
+  /** The action command for the Maximize action. */
+  protected static String MAXIMIZE_CMD = "Maximize";
+
+  /** The action command for the Move action. */
+  protected static String MOVE_CMD = "Move";
+
+  /** The action command for the Restore action. */
+  protected static String RESTORE_CMD = "Restore";
+
+  /** The action command for the Size action. */
+  protected static String SIZE_CMD = "Size";
+
+  /** The action associated with closing the JInternalFrame. */
+  protected Action closeAction;
+
+  /** The action associated with iconifying the JInternalFrame. */
+  protected Action iconifyAction;
+
+  /** The action associated with maximizing the JInternalFrame. */
+  protected Action maximizeAction;
+
+  /** The action associated with moving the JInternalFrame. */
+  protected Action moveAction;
+
+  /** The action associated with restoring the JInternalFrame. */
+  protected Action restoreAction;
+
+  /** The action associated with resizing the JInternalFrame. */
+  protected Action sizeAction;
+
+  /** The button that closes the JInternalFrame. */
+  protected JButton closeButton;
+
+  /** The button that iconifies the JInternalFrame. */
+  protected JButton iconButton;
+
+  /** The button that maximizes the JInternalFrame. */
+  protected JButton maxButton;
+
+  /** Active background color. */
+  protected Color activeBGColor;
+
+  /** Active foreground color. */
+  protected Color activeFGColor;
+
+  /** Inactive background color. */
+  protected Color inactiveBGColor;
+
+  /** Inactive foreground color. */
+  protected Color inactiveFGColor;
+
+  // FIXME: These icons need to be moved to MetalIconFactory.
+
+  /** The size of the icons in the buttons. */
+  private static final int iconSize = 16;
+
+  /** The icon displayed in the close button. */
+  protected Icon closeIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	int four = iconSize / 4;
+	int six = iconSize * 6 / 16;
+	int ten = iconSize * 10 / 16;
+	int twelve = iconSize * 12 / 16;
+
+	Polygon a = new Polygon(new int[] { four, six, ten, twelve },
+	                        new int[] { six, four, twelve, ten }, 4);
+	Polygon b = new Polygon(new int[] { four, six, ten, twelve },
+	                        new int[] { ten, twelve, four, six }, 4);
+
+	g.fillPolygon(a);
+	g.fillPolygon(b);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  // FIXME: Create new icon.
+
+  /** The icon displayed in the restore button. */
+  protected Icon minIcon;
+
+  /** The icon displayed in the maximize button. */
+  protected Icon maxIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	int four = iconSize / 4;
+	int two = four / 2;
+	int six = iconSize * 6 / 16;
+	int eight = four * 2;
+
+	g.fillRect(four, four, eight, two);
+	g.drawRect(four, six, eight, six);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The icon displayed in the iconify button. */
+  protected Icon iconIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	g.fillRect(iconSize / 4, iconSize * 10 / 16, iconSize / 2, iconSize / 8);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The JInternalFrame that this TitlePane is used in. */
+  protected JInternalFrame frame;
+
+  /** The JMenuBar that is located at the top left of the Title Pane. */
+  protected JMenuBar menuBar;
+
+  /** The JMenu inside the menuBar. */
+  protected JMenu windowMenu;
+
+  /**
+   * The text color of the TitlePane when the JInternalFrame is not selected.
+   */
+  protected Color notSelectedTextColor;
+
+  /**
+   * The background color of the TitlePane when the JInternalFrame is not
+   * selected.
+   */
+  protected Color notSelectedTitleColor;
+
+  /** The text color of the titlePane when the JInternalFrame is selected. */
+  protected Color selectedTextColor;
+
+  /**
+   * The background color of the TitlePane when the JInternalFrame is
+   * selected.
+   */
+  protected Color selectedTitleColor;
+
+  /** The Property Change listener that listens to the JInternalFrame. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /**
+   * The label used to display the title. This label is not added to the
+   * TitlePane.
+   */
+  private transient JLabel title;
+
+  /**
+   * Creates a new BasicInternalFrameTitlePane object that is used in the
+   * given JInternalFrame.
+   *
+   * @param f The JInternalFrame this BasicInternalFrameTitlePane will be used
+   *        in.
+   */
+  public BasicInternalFrameTitlePane(JInternalFrame f)
+  {
+    frame = f;
+    setLayout(createLayout());
+    title = new JLabel();
+    title.setHorizontalAlignment(SwingConstants.LEFT);
+    title.setHorizontalTextPosition(SwingConstants.LEFT);
+    title.setOpaque(false);
+    setOpaque(true);
+
+    setBackground(Color.LIGHT_GRAY);
+
+    installTitlePane();
+  }
+
+  /**
+   * This method installs the TitlePane onto the JInternalFrameTitlePane. It
+   * also creates any children components that need to be created and adds
+   * listeners to the appropriate components.
+   */
+  protected void installTitlePane()
+  {
+    installDefaults();
+    installListeners();
+    createActions();
+
+    assembleSystemMenu();
+
+    createButtons();
+    setButtonIcons();
+    addSubComponents();
+    enableActions();
+  }
+
+  /**
+   * This method adds the sub components to the TitlePane.
+   */
+  protected void addSubComponents()
+  {
+    add(menuBar);
+
+    add(closeButton);
+    add(iconButton);
+    add(maxButton);
+  }
+
+  /**
+   * This method creates the actions that are used to manipulate the
+   * JInternalFrame.
+   */
+  protected void createActions()
+  {
+    closeAction = new CloseAction();
+    closeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, CLOSE_CMD);
+
+    iconifyAction = new IconifyAction();
+    iconifyAction.putValue(AbstractAction.ACTION_COMMAND_KEY, ICONIFY_CMD);
+
+    maximizeAction = new MaximizeAction();
+    maximizeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, MAXIMIZE_CMD);
+
+    sizeAction = new SizeAction();
+    sizeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, SIZE_CMD);
+
+    restoreAction = new RestoreAction();
+    restoreAction.putValue(AbstractAction.ACTION_COMMAND_KEY, RESTORE_CMD);
+
+    moveAction = new MoveAction();
+    moveAction.putValue(AbstractAction.ACTION_COMMAND_KEY, MOVE_CMD);
+  }
+
+  /**
+   * This method is used to install the listeners.
+   */
+  protected void installListeners()
+  {
+    propertyChangeListener = new PropertyChangeHandler();
+    frame.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * This method is used to uninstall the listeners.
+   */
+  protected void uninstallListeners()
+  {
+    frame.removePropertyChangeListener(propertyChangeListener);
+    propertyChangeListener = null;
+  }
+
+  /**
+   * This method installs the defaults determined by the look and feel.
+   */
+  protected void installDefaults()
+  {
+    // FIXME: move icons to defaults.
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    setFont(defaults.getFont("InternalFrame.titleFont"));
+    activeFGColor = defaults.getColor("InternalFrame.activeTitleForeground");
+    activeBGColor = defaults.getColor("InternalFrame.activeTitleBackground");
+    inactiveFGColor = defaults.getColor("InternalFrame.inactiveTitleForeground");
+    inactiveBGColor = defaults.getColor("InternalFrame.inactiveTitleBackground");
+  }
+
+  /**
+   * This method uninstalls the defaults.
+   */
+  protected void uninstallDefaults()
+  {
+    setFont(null);
+    activeFGColor = null;
+    activeBGColor = null;
+    inactiveFGColor = null;
+    inactiveBGColor = null;
+  }
+
+  /**
+   * This method creates the buttons used in the TitlePane.
+   */
+  protected void createButtons()
+  {
+    closeButton = new PaneButton(closeAction);
+    closeButton.setOpaque(false);
+
+    iconButton = new PaneButton(iconifyAction);
+    iconButton.setOpaque(false);
+
+    maxButton = new PaneButton(maximizeAction);
+    maxButton.setOpaque(false);
+  }
+
+  /**
+   * This method sets the icons in the buttons.
+   */
+  protected void setButtonIcons()
+  {
+    closeButton.setIcon(closeIcon);
+    iconButton.setIcon(iconIcon);
+    maxButton.setIcon(maxIcon);
+  }
+
+  /**
+   * This method creates the MenuBar used in the TitlePane.
+   */
+  protected void assembleSystemMenu()
+  {
+    menuBar = createSystemMenuBar();
+    windowMenu = createSystemMenu();
+
+    menuBar.add(windowMenu);
+
+    addSystemMenuItems(windowMenu);
+    enableActions();
+  }
+
+  /**
+   * This method adds the MenuItems to the given JMenu.
+   *
+   * @param systemMenu The JMenu to add MenuItems to.
+   */
+  protected void addSystemMenuItems(JMenu systemMenu)
+  {
+    JMenuItem tmp;
+
+    tmp = new JMenuItem(RESTORE_CMD);
+    tmp.addActionListener(restoreAction);
+    tmp.setMnemonic(KeyEvent.VK_R);
+    systemMenu.add(tmp);
+
+    tmp = new JMenuItem(MOVE_CMD);
+    tmp.addActionListener(moveAction);
+    tmp.setMnemonic(KeyEvent.VK_M);
+    systemMenu.add(tmp);
+
+    tmp = new JMenuItem(SIZE_CMD);
+    tmp.addActionListener(sizeAction);
+    tmp.setMnemonic(KeyEvent.VK_S);
+    systemMenu.add(tmp);
+
+    tmp = new JMenuItem(ICONIFY_CMD);
+    tmp.addActionListener(iconifyAction);
+    tmp.setMnemonic(KeyEvent.VK_N);
+    systemMenu.add(tmp);
+
+    tmp = new JMenuItem(MAXIMIZE_CMD);
+    tmp.addActionListener(maximizeAction);
+    tmp.setMnemonic(KeyEvent.VK_X);
+    systemMenu.add(tmp);
+
+    systemMenu.addSeparator();
+
+    tmp = new JMenuItem(CLOSE_CMD);
+    tmp.addActionListener(closeAction);
+    tmp.setMnemonic(KeyEvent.VK_C);
+    systemMenu.add(tmp);
+  }
+
+  /**
+   * This method creates a new JMenubar.
+   *
+   * @return A new JMenuBar.
+   */
+  protected JMenuBar createSystemMenuBar()
+  {
+    if (menuBar == null)
+      menuBar = new SystemMenuBar();
+    menuBar.removeAll();
+    return menuBar;
+  }
+
+  /**
+   * This method creates a new JMenu.
+   *
+   * @return A new JMenu.
+   */
+  protected JMenu createSystemMenu()
+  {
+    if (windowMenu == null)
+      windowMenu = new JMenu();
+    windowMenu.removeAll();
+    return windowMenu;
+  }
+
+  /**
+   * This method programmatically shows the JMenu.
+   */
+  protected void showSystemMenu()
+  {
+    // FIXME: Untested as KeyEvents are not hooked up.
+    menuBar.getMenu(1).getPopupMenu().show();
+  }
+
+  /**
+   * This method paints the TitlePane.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  public void paintComponent(Graphics g)
+  {
+    paintTitleBackground(g);
+    Font f = g.getFont();
+    FontMetrics fm = g.getFontMetrics(f);
+    if (frame.getTitle() != null && title != null)
+      {
+	Color saved = g.getColor();
+	if (frame.isSelected())
+	  g.setColor(activeFGColor);
+	else
+	  g.setColor(inactiveFGColor);
+	title.setText(getTitle(frame.getTitle(), fm, title.getBounds().width));
+	SwingUtilities.paintComponent(g, title, null, title.getBounds());
+	g.setColor(saved);
+      }
+  }
+
+  /**
+   * This method paints the TitlePane's background.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintTitleBackground(Graphics g)
+  {
+    Color saved = g.getColor();
+    Dimension dims = getSize();
+
+    Color bg = getBackground();
+    if (frame.isSelected())
+      bg = activeBGColor;
+    else
+      bg = inactiveBGColor;
+    g.setColor(bg);
+    g.fillRect(0, 0, dims.width, dims.height);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method returns the title string based on the available width and the
+   * font metrics.
+   *
+   * @param text The desired title.
+   * @param fm The FontMetrics of the font used.
+   * @param availableWidth The available width.
+   *
+   * @return The allowable string.
+   */
+  protected String getTitle(String text, FontMetrics fm, int availableWidth)
+  {
+    Rectangle vr = new Rectangle(0, 0, availableWidth, fm.getHeight());
+    Rectangle ir = new Rectangle();
+    Rectangle tr = new Rectangle();
+    String value = SwingUtilities.layoutCompoundLabel(this, fm, text, null,
+                                                      SwingConstants.CENTER,
+                                                      SwingConstants.LEFT,
+                                                      SwingConstants.CENTER,
+                                                      SwingConstants.LEFT, vr,
+                                                      ir, tr, 0);
+    return value;
+  }
+
+  /**
+   * This method fires something similar to a WINDOW_CLOSING event.
+   *
+   * @param frame The JInternalFrame that is being closed.
+   */
+  protected void postClosingEvent(JInternalFrame frame)
+  {
+    // FIXME: Implement postClosingEvent when I figure out what
+    // it's supposed to do.
+    // It says that this fires an WINDOW_CLOSING like event. 
+    // So the closest thing is some kind of InternalFrameEvent.
+    // But none is fired.
+    // Can't see it called or anything.
+  }
+
+  /**
+   * This method enables the actions for the TitlePane given the frame's
+   * properties.
+   */
+  protected void enableActions()
+  {
+    closeAction.setEnabled(frame.isClosable());
+
+    iconifyAction.setEnabled(frame.isIconifiable());
+    // The maximize action is responsible for restoring it
+    // as well, if clicked from the button
+    maximizeAction.setEnabled(frame.isMaximizable());
+
+    // The restoring action is only active when selected
+    // from the menu.
+    restoreAction.setEnabled(frame.isMaximum());
+
+    sizeAction.setEnabled(frame.isResizable());
+
+    // FIXME: Tie MoveAction enabled status to a variable.
+    moveAction.setEnabled(false);
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener.
+   *
+   * @return A new PropertyChangeListener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method creates a new LayoutManager for the TitlePane.
+   *
+   * @return A new LayoutManager.
+   */
+  protected LayoutManager createLayout()
+  {
+    return new TitlePaneLayout();
+  }
+}
Index: javax/swing/plaf/basic/BasicInternalFrameUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicInternalFrameUI.java
diff -N javax/swing/plaf/basic/BasicInternalFrameUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicInternalFrameUI.java	6 Sep 2004 16:36:04 -0000
@@ -0,0 +1,1656 @@
+/* BasicInternalFrameUI.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.AWTEvent;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.KeyStroke;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.border.AbstractBorder;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.InternalFrameUI;
+import javax.swing.plaf.UIResource;
+
+
+/**
+ * This is the UI delegate for the Basic look and feel for JInternalFrames.
+ */
+public class BasicInternalFrameUI extends InternalFrameUI
+{
+  /**
+   * This is a helper class that listens to the JInternalFrame for
+   * InternalFrameEvents.
+   */
+  protected class BasicInternalFrameListener implements InternalFrameListener
+  {
+    /**
+     * This method is called when the JInternalFrame is activated.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameActivated(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is closed.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameClosed(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is closing.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameClosing(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is deactivated.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameDeactivated(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is  deiconified.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameDeiconified(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is  iconified.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameIconified(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is opened.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameOpened(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+  }
+
+  /**
+   * This helper class listens to the edges of the JInternalFrame and the
+   * TitlePane for mouse events. It is responsible for dragging  and resizing
+   * the JInternalFrame in response to the MouseEvents.
+   */
+  protected class BorderListener extends MouseInputAdapter
+    implements SwingConstants
+  {
+    /** FIXME: Use for something. */
+    protected int RESIZE_NONE;
+
+    /** The x offset from the top left corner of the JInternalFrame. */
+    private transient int xOffset = 0;
+
+    /** The y offset from the top left corner of the JInternalFrame. */
+    private transient int yOffset = 0;
+
+    /** The direction that the resize is occuring in. */
+    private transient int direction = -1;
+
+    /** Cache rectangle that can be reused. */
+    private transient Rectangle cacheRect = new Rectangle();
+
+    /**
+     * This method is called when the mouse is clicked.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      // There is nothing to do when the mouse is clicked
+      // on the border.
+    }
+
+    /**
+     * This method is called when the mouse is dragged. This method is
+     * responsible for resizing or dragging the JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      // If the frame is maximized, there is nothing that 
+      // can be dragged around.
+      if (frame.isMaximum())
+	return;
+      DesktopManager dm = getDesktopManager();
+      Rectangle b = frame.getBounds();
+      Dimension min = frame.getMinimumSize();
+      if (min == null)
+	min = new Dimension(0, 0);
+      Insets insets = frame.getInsets();
+      int x = e.getX();
+      int y = e.getY();
+      if (e.getSource() == frame && frame.isResizable())
+        {
+	  switch (direction)
+	    {
+	    case NORTH:
+	      cacheRect.setBounds(b.x,
+	                          Math.min(b.y + y, b.y + b.height
+	                                   - min.height), b.width, b.height
+	                          - y);
+	      break;
+	    case NORTH_EAST:
+	      cacheRect.setBounds(b.x,
+	                          Math.min(b.y + y, b.y + b.height
+	                                   - min.height), x, b.height - y);
+	      break;
+	    case EAST:
+	      cacheRect.setBounds(b.x, b.y, x, b.height);
+	      break;
+	    case SOUTH_EAST:
+	      cacheRect.setBounds(b.x, b.y, x, y);
+	      break;
+	    case SOUTH:
+	      cacheRect.setBounds(b.x, b.y, b.width, y);
+	      break;
+	    case SOUTH_WEST:
+	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+	                          b.y, b.width - x, y);
+	      break;
+	    case WEST:
+	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+	                          b.y, b.width - x, b.height);
+	      break;
+	    case NORTH_WEST:
+	      cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+	                          Math.min(b.y + y, b.y + b.height
+	                                   - min.height), b.width - x,
+	                          b.height - y);
+	      break;
+	    }
+	  dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
+	                 Math.max(min.width, cacheRect.width),
+	                 Math.max(min.height, cacheRect.height));
+        }
+      else if (e.getSource() == titlePane)
+        {
+	  Rectangle fBounds = frame.getBounds();
+
+	  dm.dragFrame(frame, e.getX() - xOffset + b.x,
+	               e.getY() - yOffset + b.y);
+        }
+    }
+
+    /**
+     * This method is called when the mouse exits the JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      // There is nothing to do when the mouse exits 
+      // the border area.
+    }
+
+    /**
+     * This method is called when the mouse is moved inside the
+     * JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // There is nothing to do when the mouse moves
+      // over the border area.
+    }
+
+    /**
+     * This method is called when the mouse is pressed.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      activateFrame(frame);
+      DesktopManager dm = getDesktopManager();
+      int x = e.getX();
+      int y = e.getY();
+      Insets insets = frame.getInsets();
+
+      if (e.getSource() == frame && frame.isResizable())
+        {
+	  direction = sectionOfClick(x, y);
+	  dm.beginResizingFrame(frame, direction);
+        }
+      else if (e.getSource() == titlePane)
+        {
+	  Rectangle tBounds = titlePane.getBounds();
+
+	  xOffset = e.getX() - tBounds.x + insets.left;
+	  yOffset = e.getY() - tBounds.y + insets.top;
+
+	  dm.beginDraggingFrame(frame);
+        }
+    }
+
+    /**
+     * This method is called when the mouse is released.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      DesktopManager dm = getDesktopManager();
+      xOffset = 0;
+      yOffset = 0;
+      if (e.getSource() == frame && frame.isResizable())
+	dm.endResizingFrame(frame);
+      else if (e.getSource() == titlePane)
+	dm.endDraggingFrame(frame);
+    }
+
+    /**
+     * This method determines the direction of the resize based on the
+     * coordinates and the size of the JInternalFrame.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     *
+     * @return The direction of the resize (a SwingConstant direction).
+     */
+    private int sectionOfClick(int x, int y)
+    {
+      Insets insets = frame.getInsets();
+      Rectangle b = frame.getBounds();
+      if (x < insets.left && y < insets.top)
+	return NORTH_WEST;
+      else if (x > b.width - insets.right && y < insets.top)
+	return NORTH_EAST;
+      else if (x > b.width - insets.right && y > b.height - insets.bottom)
+	return SOUTH_EAST;
+      else if (x < insets.left && y > b.height - insets.bottom)
+	return SOUTH_WEST;
+      else if (y < insets.top)
+	return NORTH;
+      else if (x < insets.left)
+	return WEST;
+      else if (y > b.height - insets.bottom)
+	return SOUTH;
+      else if (x > b.width - insets.right)
+	return EAST;
+
+      return -1;
+    }
+  }
+
+  /**
+   * This helper class listens to the JDesktopPane that parents this
+   * JInternalFrame and listens for resize events and resizes the
+   * JInternalFrame appropriately.
+   */
+  protected class ComponentHandler implements ComponentListener
+  {
+    /**
+     * This method is called when the JDesktopPane is hidden.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentHidden(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is moved.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentMoved(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is resized.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentResized(ComponentEvent e)
+    {
+      if (frame.isMaximum())
+        {
+	  JDesktopPane pane = (JDesktopPane) e.getSource();
+	  Insets insets = pane.getInsets();
+	  Rectangle bounds = pane.getBounds();
+
+	  frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
+	                  bounds.width - insets.left - insets.right,
+	                  bounds.height - insets.top - insets.bottom);
+	  frame.revalidate();
+	  frame.repaint();
+        }
+
+      // Sun also resizes the icons. but it doesn't seem to do anything.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is shown.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentShown(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+  }
+
+  /**
+   * This helper class acts as the LayoutManager for JInternalFrames.
+   */
+  public class InternalFrameLayout implements LayoutManager
+  {
+    /**
+     * This method is called when the given Component is added  to the
+     * JInternalFrame.
+     *
+     * @param name The name of the Component.
+     * @param c The Component added.
+     */
+    public void addLayoutComponent(String name, Component c)
+    {
+    }
+
+    /**
+     * This method is used to set the bounds of the children of the
+     * JInternalFrame.
+     *
+     * @param c The Container to lay out.
+     */
+    public void layoutContainer(Container c)
+    {
+      Dimension dims = frame.getSize();
+      Insets insets = frame.getInsets();
+
+      dims.width -= insets.left + insets.right;
+      dims.height -= insets.top + insets.bottom;
+
+      frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
+                                                   dims.height);
+      int nh = 0;
+      int sh = 0;
+      int ew = 0;
+      int ww = 0;
+
+      if (northPane != null)
+        {
+	  Dimension nDims = northPane.getPreferredSize();
+	  nh = Math.min(nDims.height, dims.height);
+
+	  northPane.setBounds(insets.left, insets.top, dims.width, nh);
+        }
+
+      if (southPane != null)
+        {
+	  Dimension sDims = southPane.getPreferredSize();
+	  sh = Math.min(sDims.height, dims.height - nh);
+
+	  southPane.setBounds(insets.left, insets.top + dims.height - sh,
+	                      dims.width, sh);
+        }
+
+      int remHeight = dims.height - sh - nh;
+
+      if (westPane != null)
+        {
+	  Dimension wDims = westPane.getPreferredSize();
+	  ww = Math.min(dims.width, wDims.width);
+
+	  westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
+        }
+
+      if (eastPane != null)
+        {
+	  Dimension eDims = eastPane.getPreferredSize();
+	  ew = Math.min(eDims.width, dims.width - ww);
+
+	  eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
+	                     ew, remHeight);
+        }
+
+      int remWidth = dims.width - ww - ew;
+
+      frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
+                                    remWidth, remHeight);
+    }
+
+    /**
+     * This method returns the minimum layout size.
+     *
+     * @param c The Container to find a minimum layout size for.
+     *
+     * @return The minimum dimensions for the JInternalFrame.
+     */
+    public Dimension minimumLayoutSize(Container c)
+    {
+      return getSize(c, true);
+    }
+
+    /**
+     * This method returns the maximum layout size.
+     *
+     * @param c The Container to find a maximum layout size for.
+     *
+     * @return The maximum dimensions for the JInternalFrame.
+     */
+    public Dimension maximumLayoutSize(Container c)
+    {
+      return preferredLayoutSize(c);
+    }
+
+    /**
+     * Th8is method returns the preferred layout size.
+     *
+     * @param c The Container to find a preferred layout size for.
+     *
+     * @return The preferred dimensions for the JInternalFrame.
+     */
+    public Dimension preferredLayoutSize(Container c)
+    {
+      return getSize(c, false);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     * @param min DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private Dimension getSize(Container c, boolean min)
+    {
+      Insets insets = frame.getInsets();
+
+      Dimension contentDims = frame.getContentPane().getPreferredSize();
+      if (min)
+	contentDims.width = contentDims.height = 0;
+      int nWidth = 0;
+      int nHeight = 0;
+      int sWidth = 0;
+      int sHeight = 0;
+      int eWidth = 0;
+      int eHeight = 0;
+      int wWidth = 0;
+      int wHeight = 0;
+      Dimension dims;
+
+      if (northPane != null)
+        {
+	  dims = northPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      nWidth = dims.width;
+	      nHeight = dims.height;
+	    }
+        }
+
+      if (southPane != null)
+        {
+	  dims = southPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      sWidth = dims.width;
+	      sHeight = dims.height;
+	    }
+        }
+
+      if (eastPane != null)
+        {
+	  dims = eastPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      sWidth = dims.width;
+	      sHeight = dims.height;
+	    }
+        }
+
+      if (westPane != null)
+        {
+	  dims = westPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      wWidth = dims.width;
+	      wHeight = dims.height;
+	    }
+        }
+
+      int width = Math.max(sWidth, nWidth);
+      width = Math.max(width, contentDims.width + eWidth + wWidth);
+
+      int height = Math.max(eHeight, wHeight);
+      height = Math.max(height, contentDims.height);
+      height += nHeight + sHeight;
+
+      width += insets.left + insets.right;
+      height += insets.top + insets.bottom;
+
+      return new Dimension(width, height);
+    }
+
+    /**
+     * This method is called when a Component is removed from the
+     * JInternalFrame.
+     *
+     * @param c The Component that was removed.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+    }
+  }
+
+  /**
+   * This helper class is used to listen to the JDesktopPane's glassPane for
+   * MouseEvents. The JInternalFrame can then be selected if a click is
+   * detected on its children.
+   */
+  protected class GlassPaneDispatcher implements MouseInputListener
+  {
+    /** The MouseEvent target. */
+    private transient Component mouseEventTarget;
+
+    /** The component pressed. */
+    private transient Component pressedComponent;
+
+    /** The last component entered. */
+    private transient Component lastComponentEntered;
+
+    /** The number of presses. */
+    private transient int pressCount;
+
+    /**
+     * This method is called when the mouse enters the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse is clicked on the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse is dragged in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse exits the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse is moved in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse is  pressed in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      activateFrame(frame);
+      handleEvent(e);
+    }
+
+    /**
+     * This method is called when the mouse is  released in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      handleEvent(e);
+    }
+
+    /**
+     * This method acquires a candidate component to dispatch the  MouseEvent
+     * to.
+     *
+     * @param me The MouseEvent to acquire a component for.
+     */
+    private void acquireComponentForMouseEvent(MouseEvent me)
+    {
+      int x = me.getX();
+      int y = me.getY();
+
+      // Find the candidate which should receive this event.
+      Component parent = frame.getContentPane();
+      if (parent == null)
+	return;
+      Component candidate = null;
+      Point p = me.getPoint();
+      while (candidate == null && parent != null)
+        {
+	  candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
+	  if (candidate == null)
+	    {
+	      p = SwingUtilities.convertPoint(parent, p.x, p.y,
+	                                      parent.getParent());
+	      parent = parent.getParent();
+	    }
+        }
+
+      // If the only candidate we found was the native container itself,
+      // don't dispatch any event at all.  We only care about the lightweight
+      // children here.
+      if (candidate == frame.getContentPane())
+	candidate = null;
+
+      // If our candidate is new, inform the old target we're leaving.
+      if (lastComponentEntered != null && lastComponentEntered.isShowing()
+          && lastComponentEntered != candidate)
+        {
+	  Point tp = SwingUtilities.convertPoint(frame.getContentPane(), x, y,
+	                                         lastComponentEntered);
+	  MouseEvent exited = new MouseEvent(lastComponentEntered,
+	                                     MouseEvent.MOUSE_EXITED,
+	                                     me.getWhen(), me.getModifiersEx(),
+	                                     tp.x, tp.y, me.getClickCount(),
+	                                     me.isPopupTrigger(),
+	                                     me.getButton());
+	  lastComponentEntered.dispatchEvent(exited);
+	  lastComponentEntered = null;
+        }
+
+      // If we have a candidate, maybe enter it.
+      if (candidate != null)
+        {
+	  mouseEventTarget = candidate;
+	  if (candidate.isLightweight() && candidate.isShowing()
+	      && candidate != frame.getContentPane()
+	      && candidate != lastComponentEntered)
+	    {
+	      lastComponentEntered = mouseEventTarget;
+	      Point cp = SwingUtilities.convertPoint(frame.getContentPane(),
+	                                             x, y, lastComponentEntered);
+	      MouseEvent entered = new MouseEvent(lastComponentEntered,
+	                                          MouseEvent.MOUSE_ENTERED,
+	                                          me.getWhen(),
+	                                          me.getModifiersEx(), cp.x,
+	                                          cp.y, me.getClickCount(),
+	                                          me.isPopupTrigger(),
+	                                          me.getButton());
+	      lastComponentEntered.dispatchEvent(entered);
+	    }
+        }
+
+      if (me.getID() == MouseEvent.MOUSE_RELEASED
+          || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
+          || me.getID() == MouseEvent.MOUSE_DRAGGED)
+	// If any of the following events occur while a button is held down,
+	// they should be dispatched to the same component to which the
+	// original MOUSE_PRESSED event was dispatched:
+	//   - MOUSE_RELEASED
+	//   - MOUSE_PRESSED: another button pressed while the first is held down
+	//   - MOUSE_DRAGGED
+	mouseEventTarget = pressedComponent;
+      else if (me.getID() == MouseEvent.MOUSE_CLICKED)
+        {
+	  // Don't dispatch CLICKED events whose target is not the same as the
+	  // target for the original PRESSED event.
+	  if (candidate != pressedComponent)
+	    mouseEventTarget = null;
+	  else if (pressCount == 0)
+	    pressedComponent = null;
+        }
+    }
+
+    /**
+     * This is a helper method that dispatches the GlassPane MouseEvents to
+     * the proper component.
+     *
+     * @param e The AWTEvent to be dispatched. Usually an instance of
+     *        MouseEvent.
+     */
+    private void handleEvent(AWTEvent e)
+    {
+      if (e instanceof MouseEvent)
+        {
+	  MouseEvent me = SwingUtilities.convertMouseEvent(frame.getRootPane()
+                                                                .getGlassPane(),
+	                                                   (MouseEvent) e,
+	                                                   frame.getRootPane()
+	                                                        .getGlassPane());
+
+	  acquireComponentForMouseEvent(me);
+
+	  // Avoid dispatching ENTERED and EXITED events twice.
+	  if (mouseEventTarget != null && mouseEventTarget.isShowing()
+	      && e.getID() != MouseEvent.MOUSE_ENTERED
+	      && e.getID() != MouseEvent.MOUSE_EXITED)
+	    {
+	      MouseEvent newEvt = SwingUtilities.convertMouseEvent(frame
+	                                                           .getContentPane(),
+	                                                           me,
+	                                                           mouseEventTarget);
+	      mouseEventTarget.dispatchEvent(newEvt);
+
+	      switch (e.getID())
+	        {
+		case MouseEvent.MOUSE_PRESSED:
+		  if (pressCount++ == 0)
+		    pressedComponent = mouseEventTarget;
+		  break;
+		case MouseEvent.MOUSE_RELEASED:
+		  // Clear our memory of the original PRESSED event, only if
+		  // we're not expecting a CLICKED event after this. If
+		  // there is a CLICKED event after this, it will do clean up.
+		  if (--pressCount == 0
+		      && mouseEventTarget != pressedComponent)
+		    pressedComponent = null;
+		  break;
+	        }
+	    }
+        }
+    }
+  }
+
+  /**
+   * This helper class listens for PropertyChangeEvents from the
+   * JInternalFrame.
+   */
+  public class InternalFramePropertyChangeListener
+    implements PropertyChangeListener
+  {
+    /**
+     * This method is called when one of the JInternalFrame's properties
+     * change.
+     *
+     * @param evt The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
+        {
+	  if (frame.isMaximum())
+	    maximizeFrame(frame);
+	  else
+	    minimizeFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
+	closeFrame(frame);
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
+        {
+	  if (frame.isIcon())
+	    iconifyFrame(frame);
+	  else
+	    deiconifyFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
+        {
+	  if (frame.isSelected())
+	    activateFrame(frame);
+	  else
+	    getDesktopManager().deactivateFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
+               || evt.getPropertyName().equals(JInternalFrame.GLASS_PANE_PROPERTY))
+        {
+	  Component old = (Component) evt.getOldValue();
+	  old.removeMouseListener(glassPaneDispatcher);
+	  old.removeMouseMotionListener(glassPaneDispatcher);
+
+	  Component newPane = (Component) evt.getNewValue();
+	  newPane.addMouseListener(glassPaneDispatcher);
+	  newPane.addMouseMotionListener(glassPaneDispatcher);
+
+	  frame.revalidate();
+        }
+      /* FIXME: need to add ancestor properties to JComponents.
+      else if (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY))
+      {
+        if (desktopPane != null)
+          desktopPane.removeComponentListener(componentListener);
+        desktopPane = frame.getDesktopPane();
+        if (desktopPane != null)
+          desktopPane.addComponentListener(componentListener);
+      }
+      */
+    }
+  }
+
+  /**
+   * This helper class is the border for the JInternalFrame.
+   */
+  private class InternalFrameBorder extends AbstractBorder
+    implements UIResource
+  {
+    /** The width of the border. */
+    private static final int bSize = 5;
+
+    /** The size of the corners. */
+    private static final int offset = 10;
+
+    /**
+     * This method returns whether the border is opaque.
+     *
+     * @return Whether the border is opaque.
+     */
+    public boolean isBorderOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method returns the insets of the border.
+     *
+     * @param c The Component to find border insets for.
+     *
+     * @return The border insets.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(bSize, bSize, bSize, bSize);
+    }
+
+    /**
+     * This method paints the border.
+     *
+     * @param c The Component that owns the border.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate to paint at.
+     * @param y The y coordinate to paint at.
+     * @param width The width of the Component.
+     * @param height The height of the Component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+      Rectangle b = frame.getBounds();
+
+      Color d = c.getBackground();
+      g.setColor(d);
+      g.fillRect(0, 0, bSize, b.height);
+      g.fillRect(0, 0, b.width, bSize);
+      g.fillRect(0, b.height - bSize, b.width, bSize);
+      g.fillRect(b.width - bSize, 0, bSize, b.height);
+
+      int x1 = 0;
+      int x2 = bSize;
+      int x3 = b.width - bSize;
+      int x4 = b.width;
+
+      int y1 = 0;
+      int y2 = bSize;
+      int y3 = b.height - bSize;
+      int y4 = b.height;
+
+      g.setColor(Color.GRAY);
+      g.fillRect(0, 0, bSize, y4);
+      g.fillRect(0, 0, x4, bSize);
+      g.fillRect(0, y3, b.width, bSize);
+      g.fillRect(x3, 0, bSize, b.height);
+
+      g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
+      g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
+      g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
+      g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
+
+      g.translate(-x, -y);
+      g.setColor(saved);
+    }
+  }
+
+  /**
+   * The MouseListener that is responsible for dragging and resizing the
+   * JInternalFrame in response to MouseEvents.
+   */
+  protected MouseInputAdapter borderListener;
+
+  /**
+   * The ComponentListener that is responsible for resizing the JInternalFrame
+   * in response to ComponentEvents from the JDesktopPane.
+   */
+  protected ComponentListener componentListener;
+
+  /**
+   * The MouseListener that is responsible for activating the JInternalFrame
+   * when the mouse press activates one of its descendents.
+   */
+  protected MouseInputListener glassPaneDispatcher;
+
+  /**
+   * The PropertyChangeListener that is responsible for listening to
+   * PropertyChangeEvents from the JInternalFrame.
+   */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The InternalFrameListener that listens to the JInternalFrame. */
+  private transient BasicInternalFrameListener internalFrameListener;
+
+  /** The JComponent placed at the east region of the JInternalFrame. */
+  protected JComponent eastPane;
+
+  /** The JComponent placed at the north region of the JInternalFrame. */
+  protected JComponent northPane;
+
+  /** The JComponent placed at the south region of the JInternalFrame. */
+  protected JComponent southPane;
+
+  /** The JComponent placed at the west region of the JInternalFrame. */
+  protected JComponent westPane;
+
+  /** The Keystroke bound to open the menu. */
+  protected KeyStroke openMenuKey;
+
+  /** The TitlePane displayed at the top of the JInternalFrame. */
+  protected BasicInternalFrameTitlePane titlePane;
+
+  /** The JInternalFrame this UI is responsible for. */
+  protected JInternalFrame frame;
+
+  /** The LayoutManager used in the JInternalFrame. */
+  protected LayoutManager internalFrameLayout;
+
+  /** The JDesktopPane that is the parent of the JInternalFrame. */
+  private transient JDesktopPane desktopPane;
+
+  /**
+   * Creates a new BasicInternalFrameUI object.
+   *
+   * @param b The JInternalFrame this UI will represent.
+   */
+  public BasicInternalFrameUI(JInternalFrame b)
+  {
+  }
+
+  /**
+   * This method will create a new BasicInternalFrameUI for the given
+   * JComponent.
+   *
+   * @param b The JComponent to create a BasicInternalFrameUI for.
+   *
+   * @return A new BasicInternalFrameUI.
+   */
+  public static ComponentUI createUI(JComponent b)
+  {
+    return new BasicInternalFrameUI((JInternalFrame) b);
+  }
+
+  /**
+   * This method installs a UI for the JInternalFrame.
+   *
+   * @param c The JComponent to install this UI on.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JInternalFrame)
+      {
+	frame = (JInternalFrame) c;
+
+	internalFrameLayout = createLayoutManager();
+	frame.setLayout(internalFrameLayout);
+
+	((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
+	frame.getRootPane().getGlassPane().setVisible(true);
+
+	installDefaults();
+	installListeners();
+	installComponents();	
+	installKeyboardActions();
+
+	frame.setOpaque(true);
+	titlePane.setOpaque(true);
+	frame.invalidate();
+      }
+  }
+
+  /**
+   * This method reverses the work done by installUI.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallComponents();    
+    uninstallListeners();
+    uninstallDefaults();
+
+    frame.setLayout(null);
+    ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
+    frame.getRootPane().getGlassPane().setVisible(false);
+
+    frame = null;
+  }
+
+  /**
+   * This method installs the defaults specified by the look and feel.
+   */
+  protected void installDefaults()
+  {
+    // FIXME: Move border to MetalBorders
+    frame.setBorder(new InternalFrameBorder());
+  }
+
+  /**
+   * This method installs the keyboard actions for the JInternalFrame.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method installs the Components for the JInternalFrame.
+   */
+  protected void installComponents()
+  {
+    setNorthPane(createNorthPane(frame));
+    setSouthPane(createSouthPane(frame));
+    setEastPane(createEastPane(frame));
+    setWestPane(createWestPane(frame));
+  }
+
+  /**
+   * This method installs the listeners for the JInternalFrame.
+   */
+  protected void installListeners()
+  {
+    glassPaneDispatcher = createGlassPaneDispatcher();
+    createInternalFrameListener();
+    borderListener = createBorderListener(frame);
+    componentListener = createComponentListener();
+    propertyChangeListener = createPropertyChangeListener();
+
+    frame.addMouseListener(borderListener);
+    frame.addMouseMotionListener(borderListener);
+    frame.addInternalFrameListener(internalFrameListener);
+    frame.addPropertyChangeListener(propertyChangeListener);
+
+    frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
+    frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
+  }
+
+  /**
+   * This method uninstalls the defaults for the JInternalFrame.
+   */
+  protected void uninstallDefaults()
+  {
+    frame.setBorder(null);
+  }
+
+  /**
+   * This method uninstalls the Components for the JInternalFrame.
+   */
+  protected void uninstallComponents()
+  {
+    setNorthPane(null);
+    setSouthPane(null);
+    setEastPane(null);
+    setWestPane(null);
+  }
+
+  /**
+   * This method uninstalls the listeners for the JInternalFrame.
+   */
+  protected void uninstallListeners()
+  {
+    if (desktopPane != null)
+      desktopPane.removeComponentListener(componentListener);
+
+    frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
+    frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
+
+    frame.removePropertyChangeListener(propertyChangeListener);
+    frame.removeInternalFrameListener(internalFrameListener);
+    frame.removeMouseMotionListener(borderListener);
+    frame.removeMouseListener(borderListener);
+
+    propertyChangeListener = null;
+    componentListener = null;
+    borderListener = null;
+    internalFrameListener = null;
+    glassPaneDispatcher = null;
+  }
+
+  /**
+   * This method uninstalls the keyboard actions for the JInternalFrame.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method creates a new LayoutManager for the JInternalFrame.
+   *
+   * @return A new LayoutManager for the JInternalFrame.
+   */
+  protected LayoutManager createLayoutManager()
+  {
+    return new InternalFrameLayout();
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener for the JInternalFrame.
+   *
+   * @return A new PropertyChangeListener for the JInternalFrame.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new InternalFramePropertyChangeListener();
+  }
+
+  /**
+   * This method returns the preferred size of the given JComponent.
+   *
+   * @param x The JComponent to find a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent x)
+  {
+    return internalFrameLayout.preferredLayoutSize(x);
+  }
+
+  /**
+   * This method returns the minimum size of the given JComponent.
+   *
+   * @param x The JComponent to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent x)
+  {
+    return internalFrameLayout.minimumLayoutSize(x);
+  }
+
+  /**
+   * This method returns the maximum size of the given JComponent.
+   *
+   * @param x The JComponent to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent x)
+  {
+    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+  }
+
+  /**
+   * This method replaces the currentPane with the newPane. When replacing it
+   * also removes the MouseHandlers for the old pane and installs  them on
+   * the new pane.
+   *
+   * @param currentPane The old pane to remove.
+   * @param newPane The new pane to install.
+   */
+  protected void replacePane(JComponent currentPane, JComponent newPane)
+  {
+    if (currentPane != null)
+      {
+	deinstallMouseHandlers(currentPane);
+	frame.remove(currentPane);
+      }
+
+    if (newPane != null)
+      {
+	installMouseHandlers(newPane);
+	frame.add(newPane);
+      }
+  }
+
+  /**
+   * This method removes the necessary MouseListeners from the given
+   * JComponent.
+   *
+   * @param c The JComponent to remove MouseListeners from.
+   */
+  protected void deinstallMouseHandlers(JComponent c)
+  {
+    c.removeMouseListener(borderListener);
+    c.removeMouseMotionListener(borderListener);
+  }
+
+  /**
+   * This method installs the necessary MouseListeners from the given
+   * JComponent.
+   *
+   * @param c The JComponent to install MouseListeners on.
+   */
+  protected void installMouseHandlers(JComponent c)
+  {
+    c.addMouseListener(borderListener);
+    c.addMouseMotionListener(borderListener);
+  }
+
+  /**
+   * This method creates the north pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a north pane for.
+   *
+   * @return The north pane.
+   */
+  protected JComponent createNorthPane(JInternalFrame w)
+  {
+    titlePane = new BasicInternalFrameTitlePane(w);
+    return titlePane;
+  }
+
+  /**
+   * This method creates the west pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a west pane for.
+   *
+   * @return The west pane.
+   */
+  protected JComponent createWestPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method creates the south pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a south pane for.
+   *
+   * @return The south pane.
+   */
+  protected JComponent createSouthPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method creates the east pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create an east pane for.
+   *
+   * @return The east pane.
+   */
+  protected JComponent createEastPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns a new BorderListener for the given JInternalFrame.
+   *
+   * @param w The JIntenalFrame to create a BorderListener for.
+   *
+   * @return A new BorderListener.
+   */
+  protected MouseInputAdapter createBorderListener(JInternalFrame w)
+  {
+    return new BorderListener();
+  }
+
+  /**
+   * This method creates a new InternalFrameListener for the JInternalFrame.
+   */
+  protected void createInternalFrameListener()
+  {
+    internalFrameListener = new BasicInternalFrameListener();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected final boolean isKeyBindingRegistered()
+  {
+    // FIXME: Implement.
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  protected final void setKeyBindingRegistered(boolean b)
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public final boolean isKeyBindingActive()
+  {
+    // FIXME: Implement.
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  protected final void setKeyBindingActive(boolean b)
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void setupMenuOpenKey()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void setupMenuCloseKey()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method returns the north pane.
+   *
+   * @return The north pane.
+   */
+  public JComponent getNorthPane()
+  {
+    return northPane;
+  }
+
+  /**
+   * This method sets the north pane to be the given JComponent.
+   *
+   * @param c The new north pane.
+   */
+  public void setNorthPane(JComponent c)
+  {
+    replacePane(northPane, c);
+    northPane = c;
+  }
+
+  /**
+   * This method returns the south pane.
+   *
+   * @return The south pane.
+   */
+  public JComponent getSouthPane()
+  {
+    return southPane;
+  }
+
+  /**
+   * This method sets the south pane to be the given JComponent.
+   *
+   * @param c The new south pane.
+   */
+  public void setSouthPane(JComponent c)
+  {
+    replacePane(southPane, c);
+    southPane = c;
+  }
+
+  /**
+   * This method sets the east pane to be the given JComponent.
+   *
+   * @param c The new east pane.
+   */
+  public void setEastPane(JComponent c)
+  {
+    replacePane(eastPane, c);
+    eastPane = c;
+  }
+
+  /**
+   * This method returns the east pane.
+   *
+   * @return The east pane.
+   */
+  public JComponent getEastPane()
+  {
+    return eastPane;
+  }
+
+  /**
+   * This method sets the west pane to be the given JComponent.
+   *
+   * @param c The new west pane.
+   */
+  public void setWestPane(JComponent c)
+  {
+    replacePane(westPane, c);
+    westPane = c;
+  }
+
+  /**
+   * This method returns the west pane.
+   *
+   * @return The west pane.
+   */
+  public JComponent getWestPane()
+  {
+    return westPane;
+  }
+
+  /**
+   * This method returns the DesktopManager to use with the JInternalFrame.
+   *
+   * @return The DesktopManager to use with the JInternalFrame.
+   */
+  protected DesktopManager getDesktopManager()
+  {
+    DesktopManager value = frame.getDesktopPane().getDesktopManager();
+    if (value == null)
+      value = createDesktopManager();
+    return value;
+  }
+
+  /**
+   * This method returns a default DesktopManager that can be used with this
+   * JInternalFrame.
+   *
+   * @return A default DesktopManager that can be used with this
+   *         JInternalFrame.
+   */
+  protected DesktopManager createDesktopManager()
+  {
+    return new DefaultDesktopManager();
+  }
+
+  /**
+   * This is a convenience method that closes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to close.
+   */
+  protected void closeFrame(JInternalFrame f)
+  {
+    getDesktopManager().closeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that maximizes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to maximize.
+   */
+  protected void maximizeFrame(JInternalFrame f)
+  {
+    getDesktopManager().maximizeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that minimizes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to minimize.
+   */
+  protected void minimizeFrame(JInternalFrame f)
+  {
+    getDesktopManager().minimizeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that iconifies the JInternalFrame.
+   *
+   * @param f The JInternalFrame to iconify.
+   */
+  protected void iconifyFrame(JInternalFrame f)
+  {
+    getDesktopManager().iconifyFrame(f);
+  }
+
+  /**
+   * This is a convenience method that deiconifies the JInternalFrame.
+   *
+   * @param f The JInternalFrame to deiconify.
+   */
+  protected void deiconifyFrame(JInternalFrame f)
+  {
+    getDesktopManager().deiconifyFrame(f);
+  }
+
+  /**
+   * This is a convenience method that activates the JInternalFrame.
+   *
+   * @param f The JInternalFrame to activate.
+   */
+  protected void activateFrame(JInternalFrame f)
+  {
+    getDesktopManager().activateFrame(f);
+  }
+
+  /**
+   * This method returns a new ComponentListener for the JDesktopPane.
+   *
+   * @return A new ComponentListener.
+   */
+  protected ComponentListener createComponentListener()
+  {
+    return new ComponentHandler();
+  }
+
+  /**
+   * This method returns a new GlassPaneDispatcher.
+   *
+   * @return A new GlassPaneDispatcher.
+   */
+  protected MouseInputListener createGlassPaneDispatcher()
+  {
+    return new GlassPaneDispatcher();
+  }
+}
Index: javax/swing/plaf/basic/BasicLabelUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicLabelUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicLabelUI.java
--- javax/swing/plaf/basic/BasicLabelUI.java	13 Jul 2003 15:29:11 -0000	1.4
+++ javax/swing/plaf/basic/BasicLabelUI.java	6 Sep 2004 16:36:04 -0000
@@ -1,5 +1,5 @@
 /* BasicLabelUI.java
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
 import java.awt.Color;
@@ -47,156 +46,382 @@
 import java.awt.Rectangle;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+
+import javax.swing.Icon;
 import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.LabelUI;
 
-public class BasicLabelUI extends LabelUI
-  implements PropertyChangeListener
+
+/**
+ * This is the Basic Look and Feel class for the JLabel.  One BasicLabelUI
+ * object is used to paint all JLabels that utilize the Basic Look and Feel.
+ */
+public class BasicLabelUI extends LabelUI implements PropertyChangeListener
 {
-    int gap = 3;
-    Color foreground;
+  /** The labelUI that is shared by all labels. */
+  protected static BasicLabelUI labelUI;
 
-    
-    public static ComponentUI createUI(final JComponent c)  {
-	return new BasicLabelUI();
-    }
-    
-    
-    public void installUI(final JComponent c)  {
-	super.installUI(c);
-	
-	foreground = new Color(0,0,250);
-    }
-    
+  /**
+   * Creates a new BasicLabelUI object.
+   */
+  public BasicLabelUI()
+  {
+    super();
+  }
 
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	JLabel b = (JLabel)c;
-        /*
-          We cannot use this method because it is not part of the
-          official Swing API.
-
-	Dimension d = BasicGraphicsUtils.getPreferredSize(b, 
-							  gap,
-							  b.getText(),
-							  b.getIcon(),
-							  b.getVerticalAlignment(),
-							  b.getHorizontalAlignment(),
-							  b.getHorizontalTextPosition(),
-							  b.getVerticalTextPosition());
-	System.out.println("JLABEL->^^^^^^^^^^^^^^^^^^^^^^   BASIC-PREF="+d + ",T="+b.getText());
-        */
-        return new Dimension(100, 30);
-    }
+  /**
+   * Creates and returns a UI for the label. Since one UI is shared by  all
+   * labels, this means creating only if necessary and returning the  shared
+   * UI.
+   *
+   * @param c The {@link JComponent} that a UI is being created for.
+   *
+   * @return A label UI for the Basic Look and Feel.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    if (labelUI == null)
+      labelUI = new BasicLabelUI();
+    return labelUI;
+  }
+
+  /**
+   * Returns the preferred size of this component as calculated by the
+   * {@link layoutCL} method.
+   *
+   * @param c This {@link JComponent} to get a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c) 
+  {
+    JLabel lab = (JLabel)c;
+    Rectangle vr = new Rectangle();
+    Rectangle ir = new Rectangle();
+    Rectangle tr = new Rectangle();
+    Insets insets = lab.getInsets();      
+    FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont());
+    layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
+    Rectangle cr = tr.union(ir);
+    return new Dimension(insets.left + cr.width + insets.right,
+                         insets.top + cr.height + insets.bottom);
     
+  }  
 
-    public void paint(Graphics g, JComponent c)
-    {      
-	JLabel b = (JLabel) c;
-
-	Rectangle tr = new Rectangle();
-	Rectangle ir = new Rectangle();
-	Rectangle vr = new Rectangle();
-
-        Font f = c.getFont();
-
-        g.setFont(f);
-
-        FontMetrics fm = g.getFontMetrics(f);
-
-        Insets i = c.getInsets();
-
-	Rectangle bound = c.getBounds();
-	
-	System.out.println("BOUND=" + bound + ", insets = " + i + ", " + b.getText());
-	
-	if (bound == null)
-	    {
-		vr.x      = i.left;
-		vr.y      = i.top;
-		vr.width  = b.getWidth() - (i.right  + i.left);
-		vr.height = b.getHeight() - (i.bottom + i.top);
-	    }
-	else
-	    {
-		vr.x      = bound.x + i.left;
-		vr.y      = bound.y + i.top;
-		vr.width  = bound.width - (i.right  + i.left);
-		vr.height = bound.height - (i.bottom + i.top);
-	    }
-
-	System.out.println("             VIEW-RECT-JLABEL="+vr+", insets="+i+", FONTM="+fm);
-
-	String text = SwingUtilities.layoutCompoundLabel(c,
-							 fm, 
-							 b.getText(),
-							 b.getIcon(),
-							 b.getVerticalAlignment(), 
-							 b.getHorizontalAlignment(),
-							 b.getVerticalTextPosition(), 
-							 b.getHorizontalTextPosition(),
-							 vr,
-							 ir,
-							 tr,
-							 gap);
-
-	paintIcon(g, c, ir);
-	paintText(g, c, tr, b.getText());
-	paintFocus(g, c, vr, tr, ir);
-    }
+  /**
+   * This method returns the minimum size of the {@link JComponent} given. If
+   * this method returns null, then it is up to the Layout Manager to give
+   * this component a minimum size.
+   *
+   * @param c The {@link JComponent} to get a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
 
+  /**
+   * This method returns the maximum size of the {@link JComponent} given. If
+   * this method returns null, then it is up to the Layout Manager to give
+   * this component a maximum size.
+   *
+   * @param c The {@link JComponent} to get a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
 
-    protected void paintFocus(Graphics g, 
-			      JComponent c,
-			      Rectangle vr,
-			      Rectangle tr,
-			      Rectangle ir)
-    {
-    }
+  /**
+   * The method that paints the label according to its current state.
+   *
+   * @param g The {@link Graphics} object to paint with.
+   * @param c The {@link JComponent} to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    JLabel b = (JLabel) c;
 
-    protected void paintIcon(Graphics g, 
-			     JComponent c, 
-			     Rectangle iconRect)
-    {
-	JLabel b = (JLabel) c;
-	if (b.getIcon() != null)
-	    {
-		int x = iconRect.x;
-		int y = iconRect.y;
-
-		System.out.println("WE HAVE AN ICON: " + b.getIcon());
- 
-		b.getIcon().paintIcon(c, g, x, y);
-	    }
-	else
-	    {
-		//System.out.println("NO ICON FOR BUTTON:" + b.text);
-	    }
-    }
+    Font saved_font = g.getFont();
+
+    Rectangle tr = new Rectangle();
+    Rectangle ir = new Rectangle();
+    Rectangle vr = new Rectangle();
+
+    Font f = c.getFont();
+
+    g.setFont(f);
+    FontMetrics fm = g.getFontMetrics(f);
 
+    vr = SwingUtilities.calculateInnerArea(c, vr);
+
+    if (vr.width < 0)
+      vr.width = 0;
+    if (vr.height < 0)
+      vr.height = 0;
+      
+    Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
+
+    String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
     
-    protected void paintText(Graphics g,
-			     JComponent c,
-			     Rectangle textRect,
-			     String text) 
+    if (icon != null)
+      icon.paintIcon(b, g, ir.x, ir.y);
+    if (text != null && ! text.equals(""))
     {
-	//        AbstractLabel b = (AbstractLabel) c;
-	
-	System.out.println("JLabel: drawing string: " + text + ", at:" + textRect);
-	
-	g.setColor(foreground);
-	//g.setBackColor(new Color(190,190,190));
-
-	g.drawLine(0,0,100,100);
-	
-	BasicGraphicsUtils.drawString(g, text, 0, 0 /*textRect.x*/, 0 /*textRect.y*/);
+      if (b.isEnabled())
+        paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
+      else
+        paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
     }
+    g.setFont(saved_font);
+  }
+
+  /**
+   * This method is simply calls SwingUtilities's layoutCompoundLabel.
+   *
+   * @param label The label to lay out.
+   * @param fontMetrics The FontMetrics for the font used.
+   * @param text The text to paint.
+   * @param icon The icon to draw.
+   * @param viewR The entire viewable rectangle.
+   * @param iconR The icon bounds rectangle.
+   * @param textR The text bounds rectangle.
+   *
+   * @return A possibly clipped version of the text.
+   */
+  protected String layoutCL(JLabel label, FontMetrics fontMetrics,
+                            String text, Icon icon, Rectangle viewR,
+                            Rectangle iconR, Rectangle textR)
+  {
+    return SwingUtilities.layoutCompoundLabel(label, fontMetrics, text, icon,
+                                              label.getVerticalAlignment(),
+                                              label.getHorizontalAlignment(),
+                                              label.getVerticalTextPosition(),
+                                              label.getHorizontalTextPosition(),
+                                              viewR, iconR, textR,
+                                              label.getIconTextGap());
+  }
+
+  /**
+   * Paints the text if the label is disabled. By default, this paints the
+   * clipped text returned by layoutCompoundLabel using the
+   * background.brighter() color. It also paints the same text using the
+   * background.darker() color one pixel to the right and one pixel down.
+   *
+   * @param l The {@link JLabel} being painted.
+   * @param g The {@link Graphics} object to paint with.
+   * @param s The String to paint.
+   * @param textX The x coordinate of the start of the baseline.
+   * @param textY The y coordinate of the start of the baseline.
+   */
+  protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
+                                   int textY)
+  {
+    Color saved_color = g.getColor();
+
+    g.setColor(l.getBackground().brighter());
+
+    int mnemIndex = l.getDisplayedMnemonicIndex();
+
+    if (mnemIndex != -1)
+      BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
+                                                   textY);
+    else
+      g.drawString(s, textX, textY);
+
+    g.setColor(l.getBackground().darker());
+    if (mnemIndex != -1)
+      BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX + 1,
+                                                   textY + 1);
+    else
+      g.drawString(s, textX + 1, textY + 1);
+
+    g.setColor(saved_color);
+  }
+
+  /**
+   * Paints the text if the label is enabled. The text is painted using the
+   * foreground color.
+   *
+   * @param l The {@link JLabel} being painted.
+   * @param g The {@link Graphics} object to paint with.
+   * @param s The String to paint.
+   * @param textX The x coordinate of the start of the baseline.
+   * @param textY The y coordinate of the start of the baseline.
+   */
+  protected void paintEnabledText(JLabel l, Graphics g, String s, int textX,
+                                  int textY)
+  {
+    Color saved_color = g.getColor();
+    g.setColor(l.getForeground());
+
+    int mnemIndex = l.getDisplayedMnemonicIndex();
+
+    if (mnemIndex != -1)
+      BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
+                                                   textY);
+    else
+      g.drawString(s, textX, textY);
+
+    g.setColor(saved_color);
+  }
+
+  /**
+   * This method installs the UI for the given {@link JComponent}.  This
+   * method will install the component, defaults, listeners,  and keyboard
+   * actions.
+   *
+   * @param c The {@link JComponent} that this UI is being installed on.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    if (c instanceof JLabel)
+      {
+	JLabel l = (JLabel) c;
+
+	installComponents(l);
+	installDefaults(l);
+	installListeners(l);
+	installKeyboardActions(l);
+      }
+  }
+
+  /**
+   * This method uninstalls the UI for the given {@link JComponent}. This
+   * method will uninstall the component, defaults, listeners,  and keyboard
+   * actions.
+   *
+   * @param c The {@link JComponent} that this UI is being installed on.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    super.uninstallUI(c);
+    if (c instanceof JLabel)
+      {
+	JLabel l = (JLabel) c;
+
+	uninstallKeyboardActions(l);
+	uninstallListeners(l);
+	uninstallDefaults(l);
+	uninstallComponents(l);
+      }
+  }
+
+  /**
+   * This method installs the components for this {@link JLabel}.
+   *
+   * @param c The {@link JLabel} to install components for.
+   */
+  protected void installComponents(JLabel c)
+  {
+    //FIXME: fix javadoc + implement.
+  }
+
+  /**
+   * This method uninstalls the components for this {@link JLabel}.
+   *
+   * @param c The {@link JLabel} to uninstall components for.
+   */
+  protected void uninstallComponents(JLabel c)
+  {
+    //FIXME: fix javadoc + implement.
+  }
+
+  /**
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this {@link JLabel}.
+   *
+   * @param c The {@link JLabel} to install defaults for.
+   */
+  protected void installDefaults(JLabel c)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    c.setForeground(defaults.getColor("Label.foreground"));
+    c.setBackground(defaults.getColor("Label.background"));
+    c.setFont(defaults.getFont("Label.font"));
+    c.setBorder(defaults.getBorder("Label.border"));
+    c.setOpaque(true);
+    //XXX: There are properties we don't use called disabledForeground
+    //and disabledShadow.
+  }
+
+  /**
+   * This method uninstalls the defaults that are defined in the Basic look
+   * and feel for this {@link JLabel}.
+   *
+   * @param c The {@link JLabel} to uninstall defaults for.
+   */
+  protected void uninstallDefaults(JLabel c)
+  {
+    c.setForeground(null);
+    c.setBackground(null);
+    c.setFont(null);
+    c.setBorder(null);
+  }
+
+  /**
+   * This method installs the keyboard actions for the given {@link JLabel}.
+   *
+   * @param l The {@link JLabel} to install keyboard actions for.
+   */
+  protected void installKeyboardActions(JLabel l)
+  {
+    //FIXME: implement.
+  }
+
+  /**
+   * This method uninstalls the keyboard actions for the given {@link JLabel}.
+   *
+   * @param l The {@link JLabel} to uninstall keyboard actions for.
+   */
+  protected void uninstallKeyboardActions(JLabel l)
+  {
+    //FIXME: implement.
+  }
+
+  /**
+   * This method installs the listeners for the  given {@link JLabel}. The UI
+   * delegate only listens to  the label.
+   *
+   * @param c The {@link JLabel} to install listeners for.
+   */
+  protected void installListeners(JLabel c)
+  {
+    c.addPropertyChangeListener(this);
+  }
+
+  /**
+   * This method uninstalls the listeners for the given {@link JLabel}. The UI
+   * delegate only listens to the label.
+   *
+   * @param c The {@link JLabel} to uninstall listeners for.
+   */
+  protected void uninstallListeners(JLabel c)
+  {
+    c.removePropertyChangeListener(this);
+  }
 
-  public void propertyChange (PropertyChangeEvent event)
+  /**
+   * This method is called whenever any JLabel's that use this UI has one of
+   * their properties change.
+   *
+   * @param e The {@link PropertyChangeEvent} that describes the change.
+   */
+  public void propertyChange(PropertyChangeEvent e)
   {
-    throw new Error ("Not implemented");
+    JLabel c = (JLabel) e.getSource();
+    c.revalidate();
+    c.repaint();
   }
 }
Index: javax/swing/plaf/basic/BasicListUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicListUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicListUI.java
--- javax/swing/plaf/basic/BasicListUI.java	10 Jan 2004 21:59:30 -0000	1.4
+++ javax/swing/plaf/basic/BasicListUI.java	6 Sep 2004 16:36:04 -0000
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
 import java.awt.Color;
@@ -44,141 +43,659 @@
 import java.awt.Graphics;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import javax.swing.JComponent;
 import javax.swing.JList;
 import javax.swing.ListCellRenderer;
+import javax.swing.ListModel;
+import javax.swing.ListSelectionModel;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.MouseInputListener;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.ListUI;
 
+
+/**
+ * The Basic Look and Feel UI delegate for the 
+ * JList.
+ */
 public class BasicListUI extends ListUI
 {
-    int gap_between_cells;
-    Color textColor, disabledTextColor, pressedBackgroundColor, normalBackgroundColor;
-    
+  /**
+   * A helper class which listens for {@link FocusEvents}
+   * from the JList.
+   */
+  class FocusHandler implements FocusListener
+  {
+    /**
+     * Called when the JList acquires focus.
+     *
+     * @param e The FocusEvent representing focus acquisition
+     */
+    public void focusGained(FocusEvent e)
+    {
+      repaintCellFocus();
+    }
 
-    public static ComponentUI createUI(final JComponent c) 
+    /**
+     * Called when the JList loses focus.
+     *
+     * @param e The FocusEvent representing focus loss
+     */
+    public void focusLost(FocusEvent e)
     {
-	return new BasicButtonUI();
+      repaintCellFocus();
     }
 
-    
-    public void installUI(final JComponent c) 
+    /**
+     * Helper method to repaint the focused cell's 
+     * lost or acquired focus state.
+     */
+    void repaintCellFocus()
     {
-	super.installUI(c);
+    }
+  }
 
-	textColor                = new Color(0,0,0);
-	disabledTextColor        = new Color(130, 130, 130);
-	pressedBackgroundColor   = new Color(150,150,150);
-	normalBackgroundColor    = new Color(192,192,192);
+  /**
+   * A helper class which listens for {@link ListDataEvent}s generated by
+   * the {@link JList}'s {@link ListModel}.
+   *
+   * @see javax.swing.JList#model
+   */
+  class ListDataHandler implements ListDataListener
+  {
+    /**
+     * Called when a general change has happened in the model which cannot
+     * be represented in terms of a simple addition or deletion.
+     *
+     * @param e The event representing the change
+     */
+    public void contentsChanged(ListDataEvent e)
+    {
+      BasicListUI.this.damageLayout();
     }
 
-    public Dimension getPreferredSize(JComponent c) 
+    /**
+     * Called when an interval of objects has been added to the model.
+     *
+     * @param e The event representing the addition
+     */
+    public void intervalAdded(ListDataEvent e)
     {
-	JList l = (JList) c;
+      BasicListUI.this.damageLayout();
+    }
 
-	System.out.println("XXXXXXXXXXXXXXXxx   getPreferredSize------------> " + l);
+    /**
+     * Called when an inteval of objects has been removed from the model.
+     *
+     * @param e The event representing the removal
+     */
+    public void intervalRemoved(ListDataEvent e)
+    {
+      BasicListUI.this.damageLayout();
+    }
+  }
 
-	
-	int rows = l.getVisibleRowCount();
+  /**
+   * A helper class which listens for {@link ListSelectionEvent}s
+   * from the {@link JList}'s {@link ListSelectionModel}.
+   */
+  class ListSelectionHandler implements ListSelectionListener
+  {
+    /**
+     * Called when the list selection changes.  
+     *
+     * @param e The event representing the change
+     */
+    public void valueChanged(ListSelectionEvent e)
+    {
+    }
+  }
 
-	ListCellRenderer render = l.getCellRenderer();
-	
-	int width  = 200;
-	int height = rows * 16; 
-	
-	if (l.getModel().getSize() == 0)
-	    {
-		return new Dimension(width, height);
-	    }
+  /**
+   * A helper class which listens for {@link MouseEvent}s 
+   * from the {@link JList}.
+   */
+  class MouseInputHandler implements MouseInputListener
+  {
+    /**
+     * Called when a mouse button press/release cycle completes
+     * on the {@link JList}
+     *
+     * @param event The event representing the mouse click
+     */
+    public void mouseClicked(MouseEvent event)
+    {
+    }
 
-	System.out.println("BASIC_LIST_UI ====-> " + l.getModel().getElementAt(0));
+    /**
+     * Called when a mouse button is pressed down on the
+     * {@link JList}.
+     *
+     * @param event The event representing the mouse press
+     */
+    public void mousePressed(MouseEvent event)
+    {
+      int row = BasicListUI.this.convertYToRow(event.getY());
+      if (row == -1)
+        return;
 
-	Component elt = render.getListCellRendererComponent(l,
-							    l.getModel().getElementAt(0),
-							    0,            
-							    false,
-							    false);
-	Dimension a = elt.getPreferredSize();
-	if (a == null)
-	    {
-		return new Dimension(width, height);
-	    }
+      BasicListUI.this.list.setSelectedIndex(row);
+    }
 
-	return new Dimension(a.width,
-			     a.height * rows);
+    /**
+     * Called when a mouse button is released on
+     * the {@link JList}
+     *
+     * @param event The event representing the mouse press
+     */
+    public void mouseReleased(MouseEvent event)
+    {
     }
 
-    public void paintBackground(Graphics g,
-			 JComponent c)
+    /**
+     * Called when the mouse pointer enters the area bounded
+     * by the {@link JList}
+     *
+     * @param event The event representing the mouse entry
+     */
+    public void mouseEntered(MouseEvent event)
     {
-	Dimension size = getPreferredSize(c);
+    }
 
-	g.setColor(normalBackgroundColor);
-	g.fillRect(0,0,size.width, size.height);  
+    /**
+     * Called when the mouse pointer leaves the area bounded
+     * by the {@link JList}
+     *
+     * @param event The event representing the mouse exit
+     */
+    public void mouseExited(MouseEvent event)
+    {
     }
 
-    public void paint(Graphics g, 
-		      JComponent c)
-    {      
-	JList l = (JList) c;
+    /**
+     * Called when the mouse pointer moves over the area bounded
+     * by the {@link JList} while a button is held down.
+     *
+     * @param event The event representing the mouse drag
+     */
+    public void mouseDragged(MouseEvent event)
+    {
+    }
+
+    /**
+     * Called when the mouse pointer moves over the area bounded
+     * by the {@link JList}.
+     *
+     * @param event The event representing the mouse move
+     */
+    public void mouseMoved(MouseEvent event)
+    {
+    }
+  }
 
-	int rows = l.getVisibleRowCount();
+  /**
+   * Helper class which listens to {@link PropertyChangeEvent}s
+   * from the {@link JList}.
+   */
+  class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * Called when the {@link JList} changes one of its bound properties.
+     *
+     * @param e The event representing the property change
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getSource() == BasicListUI.this.list)
+        {
+          if (e.getOldValue() != null && e.getOldValue() instanceof ListModel)
+            ((ListModel) e.getOldValue()).removeListDataListener(BasicListUI.this.listDataListener);
+
+          if (e.getNewValue() != null && e.getNewValue() instanceof ListModel)
+            ((ListModel) e.getNewValue()).addListDataListener(BasicListUI.this.listDataListener);
+        }
+      BasicListUI.this.damageLayout();
+    }
+  }
 
-	ListCellRenderer render = l.getCellRenderer();
+  /**
+   * Creates a new BasicListUI for the component.
+   *
+   * @param c The component to create a UI for
+   *
+   * @return A new UI
+   */
+  public static ComponentUI createUI(final JComponent c)
+  {
+    return new BasicListUI();
+  }
 
-	System.out.println("RENDER-JLIST: " + rows + ", " + l.getModel().getSize());
+  /** The current focus listener. */
+  FocusHandler focusListener;
 
-	paintBackground(g, c);
+  /** The data listener listening to the model. */
+  ListDataHandler listDataListener;
 
-	if (l.getModel().getSize() == 0)
-	    return;
+  /** The selection listener listening to the selection model. */
+  ListSelectionHandler listSelectionListener;
 
-	// use element 0 to figure out how big we are:
-	Component elt = render.getListCellRendererComponent(l,
-							    l.getModel().getElementAt(0),
-							    0,       
-							    false,
-							    false);
-	Dimension dim = elt.getPreferredSize();
-	
-	Rectangle a = new Rectangle(0,
-				    0,
-				    dim.width,
-				    dim.height);
+  /** The mouse listener listening to the list. */
+  MouseInputHandler mouseInputListener;
+
+  /** The property change listener listening to the list. */
+  PropertyChangeHandler propertyChangeListener;
+
+  /** Saved reference to the list this UI was created for. */
+  JList list;
+
+  /** The height of a single cell in the list. */
+  int cellHeight;
+
+  /** The width of a single cell in the list. */
+  int cellWidth;
+
+  /** 
+   * An array of varying heights of cells in the list, in cases where each
+   * cell might have a different height.
+   */
+  int[] cellHeights;
+
+  /**
+   * A simple counter. When nonzero, indicates that the UI class is out of
+   * date with respect to the underlying list, and must recalculate the
+   * list layout before painting or performing size calculations.
+   */
+  int updateLayoutStateNeeded;
+
+  /**
+   * Calculate the height of a particular row. If there is a fixed {@link
+   * #cellHeight}, return it; otherwise return the specific row height
+   * requested from the {@link #cellHeights} array. If the requested row
+   * is invalid, return <code>-1</code>.
+   *
+   * @param row The row to get the height of
+   *
+   * @return The height, in pixels, of the specified row
+   */
+  int getRowHeight(int row)
+  {
+    if (row < 0 || row >= cellHeights.length)
+      return -1;
+    else if (cellHeight != -1)
+      return cellHeight;
+    else
+      return cellHeights[row];
+  }
 
-	for (int i=0;i<l.getModel().getSize();i++)
-	    {
-		boolean is_sel = false;
-		boolean has_focus = false;
+  /**
+   * Calculate the bounds of a particular cell, considering the upper left
+   * corner of the list as the origin position <code>(0,0)</code>.
+   *
+   * @param l Ignored; calculates over <code>this.list</code>
+   * @param index1 The first row to include in the bounds
+   * @param index2 The last row to incude in the bounds
+   *
+   * @return A rectangle encompassing the range of rows between 
+   * <code>index1</code> and <code>index2</code> inclusive
+   */
+  public Rectangle getCellBounds(JList l, int index1, int index2)
+  {
+    maybeUpdateLayoutState();
 
-		Component comp = render.getListCellRendererComponent(l,
-								     l.getModel().getElementAt(i),
-								     i,            
-								     is_sel,
-								     has_focus);
+    if (l != list || cellWidth == -1)
+      return null;
 
-		//System.out.println("AAAAA=> " + a + ", " + comp + ", index = " + i);
+    int lo = Math.min(index1, index2);
+    int hi = Math.max(index1, index2);
+    Rectangle lobounds = new Rectangle(0, convertRowToY(lo), cellWidth,
+                                       getRowHeight(lo));
+    Rectangle hibounds = new Rectangle(0, convertRowToY(hi), cellWidth,
+                                       getRowHeight(hi));
 
-		comp.setBounds(a);
+    return lobounds.union(hibounds);
+  }
 
-		comp.paint(g);
+  /**
+   * Calculate the Y coordinate of the upper edge of a particular row,
+   * considering the Y coordinate <code>0</code> to occur at the top of the
+   * list.
+   *
+   * @param row The row to calculate the Y coordinate of
+   *
+   * @return The Y coordinate of the specified row, or <code>-1</code> if
+   * the specified row number is invalid
+   */
+  int convertRowToY(int row)
+  {
+    int y = 0;
+    for (int i = 0; i < row; ++i)
+      {
+        int h = getRowHeight(i);
+        if (h == -1)
+          return -1;
+        y += h;
+      }
+    return y;
+  }
 
-		a.y += dim.height + gap_between_cells;
-	    }
-    }
+  /**
+   * Calculate the row number containing a particular Y coordinate,
+   * considering the Y coodrinate <code>0</code> to occur at the top of the
+   * list.
+   *
+   * @param y0 The Y coordinate to calculate the row number for
+   *
+   * @return The row number containing the specified Y value, or <code>-1</code>
+   * if the specified Y coordinate is invalid
+   */
+  int convertYToRow(int y0)
+  {
+    for (int row = 0; row < cellHeights.length; ++row)
+      {
+        int h = getRowHeight(row);
+
+        if (y0 < h)
+          return row;
+        y0 -= h;
+      }
+    return -1;
+  }
 
-  public int locationToIndex(JList list, Point location)
+  /**
+   * Recomputes the {@link #cellHeights}, {@link #cellHeight}, and {@link
+   * #cellWidth} properties by examining the variouis properties of the
+   * {@link JList}.
+   */
+  void updateLayoutState()
   {
-    throw new Error ("Not implemented");
+    int nrows = list.getModel().getSize();
+    cellHeight = -1;
+    cellWidth = -1;
+    if (cellHeights == null || cellHeights.length != nrows)
+      cellHeights = new int[nrows];
+    if (list.getFixedCellHeight() == -1 || list.getFixedCellWidth() == -1)
+      {
+        ListCellRenderer rend = list.getCellRenderer();
+        for (int i = 0; i < nrows; ++i)
+          {
+            Component flyweight = rend.getListCellRendererComponent(list,
+                                                                    list.getModel()
+                                                                        .getElementAt(i),
+                                                                    0, false,
+                                                                    false);
+            Dimension dim = flyweight.getPreferredSize();
+            cellHeights[i] = dim.height;
+            cellWidth = Math.max(cellWidth, dim.width);
+          }
+      }
+    else
+      {
+        cellHeight = list.getFixedCellHeight();
+        cellWidth = list.getFixedCellWidth();
+      }
   }
 
-  public Point indexToLocation(JList list, int index)
+  /**
+   * Marks the current layout as damaged and requests revalidation from the
+   * JList.
+   *
+   * @see #updateLayoutStateNeeded
+   */
+  void damageLayout()
+  {
+    updateLayoutStateNeeded = 1;
+    list.revalidate();
+  }
+
+  /**
+   * Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded}
+   * is nonzero, then resets {@link #updateLayoutStateNeeded} to zero.
+   */
+  void maybeUpdateLayoutState()
   {
-    throw new Error ("Not implemented");
+    if (updateLayoutStateNeeded != 0)
+      {
+        updateLayoutState();
+        updateLayoutStateNeeded = 0;
+      }
   }
 
-  public Rectangle getCellBounds(JList list, int index1, int index2)
+  /**
+   * Creates a new BasicListUI object.
+   */
+  public BasicListUI()
+  {
+    focusListener = new FocusHandler();
+    listDataListener = new ListDataHandler();
+    listSelectionListener = new ListSelectionHandler();
+    mouseInputListener = new MouseInputHandler();
+    propertyChangeListener = new PropertyChangeHandler();
+    updateLayoutStateNeeded = 1;
+  }
+
+  /**
+   * Installs various default settings (mostly colors) from the {@link
+   * UIDefaults} into the {@link JList}
+   *
+   * @see #uninstallDefaults
+   */
+  void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    list.setForeground(defaults.getColor("List.foreground"));
+    list.setBackground(defaults.getColor("List.background"));
+    list.setSelectionForeground(defaults.getColor("List.selectionForeground"));
+    list.setSelectionBackground(defaults.getColor("List.selectionBackground"));
+    list.setOpaque(true);
+  }
+
+  /**
+   * Resets to <code>null</code> those defaults which were installed in 
+   * {@link #installDefaults}
+   */
+  void uninstallDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    list.setForeground(null);
+    list.setBackground(null);
+    list.setSelectionForeground(null);
+    list.setSelectionBackground(null);
+  }
+
+  /**
+   * Attaches all the listeners we have in the UI class to the {@link
+   * JList}, its model and its selection model.
+   *
+   * @see #uninstallListeners
+   */
+  void installListeners()
+  {
+    list.addFocusListener(focusListener);
+    list.getModel().addListDataListener(listDataListener);
+    list.addListSelectionListener(listSelectionListener);
+    list.addMouseListener(mouseInputListener);
+    list.addMouseMotionListener(mouseInputListener);
+    list.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * Detaches all the listeners we attached in {@link #installListeners}.
+   */
+  void uninstallListeners()
+  {
+    list.removeFocusListener(focusListener);
+    list.getModel().removeListDataListener(listDataListener);
+    list.removeListSelectionListener(listSelectionListener);
+    list.removeMouseListener(mouseInputListener);
+    list.removeMouseMotionListener(mouseInputListener);
+    list.removePropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * Installs keyboard actions for this UI in the {@link JList}.
+   */
+  void installKeyboardActions()
+  {
+  }
+
+  /**
+   * Uninstalls keyboard actions for this UI in the {@link JList}.
+   */
+  void uninstallKeyboardActions()
+  {
+  }
+
+  /**
+   * Installs the various aspects of the UI in the {@link JList}. In
+   * particular, calls {@link #installDefaults}, {@link #installListeners}
+   * and {@link #installKeyboardActions}. Also saves a reference to the
+   * provided component, cast to a {@link JList}.
+   *
+   * @param c The {@link JList} to install the UI into
+   */
+  public void installUI(final JComponent c)
+  {
+    super.installUI(c);
+    list = (JList) c;
+    installDefaults();
+    installListeners();
+    installKeyboardActions();
+    maybeUpdateLayoutState();
+  }
+
+  /**
+   * Uninstalls all the aspects of the UI which were installed in {@link
+   * #installUI}. When finished uninstalling, drops the saved reference to
+   * the {@link JList}.
+   *
+   * @param c Ignored; the UI is uninstalled from the {@link JList}
+   * reference saved during the call to {@link #installUI}
+   */
+  public void uninstallUI(final JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallDefaults();
+    list = null;
+  }
+
+  /**
+   * Gets the maximum size this list can assume.
+   *
+   * @param c The component to measure the size of
+   *
+   * @return A new Dimension representing the component's maximum size
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+  }
+
+  /**
+   * Gets the size this list would prefer to assume. This is calculated by
+   * calling {@link #getCellBounds} over the entire list.
+   *
+   * @param c Ignored; uses the saved {@link JList} reference 
+   *
+   * @return DOCUMENT ME!
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    if (list.getModel().getSize() == 0)
+      return new Dimension(0, 0);
+    Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1);
+    return bounds.getSize();
+  }
+
+  /**
+   * Paints the packground of the list using the background color
+   * of the specified component.
+   *
+   * @param g The graphics context to paint in
+   * @param c The component to paint the background of
+   */
+  public void paintBackground(Graphics g, JComponent c)
+  {
+    Dimension size = getPreferredSize(c);
+    Color save = g.getColor();
+    g.setColor(c.getBackground());
+    g.fillRect(0, 0, size.width, size.height);
+    g.setColor(save);
+  }
+
+  /**
+   * Paints a single cell in the list.
+   *
+   * @param g The graphics context to paint in
+   * @param row The row number to paint
+   * @param bounds The bounds of the cell to paint, assuming a coordinate
+   * system beginning at <code>(0,0)</code> in the upper left corner of the
+   * list
+   * @param rend A cell renderer to paint with
+   * @param data The data to provide to the cell renderer
+   * @param sel A selection model to provide to the cell renderer
+   * @param lead The lead selection index of the list
+   */
+  void paintCell(Graphics g, int row, Rectangle bounds, ListCellRenderer rend,
+                 ListModel data, ListSelectionModel sel, int lead)
+  {
+    boolean is_sel = list.isSelectedIndex(row);
+    boolean has_focus = false;
+    Component comp = rend.getListCellRendererComponent(list,
+                                                       data.getElementAt(row),
+                                                       0, is_sel, has_focus);
+    g.translate(bounds.x, bounds.y);
+    comp.setBounds(new Rectangle(0, 0, bounds.width, bounds.height));
+    comp.paint(g);
+    g.translate(-bounds.x, -bounds.y);
+  }
+
+  /**
+   * Paints the list by calling {@link #paintBackground} and then repeatedly
+   * calling {@link #paintCell} for each visible cell in the list.
+   *
+   * @param g The graphics context to paint with
+   * @param c Ignored; uses the saved {@link JList} reference 
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    int nrows = list.getModel().getSize();
+    if (nrows == 0)
+      return;
+
+    maybeUpdateLayoutState();
+    ListCellRenderer render = list.getCellRenderer();
+    ListModel model = list.getModel();
+    ListSelectionModel sel = list.getSelectionModel();
+    int lead = sel.getLeadSelectionIndex();
+    Rectangle clip = g.getClipBounds();
+    paintBackground(g, list);
+
+    for (int row = 0; row < nrows; ++row)
+      {
+        Rectangle bounds = getCellBounds(list, row, row);
+        if (bounds.intersects(clip))
+        paintCell(g, row, bounds, render, model, sel, lead);
+      }
+  }
+
+  public int locationToIndex(JList list, Point location)
+  {
+    return convertYToRow(location.y);
+  }
+
+  public Point indexToLocation(JList list, int index)
   {
-    throw new Error ("Not implemented");
+    return new Point(0, convertRowToY(index));
   }
 }
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.3
diff -u -r1.3 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java	13 Jul 2003 15:29:11 -0000	1.3
+++ javax/swing/plaf/basic/BasicLookAndFeel.java	6 Sep 2004 16:36:05 -0000
@@ -1,5 +1,5 @@
 /* BasicLookAndFeel.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -41,6 +41,7 @@
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.io.Serializable;
 import java.util.Enumeration;
@@ -110,6 +111,7 @@
       "DesktopIconUI", "javax.swing.plaf.basic.BasicDesktopIconUI",
       "DesktopPaneUI", "javax.swing.plaf.basic.BasicDesktopPaneUI",
       "EditorPaneUI", "javax.swing.plaf.basic.BasicEditorPaneUI",
+      "FormattedTextFieldUI", "javax.swing.plaf.basic.BasicFormattedTextFieldUI",
       "InternalFrameUI", "javax.swing.plaf.basic.BasicInternalFrameUI",
       "LabelUI", "javax.swing.plaf.basic.BasicLabelUI",
       "ListUI", "javax.swing.plaf.basic.BasicListUI",
@@ -130,6 +132,7 @@
       "SeparatorUI", "javax.swing.plaf.basic.BasicSeparatorUI",
       "SliderUI", "javax.swing.plaf.basic.BasicSliderUI",
       "SplitPaneUI", "javax.swing.plaf.basic.BasicSplitPaneUI",
+      "SpinnerUI", "javax.swing.plaf.basic.BasicSpinnerUI",
       "StandardDialogUI", "javax.swing.plaf.basic.BasicStandardDialogUI",
       "TabbedPaneUI", "javax.swing.plaf.basic.BasicTabbedPaneUI",
       "TableHeaderUI", "javax.swing.plaf.basic.BasicTableHeaderUI",
@@ -205,15 +208,15 @@
   private void loadResourceBundle(UIDefaults defaults)
   {
     ResourceBundle bundle;
-    Enumeration enum;
+    Enumeration e;
     String key;
     String value;
     bundle = ResourceBundle.getBundle("resources/basic");
     // Process Resources
-    enum = bundle.getKeys();
-    while (enum.hasMoreElements())
+    e = bundle.getKeys();
+    while (e.hasMoreElements())
       {
-        key = (String) enum.nextElement();
+        key = (String) e.nextElement();
         value = bundle.getString(key);
         defaults.put(key, value);
       }
@@ -226,30 +229,49 @@
   protected void initComponentDefaults(UIDefaults defaults)
   {
     Object[] uiDefaults;
+    
+    // The default Look and Feel happens to use these three purple shades
+    // extensively.
+    Color lightPurple = new Color(0xCC, 0xCC, 0xFF);
+    Color midPurple = new Color(0x99, 0x99, 0xCC);
+    Color darkPurple = new Color(0x66, 0x66, 0x99);
+
     uiDefaults = new Object[] {
+
+      "AbstractUndoableEdit.undoText", "Undo",
+      "AbstractUndoableEdit.redoText", "Redo",
+
       "Button.background", new ColorUIResource(Color.lightGray),
-      "Button.border", new BorderUIResource.CompoundBorderUIResource(null,
-                                                                     null),
+      "Button.border", BorderUIResource.getEtchedBorderUIResource(),
+      "Button.darkShadow", new ColorUIResource(Color.darkGray),
       "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "SPACE",  "pressed",
         "released SPACE", "released"
       }),
+      "Button.focus", midPurple,
       "Button.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "Button.foreground", new ColorUIResource(Color.black),
+      "Button.highlight", new ColorUIResource(Color.white),
+      "Button.light", new ColorUIResource(Color.lightGray.brighter()),
       "Button.margin", new InsetsUIResource(2, 14, 2, 14),
+      "Button.shadow", new ColorUIResource(Color.gray),
       "Button.textIconGap", new Integer(4),
       "Button.textShiftOffset", new Integer(0),
       "CheckBox.background", new ColorUIResource(Color.lightGray),
       "CheckBox.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                        null),
+      "CheckBox.darkShadow", new ColorUIResource(Color.darkGray),
       "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "SPACE",  "pressed",
         "released SPACE", "released"
       }),
       "CheckBox.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "CheckBox.foreground", new ColorUIResource(Color.black),
+      "CheckBox.highlight", new ColorUIResource(Color.white),
       "CheckBox.icon", BasicIconFactory.getCheckBoxIcon(),
+      "CheckBox.light", new ColorUIResource(Color.lightGray.brighter()),
       "CheckBox.margin",new InsetsUIResource(2, 2, 2, 2),
+      "CheckBox.shadow", new ColorUIResource(Color.gray),
       "CheckBox.textIconGap", new Integer(4),
       "CheckBox.textShiftOffset", new Integer(0),
       "CheckBoxMenuItem.acceleratorFont", new FontUIResource("Dialog",
@@ -264,8 +286,8 @@
       "CheckBoxMenuItem.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "CheckBoxMenuItem.foreground", new ColorUIResource(Color.black),
       "CheckBoxMenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
-      "CheckBoxMenuItem.selectionBackground", new ColorUIResource(0, 0, 128),
-      "CheckBoxMenuItem.selectionForeground", new ColorUIResource(Color.white),
+      "CheckBoxMenuItem.selectionBackground", new ColorUIResource(lightPurple),
+      "CheckBoxMenuItem.selectionForeground", new ColorUIResource(Color.black),
       "ColorChooser.background", new ColorUIResource(Color.lightGray),
       "ColorChooser.cancelText", "Cancel",
       "ColorChooser.font", new FontUIResource("Dialog", Font.PLAIN, 12),
@@ -305,8 +327,8 @@
       "ComboBox.disabledForeground", new ColorUIResource(Color.gray),
       "ComboBox.font", new FontUIResource("SansSerif", Font.PLAIN, 12),
       "ComboBox.foreground", new ColorUIResource(Color.black),
-      "ComboBox.selectionBackground", new ColorUIResource(0, 0, 128),
-      "ComboBox.selectionForeground", new ColorUIResource(Color.white),
+      "ComboBox.selectionBackground", new ColorUIResource(lightPurple),
+      "ComboBox.selectionForeground", new ColorUIResource(Color.black),
       "Desktop.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "KP_LEFT", "left",
         "KP_RIGHT", "right",
@@ -328,7 +350,7 @@
         "ctrl F10", "maximize",
         "ctrl alt shift F6","selectPreviousFrame"
       }),
-      "Desktop.background", new ColorUIResource(0, 92, 92),
+      "Desktop.background", new ColorUIResource(175, 163, 236),
       "DesktopIcon.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                           null),
       "EditorPane.background", new ColorUIResource(Color.white),
@@ -401,16 +423,16 @@
       "FocusManagerClassName", "TODO",
       "FormView.resetButtonText", "Reset",
       "FormView.submitButtonText", "Submit Query",
-      "InternalFrame.activeTitleBackground", new ColorUIResource(0, 0, 128),
-      "InternalFrame.activeTitleForeground", new ColorUIResource(Color.white),
+      "InternalFrame.activeTitleBackground", new ColorUIResource(162, 167, 241),
+      "InternalFrame.activeTitleForeground", new ColorUIResource(Color.black),
       "InternalFrame.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                             null),
       "InternalFrame.closeIcon", BasicIconFactory.createEmptyFrameIcon(),
       // XXX Don't use gif
       "InternalFrame.icon", new IconUIResource(new ImageIcon("icons/JavaCup.gif")),
       "InternalFrame.iconifyIcon", BasicIconFactory.createEmptyFrameIcon(),
-      "InternalFrame.inactiveTitleBackground", new ColorUIResource(Color.gray),
-      "InternalFrame.inactiveTitleForeground", new ColorUIResource(Color.lightGray),
+      "InternalFrame.inactiveTitleBackground", new ColorUIResource(Color.lightGray),
+      "InternalFrame.inactiveTitleForeground", new ColorUIResource(Color.black),
       "InternalFrame.maximizeIcon", BasicIconFactory.createEmptyFrameIcon(),
       "InternalFrame.minimizeIcon", BasicIconFactory.createEmptyFrameIcon(),
       "InternalFrame.titleFont", new FontUIResource("Dialog", Font.PLAIN, 12),
@@ -423,6 +445,9 @@
       "Label.disabledForeground", new ColorUIResource(Color.white),
       "Label.disabledShadow", new ColorUIResource(Color.gray),
       "Label.font", new FontUIResource("Dialog", Font.PLAIN, 12),
+      "Label.foreground", new ColorUIResource(Color.black),
+      "List.background", new ColorUIResource(Color.white),
+      "List.border", new BasicBorders.MarginBorder(),
       "List.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "PAGE_UP", "scrollUp",
         "ctrl \\", "clearSelection",
@@ -444,8 +469,8 @@
         "KP_DOWN", "selectNextRow"
       }),
       "List.foreground", new ColorUIResource(Color.black),
-      "List.selectionBackground", new ColorUIResource(0, 0, 128),
-      "List.selectionForeground", new ColorUIResource(Color.white),
+      "List.selectionBackground", new ColorUIResource(0xCC, 0xCC, 0xFF),
+      "List.selectionForeground", new ColorUIResource(Color.black),
       "Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12),
       "Menu.acceleratorForeground", new ColorUIResource(Color.black),
       "Menu.acceleratorSelectionForeground", new ColorUIResource(Color.white),
@@ -471,8 +496,8 @@
         "ENTER", "return",
         "SPACE", "return"
       },
-      "Menutext.selectionBackground", new ColorUIResource(0, 0, 128),
-      "Menu.selectionForeground", new ColorUIResource(Color.white),
+      "Menu.selectionBackground", new ColorUIResource(lightPurple),
+      "Menu.selectionForeground", new ColorUIResource(Color.black),
       "MenuBar.background", new ColorUIResource(Color.lightGray),
       "MenuBar.border", new BasicBorders.MenuBarBorder(null, null),
       "MenuBar.font", new FontUIResource("Dialog", Font.PLAIN, 12),
@@ -480,7 +505,7 @@
       "MenuBar.windowBindings", new Object[] {
         "F10", "takeFocus"
       },
-      "MenuItem.acceleratorDelimiter", "+",
+      "MenuItem.acceleratorDelimiter", "-",
       "MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12),
       "MenuItem.acceleratorForeground", new ColorUIResource(Color.black),
       "MenuItem.acceleratorSelectionForeground", new ColorUIResource(Color.white),
@@ -492,8 +517,8 @@
       "MenuItem.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "MenuItem.foreground", new ColorUIResource(Color.black),
       "MenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
-      "MenuItem.selectionBackground", new ColorUIResource(0, 0, 128),
-      "MenuItem.selectionForeground", new ColorUIResource(Color.white),
+      "MenuItem.selectionBackground", new ColorUIResource(lightPurple),
+      "MenuItem.selectionForeground", new ColorUIResource(Color.black),
       "OptionPane.background", new ColorUIResource(Color.lightGray),
       "OptionPane.border", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0),
       "OptionPane.buttonAreaBorder", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0),
@@ -533,31 +558,37 @@
                                                              0),
                                       "notify-field-accept")},
       "PasswordField.margin", new InsetsUIResource(0, 0, 0, 0),
-      "PasswordField.selectionBackground", new ColorUIResource(0, 0, 128),
-      "PasswordField.selectionForeground", new ColorUIResource(Color.white),
+      "PasswordField.selectionBackground", new ColorUIResource(lightPurple),
+      "PasswordField.selectionForeground", new ColorUIResource(Color.black),
       "PopupMenu.background", new ColorUIResource(Color.lightGray),
       "PopupMenu.border", new BorderUIResource.BevelBorderUIResource(0),
       "PopupMenu.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "PopupMenu.foreground", new ColorUIResource(Color.black),
       "ProgressBar.background", new ColorUIResource(Color.lightGray),
-      "ProgressBar.border", new BorderUIResource.LineBorderUIResource(null),
+      "ProgressBar.border", new BorderUIResource.LineBorderUIResource(Color.darkGray),
       "ProgressBar.cellLength", new Integer(1),
       "ProgressBar.cellSpacing", new Integer(0),
       "ProgressBar.font", new FontUIResource("Dialog", Font.PLAIN, 12),
-      "ProgressBar.foreground", new ColorUIResource(0, 0, 128),
-      "ProgressBar.selectionBackground", new ColorUIResource(0, 0, 128),
+      "ProgressBar.foreground", new ColorUIResource(midPurple),
+      "ProgressBar.selectionBackground", new ColorUIResource(lightPurple),
       "ProgressBar.selectionForeground", new ColorUIResource(Color.lightGray),
+      "ProgressBar.repaintInterval", new Integer(250),
+      "ProgressBar.cycleTime", new Integer(6000),
       "RadioButton.background", new ColorUIResource(Color.lightGray),
       "RadioButton.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                           null),
+      "RadioButton.darkShadow", new ColorUIResource(Color.darkGray),
       "RadioButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "SPACE",  "pressed",
         "released SPACE", "released"
       }),
       "RadioButton.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "RadioButton.foreground", new ColorUIResource(Color.black),
+      "RadioButton.highlight", new ColorUIResource(Color.white),
       "RadioButton.icon", BasicIconFactory.getRadioButtonIcon(),
+      "RadioButton.light", new ColorUIResource(Color.lightGray.brighter()),
       "RadioButton.margin", new InsetsUIResource(2, 2, 2, 2),
+      "RadioButton.shadow", new ColorUIResource(Color.gray),
       "RadioButton.textIconGap", new Integer(4),
       "RadioButton.textShiftOffset", new Integer(0),
       "RadioButtonMenuItem.acceleratorFont", new FontUIResource("Dialog",
@@ -572,8 +603,8 @@
       "RadioButtonMenuItem.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "RadioButtonMenuItem.foreground", new ColorUIResource(Color.black),
       "RadioButtonMenuItem.margin", new InsetsUIResource(2, 2, 2, 2),
-      "RadioButtonMenuItem.selectionBackground", new ColorUIResource(0, 0, 128),
-      "RadioButtonMenuItem.selectionForeground", new ColorUIResource(Color.white),
+      "RadioButtonMenuItem.selectionBackground", new ColorUIResource(lightPurple),
+      "RadioButtonMenuItem.selectionForeground", new ColorUIResource(Color.black),
       "RootPane.defaultButtonWindowKeyBindings", new Object[] {
         "ENTER",  "press",
         "released ENTER", "release",
@@ -648,6 +679,9 @@
       "Slider.foreground", new ColorUIResource(Color.lightGray),
       "Slider.highlight", new ColorUIResource(Color.white),
       "Slider.shadow", new ColorUIResource(Color.gray),
+      "Slider.thumbHeight", new Integer(20),
+      "Slider.thumbWidth", new Integer(10),
+      "Slider.tickHeight", new Integer(12),
       "SplitPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "F6",  "toggleFocus",
         "F8",  "startResize",
@@ -664,7 +698,7 @@
       }),
       "SplitPane.background", new ColorUIResource(Color.lightGray),
       "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null),
-      "SplitPane.dividerSize", new Integer(7),
+      "SplitPane.dividerSize", new Integer(10),
       "SplitPane.highlight", new ColorUIResource(Color.white),
       "SplitPane.shadow", new ColorUIResource(Color.gray),
       "TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
@@ -673,9 +707,9 @@
         "ctrl UP", "requestFocus",
         "ctrl KP_UP", "requestFocus"
       }),
-      "TabbedPane.background", new ColorUIResource(Color.lightGray),
+      "TabbedPane.background", new ColorUIResource(Color.LIGHT_GRAY),
       "TabbedPane.contentBorderInsets", new InsetsUIResource(2, 2, 3, 3),
-      "TabbedPane.darkShadow", new ColorUIResource(Color.black),
+      "TabbedPane.darkShadow", new ColorUIResource(Color.darkGray),
       "TabbedPane.focus", new ColorUIResource(Color.black),
       "TabbedPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "LEFT",  "navigateLeft",
@@ -695,8 +729,10 @@
       "TabbedPane.lightHighlight", new ColorUIResource(Color.white),
       "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1),
       "TabbedPane.shadow", new ColorUIResource(Color.gray),
-      "TabbedPane.tabAreaInsets", new InsetsUIResource(3, 2, 0, 2),
-      "TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 4),
+      "TabbedPane.tabbedPaneTabAreaInsets", new InsetsUIResource(3, 2, 1, 2),
+      "TabbedPane.tabbedPaneTabInsets", new InsetsUIResource(1, 4, 1, 4),
+      "TabbedPane.tabbedPaneContentBorderInsets", new InsetsUIResource(3, 2, 1, 2),
+      "TabbedPane.tabbedPaneTabPadInsets", new InsetsUIResource(1, 1, 1, 1),
       "TabbedPane.tabRunOverlay", new Integer(2),
       "TabbedPane.textIconGap", new Integer(4),
       "Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
@@ -742,13 +778,13 @@
       "Table.background", new ColorUIResource(Color.white),
       "Table.focusCellBackground", new ColorUIResource(Color.white),
       "Table.focusCellForeground", new ColorUIResource(Color.black),
-      "Table.focusCellHighlightBorder", new BorderUIResource.LineBorderUIResource(null),
+      "Table.focusCellHighlightBorder", new BorderUIResource.LineBorderUIResource(Color.white),
       "Table.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "Table.foreground", new ColorUIResource(Color.black),
       "Table.gridColor", new ColorUIResource(Color.gray),
       "Table.scrollPaneBorder", new BorderUIResource.BevelBorderUIResource(0),
-      "Table.selectionBackground", new ColorUIResource(0, 0, 128),
-      "Table.selectionForeground", new ColorUIResource(Color.white),
+      "Table.selectionBackground", new ColorUIResource(lightPurple),
+      "Table.selectionForeground", new ColorUIResource(Color.black),
       "TableHeader.background", new ColorUIResource(Color.lightGray),
       "TableHeader.cellBorder", new BorderUIResource.BevelBorderUIResource(0),
       "TableHeader.font", new FontUIResource("Dialog", Font.PLAIN, 12),
@@ -775,8 +811,8 @@
                                                              0), "insert-tab")
           },
       "TextArea.margin", new InsetsUIResource(0, 0, 0, 0),
-      "TextArea.selectionBackground", new ColorUIResource(0, 0, 128),
-      "TextArea.selectionForeground", new ColorUIResource(Color.white),
+      "TextArea.selectionBackground", new ColorUIResource(lightPurple),
+      "TextArea.selectionForeground", new ColorUIResource(Color.black),
       "TextField.background", new ColorUIResource(Color.white),
       "TextField.border", new BasicBorders.FieldBorder(null, null, null, null),
       "TextField.caretBlinkRate", new Integer(500),
@@ -787,10 +823,17 @@
       "TextField.keyBindings", new JTextComponent.KeyBinding[] {
         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
                                                              0),
-                                      "notify-field-accept")},
+                                      "notify-field-accept"),
+        new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
+							     InputEvent.SHIFT_DOWN_MASK),
+							     "selection-backward"),
+        new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
+							     InputEvent.SHIFT_DOWN_MASK),
+							     "selection-forward"),
+          },
       "TextField.margin", new InsetsUIResource(0, 0, 0, 0),
-      "TextField.selectionBackground", new ColorUIResource(0, 0, 128),
-      "TextField.selectionForeground", new ColorUIResource(Color.white),
+      "TextField.selectionBackground", new ColorUIResource(lightPurple),
+      "TextField.selectionForeground", new ColorUIResource(Color.black),
       "TextPane.background", new ColorUIResource(Color.white),
       "TextPane.border", new BasicBorders.MarginBorder(),
       "TextPane.caretBlinkRate", new Integer(500),
@@ -842,14 +885,14 @@
       "ToolBar.background", new ColorUIResource(Color.lightGray),
       "ToolBar.border", new BorderUIResource.EtchedBorderUIResource(),
       "ToolBar.dockingBackground", new ColorUIResource(Color.lightGray),
-      "ToolBar.dockingForeground", new ColorUIResource(Color.red),
+      "ToolBar.dockingForeground", new ColorUIResource(11, 30, 143),
       "ToolBar.floatingBackground", new ColorUIResource(Color.lightGray),
-      "ToolBar.floatingForeground", new ColorUIResource(Color.darkGray),
+      "ToolBar.floatingForeground", new ColorUIResource(113, 171, 212),
       "ToolBar.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "ToolBar.foreground", new ColorUIResource(Color.black),
-      "ToolBar.separatorSize", new DimensionUIResource(10, 10),
-      "ToolTip.background", new ColorUIResource(Color.white),
-      "ToolTip.border", new BorderUIResource.LineBorderUIResource(null),
+      "ToolBar.separatorSize", new DimensionUIResource(20, 20),
+      "ToolTip.background", new ColorUIResource(122, 178, 241),
+      "ToolTip.border", new BorderUIResource.LineBorderUIResource(Color.lightGray),
       "ToolTip.font", new FontUIResource("SansSerif", Font.PLAIN, 12),
       "ToolTip.foreground", new ColorUIResource(Color.black),
       "Tree.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
@@ -860,7 +903,7 @@
       // XXX Don't use gif
       "Tree.closedIcon", new IconUIResource(new ImageIcon("icons/TreeClosed.gif")),
       "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE,
-      "Tree.editorBorder", new BorderUIResource.LineBorderUIResource(null),
+      "Tree.editorBorder", new BorderUIResource.LineBorderUIResource(Color.lightGray),
       "Tree.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "shift PAGE_DOWN", "scrollDownExtendSelection",
         "PAGE_DOWN", "scrollDownChangeSelection",
@@ -916,9 +959,9 @@
       "Tree.rightChildIndent", new Integer(13),
       "Tree.rowHeight", new Integer(16),
       "Tree.scrollsOnExpand", Boolean.TRUE,
-      "Tree.selectionBackground", new ColorUIResource(0, 0, 128),
+      "Tree.selectionBackground", new ColorUIResource(lightPurple),
       "Tree.selectionBorderColor", new ColorUIResource(Color.black),
-      "Tree.selectionForeground", new ColorUIResource(Color.white),
+      "Tree.selectionForeground", new ColorUIResource(Color.black),
       "Tree.textBackground", new ColorUIResource(Color.lightGray),
       "Tree.textForeground", new ColorUIResource(Color.black),
       "Viewport.background", new ColorUIResource(Color.lightGray),
Index: javax/swing/plaf/basic/BasicMenuBarUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicMenuBarUI.java
diff -N javax/swing/plaf/basic/BasicMenuBarUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicMenuBarUI.java	6 Sep 2004 16:36:05 -0000
@@ -0,0 +1,323 @@
+/* BasicMenuBarUI.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.KeyStroke;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.MenuListener;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.MenuBarUI;
+import javax.swing.plaf.MenuItemUI;
+
+
+/**
+ * UI Delegate for JMenuBar.
+ */
+public class BasicMenuBarUI extends MenuBarUI
+{
+  protected ChangeListener changeListener;
+
+  /*ContainerListener that listens to the ContainerEvents fired from menu bar*/
+  protected ContainerListener containerListener;
+
+  /*Property change listeners that listener to PropertyChangeEvent from menu bar*/
+  protected PropertyChangeListener propertyChangeListener;
+
+  /* menu bar for which this UI delegate is for*/
+  protected JMenuBar menuBar;
+
+  /**
+   * Creates a new BasicMenuBarUI object.
+   */
+  public BasicMenuBarUI()
+  {
+    changeListener = createChangeListener();
+    containerListener = createContainerListener();
+    propertyChangeListener = new PropertyChangeHandler();
+  }
+
+  /**
+   * Creates ChangeListener
+   *
+   * @return The ChangeListener
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ChangeHandler();
+  }
+
+  /**
+   * Creates ContainerListener() to listen for ContainerEvents
+   * fired by JMenuBar.
+   *
+   * @return The ContainerListener
+   */
+  protected ContainerListener createContainerListener()
+  {
+    return new ContainerHandler();
+  }
+
+  /**
+   * Factory method to create a BasicMenuBarUI for the given {@link
+   * JComponent}, which should be a {@link JMenuBar}.
+   *
+   * @param b The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicMenuBarUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent x)
+  {
+    return new BasicMenuBarUI();
+  }
+
+  /**
+   * Returns maximum size for the specified menu bar
+   *
+   * @param c component for which to get maximum size
+   *
+   * @return  Maximum size for the specified menu bar
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    // let layout manager calculate its size
+    return null;
+  }
+
+  /**
+   * Returns maximum allowed size of JMenuBar.
+   *
+   * @param c menuBar for which to return maximum size
+   *
+   * @return Maximum size of the give menu bar.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    // let layout manager calculate its size
+    return null;
+  }
+
+  /**
+   * Returns preferred size of JMenuBar.
+   *
+   * @param c menuBar for which to return preferred size
+   *
+   * @return Preferred size of the give menu bar.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    // let layout manager calculate its size
+    return null;
+  }
+
+  /**
+   * Initializes any default properties that this UI has from the defaults for
+   * the Basic look and feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    menuBar.setBackground(defaults.getColor("MenuBar.background"));
+    menuBar.setBorder(defaults.getBorder("MenuBar.border"));
+    menuBar.setFont(defaults.getFont("MenuBar.font"));
+    menuBar.setForeground(defaults.getColor("MenuBar.foreground"));
+  }
+
+  /**
+   * This method installs the keyboard actions for the JMenuBar.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: implement
+  }
+
+  /**
+   * This method installs the listeners needed for this UI to function.
+   */
+  protected void installListeners()
+  {
+    menuBar.addContainerListener(containerListener);
+    menuBar.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+  * Installs and initializes all fields for this UI delegate. Any properties
+  * of the UI that need to be initialized and/or set to defaults will be
+  * done now. It will also install any listeners necessary.
+  *
+  * @param c The {@link JComponent} that is having this UI installed.
+  */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    menuBar = (JMenuBar) c;
+    menuBar.setLayout(new BoxLayout(menuBar, BoxLayout.X_AXIS));
+    installDefaults();
+    installListeners();
+    installKeyboardActions();
+  }
+
+  /**
+   * This method uninstalls the defaults and nulls any objects created during
+   * install.
+   */
+  protected void uninstallDefaults()
+  {
+    menuBar.setBackground(null);
+    menuBar.setBorder(null);
+    menuBar.setFont(null);
+    menuBar.setForeground(null);
+  }
+
+  /**
+   * This method reverses the work done in installKeyboardActions.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: implement. 
+  }
+
+  /**
+   * Unregisters all the listeners that this UI delegate was using.
+   */
+  protected void uninstallListeners()
+  {
+    menuBar.removeContainerListener(containerListener);
+    menuBar.removePropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * Performs the opposite of installUI. Any properties or resources that need
+   * to be cleaned up will be done now. It will also uninstall any listeners
+   * it has. In addition, any properties of this UI will be nulled.
+   *
+   * @param c The {@link JComponent} that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallDefaults();
+    uninstallListeners();
+    uninstallKeyboardActions();
+    menuBar = null;
+  }
+
+  protected class ChangeHandler implements ChangeListener
+  {
+    public void stateChanged(ChangeEvent event)
+    {
+    }
+  }
+
+  /**
+   * This class handles ContainerEvents fired by JMenuBar. It revalidates
+   * and repaints menu bar whenever menu is added or removed from it.
+   */
+  protected class ContainerHandler implements ContainerListener
+  {
+    /**
+     * This method is called whenever menu is added to the menu bar
+     *
+     * @param e The ContainerEvent.
+     */
+    public void componentAdded(ContainerEvent e)
+    {
+      menuBar.revalidate();
+      menuBar.repaint();
+    }
+
+    /**
+     * This method is called whenever menu is removed from the menu bar.
+     *
+     * @param e The ContainerEvent.
+     */
+    public void componentRemoved(ContainerEvent e)
+    {
+      menuBar.revalidate();
+      menuBar.repaint();
+    }
+  }
+
+  /**
+   * This class handles PropertyChangeEvents fired from the JMenuBar
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called whenever one of the properties of the MenuBar
+     * changes.
+     *
+     * @param e The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JMenuBar.BORDER_PAINTED_CHANGED_PROPERTY))
+	menuBar.repaint();
+      if (e.getPropertyName().equals(JMenuBar.MARGIN_CHANGED_PROPERTY))
+	menuBar.repaint();
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicMenuItemUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicMenuItemUI.java
diff -N javax/swing/plaf/basic/BasicMenuItemUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicMenuItemUI.java	6 Sep 2004 16:36:05 -0000
@@ -0,0 +1,1009 @@
+/* BasicMenuItemUI.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Stroke;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Vector;
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.KeyStroke;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.MenuItemUI;
+
+
+/**
+ * UI Delegate for JMenuItem.
+ */
+public class BasicMenuItemUI extends MenuItemUI
+{
+  /**
+   * Font to be used when displaying menu item's accelerator.
+   */
+  protected Font acceleratorFont;
+
+  /**
+   * Color to be used when displaying menu item's accelerator.
+   */
+  protected Color acceleratorForeground;
+
+  /**
+   * Color to be used when displaying menu item's accelerator when menu item is
+   * selected.
+   */
+  protected Color acceleratorSelectionForeground;
+
+  /**
+   * Icon that is displayed after the text to indicated that this menu contains
+   * submenu.
+   */
+  protected Icon arrowIcon;
+
+  /**
+   * Icon that is displayed before the text. This icon is only used in
+   * JCheckBoxMenuItem or JRadioBoxMenuItem.
+   */
+  protected Icon checkIcon;
+
+  /**
+   * Number of spaces between icon and text.
+   */
+  protected int defaultTextIconGap = 4;
+
+  /**
+   * Color of the text when menu item is disabled
+   */
+  protected Color disabledForeground;
+
+  /**
+   * The menu Drag mouse listener listening to the menu item.
+   */
+  protected MenuDragMouseListener menuDragMouseListener;
+
+  /**
+   * The menu item itself
+   */
+  protected JMenuItem menuItem;
+
+  /**
+   * Menu Key listener listening to the menu item.
+   */
+  protected MenuKeyListener menuKeyListener;
+
+  /**
+   * mouse input listener listening to menu item.
+   */
+  protected MouseInputListener mouseInputListener;
+
+  /**
+   * Indicates if border should be painted
+   */
+  protected boolean oldBorderPainted;
+
+  /**
+   * Color of text that is used when menu item is selected
+   */
+  protected Color selectionBackground;
+
+  /**
+   * Color of the text that is used when menu item is selected.
+   */
+  protected Color selectionForeground;
+
+  /**
+   * String that separates description of the modifiers and the key
+   */
+  private String acceleratorDelimiter;
+
+  /**
+   * PropertyChangeListener to listen for property changes in the menu item
+   */
+  private PropertyChangeListener propertyChangeListener;
+
+  /**
+   * Number of spaces between accelerator and menu item's label.
+   */
+  private int defaultAcceleratorLabelGap = 4;
+
+  /**
+   * Creates a new BasicMenuItemUI object.
+   */
+  public BasicMenuItemUI()
+  {
+    mouseInputListener = createMouseInputListener(menuItem);
+    menuDragMouseListener = createMenuDragMouseListener(menuItem);
+    menuKeyListener = createMenuKeyListener(menuItem);
+    propertyChangeListener = new PropertyChangeHandler();
+  }
+
+  /**
+   * Create MenuDragMouseListener to listen for mouse dragged events.
+   *
+   * @param c menu item to listen to
+   *
+   * @return The MenuDragMouseListener
+   */
+  protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
+  {
+    return new MenuDragMouseHandler();
+  }
+
+  /**
+   * Creates MenuKeyListener to listen to key events occuring when menu item
+   * is visible on the screen.
+   *
+   * @param c menu item to listen to
+   *
+   * @return The MenuKeyListener
+   */
+  protected MenuKeyListener createMenuKeyListener(JComponent c)
+  {
+    return new MenuKeyHandler();
+  }
+
+  /**
+   * Handles mouse input events occuring for this menu item
+   *
+   * @param c menu item to listen to
+   *
+   * @return The MouseInputListener
+   */
+  protected MouseInputListener createMouseInputListener(JComponent c)
+  {
+    return new MouseInputHandler();
+  }
+
+  /**
+   * Factory method to create a BasicMenuItemUI for the given {@link
+   * JComponent}, which should be a {@link JMenuItem}.
+   *
+   * @param c The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicMenuItemUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicMenuItemUI();
+  }
+
+  /**
+   * Programatically clicks menu item.
+   *
+   * @param msm MenuSelectionManager for the menu hierarchy
+   */
+  protected void doClick(MenuSelectionManager msm)
+  {
+    menuItem.doClick();
+    msm.clearSelectedPath();
+  }
+
+  /**
+   * Returns maximum size for the specified menu item
+   *
+   * @param c component for which to get maximum size
+   *
+   * @return Maximum size for the specified menu item.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * Returns minimum size for the specified menu item
+   *
+   * @param c component for which to get minimum size
+   *
+   * @return Minimum size for the specified menu item.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * Returns path to this menu item.
+   *
+   * @return $MenuElement[]$ Returns array of menu elements
+   * that constitute a path to this menu item.
+   */
+  public MenuElement[] getPath()
+  {
+    ArrayList path = new ArrayList();
+
+    // Path to menu should also include its popup menu.
+    if (menuItem instanceof JMenu)
+      path.add(((JMenu) menuItem).getPopupMenu());
+
+    Component c = menuItem;
+    while (c instanceof MenuElement)
+      {
+	path.add(0, (MenuElement) c);
+
+	if (c instanceof JPopupMenu)
+	  c = ((JPopupMenu) c).getInvoker();
+	else
+	  c = c.getParent();
+      }
+
+    MenuElement[] pathArray = new MenuElement[path.size()];
+    path.toArray(pathArray);
+    return pathArray;
+  }
+
+  /**
+   * Returns preferred size for the given menu item.
+   *
+   * @param c menu item for which to get preferred size
+   * @param checkIcon chech icon displayed in the given menu item
+   * @param arrowIcon arrow icon displayed in the given menu item
+   * @param defaultTextIconGap space between icon and text in the given menuItem
+   *
+   * @return $Dimension$ preferred size for the given menu item
+   */
+  protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon,
+                                               Icon arrowIcon,
+                                               int defaultTextIconGap)
+  {
+    JMenuItem m = (JMenuItem) c;
+    Dimension d = BasicGraphicsUtils.getPreferredButtonSize(m,
+                                                            defaultTextIconGap);
+
+    // if menu item has accelerator then take accelerator's size into account
+    // when calculating preferred size.
+    KeyStroke accelerator = m.getAccelerator();
+    Rectangle rect;
+
+    if (accelerator != null)
+      {
+	rect = getAcceleratorRect(accelerator,
+	                          m.getToolkit().getFontMetrics(acceleratorFont));
+
+	// add width of accelerator's text
+	d.width = d.width + rect.width + defaultAcceleratorLabelGap;
+
+	// adjust the heigth of the preferred size if necessary
+	if (d.height < rect.height)
+	  d.height = rect.height;
+      }
+
+    if (checkIcon != null)
+      {
+	d.width = d.width + checkIcon.getIconWidth() + defaultTextIconGap;
+
+	if (checkIcon.getIconHeight() > d.height)
+	  d.height = checkIcon.getIconHeight();
+      }
+
+    if (arrowIcon != null && (c instanceof JMenu))
+      {
+	d.width = d.width + arrowIcon.getIconWidth() + defaultTextIconGap;
+
+	if (arrowIcon.getIconHeight() > d.height)
+	  d.height = arrowIcon.getIconHeight();
+      }
+
+    return d;
+  }
+
+  /**
+   * Returns preferred size of the given component
+   *
+   * @param c component for which to return preferred size
+   *
+   * @return $Dimension$ preferred size for the given component
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap);
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return null;
+  }
+
+  /**
+   * This method installs the components for this {@link JMenuItem}.
+   *
+   * @param menuItem The {@link JMenuItem} to install components for.
+   */
+  protected void installComponents(JMenuItem menuItem)
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this {@link JMenuItem}.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    menuItem.setBackground(defaults.getColor("MenuItem.background"));
+    menuItem.setBorder(defaults.getBorder("MenuItem.border"));
+    menuItem.setFont(defaults.getFont("MenuItem.font"));
+    menuItem.setForeground(defaults.getColor("MenuItem.foreground"));
+    menuItem.setMargin(defaults.getInsets("MenuItem.margin"));
+    menuItem.setOpaque(true);
+    acceleratorFont = defaults.getFont("MenuItem.acceleratorFont");
+    acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground");
+    acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground");
+    selectionBackground = defaults.getColor("MenuItem.selectionBackground");
+    selectionForeground = defaults.getColor("MenuItem.selectionForeground");
+    acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter");
+  }
+
+  /**
+   * This method installs the keyboard actions for this {@link JMenuItem}.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method installs the listeners for the {@link JMenuItem}.
+   */
+  protected void installListeners()
+  {
+    menuItem.addMouseListener(mouseInputListener);
+    menuItem.addMouseMotionListener(mouseInputListener);
+    menuItem.addMenuDragMouseListener(menuDragMouseListener);
+    menuItem.addMenuKeyListener(menuKeyListener);
+    menuItem.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * Installs and initializes all fields for this UI delegate. Any properties
+   * of the UI that need to be initialized and/or set to defaults will be
+   * done now. It will also install any listeners necessary.
+   *
+   * @param c The {@link JComponent} that is having this UI installed.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    menuItem = (JMenuItem) c;
+    installDefaults();
+    installComponents(menuItem);
+    installListeners();
+  }
+
+  /**
+   * Paints given menu item using specified graphics context
+   *
+   * @param g The graphics context used to paint this menu item
+   * @param c Menu Item to paint
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(),
+                  c.getForeground(), defaultTextIconGap);
+  }
+
+  /**
+   * Paints background of the menu item
+   *
+   * @param g The graphics context used to paint this menu item
+   * @param menuItem menu item to paint
+   * @param bgColor Background color to use when painting menu item
+   */
+  protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)
+  {
+    Dimension size = getPreferredSize(menuItem);
+    Color foreground = g.getColor();
+    g.setColor(bgColor);
+    g.drawRect(0, 0, size.width, size.height);
+    g.setColor(foreground);
+  }
+
+  /**
+   * Paints specified menu item
+   *
+   * @param g The graphics context used to paint this menu item
+   * @param c menu item to paint
+   * @param checkIcon check icon to use when painting menu item
+   * @param arrowIcon arrow icon to use when painting menu item
+   * @param background Background color of the menu item
+   * @param foreground Foreground color of the menu item
+   * @param defaultTextIconGap space to use between icon and
+   *  text when painting menu item
+   */
+  protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon,
+                               Icon arrowIcon, Color background,
+                               Color foreground, int defaultTextIconGap)
+  {
+    JMenuItem m = (JMenuItem) c;
+    Rectangle tr = new Rectangle(); // text rectangle
+    Rectangle ir = new Rectangle(); // icon rectangle
+    Rectangle vr = new Rectangle(); // view rectangle
+    Rectangle br = new Rectangle(); // border rectangle
+    Rectangle ar = new Rectangle(); // accelerator rectangle
+    Rectangle cr = new Rectangle(); // checkIcon rectangle
+
+    int vertAlign = m.getVerticalAlignment();
+    int horAlign = m.getHorizontalAlignment();
+    int vertTextPos = m.getVerticalTextPosition();
+    int horTextPos = m.getHorizontalTextPosition();
+
+    Font f = m.getFont();
+    g.setFont(f);
+    FontMetrics fm = g.getFontMetrics(f);
+    SwingUtilities.calculateInnerArea(m, br);
+    SwingUtilities.calculateInsetArea(br, m.getInsets(), vr);
+    paintBackground(g, m, m.getBackground());
+
+    /* MenuItems insets are equal to menuItems margin, space between text and
+       menuItems border. We need to paint insets region as well. */
+    Insets insets = m.getInsets();
+    br.x -= insets.left;
+    br.y -= insets.top;
+    br.width += insets.right + insets.left;
+    br.height += insets.top + insets.bottom;
+
+    /* Menu item is considered to be highlighted when it is selected.
+       It is considered to be selected if menu item is inside some menu
+       and is armed or if it is both armed and pressed */
+    if (m.getModel().isArmed()
+        && (m.getParent() instanceof MenuElement || m.getModel().isPressed()))
+      {
+	if (m.isContentAreaFilled())
+	  {
+	    g.setColor(selectionBackground);
+	    g.fillRect(br.x, br.y, br.width, br.height);
+	  }
+      }
+    else
+      {
+	if (m.isContentAreaFilled())
+	  {
+	    g.setColor(m.getBackground());
+	    g.fillRect(br.x, br.y, br.width, br.height);
+	  }
+      }
+
+    // If this menu item is a JCheckBoxMenuItem then paint check icon
+    if (checkIcon != null)
+      {
+	SwingUtilities.layoutCompoundLabel(m, fm, null, checkIcon, vertAlign,
+	                                   horAlign, vertTextPos, horTextPos,
+	                                   vr, cr, tr, defaultTextIconGap);
+	checkIcon.paintIcon(m, g, cr.x, cr.y);
+
+	// We need to calculate position of the menu text and position of
+	// user menu icon if there exists one relative to the check icon.
+	// So we need to adjust view rectangle s.t. its starting point is at
+	// checkIcon.width + defaultTextIconGap. 
+	vr.x = cr.x + cr.width + defaultTextIconGap;
+      }
+
+    // if this is a submenu, then paint arrow icon to indicate it.
+    if (arrowIcon != null && (c instanceof JMenu))
+      {
+	if (! ((JMenu) c).isTopLevelMenu())
+	  {
+	    int width = arrowIcon.getIconWidth();
+	    int height = arrowIcon.getIconHeight();
+
+	    arrowIcon.paintIcon(m, g, vr.width - width + defaultTextIconGap,
+	                        vr.y + 2);
+	  }
+      }
+
+    // paint icon
+    // FIXME: should paint different icon at different button state's.
+    // i.e disabled icon when button is disabled.. etc.
+    Icon i = m.getIcon();
+    if (i != null)
+      {
+	i.paintIcon(c, g, vr.x, vr.y);
+
+	// Adjust view rectangle, s.t text would be drawn after menu item's icon.
+	vr.x += i.getIconWidth() + defaultTextIconGap;
+      }
+
+    // paint text and user menu icon if it exists	     
+    SwingUtilities.layoutCompoundLabel(c, fm, m.getText(), m.getIcon(),
+                                       vertAlign, horAlign, vertTextPos,
+                                       horTextPos, vr, ir, tr,
+                                       defaultTextIconGap);
+
+    paintText(g, m, tr, m.getText());
+
+    // paint accelerator    
+    String acceleratorText = "";
+
+    if (m.getAccelerator() != null)
+      {
+	acceleratorText = getAcceleratorText(m.getAccelerator());
+	fm = g.getFontMetrics(acceleratorFont);
+	ar.width = fm.stringWidth(acceleratorText);
+	ar.x = br.width - ar.width;
+	vr.x = br.width - ar.width;
+
+	SwingUtilities.layoutCompoundLabel(m, fm, acceleratorText, null,
+	                                   vertAlign, horAlign, vertTextPos,
+	                                   horTextPos, vr, ir, ar,
+	                                   defaultTextIconGap);
+
+	paintAccelerator(g, m, ar, acceleratorText);
+      }
+  }
+
+  /**
+   * Paints label for the given menu item
+   *
+   * @param g The graphics context used to paint this menu item
+   * @param menuItem menu item for which to draw its label
+   * @param textRect rectangle specifiying position of the text relative to
+   * the given menu item
+   * @param text label of the menu item
+   */
+  protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect,
+                           String text)
+  {
+    Font f = menuItem.getFont();
+    g.setFont(f);
+    FontMetrics fm = g.getFontMetrics(f);
+
+    if (text != null && ! text.equals(""))
+      {
+	if (menuItem.isEnabled())
+	  g.setColor(menuItem.getForeground());
+	else
+	  // FIXME: should fix this to use 'disabledForeground', but its
+	  // default value in BasicLookAndFeel is null.	  
+	  g.setColor(Color.gray);
+
+	int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
+
+	if (mnemonicIndex != -1)
+	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex,
+	                                               textRect.x,
+	                                               textRect.y
+	                                               + fm.getAscent());
+	else
+    BasicGraphicsUtils.drawString(g, text, 0, textRect.x,
+                                  textRect.y + fm.getAscent());
+  }
+  }
+
+  /**
+   * This method uninstalls the components for this {@link JMenuItem}.
+   *
+   * @param menuItem The {@link JMenuItem} to uninstall components for.
+   */
+  protected void uninstallComponents(JMenuItem menuItem)
+  {
+    // FIXME: need to implement
+  }
+
+  /**
+   * This method uninstalls the defaults and sets any objects created during
+   * install to null
+   */
+  protected void uninstallDefaults()
+  {
+    menuItem.setForeground(null);
+    menuItem.setBackground(null);
+    menuItem.setBorder(null);
+    menuItem.setMargin(null);
+    menuItem.setBackground(null);
+    menuItem.setBorder(null);
+    menuItem.setFont(null);
+    menuItem.setForeground(null);
+    menuItem.setMargin(null);
+    acceleratorFont = null;
+    acceleratorForeground = null;
+    acceleratorSelectionForeground = null;
+    arrowIcon = null;
+    selectionBackground = null;
+    selectionForeground = null;
+    acceleratorDelimiter = null;
+  }
+
+  /**
+   * Uninstalls any keyboard actions.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: need to implement
+  }
+
+  /**
+   * Unregisters all the listeners that this UI delegate was using.
+   */
+  protected void uninstallListeners()
+  {
+    menuItem.removeMouseListener(mouseInputListener);
+    menuItem.removeMenuDragMouseListener(menuDragMouseListener);
+    menuItem.removeMenuKeyListener(menuKeyListener);
+    menuItem.removePropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * Performs the opposite of installUI. Any properties or resources that need
+   * to be cleaned up will be done now. It will also uninstall any listeners
+   * it has. In addition, any properties of this UI will be nulled.
+   *
+   * @param c The {@link JComponent} that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallListeners();
+    uninstallDefaults();
+    uninstallComponents(menuItem);
+    menuItem = null;
+  }
+
+  /**
+   * This method calls paint.
+   *
+   * @param g The graphics context used to paint this menu item
+   * @param c The menu item to paint
+   */
+  public void update(Graphics g, JComponent c)
+  {
+    paint(g, c);
+  }
+
+  /**
+   * Return text representation of the specified accelerator
+   *
+   * @param accelerator Accelerator for which to return string representation
+   *
+   * @return $String$ Text representation of the given accelerator
+   */
+  private String getAcceleratorText(KeyStroke accelerator)
+  {
+    // convert keystroke into string format
+    String modifiersText = "";
+    int modifiers = accelerator.getModifiers();
+    char keyChar = accelerator.getKeyChar();
+    int keyCode = accelerator.getKeyCode();
+
+    if (modifiers != 0)
+      modifiersText = KeyEvent.getKeyModifiersText(modifiers)
+                      + acceleratorDelimiter;
+
+    if (keyCode == KeyEvent.VK_UNDEFINED)
+      return modifiersText + keyChar;
+    else
+      return modifiersText + KeyEvent.getKeyText(keyCode);
+  }
+
+  /**
+   * Calculates and return rectange in which accelerator should be displayed
+   *
+   * @param accelerator accelerator for which to return the display rectangle
+   * @param fm The font metrics used to measure the text
+   *
+   * @return $Rectangle$ reactangle which will be used to display accelerator
+   */
+  private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
+  {
+    int width = fm.stringWidth(getAcceleratorText(accelerator));
+    int height = fm.getHeight();
+    return new Rectangle(0, 0, width, height);
+  }
+
+  /**
+   * Paints accelerator inside menu item
+   *
+   * @param g The graphics context used to paint the border
+   * @param menuItem Menu item for which to draw accelerator
+   * @param acceleratorRect rectangle representing position
+   * of the accelerator relative to the menu item
+   * @param acceleratorText accelerator's text
+   */
+  private void paintAccelerator(Graphics g, JMenuItem menuItem,
+                                Rectangle acceleratorRect,
+                                String acceleratorText)
+  {
+    g.setFont(acceleratorFont);
+    FontMetrics fm = g.getFontMetrics(acceleratorFont);
+
+    if (menuItem.isEnabled())
+    g.setColor(acceleratorForeground);
+    else
+      // FIXME: should fix this to use 'disabledForeground', but its
+      // default value in BasicLookAndFeel is null.
+      g.setColor(Color.gray);
+
+    BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x,
+                                  acceleratorRect.y + fm.getAscent());
+  }
+
+  /**
+   * This class handles mouse events occuring inside the menu item.
+   * Most of the events are forwarded for processing to MenuSelectionManager
+   * of the current menu hierarchy.
+   *
+   */
+  protected class MouseInputHandler implements MouseInputListener
+  {
+    /**
+     * Creates a new MouseInputHandler object.
+     */
+    protected MouseInputHandler()
+    {
+    }
+
+    /**
+     * This method is called when mouse is clicked on the menu item.
+     * It forwards this event to MenuSelectionManager.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    /**
+     * This method is called when mouse is dragged inside the menu item.
+     * It forwards this event to MenuSelectionManager.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    /**
+     * This method is called when mouse enters menu item.
+     * When this happens menu item is considered to be selected and selection path
+     * in MenuSelectionManager is set. This event is also forwarded to MenuSelection
+     * Manager for further processing.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+      Component source = (Component) e.getSource();
+      if (source.getParent() instanceof MenuElement)
+        {
+	  MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+	  manager.setSelectedPath(getPath());
+	  manager.processMouseEvent(e);
+        }
+    }
+
+    /**
+     * This method is called when mouse exits menu item. The event is
+     * forwarded to MenuSelectionManager for processing.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    /**
+     * This method is called when mouse is inside the menu item.
+     * This event is forwarder to MenuSelectionManager for further processing.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    /**
+     * This method is called when mouse is pressed. This event is forwarded to
+     * MenuSelectionManager for further processing.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    /**
+     * This method is called when mouse is released. If the mouse is released
+     * inside this menuItem, then this menu item is considered to be chosen and
+     * the menu hierarchy should be closed.
+     *
+     * @param e A {@link MouseEvent}.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      Rectangle size = menuItem.getBounds();
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0
+          && e.getY() < size.height)
+        {
+	  manager.clearSelectedPath();
+	  menuItem.doClick();
+        }
+
+      else
+	manager.processMouseEvent(e);
+    }
+  }
+
+  /**
+   * This class handles mouse dragged events.
+   */
+  protected class MenuDragMouseHandler implements MenuDragMouseListener
+  {
+    /**
+     * Tbis method is invoked when mouse is dragged over the menu item.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseDragged(MenuDragMouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.setSelectedPath(e.getPath());
+    }
+
+    /**
+     * Tbis method is invoked when mouse enters the menu item while it is
+     * being dragged.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseEntered(MenuDragMouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.setSelectedPath(e.getPath());
+    }
+
+    /**
+     * Tbis method is invoked when mouse exits the menu item while
+     * it is being dragged
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseExited(MenuDragMouseEvent e)
+    {
+    }
+
+    /**
+     * Tbis method is invoked when mouse was dragged and released
+     * inside the menu item.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseReleased(MenuDragMouseEvent e)
+    {
+      MenuElement[] path = e.getPath();
+
+      if (path[path.length - 1] instanceof JMenuItem)
+	((JMenuItem) path[path.length - 1]).doClick();
+
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+  }
+
+  /**
+   * This class handles key events occuring when menu item is visible on the
+   * screen.
+   */
+  protected class MenuKeyHandler implements MenuKeyListener
+  {
+    /**
+     * This method is invoked when key has been pressed
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyPressed(MenuKeyEvent e)
+    {
+    }
+
+    /**
+     * This method is invoked when key has been pressed
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyReleased(MenuKeyEvent e)
+    {
+    }
+
+    /**
+     * This method is invoked when key has been typed
+     * It handles the mnemonic key for the menu item.
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyTyped(MenuKeyEvent e)
+    {
+    }
+  }
+
+  /**
+   * Helper class that listens for changes to the properties of the {@link
+   * JMenuItem}.
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called when one of the menu item's properties change.
+     *
+     * @param evt A {@link PropertyChangeEvent}.
+     */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      menuItem.revalidate();
+      menuItem.repaint();
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicMenuUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicMenuUI.java
diff -N javax/swing/plaf/basic/BasicMenuUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicMenuUI.java	6 Sep 2004 16:36:05 -0000
@@ -0,0 +1,528 @@
+/* BasicMenuUI.java
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.MenuListener;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.MenuItemUI;
+
+
+/**
+ * UI Delegate for JMenu
+ */
+public class BasicMenuUI extends BasicMenuItemUI
+{
+  protected ChangeListener changeListener;
+
+  /* MenuListener listens to MenuEvents fired by JMenu */
+  protected MenuListener menuListener;
+
+  /* PropertyChangeListner that listens to propertyChangeEvents occuring in JMenu*/
+  protected PropertyChangeListener propertyChangeListener;
+
+  /**
+   * Creates a new BasicMenuUI object.
+   */
+  public BasicMenuUI()
+  {
+    mouseInputListener = createMouseInputListener((JMenu) menuItem);
+    menuListener = createMenuListener((JMenu) menuItem);
+    propertyChangeListener = createPropertyChangeListener((JMenu) menuItem);
+  }
+
+  /**
+   * This method creates a new ChangeListener.
+   *
+   * @return A new ChangeListener.
+   */
+  protected ChangeListener createChangeListener(JComponent c)
+  {
+    return new ChangeHandler();
+  }
+
+  /**
+   * This method creates new MenuDragMouseListener to listen to mouse dragged events
+   * occuring in the Menu
+   *
+   * @param c the menu to listen to
+   *
+   * @return The MenuDrageMouseListener
+   */
+  protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
+  {
+    return new MenuDragMouseHandler();
+  }
+
+  /**
+   * This method creates new MenuDragKeyListener to listen to key events
+   *
+   * @param c the menu to listen to
+   *
+   * @return The MenuKeyListener
+   */
+  protected MenuKeyListener createMenuKeyListener(JComponent c)
+  {
+    return new MenuKeyHandler();
+  }
+
+  /**
+   * This method creates new MenuListener to listen to menu events
+   * occuring in the Menu
+   *
+   * @param c the menu to listen to
+   *
+   * @return The MenuListener
+   */
+  protected MenuListener createMenuListener(JComponent c)
+  {
+    return new MenuHandler();
+  }
+
+  /**
+   * This method creates new MouseInputListener to listen to mouse input events
+   * occuring in the Menu
+   *
+   * @param c the menu to listen to
+   *
+   * @return The MouseInputListener
+   */
+  protected MouseInputListener createMouseInputListener(JComponent c)
+  {
+    return new MouseInputHandler();
+  }
+
+  /**
+   * This method creates newPropertyChangeListener to listen to property changes
+   * occuring in the Menu
+   *
+   * @param c the menu to listen to
+   *
+   * @return The PropertyChangeListener
+   */
+  protected PropertyChangeListener createPropertyChangeListener(JComponent c)
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method creates a new BasicMenuUI.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicMenuUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicMenuUI();
+  }
+
+  /**
+   * Get the component's maximum size.
+   *
+   * @param c The JComponent for which to get maximum size
+   *
+   * @return The maximum size of the component
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return null;
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return null;
+  }
+
+  /**
+   * Initializes any default properties that this UI has from the defaults for
+   * the Basic look and feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    menuItem.setBackground(defaults.getColor("Menu.background"));
+    menuItem.setBorder(defaults.getBorder("Menu.border"));
+    menuItem.setFont(defaults.getFont("Menu.font"));
+    menuItem.setForeground(defaults.getColor("Menu.foreground"));
+    menuItem.setMargin(defaults.getInsets("Menu.margin"));
+    acceleratorFont = defaults.getFont("Menu.acceleratorFont");
+    acceleratorForeground = defaults.getColor("Menu.acceleratorForeground");
+    acceleratorSelectionForeground = defaults.getColor("Menu.acceleratorSelectionForeground");
+    selectionBackground = defaults.getColor("Menu.selectionBackground");
+    selectionForeground = defaults.getColor("Menu.selectionForeground");
+    arrowIcon = defaults.getIcon("Menu.arrowIcon");
+    oldBorderPainted = defaults.getBoolean("Menu.borderPainted");
+    menuItem.setOpaque(true);
+  }
+
+  /**
+   * Installs any keyboard actions. The list of keys that need to be bound are
+   * listed in Basic look and feel's defaults.
+   *
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * Creates and registers all the listeners for this UI delegate.
+   */
+  protected void installListeners()
+  {
+    ((JMenu) menuItem).addMouseListener(mouseInputListener);
+    ((JMenu) menuItem).addMouseMotionListener(mouseInputListener);
+    ((JMenu) menuItem).addMenuListener(menuListener);
+    ((JMenu) menuItem).addMenuDragMouseListener(menuDragMouseListener);
+  }
+
+  protected void setupPostTimer(JMenu menu)
+  {
+  }
+
+  /**
+   * This method uninstalls the defaults and sets any objects created during
+   * install to null
+   */
+  protected void uninstallDefaults()
+  {
+    menuItem.setBackground(null);
+    menuItem.setBorder(null);
+    menuItem.setFont(null);
+    menuItem.setForeground(null);
+    menuItem.setMargin(null);
+    acceleratorFont = null;
+    acceleratorForeground = null;
+    acceleratorSelectionForeground = null;
+    selectionBackground = null;
+    selectionForeground = null;
+    arrowIcon = null;
+  }
+
+  /**
+   * Uninstalls any keyboard actions. The list of keys used  are listed in
+   * Basic look and feel's defaults.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * Unregisters all the listeners that this UI delegate was using. In
+   * addition, it will also null any listeners that it was using.
+   */
+  protected void uninstallListeners()
+  {
+    ((JMenu) menuItem).removeMouseListener(mouseInputListener);
+    ((JMenu) menuItem).removeMenuListener(menuListener);
+    ((JMenu) menuItem).removePropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * This class is used by menus to handle mouse events occuring in the
+   * menu.
+   */
+  protected class MouseInputHandler implements MouseInputListener
+  {
+    public void mouseClicked(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    public void mouseDragged(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    public void mouseEntered(MouseEvent e)
+    {
+      /* When mouse enters menu item, it should be considered selected
+
+       if (i) if this menu is a submenu in some other menu
+          (ii) or if this menu is in a menu bar and some other menu in a menu bar was just
+               selected. (If nothing was selected, menu should be pressed before
+               it will be selected)      
+      */
+      JMenu menu = (JMenu) menuItem;
+      if (! menu.isTopLevelMenu()
+          || (menu.isTopLevelMenu()
+          && (((JMenuBar) menu.getParent()).isSelected() && ! menu.isArmed())))
+        {
+	  // set new selection and forward this event to MenuSelectionManager
+	  MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+	  manager.setSelectedPath(getPath());
+	  manager.processMouseEvent(e);
+        }
+    }
+
+    public void mouseExited(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+
+    public void mouseMoved(MouseEvent e)
+    {
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      JMenu menu = (JMenu) menuItem;
+      manager.processMouseEvent(e);
+      
+      // Menu should be displayed when the menu is pressed only if 
+      // it is top-level menu
+      if (menu.isTopLevelMenu())
+        {
+	  if (menu.getPopupMenu().isVisible())
+	      // If menu is visible and menu button was pressed.. 
+	      // then need to cancel the menu
+	      manager.clearSelectedPath();
+	  else
+	    {
+	      // Display the menu
+	      int x = 0;
+	      int y = menu.getHeight();
+
+	      manager.setSelectedPath(getPath());
+
+	      JMenuBar mb = (JMenuBar) menu.getParent();
+
+	      // set selectedIndex of the selectionModel of a menuBar
+	      mb.getSelectionModel().setSelectedIndex(mb.getComponentIndex(menu));
+	    }
+        }
+    }
+
+    public void mouseReleased(MouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.processMouseEvent(e);
+    }
+  }
+
+  /**
+   * This class handles MenuEvents fired by the JMenu
+   */
+  protected class MenuHandler implements MenuListener
+  {
+    /**
+     * This method is called when menu is cancelled. The menu is cancelled
+     * when its popup menu is closed without selection. It clears selected index
+     * in the selectionModel of the menu parent.
+     *
+     * @param e The MenuEvent.
+     */
+    public void menuCanceled(MenuEvent e)
+    {
+      menuDeselected(e);
+    }
+
+    /**
+     * This method is called when menu is deselected. It clears selected index
+     * in the selectionModel of the menu parent.
+     *
+     * @param e The MenuEvent.
+     */
+    public void menuDeselected(MenuEvent e)
+    {
+      JMenu menu = (JMenu) menuItem;
+      if (menu.isTopLevelMenu())
+	((JMenuBar) menu.getParent()).getSelectionModel().clearSelection();
+      else
+	((JPopupMenu) menu.getParent()).getSelectionModel().clearSelection();
+    }
+
+    /**
+     * This method is called when menu is selected.  It sets selected index
+     * in the selectionModel of the menu parent.
+     *
+     * @param e The MenuEvent.
+     */
+    public void menuSelected(MenuEvent e)
+    {
+      JMenu menu = (JMenu) menuItem;
+      if (menu.isTopLevelMenu())
+	((JMenuBar) menu.getParent()).setSelected(menu);
+      else
+	((JPopupMenu) menu.getParent()).setSelected(menu);
+    }
+  }
+
+  /**
+   * This class handles PropertyChangeEvents fired from the JMenu
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+      * This method is called whenever one of the properties of the menu item
+      * changes.
+      *
+      * @param e The PropertyChangeEvent.
+      */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+    }
+  }
+
+  protected class ChangeHandler implements ChangeListener
+  {
+    public void stateChanged(ChangeEvent e)
+    {
+      // FIXME: It seems that this class is not used anywhere
+    }
+  }
+
+  /**
+   * This class handles mouse dragged events occuring in the menu.
+   */
+  protected class MenuDragMouseHandler implements MenuDragMouseListener
+  {
+    /**
+     * This method is invoked when mouse is dragged over the menu item.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseDragged(MenuDragMouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.setSelectedPath(e.getPath());
+    }
+
+    /**
+     * This method is invoked when mouse enters the menu item while it is
+     * being dragged.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseEntered(MenuDragMouseEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.setSelectedPath(e.getPath());
+    }
+
+    /**
+     * This method is invoked when mouse exits the menu item while
+     * it is being dragged
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseExited(MenuDragMouseEvent e)
+    {
+    }
+
+    /**
+     * This method is invoked when mouse was dragged and released
+     * inside the menu item.
+     *
+     * @param e The MenuDragMouseEvent
+     */
+    public void menuDragMouseReleased(MenuDragMouseEvent e)
+    {
+    }
+  }
+
+  /**
+   * This class handles key events occuring when menu item is visible on the
+   * screen.
+   */
+  protected class MenuKeyHandler implements MenuKeyListener
+  {
+    /**
+     * This method is invoked when key has been pressed
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyPressed(MenuKeyEvent e)
+    {
+    }
+
+    /**
+     * This method is invoked when key has been pressed
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyReleased(MenuKeyEvent e)
+    {
+    }
+
+    /**
+     * This method is invoked when key has been typed
+     * It handles the mnemonic key for the menu item.
+     *
+     * @param e A {@link MenuKeyEvent}.
+     */
+    public void menuKeyTyped(MenuKeyEvent e)
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicOptionPaneUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicOptionPaneUI.java,v
retrieving revision 1.6
diff -u -r1.6 BasicOptionPaneUI.java
--- javax/swing/plaf/basic/BasicOptionPaneUI.java	10 Jan 2004 21:59:30 -0000	1.6
+++ javax/swing/plaf/basic/BasicOptionPaneUI.java	6 Sep 2004 16:36:06 -0000
@@ -1,5 +1,5 @@
 /* BasicOptionPaneUI.java
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,124 +35,1295 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
+import java.awt.BorderLayout;
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Container;
 import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
 import java.awt.LayoutManager;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.Icon;
 import javax.swing.JButton;
+import javax.swing.JComboBox;
 import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
+import javax.swing.JList;
 import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
 import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.IconUIResource;
 import javax.swing.plaf.OptionPaneUI;
 
+
+/**
+ * This class is the UI delegate for JOptionPane in the Basic Look and Feel.
+ */
 public class BasicOptionPaneUI extends OptionPaneUI
 {
-    JOptionPane pane;
+  /**
+   * This is a helper class that listens to the buttons located at the bottom
+   * of the JOptionPane.
+   */
+  protected class ButtonActionListener implements ActionListener
+  {
+    /** The index of the option this button represents. */
+    protected int buttonIndex;
+
+    /**
+     * Creates a new ButtonActionListener object with the given buttonIndex.
+     *
+     * @param buttonIndex The index of the option this button represents.
+     */
+    public ButtonActionListener(int buttonIndex)
+    {
+      this.buttonIndex = buttonIndex;
+    }
+
+    /**
+     * This method is called when one of the option buttons are pressed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      Object value = new Integer(JOptionPane.CLOSED_OPTION);
+      Object[] options = optionPane.getOptions();
+      if (options != null)
+	value = new Integer(buttonIndex);
+      else
+        {
+	  String text = ((JButton) e.getSource()).getText();
+	  if (text.equals(OK_STRING))
+	    value = new Integer(JOptionPane.OK_OPTION);
+	  if (text.equals(CANCEL_STRING))
+	    value = new Integer(JOptionPane.CANCEL_OPTION);
+	  if (text.equals(YES_STRING))
+	    value = new Integer(JOptionPane.YES_OPTION);
+	  if (text.equals(NO_STRING))
+	    value = new Integer(JOptionPane.NO_OPTION);
+        }
+      optionPane.setValue(value);
+      resetInputValue();
+
+      Window owner = SwingUtilities.windowForComponent(optionPane);
+
+      if (owner instanceof JDialog)
+	((JDialog) owner).dispose();
+
+      //else we probably have some kind of internal frame.
+      JInternalFrame inf = (JInternalFrame) SwingUtilities.getAncestorOfClass(JInternalFrame.class,
+                                                                              optionPane);
+      if (inf != null)
+        {
+	  try
+	    {
+	      inf.setClosed(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+  }
 
-    BasicOptionPaneUI()
+  /**
+   * This helper layout manager is responsible for the layout of the button
+   * area. The button area is the panel that holds the buttons which
+   * represent the options.
+   */
+  protected class ButtonAreaLayout implements LayoutManager
+  {
+    /** Whether this layout will center the buttons. */
+    protected boolean centersChildren = true;
+
+    /** The space between the buttons. */
+    protected int padding;
+
+    /** Whether the buttons will share the same widths. */
+    protected boolean syncAllWidths;
+
+    /** The width of the widest button. */
+    private transient int widthOfWidestButton;
+
+    /** The height of the tallest button. */
+    private transient int tallestButton;
+
+    /**
+     * Creates a new ButtonAreaLayout object with the given sync widths
+     * property and padding.
+     *
+     * @param syncAllWidths Whether the buttons will share the same widths.
+     * @param padding The padding between the buttons.
+     */
+    public ButtonAreaLayout(boolean syncAllWidths, int padding)
     {
+      this.syncAllWidths = syncAllWidths;
+      this.padding = padding;
     }
 
-    public static ComponentUI createUI(JComponent x) 
+    /**
+     * This method is called when a component is added to the container.
+     *
+     * @param string The constraints string.
+     * @param comp The component added.
+     */
+    public void addLayoutComponent(String string, Component comp)
     {
-        return new BasicOptionPaneUI();
+      // Do nothing.
     }
 
-    public void installUI(JComponent c)
+    /**
+     * This method returns whether the children will be centered.
+     *
+     * @return Whether the children will be centered.
+     */
+    public boolean getCentersChildren()
     {
-	super.installUI(c);
-	pane = (JOptionPane)c;
+      return centersChildren;
+    }
 
-	System.out.println("     -------------: " + pane);
+    /**
+     * This method returns the amount of space between components.
+     *
+     * @return The amount of space between components.
+     */
+    public int getPadding()
+    {
+      return padding;
+    }
 
-	JLabel  message   = null;
-	JButton ok_button = new JButton("Ok");	
+    /**
+     * This method returns whether all components will share widths (set to
+     * largest width).
+     *
+     * @return Whether all components will share widths.
+     */
+    public boolean getSyncAllWidths()
+    {
+      return syncAllWidths;
+    }
 
-	ok_button.addActionListener(new ActionListener()
+    /**
+     * This method lays out the given container.
+     *
+     * @param container The container to lay out.
+     */
+    public void layoutContainer(Container container)
+    {
+      Component[] buttonList = container.getComponents();
+      int x = container.getInsets().left;
+      if (getCentersChildren())
+	x += (int) ((double) (container.getSize().width) / 2
+	- (double) (buttonRowLength(container)) / 2);
+      for (int i = 0; i < buttonList.length; i++)
+        {
+	  Dimension dims = buttonList[i].getPreferredSize();
+	  if (getSizeButtonsToSameWidth())
 	    {
-		public void actionPerformed(ActionEvent a)
-		{
-		    System.out.println("ACTION ---> " + a);
-		    //		    pane.dialog.dispose();
-
-		    if (pane.dialog.isModal())
-			{
-			    System.out.println("modal dialog !!");
-			    pane.dialog.setModal(false);
-			}
-		    pane.dialog.setVisible(false);
-		}
-	    });
-
-	Object[] options = null;
-	if (options != null)
+	      buttonList[i].setBounds(x, 0, widthOfWidestButton, dims.height);
+	      x += widthOfWidestButton + getPadding();
+	    }
+	  else
 	    {
-		for (int i=0; i<options.length; i++)
-		    {
-			Object o = options[i];
-			if (o != null)
-			    {
-				if (o instanceof String)
-				    {
-					String s = (String) o;
-					JLabel m = new JLabel(s);
-					pane.add(m);
-				    }
-				else if (o instanceof Component)
-				    {
-					Component com = (Component) o;
-					pane.add(com);
-				    }
-				else
-				    {
-					System.out.println("UNRECOGNIZED ARG: " + o);
-				    }
-			    }
-		    }
+	      buttonList[i].setBounds(x, 0, dims.width, dims.height);
+	      x += dims.width + getPadding();
 	    }
+        }
+    }
+
+    /**
+     * This method returns the width of the given container taking into
+     * consideration the padding and syncAllWidths.
+     *
+     * @param c The container to calculate width for.
+     *
+     * @return The width of the given container.
+     */
+    private int buttonRowLength(Container c)
+    {
+      Component[] buttonList = c.getComponents();
+
+      int buttonLength = 0;
+      int widest = 0;
+      int tallest = 0;
+
+      for (int i = 0; i < buttonList.length; i++)
+        {
+	  Dimension dims = buttonList[i].getPreferredSize();
+	  buttonLength += dims.width + getPadding();
+	  widest = Math.max(widest, dims.width);
+	  tallest = Math.max(tallest, dims.height);
+        }
+
+      widthOfWidestButton = widest;
+      tallestButton = tallest;
+
+      int width;
+      if (getSyncAllWidths())
+	width = widest * buttonList.length
+	        + getPadding() * (buttonList.length - 1);
+      else
+	width = buttonLength;
 
-	pane.add(message);
-	pane.add(ok_button);
+      Insets insets = c.getInsets();
+      width += insets.left + insets.right;
+
+      return width;
     }
 
-    Dimension getMinimumOptionPaneSize()
+    /**
+     * This method returns the minimum layout size for the given container.
+     *
+     * @param c The container to measure.
+     *
+     * @return The minimum layout size.
+     */
+    public Dimension minimumLayoutSize(Container c)
     {
-	return new Dimension(300,100);
+      return preferredLayoutSize(c);
     }
 
-    public Dimension getPreferredSize(JComponent c)
+    /**
+     * This method returns the preferred size of the given container.
+     *
+     * @param c The container to measure.
+     *
+     * @return The preferred size.
+     */
+    public Dimension preferredLayoutSize(Container c)
     {
-	if (c == null)
-	    return getMinimumOptionPaneSize();
+      int w = buttonRowLength(c);
 
-	if (c != pane)
-	    return null;
+      return new Dimension(w, tallestButton);
+    }
+
+    /**
+     * This method removes the given component from the layout manager's
+     * knowledge.
+     *
+     * @param c The component to remove.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+      // Do nothing.
+    }
 
-	LayoutManager l  = c.getLayout();
-	if (l == null)
-	    return getMinimumOptionPaneSize();
+    /**
+     * This method sets whether the children will be centered.
+     *
+     * @param newValue Whether the children will be centered.
+     */
+    public void setCentersChildren(boolean newValue)
+    {
+      centersChildren = newValue;
+      optionPane.invalidate();
+    }
 
-	Dimension d1 = l.preferredLayoutSize(c);
-	Dimension d2 = getMinimumOptionPaneSize();
-	
-	d1.width = Math.max(d1.width, d2.width);
-	d1.height = Math.max(d1.height, d2.height);
+    /**
+     * This method sets the amount of space between each component.
+     *
+     * @param newPadding The padding between components.
+     */
+    public void setPadding(int newPadding)
+    {
+      padding = newPadding;
+      optionPane.invalidate();
+    }
 
-	return d2;
+    /**
+     * This method sets whether the widths will be synced.
+     *
+     * @param newValue Whether the widths will be synced.
+     */
+    public void setSyncAllWidths(boolean newValue)
+    {
+      syncAllWidths = newValue;
+      optionPane.invalidate();
     }
+  }
 
-  public void selectInitialValue(JOptionPane op)
+  /**
+   * This helper class handles property change events from the JOptionPane.
+   */
+  public class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called when one of the properties of the JOptionPane
+     * changes.
+     *
+     * @param e The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JOptionPane.ICON_PROPERTY)
+          || e.getPropertyName().equals(JOptionPane.MESSAGE_TYPE_PROPERTY))
+	addIcon(messageAreaContainer);
+      else if (e.getPropertyName().equals(JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY))
+	resetSelectedValue();
+      else if (e.getPropertyName().equals(JOptionPane.INITIAL_VALUE_PROPERTY)
+               || e.getPropertyName().equals(JOptionPane.OPTIONS_PROPERTY)
+               || e.getPropertyName().equals(JOptionPane.OPTION_TYPE_PROPERTY))
+        {
+	  Container newButtons = createButtonArea();
+	  optionPane.remove(buttonContainer);
+	  optionPane.add(newButtons);
+	  buttonContainer = newButtons;
+        }
+
+      else if (e.getPropertyName().equals(JOptionPane.MESSAGE_PROPERTY)
+               || e.getPropertyName().equals(JOptionPane.WANTS_INPUT_PROPERTY)
+               || e.getPropertyName().equals(JOptionPane.SELECTION_VALUES_PROPERTY))
+        {
+	  optionPane.removeAll();
+	  messageAreaContainer = createMessageArea();
+	  optionPane.add(messageAreaContainer);
+	  optionPane.add(buttonContainer);
+        }
+      optionPane.invalidate();
+      optionPane.repaint();
+    }
+  }
+
+  /** Whether the JOptionPane contains custom components. */
+  protected boolean hasCustomComponents = false;
+
+  // The initialFocusComponent seems to always be set to a button (even if 
+  // I try to set initialSelectionValue). This is different from what the 
+  // javadocs state (which should switch this reference to the input component 
+  // if one is present since that is what's going to get focus). 
+
+  /**
+   * The button that will receive focus based on initialValue when no input
+   * component is present. If an input component is present, then the input
+   * component will receive focus instead.
+   */
+  protected Component initialFocusComponent;
+
+  /** The component that receives input when the JOptionPane needs it. */
+  protected JComponent inputComponent;
+
+  /** The minimum height of the JOptionPane. */
+  public static int minimumHeight;
+
+  /** The minimum width of the JOptionPane. */
+  public static int minimumWidth;
+
+  /** The minimum dimensions of the JOptionPane. */
+  protected Dimension minimumSize;
+
+  /** The propertyChangeListener for the JOptionPane. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The JOptionPane this UI delegate is used for. */
+  protected JOptionPane optionPane;
+
+  /** The size of the icons. */
+  private static int iconSize = 36;
+
+  /** The foreground color for the message area. */
+  private transient Color messageForeground;
+
+  /** The border around the message area. */
+  private transient Border messageBorder;
+
+  /** The border around the button area. */
+  private transient Border buttonBorder;
+
+  /** The string used to describe OK buttons. */
+  private static String OK_STRING = "OK";
+
+  /** The string used to describe Yes buttons. */
+  private static String YES_STRING = "Yes";
+
+  /** The string used to describe No buttons. */
+  private static String NO_STRING = "No";
+
+  /** The string used to describe Cancel buttons. */
+  private static String CANCEL_STRING = "Cancel";
+
+  /** The container for the message area. */
+  private transient Container messageAreaContainer;
+
+  /** The container for the buttons. */
+  private transient Container buttonContainer;
+
+  /**
+   * A helper class that implements Icon. This is used temporarily until
+   * ImageIcons are fixed.
+   */
+  private static class messageIcon implements Icon
+  {
+    /**
+     * This method returns the width of the icon.
+     *
+     * @return The width of the icon.
+     */
+    public int getIconWidth()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This method returns the height of the icon.
+     *
+     * @return The height of the icon.
+     */
+    public int getIconHeight()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This method paints the icon as a part of the given component using the
+     * given graphics and the given x and y position.
+     *
+     * @param c The component that owns this icon.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate.
+     * @param y The y coordinate.
+     */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+    }
+  }
+
+  /** The icon displayed for ERROR_MESSAGE. */
+  private static messageIcon errorIcon = new messageIcon()
+    {
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	Polygon oct = new Polygon(new int[] { 0, 0, 9, 27, 36, 36, 27, 9 },
+	                          new int[] { 9, 27, 36, 36, 27, 9, 0, 0 }, 8);
+	g.translate(x, y);
+
+	Color saved = g.getColor();
+	g.setColor(Color.RED);
+
+	g.fillPolygon(oct);
+
+	g.setColor(Color.BLACK);
+	g.drawRect(13, 16, 10, 4);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The icon displayed for INFORMATION_MESSAGE. */
+  private static messageIcon infoIcon = new messageIcon()
+    {
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+
+	// Should be purple.
+	g.setColor(Color.RED);
+
+	g.fillOval(0, 0, iconSize, iconSize);
+
+	g.setColor(Color.BLACK);
+	g.drawOval(16, 6, 4, 4);
+
+	Polygon bottomI = new Polygon(new int[] { 15, 15, 13, 13, 23, 23, 21, 21 },
+	                              new int[] { 12, 28, 28, 30, 30, 28, 28, 12 },
+	                              8);
+	g.drawPolygon(bottomI);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The icon displayed for WARNING_MESSAGE. */
+  private static messageIcon warningIcon = new messageIcon()
+    {
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.YELLOW);
+
+	Polygon triangle = new Polygon(new int[] { 0, 18, 36 },
+	                               new int[] { 36, 0, 36 }, 3);
+	g.fillPolygon(triangle);
+
+	g.setColor(Color.BLACK);
+
+	Polygon excl = new Polygon(new int[] { 15, 16, 20, 21 },
+	                           new int[] { 8, 26, 26, 8 }, 4);
+	g.drawPolygon(excl);
+	g.drawOval(16, 30, 4, 4);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The icon displayed for MESSAGE_ICON. */
+  private static messageIcon questionIcon = new messageIcon()
+    {
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.GREEN);
+
+	g.fillRect(0, 0, iconSize, iconSize);
+
+	g.setColor(Color.BLACK);
+
+	g.drawOval(11, 2, 16, 16);
+	g.drawOval(14, 5, 10, 10);
+
+	g.setColor(Color.GREEN);
+	g.fillRect(0, 10, iconSize, iconSize - 10);
+
+	g.setColor(Color.BLACK);
+
+	g.drawLine(11, 10, 14, 10);
+
+	g.drawLine(24, 10, 17, 22);
+	g.drawLine(27, 10, 20, 22);
+	g.drawLine(17, 22, 20, 22);
+
+	g.drawOval(17, 25, 3, 3);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  // FIXME: Uncomment when the ImageIcons are fixed.
+
+  /*  IconUIResource warningIcon, questionIcon, infoIcon, errorIcon;*/
+
+  /**
+   * Creates a new BasicOptionPaneUI object.
+   */
+  public BasicOptionPaneUI()
+  {
+  }
+
+  /**
+   * This method is messaged to add the buttons to the given container.
+   *
+   * @param container The container to add components to.
+   * @param buttons The buttons to add. (If it is an instance of component,
+   *        the Object is added directly. If it is an instance of Icon, it is
+   *        packed into a label and added. For all other cases, the string
+   *        representation of the Object is retreived and packed into a
+   *        label.)
+   * @param initialIndex The index of the component that is the initialValue.
+   */
+  protected void addButtonComponents(Container container, Object[] buttons,
+                                     int initialIndex)
+  {
+    if (buttons == null)
+      return;
+    for (int i = 0; i < buttons.length; i++)
+      {
+	if (buttons[i] != null)
+	  {
+	    Component toAdd;
+	    if (buttons[i] instanceof Component)
+	      toAdd = (Component) buttons[i];
+	    else
+	      {
+		if (buttons[i] instanceof Icon)
+		  toAdd = new JButton((Icon) buttons[i]);
+		else
+		  toAdd = new JButton(buttons[i].toString());
+		hasCustomComponents = true;
+	      }
+	    if (toAdd instanceof JButton)
+	      ((JButton) toAdd).addActionListener(createButtonActionListener(i));
+	    if (i == initialIndex)
+	      initialFocusComponent = toAdd;
+	    container.add(toAdd);
+	  }
+      }
+    selectInitialValue(optionPane);
+  }
+
+  /**
+   * This method adds the appropriate icon the given container.
+   *
+   * @param top The container to add an icon to.
+   */
+  protected void addIcon(Container top)
+  {
+    JLabel iconLabel = null;
+    Icon icon = getIcon();
+    if (icon != null)
+      {
+	iconLabel = new JLabel(icon);
+	top.add(iconLabel, BorderLayout.WEST);
+      }
+  }
+
+  /**
+   * A helper method that returns an instance of GridBagConstraints to be used
+   * for creating the message area.
+   *
+   * @return An instance of GridBagConstraints.
+   */
+  private static GridBagConstraints createConstraints()
+  {
+    GridBagConstraints constraints = new GridBagConstraints();
+    constraints.gridx = GridBagConstraints.REMAINDER;
+    constraints.gridy = GridBagConstraints.REMAINDER;
+    constraints.gridwidth = 0;
+    constraints.anchor = GridBagConstraints.LINE_START;
+    constraints.fill = GridBagConstraints.NONE;
+    constraints.insets = new Insets(0, 0, 3, 0);
+
+    return constraints;
+  }
+
+  /**
+   * This method creates the proper object (if necessary) to represent msg.
+   * (If msg is an instance of Component, it will add it directly. If it is
+   * an icon, then it will pack it in a label and add it. Otherwise, it gets
+   * treated as a string. If the string is longer than maxll, a box is
+   * created and the burstStringInto is called with the box as the container.
+   * The box is then added to the given container. Otherwise, the string is
+   * packed in a label and placed in the given container.) This method is
+   * also used for adding the inputComponent to the container.
+   *
+   * @param container The container to add to.
+   * @param cons The constraints when adding.
+   * @param msg The message to add.
+   * @param maxll The max line length.
+   * @param internallyCreated Whether the msg is internally created.
+   */
+  protected void addMessageComponents(Container container,
+                                      GridBagConstraints cons, Object msg,
+                                      int maxll, boolean internallyCreated)
+  {
+    if (msg == null)
+      return;
+    hasCustomComponents = internallyCreated;
+    if (msg instanceof Object[])
+      {
+	Object[] arr = (Object[]) msg;
+	for (int i = 0; i < arr.length; i++)
+	  addMessageComponents(container, cons, arr[i], maxll,
+	                       internallyCreated);
+	return;
+      }
+    else if (msg instanceof Component)
+      {
+	container.add((Component) msg, cons);
+	cons.gridy++;
+      }
+    else if (msg instanceof Icon)
+      {
+	container.add(new JLabel((Icon) msg), cons);
+	cons.gridy++;
+      }
+    else
+      {
+	// Undocumented behaviour.
+	// if msg.toString().length greater than maxll
+	// it will create a box and burst the string.
+	// otherwise, it will just create a label and re-call 
+	// this method with the label o.O
+	if (msg.toString().length() > maxll)
+	  {
+	    Box tmp = new Box(BoxLayout.Y_AXIS);
+	    burstStringInto(tmp, msg.toString(), maxll);
+	    addMessageComponents(container, cons, tmp, maxll, true);
+	  }
+	else
+	  addMessageComponents(container, cons, new JLabel(msg.toString()),
+	                       maxll, true);
+      }
+  }
+
+  /**
+   * This method creates instances of d (recursively if necessary based on
+   * maxll) and adds to c.
+   *
+   * @param c The container to add to.
+   * @param d The string to burst.
+   * @param maxll The max line length.
+   */
+  protected void burstStringInto(Container c, String d, int maxll)
   {
-     throw new Error ("Not implemented");
+    // FIXME: Verify that this is the correct behaviour.
+    // One interpretation of the spec is that this method
+    // should recursively call itself to create (and add) 
+    // JLabels to the container if the length of the String d
+    // is greater than maxll.
+    // but in practice, even with a really long string, this is 
+    // all that happens.
+    if (d == null || c == null)
+      return;
+    JLabel label = new JLabel(d);
+    c.add(label);
   }
 
+  /**
+   * This method returns true if the given JOptionPane contains custom
+   * components.
+   *
+   * @param op The JOptionPane to check.
+   *
+   * @return True if the JOptionPane contains custom components.
+   */
   public boolean containsCustomComponents(JOptionPane op)
   {
-     throw new Error ("Not implemented");
+    return hasCustomComponents;
+  }
+
+  /**
+   * This method creates a button action listener for the given button index.
+   *
+   * @param buttonIndex The index of the button in components.
+   *
+   * @return A new ButtonActionListener.
+   */
+  protected ActionListener createButtonActionListener(int buttonIndex)
+  {
+    return new ButtonActionListener(buttonIndex);
+  }
+
+  /**
+   * This method creates the button area.
+   *
+   * @return A new Button Area.
+   */
+  protected Container createButtonArea()
+  {
+    JPanel buttonPanel = new JPanel();
+
+    buttonPanel.setLayout(createLayoutManager());
+    addButtonComponents(buttonPanel, getButtons(), getInitialValueIndex());
+
+    return buttonPanel;
+  }
+
+  /**
+   * This method creates a new LayoutManager for the button area.
+   *
+   * @return A new LayoutManager for the button area.
+   */
+  protected LayoutManager createLayoutManager()
+  {
+    return new ButtonAreaLayout(getSizeButtonsToSameWidth(), 6);
+  }
+
+  /**
+   * This method creates the message area.
+   *
+   * @return A new message area.
+   */
+  protected Container createMessageArea()
+  {
+    JPanel messageArea = new JPanel();
+    messageArea.setLayout(new BorderLayout());
+    addIcon(messageArea);
+
+    JPanel rightSide = new JPanel()
+    {
+    public Dimension getPreferredSize()
+    {
+	  int w = Math.max(optionPane.getSize().width, minimumWidth);
+      Insets i = optionPane.getInsets();
+      Dimension orig = super.getPreferredSize();
+      Dimension value = new Dimension(w - i.left - i.right - iconSize,
+                                      orig.height);
+      return value;
+    }
+    };    
+    rightSide.setLayout(new GridBagLayout());
+    GridBagConstraints con = createConstraints();
+
+    addMessageComponents(rightSide, con, getMessage(),
+                         getMaxCharactersPerLineCount(), false);
+
+    if (optionPane.getWantsInput())
+      {
+	Object[] selection = optionPane.getSelectionValues();
+
+//	if (selection == null)
+//	  inputComponent = new JTextField();
+//	else if (selection.length < 20)
+//	  inputComponent = new JComboBox(selection);
+	// FIXME: Uncomment when the widgets are done.
+	if (selection == null)
+	  inputComponent = null;
+	else
+	  inputComponent = new JList(selection);
+	if (inputComponent != null)
+	  {
+	    addMessageComponents(rightSide, con, inputComponent,
+	                         getMaxCharactersPerLineCount(), true);
+	    resetSelectedValue();
+	    selectInitialValue(optionPane);
+	  }
+      }
+
+    messageArea.add(rightSide, BorderLayout.EAST);
+
+    return messageArea;
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener for listening to the
+   * JOptionPane.
+   *
+   * @return A new PropertyChangeListener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method creates a Container that will separate the message and button
+   * areas.
+   *
+   * @return A Container that will separate the message and button areas.
+   */
+  protected Container createSeparator()
+  {
+    return null;
+  }
+
+  /**
+   * This method creates a new BasicOptionPaneUI for the given component.
+   *
+   * @param x The component to create a UI for.
+   *
+   * @return A new BasicOptionPaneUI.
+   */
+  public static ComponentUI createUI(JComponent x)
+  {
+    return new BasicOptionPaneUI();
+  }
+
+  /**
+   * This method returns the buttons for the JOptionPane. If no options are
+   * set, a set of options will be created based upon the optionType.
+   *
+   * @return The buttons that will be added.
+   */
+  protected Object[] getButtons()
+  {
+    if (optionPane.getOptions() != null)
+      return optionPane.getOptions();
+    switch (optionPane.getOptionType())
+      {
+      case JOptionPane.YES_NO_OPTION:
+	return new Object[] { YES_STRING, NO_STRING };
+      case JOptionPane.YES_NO_CANCEL_OPTION:
+	return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING };
+      case JOptionPane.OK_CANCEL_OPTION:
+      case JOptionPane.DEFAULT_OPTION:
+	return new Object[] { OK_STRING, CANCEL_STRING };
+      }
+    return null;
+  }
+
+  /**
+   * This method will return the icon the user has set or the icon that will
+   * be used based on message type.
+   *
+   * @return The icon to use in the JOptionPane.
+   */
+  protected Icon getIcon()
+  {
+    if (optionPane.getIcon() != null)
+      return optionPane.getIcon();
+    else
+      return getIconForType(optionPane.getMessageType());
+  }
+
+  /**
+   * This method returns the icon for the given messageType.
+   *
+   * @param messageType The type of message.
+   *
+   * @return The icon for the given messageType.
+   */
+  protected Icon getIconForType(int messageType)
+  {
+    Icon tmp = null;
+    switch (messageType)
+      {
+      case JOptionPane.ERROR_MESSAGE:
+	tmp = errorIcon;
+	break;
+      case JOptionPane.INFORMATION_MESSAGE:
+	tmp = infoIcon;
+	break;
+      case JOptionPane.WARNING_MESSAGE:
+	tmp = warningIcon;
+	break;
+      case JOptionPane.QUESTION_MESSAGE:
+	tmp = questionIcon;
+	break;
+      }
+    return tmp;
+    // FIXME: Don't cast till the default icons are in.
+    // return new IconUIResource(tmp);
+  }
+
+  /**
+   * This method returns the index of the initialValue in the options array.
+   *
+   * @return The index of the initalValue.
+   */
+  protected int getInitialValueIndex()
+  {
+    Object[] buttons = getButtons();
+
+    if (buttons == null)
+      return -1;
+
+    Object select = optionPane.getInitialValue();
+
+    for (int i = 0; i < buttons.length; i++)
+      {
+	if (select == buttons[i])
+	  return i;
+      }
+    return 0;
+  }
+
+  /**
+   * This method returns the maximum number of characters that should be
+   * placed on a line.
+   *
+   * @return The maximum number of characteres that should be placed on a
+   *         line.
+   */
+  protected int getMaxCharactersPerLineCount()
+  {
+    return optionPane.getMaxCharactersPerLineCount();
+  }
+
+  /**
+   * This method returns the maximum size.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the message of the JOptionPane.
+   *
+   * @return The message.
+   */
+  protected Object getMessage()
+  {
+    return optionPane.getMessage();
+  }
+
+  /**
+   * This method returns the minimum size of the JOptionPane.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumOptionPaneSize()
+  {
+    return minimumSize;
+  }
+
+  /**
+   * This method returns the minimum size.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the preferred size of the JOptionPane. The preferred
+   * size is the maximum of the size desired by the layout and the minimum
+   * size.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    Dimension d = optionPane.getLayout().preferredLayoutSize(optionPane);
+    Dimension d2 = getMinimumOptionPaneSize();
+
+    int w = Math.max(d.width, d2.width);
+    int h = Math.max(d.height, d2.height);
+    return new Dimension(w, h);
+  }
+
+  /**
+   * This method returns whether all buttons should have the same width.
+   *
+   * @return Whether all buttons should have the same width.
+   */
+  protected boolean getSizeButtonsToSameWidth()
+  {
+    return true;
+  }
+
+  /**
+   * This method installs components for the JOptionPane.
+   */
+  protected void installComponents()
+  {
+    // reset it.
+    hasCustomComponents = false;
+    Container msg = createMessageArea();
+    if (msg != null)
+      {
+	((JComponent) msg).setBorder(messageBorder);
+	msg.setForeground(messageForeground);
+	messageAreaContainer = msg;
+	optionPane.add(msg);
+      }
+
+    Container sep = createSeparator();
+    if (sep != null)
+      optionPane.add(sep);
+
+    Container button = createButtonArea();
+    if (button != null)
+      {
+	((JComponent) button).setBorder(buttonBorder);
+	buttonContainer = button;
+	optionPane.add(button);
+      }
+
+    optionPane.invalidate();
+  }
+
+  /**
+   * This method installs defaults for the JOptionPane.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    optionPane.setFont(defaults.getFont("OptionPane.font"));
+    optionPane.setBackground(defaults.getColor("OptionPane.background"));
+    optionPane.setForeground(defaults.getColor("OptionPane.foreground"));
+    optionPane.setBorder(defaults.getBorder("OptionPane.border"));
+
+    messageBorder = defaults.getBorder("OptionPane.messageAreaBorder");
+    messageForeground = defaults.getColor("OptionPane.messageForeground");
+    buttonBorder = defaults.getBorder("OptionPane.buttonAreaBorder");
+
+    minimumSize = defaults.getDimension("OptionPane.minimumSize");
+    minimumWidth = minimumSize.width;
+    minimumHeight = minimumSize.height;
+
+    // FIXME: Image icons don't seem to work properly right now.
+    // Once they do, replace the synthetic icons with these ones.
+
+    /*
+    warningIcon = (IconUIResource) defaults.getIcon("OptionPane.warningIcon");
+    infoIcon = (IconUIResource) defaults.getIcon("OptionPane.informationIcon");
+    errorIcon = (IconUIResource) defaults.getIcon("OptionPane.errorIcon");
+    questionIcon = (IconUIResource) defaults.getIcon("OptionPane.questionIcon");
+    */
+  }
+
+  /**
+   * This method installs keyboard actions for the JOptionpane.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: implement.
+  }
+
+  /**
+   * This method installs listeners for the JOptionPane.
+   */
+  protected void installListeners()
+  {
+    propertyChangeListener = createPropertyChangeListener();
+
+    optionPane.addPropertyChangeListener(propertyChangeListener);
+  }
+
+  /**
+   * This method installs the UI for the JOptionPane.
+   *
+   * @param c The JComponent to install the UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JOptionPane)
+      {
+	optionPane = (JOptionPane) c;
+
+	installDefaults();
+	installComponents();
+	installListeners();
+	installKeyboardActions();
+      }
+  }
+
+  /**
+   * Changes the inputValue property in the JOptionPane based on the current
+   * value of the inputComponent.
+   */
+  protected void resetInputValue()
+  {
+    if (optionPane.getWantsInput() && inputComponent != null)
+      {
+	Object output = null;
+	if (inputComponent instanceof JTextField)
+	  output = ((JTextField) inputComponent).getText();
+	else if (inputComponent instanceof JComboBox)
+	  output = ((JComboBox) inputComponent).getSelectedItem();
+	else if (inputComponent instanceof JList)
+	  output = ((JList) inputComponent).getSelectedValue();
+
+	if (output != null)
+	  optionPane.setInputValue(output);
+      }
+  }
+
+  /**
+   * This method requests focus to the inputComponent (if one is present) and
+   * the initialFocusComponent otherwise.
+   *
+   * @param op The JOptionPane.
+   */
+  public void selectInitialValue(JOptionPane op)
+  {
+    if (inputComponent != null)
+      {
+	inputComponent.requestFocus();
+	return;
+      }
+    if (initialFocusComponent != null)
+      initialFocusComponent.requestFocus();
+  }
+
+  /**
+   * This method resets the value in the inputComponent to the
+   * initialSelectionValue property.
+   */
+  private void resetSelectedValue()
+  {
+    if (inputComponent != null)
+      {
+	Object init = optionPane.getInitialSelectionValue();
+	if (init == null)
+	  return;
+	if (inputComponent instanceof JTextField)
+	  ((JTextField) inputComponent).setText((String) init);
+	else if (inputComponent instanceof JComboBox)
+	  ((JComboBox) inputComponent).setSelectedItem(init);
+	else if (inputComponent instanceof JList)
+	  {
+	    //  ((JList) inputComponent).setSelectedValue(init, true);
+	  }
+      }
+  }
+
+  /**
+   * This method uninstalls all the components in the JOptionPane.
+   */
+  protected void uninstallComponents()
+  {
+    optionPane.removeAll();
+    buttonContainer = null;
+    messageAreaContainer = null;
+  }
+
+  /**
+   * This method uninstalls the defaults for the JOptionPane.
+   */
+  protected void uninstallDefaults()
+  {
+    optionPane.setFont(null);
+    optionPane.setForeground(null);
+    optionPane.setBackground(null);
+
+    minimumSize = null;
+
+    messageBorder = null;
+    buttonBorder = null;
+    messageForeground = null;
+
+    // FIXME: ImageIcons don't seem to work properly
+
+    /*
+    warningIcon = null;
+    errorIcon = null;
+    questionIcon = null;
+    infoIcon = null;
+    */
+  }
+
+  /**
+   * This method uninstalls keyboard actions for the JOptionPane.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: implement.
+  }
+
+  /**
+   * This method uninstalls listeners for the JOptionPane.
+   */
+  protected void uninstallListeners()
+  {
+    optionPane.removePropertyChangeListener(propertyChangeListener);
+    propertyChangeListener = null;
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent.
+   *
+   * @param c The JComponent to uninstall for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallComponents();
+    uninstallDefaults();
+
+    optionPane = null;
   }
 }
Index: javax/swing/plaf/basic/BasicPanelUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicPanelUI.java,v
retrieving revision 1.3
diff -u -r1.3 BasicPanelUI.java
--- javax/swing/plaf/basic/BasicPanelUI.java	10 Jan 2004 21:59:30 -0000	1.3
+++ javax/swing/plaf/basic/BasicPanelUI.java	6 Sep 2004 16:36:06 -0000
@@ -44,8 +44,6 @@
 
 public class BasicPanelUI extends PanelUI
 {
-    int gap = 3;
-
     public static ComponentUI createUI(JComponent x) 
     {
         return new BasicPanelUI();
@@ -53,6 +51,6 @@
 
     public void installUI(JComponent c)
     {
-	super.installUI(c);
+      super.installUI(c);
     }
 }
Index: javax/swing/plaf/basic/BasicPasswordFieldUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicPasswordFieldUI.java
diff -N javax/swing/plaf/basic/BasicPasswordFieldUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicPasswordFieldUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,61 @@
+/* BasicPasswordFieldUI.java
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.plaf.basic;
+
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+
+public class BasicPasswordFieldUI extends BasicTextFieldUI
+{
+  public BasicPasswordFieldUI()
+  {
+  }
+
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicPasswordFieldUI();
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "PasswordField";
+  }
+}
Index: javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java
diff -N javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,118 @@
+/* BasicPopupMenuSeparatorUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.SeparatorUI;
+
+
+/**
+ * The Basic Look and Feel UI delegate for JPopupMenu.Separator.
+ */
+public class BasicPopupMenuSeparatorUI extends BasicSeparatorUI
+{
+  /**
+   * Creates a new BasicPopupMenuSeparatorUI object.
+   */
+  public BasicPopupMenuSeparatorUI()
+  {
+    super();
+  }
+
+  /**
+   * Creates a new UI delegate for the given JComponent.
+   *
+   * @param c The JComponent to create a delegate for.
+   *
+   * @return A new BasicPopupMenuSeparatorUI
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicPopupMenuSeparatorUI();
+  }
+
+  /**
+   * The Popup Menu Separator has two lines. The top line will be
+   * painted using highlight color and the bottom using shadow color.
+   *
+   * @param g The Graphics object to paint with
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    if (! (c instanceof JPopupMenu.Separator))
+      return;
+
+    Rectangle r = new Rectangle();
+    SwingUtilities.calculateInnerArea(c, r);
+    Color saved = g.getColor();
+
+    int midAB = r.width / 2 + r.x;
+    int midAD = r.height / 2 + r.y;
+
+    g.setColor(highlight);
+    g.drawLine(r.x, midAD, r.x + r.width, midAD);
+
+    g.setColor(shadow);
+    g.drawLine(r.x, midAD + 1, r.x + r.width, midAD + 1);
+  }
+
+  /**
+    * This method returns the preferred size of the
+    * JComponent.
+    *
+    * @param c The JComponent to measure.
+    *
+    * @return The preferred size.
+    */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return super.getPreferredSize(c);
+  }
+}
Index: javax/swing/plaf/basic/BasicPopupMenuUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicPopupMenuUI.java
diff -N javax/swing/plaf/basic/BasicPopupMenuUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicPopupMenuUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,433 @@
+/* BasicPopupMenuUI.java
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.AWTKeyStroke;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Stroke;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.EventListener;
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.KeyStroke;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.MouseInputListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.MenuItemUI;
+import javax.swing.plaf.PopupMenuUI;
+
+
+/**
+ * UI Delegate for JPopupMenu
+ */
+public class BasicPopupMenuUI extends PopupMenuUI
+{
+  /* popupMenu for which this UI delegate is for*/
+  protected JPopupMenu popupMenu;
+
+  /* MouseInputListener listens to mouse events */
+  private static transient MouseInputListener mouseInputListener;
+
+  /* PopupMenuListener listens to popup menu events fired by JPopupMenu*/
+  private transient PopupMenuListener popupMenuListener;
+
+  /* ComponentListener listening to popupMenu's invoker. */
+  private TopWindowListener topWindowListener;
+
+  /**
+   * Creates a new BasicPopupMenuUI object.
+   */
+  public BasicPopupMenuUI()
+  {
+    popupMenuListener = new PopupMenuHandler();
+    mouseInputListener = new MouseInputHandler();
+    topWindowListener = new TopWindowListener();
+  }
+
+  /**
+   * Factory method to create a BasicPopupMenuUI for the given {@link
+   * JComponent}, which should be a {@link JMenuItem}.
+   *
+   * @param x The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicPopupMenuUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent x)
+  {
+    return new BasicPopupMenuUI();
+  }
+
+  /**
+   * Installs and initializes all fields for this UI delegate. Any properties
+   * of the UI that need to be initialized and/or set to defaults will be
+   * done now. It will also install any listeners necessary.
+   *
+   * @param c The {@link JComponent} that is having this UI installed.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    popupMenu = (JPopupMenu) c;
+    popupMenu.setLayout(new GridBagLayout());
+    popupMenu.setBorderPainted(true);
+    JPopupMenu.setDefaultLightWeightPopupEnabled(true);
+
+    installDefaults();
+    installListeners();
+  }
+
+  /**
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this {@link JPopupMenu}.
+   */
+  public void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    popupMenu.setBackground(defaults.getColor("PopupMenu.background"));
+    popupMenu.setBorder(defaults.getBorder("PopupMenu.border"));
+    popupMenu.setFont(defaults.getFont("PopupMenu.font"));
+    popupMenu.setForeground(defaults.getColor("PopupMenu.foreground"));
+    popupMenu.setOpaque(true);
+  }
+
+  /**
+   * This method installs the listeners for the {@link JMenuItem}.
+   */
+  protected void installListeners()
+  {
+    popupMenu.addMouseListener(mouseInputListener);
+    popupMenu.addMouseMotionListener(mouseInputListener);
+    popupMenu.addPopupMenuListener(popupMenuListener);
+  }
+
+  /**
+   * This method installs the keyboard actions for this {@link JPopupMenu}.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * Performs the opposite of installUI. Any properties or resources that need
+   * to be cleaned up will be done now. It will also uninstall any listeners
+   * it has. In addition, any properties of this UI will be nulled.
+   *
+   * @param c The {@link JComponent} that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallListeners();
+    uninstallDefaults();
+    popupMenu = null;
+  }
+
+  /**
+   * This method uninstalls the defaults and sets any objects created during
+   * install to null
+   */
+  protected void uninstallDefaults()
+  {
+    popupMenu.setBackground(null);
+    popupMenu.setBorder(null);
+    popupMenu.setFont(null);
+    popupMenu.setForeground(null);
+  }
+
+  /**
+   * Unregisters all the listeners that this UI delegate was using.
+   */
+  protected void uninstallListeners()
+  {
+    popupMenu.removeMouseListener(mouseInputListener);
+    popupMenu.removeMouseMotionListener(mouseInputListener);
+    popupMenu.removePopupMenuListener(popupMenuListener);
+  }
+
+  /**
+   * Uninstalls any keyboard actions.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Need to implement
+  }
+
+  /**
+   * This method returns the minimum size of the JPopupMenu.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the preferred size of the JPopupMenu.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the minimum size of the JPopupMenu.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return null;
+  }
+
+  /**
+   * Return true if given mouse event is a platform popup trigger, and false
+   * otherwise
+   *
+   * @param e MouseEvent that is to be checked for popup trigger event
+   *
+   * @return true if given mouse event is a platform popup trigger, and false
+   *         otherwise
+   */
+  public boolean isPopupTrigger(MouseEvent e)
+  {
+    return false;
+  }
+
+  /**
+   * This listener handles PopupMenuEvents fired by JPopupMenu
+   */
+  private class PopupMenuHandler implements PopupMenuListener
+  {
+    /**
+     * This method is invoked when JPopupMenu is cancelled.
+     *
+     * @param event the PopupMenuEvent
+     */
+    public void popupMenuCanceled(PopupMenuEvent event)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+
+    /**
+     * This method is invoked when JPopupMenu becomes invisible
+     *
+     * @param event the PopupMenuEvent
+     */
+    public void popupMenuWillBecomeInvisible(PopupMenuEvent event)
+    {
+      // remove listener that listens to component events fired 
+      // by the top - level window that this popup belongs to.
+      Component invoker = popupMenu.getInvoker();
+
+      Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
+      rootContainer.removeComponentListener(topWindowListener);
+    }
+
+    /**
+     * This method is invoked when JPopupMenu becomes visible
+     *
+     * @param event the PopupMenuEvent
+     */
+    public void popupMenuWillBecomeVisible(PopupMenuEvent event)
+    {
+      // Adds topWindowListener to top-level window to listener to 
+      // ComponentEvents fired by it. We need to cancel this popup menu
+      // if topWindow to which this popup belongs was resized or moved.
+      Component invoker = popupMenu.getInvoker();
+      Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
+      rootContainer.addComponentListener(topWindowListener);
+
+      // if this popup menu is a free floating popup menu,
+      // then by default its first element should be always selected when
+      // this popup menu becomes visible. 
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+
+      if (manager.getSelectedPath().length == 0)
+        {
+	  // Set selected path to point to the first item in the popup menu
+	  MenuElement[] path = new MenuElement[2];
+	  path[0] = popupMenu;
+	  Component[] comps = popupMenu.getComponents();
+	  if (comps.length != 0 && comps[0] instanceof MenuElement)
+	    {
+	      path[1] = (MenuElement) comps[0];
+	      manager.setSelectedPath(path);
+	    }
+        }
+    }
+  }
+
+  /**
+   * ComponentListener that listens to Component Events fired by the top -
+   * level window to which popup menu belongs. If top-level window was
+   * resized, moved or hidded then popup menu will be hidded and selected
+   * path of current menu hierarchy will be set to null.
+   */
+  private class TopWindowListener implements ComponentListener
+  {
+    /**
+     * This method is invoked when top-level window is resized. This method
+     * closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentResized(ComponentEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+
+    /**
+     * This method is invoked when top-level window is moved. This method
+     * closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentMoved(ComponentEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+
+    /**
+     * This method is invoked when top-level window is shown This method does
+     * nothing by default.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentShown(ComponentEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+
+    /**
+     * This method is invoked when top-level window is hidden This method
+     * closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentHidden(ComponentEvent e)
+    {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+      manager.clearSelectedPath();
+    }
+  }
+
+  private class MouseInputHandler implements MouseInputListener
+  {
+    public void mouseClicked(MouseEvent e)
+    {
+    }
+
+    public void mouseDragged(MouseEvent e)
+    {
+    }
+
+    public void mouseEntered(MouseEvent e)
+    {
+    }
+
+    public void mouseExited(MouseEvent e)
+    {
+    }
+
+    public void mouseMoved(MouseEvent e)
+    {
+    }
+
+    public void mousePressed(MouseEvent e)
+    {
+    }
+
+    public void mouseReleased(MouseEvent e)
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicProgressBarUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicProgressBarUI.java
diff -N javax/swing/plaf/basic/BasicProgressBarUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicProgressBarUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,824 @@
+/* BasicProgressBarUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JComponent;
+import javax.swing.JProgressBar;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.ProgressBarUI;
+
+
+/**
+ * The Basic Look and Feel UI delegate for the 
+ * JProgressBar.
+ */
+public class BasicProgressBarUI extends ProgressBarUI
+{
+  /**
+   * A helper class that listens for ChangeEvents 
+   * from the progressBar's model.
+   */
+  protected class ChangeHandler implements ChangeListener
+  {
+    /**
+     * Called every time the state of the model changes.
+     *
+     * @param e The ChangeEvent given by the model.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      // Nothing to do but repaint.
+      progressBar.repaint();
+    }
+  }
+
+  /**
+   * This helper class is used to listen for 
+   * PropertyChangeEvents from the progressBar.
+   */
+  private class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * Called every time the properties of the 
+     * progressBar change.
+     *
+     * @param e The PropertyChangeEvent given by the progressBar.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      // Only need to listen for indeterminate changes.
+      // All other things are done on a repaint.
+      if (e.getPropertyName().equals(JProgressBar.INDETERMINATE_CHANGED_PROPERTY))
+	if (((Boolean) e.getNewValue()).booleanValue())
+	  startAnimationTimer();
+	else
+	  stopAnimationTimer();
+      else
+        progressBar.repaint();
+    }
+  }
+
+  /**
+   * This helper class is used to listen for 
+   * the animationTimer's intervals. On every interval,
+   * the bouncing box should move.
+   */
+  private class Animator implements ActionListener
+  {
+    /**
+     * Called every time the animationTimer reaches
+     * its interval.
+     *
+     * @param e The ActionEvent given by the timer.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      // Incrementing the animation index will cause
+      // a repaint.
+      incrementAnimationIndex();
+    }
+  }
+
+  /** The timer used to move the bouncing box. */
+  private transient Timer animationTimer;
+
+  // The total number of frames must be an even number.
+  // The total number of frames is calculated from
+  // the cycleTime and repaintInterval given by
+  // the basic Look and Feel defaults.
+  //
+  // +-----------------------------------------------+
+  // | frame0 | frame1 | frame2 | frame 3 | frame 4  |
+  // |        | frame7 | frame6 | frame 5 |          |
+  // +-----------------------------------------------+
+  
+  /** The current animation index. */
+  private transient int animationIndex;
+
+  /** The total number of frames.*/
+  private transient int numFrames;
+
+  /** The helper that moves the bouncing box. */
+  private transient Animator animation;
+
+  /** The helper that listens for property change events. */
+  private transient PropertyChangeHandler propertyListener;
+
+  /** The Listener for the model. */
+  protected ChangeListener changeListener;
+
+  /** The progressBar for this UI. */
+  protected JProgressBar progressBar;
+
+  /** The length of the cell. The cell is the painted part. */
+  private transient int cellLength;
+
+  /** The gap between cells. */
+  private transient int cellSpacing;
+
+  /** The color of the text when the bar is not over it.*/
+  private transient Color selectionBackground;
+
+  /** The color of the text when the bar is over it. */
+  private transient Color selectionForeground;
+
+  /**
+   * Creates a new BasicProgressBarUI object.
+   */
+  public BasicProgressBarUI()
+  {
+    super();
+  }
+
+  /**
+   * Creates a new BasicProgressBarUI for the component.
+   *
+   * @param x The JComponent to create the UI for.
+   *
+   * @return A new BasicProgressBarUI.
+   */
+  public static ComponentUI createUI(JComponent x)
+  {
+    return new BasicProgressBarUI();
+  }
+
+  /**
+   * This method returns the length of the bar (from the minimum)
+   * in pixels (or units that the Graphics object draws in) based
+   * on the progressBar's getPercentComplete() value.
+   *
+   * @param b The insets of the progressBar.
+   * @param width The width of the progressBar.
+   * @param height The height of the progressBar.
+   *
+   * @return The length of the bar that should be painted in pixels.
+   */
+  protected int getAmountFull(Insets b, int width, int height)
+  {
+    double percentDone = progressBar.getPercentComplete();
+    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
+      return (int) (percentDone * (width - b.left - b.right));
+    else
+      return (int) (percentDone * (height - b.top - b.bottom));
+  }
+
+  /**
+   * The current animation index.
+   *
+   * @return The current animation index.
+   */
+  protected int getAnimationIndex()
+  {
+    return animationIndex;
+  }
+
+  /**
+   * This method returns the size and position of the bouncing box
+   * for the current animation index. It stores the values in the 
+   * given rectangle and returns it. It returns null if no box should
+   * be drawn.
+   *
+   * @param r The bouncing box rectangle.
+   *
+   * @return The bouncing box rectangle.
+   */
+  protected Rectangle getBox(Rectangle r)
+  {
+    if (!progressBar.isIndeterminate())
+      return null;
+    //numFrames has to be an even number as defined by spec.
+    int iterations = numFrames / 2 + 1;
+
+    double boxDependent;
+    double boxIndependent;
+
+    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
+      {
+	Dimension dims = getPreferredInnerHorizontal();
+	boxDependent = (double) dims.width / iterations;
+	boxIndependent = dims.height;
+      }
+    else
+      {
+	Dimension dims = getPreferredInnerVertical();
+	boxDependent = (double) dims.height / iterations;
+	boxIndependent = dims.width;
+      }
+
+    Rectangle vr = new Rectangle();
+    SwingUtilities.calculateInnerArea(progressBar, vr);
+
+    int index = getAnimationIndex();
+    if (animationIndex > (numFrames + 1) / 2)
+      index = numFrames - getAnimationIndex();
+
+    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
+      {
+	r.x = vr.x + (int) (index * boxDependent);
+	r.y = vr.y;
+	r.width = (int) boxDependent;
+	r.height = (int) boxIndependent;
+      }
+    else
+      {
+	index++;
+	r.x = vr.x;
+	r.y = vr.height - (int) (index * boxDependent) + vr.y;
+	r.width = (int) boxIndependent;
+	r.height = (int) boxDependent;
+      }
+
+    return r;
+  }
+
+  /**
+   * This method returns the length of the cells.
+   *
+   * @return The cell length.
+   */
+  protected int getCellLength()
+  {
+    return cellLength;
+  }
+
+  /**
+   * This method returns the spacing between cells.
+   *
+   * @return The cell gap.
+   */
+  protected int getCellSpacing()
+  {
+    return cellSpacing;
+  }
+
+  /**
+   * This method returns the maximum size of the JComponent.
+   * If it returns null, it is up to the LayoutManager
+   * to give it a size.
+   *
+   * @param c The component to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the minimum size of the JComponent.
+   * If it returns null, it is up to the LayoutManager to
+   * give it a size.
+   *
+   * @param c The component to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the preferred size of the inner
+   * rectangle (the bounds without the insets) if the
+   * progressBar is horizontal.
+   *
+   * @return The preferred size of the progressBar minus 
+   *         insets if it's horizontal.
+   */
+  protected Dimension getPreferredInnerHorizontal()
+  {
+    Rectangle vr = new Rectangle();
+
+    SwingUtilities.calculateInnerArea(progressBar, vr);
+
+    return new Dimension(vr.width, vr.height);
+  }
+
+  /**
+   * This method returns the preferred size of the inner
+   * rectangle (the bounds without insets) if the 
+   * progressBar is vertical.
+   *
+   * @return The preferred size of the progressBar minus
+   *         insets if it's vertical.
+   */
+  protected Dimension getPreferredInnerVertical()
+  {
+    Rectangle vr = new Rectangle();
+
+    SwingUtilities.calculateInnerArea(progressBar, vr);
+
+    return new Dimension(vr.width, vr.height);
+  }
+
+  /**
+   * This method returns the preferred size of the 
+   * given JComponent. If it returns null, then it
+   * is up to the LayoutManager to give it a size.
+   *
+   * @param c The component to find the preferred size for.
+   *
+   * @return The preferred size of the component.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    // The only thing we need to worry about is
+    // the text size.
+    Graphics g = progressBar.getGraphics();
+
+    Insets insets = c.getInsets();
+
+    FontMetrics fm = g.getFontMetrics(c.getFont());
+
+    int textW = fm.stringWidth(progressBar.getString());
+    int textH = fm.getHeight();
+
+    g.dispose();
+
+    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
+      {
+	if (textH < 20)
+	  textH = 20;
+	if (textW < 200)
+	  textW = 200;
+      }
+    else
+      {
+	if (textH < 200)
+	  textH = 200;
+	if (textW < 20)
+	  textW = 20;
+      }
+    textW += insets.left + insets.right;
+    textH += insets.top + insets.bottom;
+    return new Dimension(textW, textH);
+  }
+
+  /**
+   * This method returns the Color that the text is shown in when the bar is
+   * not over the text.
+   *
+   * @return The color of the text when the bar is not over it.
+   */
+  protected Color getSelectionBackground()
+  {
+    return selectionBackground;
+  }
+
+  /**
+   * This method returns the Color that the text is shown in  when the bar is
+   * over the text.
+   *
+   * @return The color of the text when the bar is over it.
+   */
+  protected Color getSelectionForeground()
+  {
+    return selectionForeground;
+  }
+
+  /**
+   * This method returns the point (the top left of the bounding box)
+   * where the text should be painted. 
+   *
+   * @param g The Graphics object to measure FontMetrics with.
+   * @param progressString The string to paint.
+   * @param x The x coordinate of the overall bounds box.
+   * @param y The y coordinate of the overall bounds box.
+   * @param width The width of the overall bounds box.
+   * @param height The height of the overall bounds box.
+   *
+   * @return The top left of the bounding box where text should be painted.
+   */
+  protected Point getStringPlacement(Graphics g, String progressString, int x,
+                                     int y, int width, int height)
+  {
+    Rectangle tr = new Rectangle();
+    Rectangle vr = new Rectangle(x, y, width, height);
+    Rectangle ir = new Rectangle();
+
+    Font f = g.getFont();
+    FontMetrics fm = g.getFontMetrics(f);
+
+    SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER, vr, ir, tr, 0);
+    return new Point(tr.x, tr.y);
+  }
+
+  /**
+   * This method increments the animation index.
+   */
+  public void incrementAnimationIndex()
+  {
+    animationIndex++;
+    //numFrames is like string length, it should be named numFrames or something
+    if (animationIndex >= numFrames)
+      animationIndex = 0;
+    progressBar.repaint();
+  }
+
+  /**
+   * This method paints the progressBar. It delegates its responsibilities
+   * to paintDeterminate and paintIndeterminate.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    if (! progressBar.isIndeterminate())
+      paintDeterminate(g, c);
+    else
+      paintIndeterminate(g, c);
+      
+    if (progressBar.isBorderPainted())
+      progressBar.getBorder().paintBorder(progressBar, g, 0, 0,
+                                          progressBar.getWidth(),
+					  progressBar.getHeight());
+  }
+
+  /**
+   * This method is called if the painting to be done is 
+   * for a determinate progressBar.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  protected void paintDeterminate(Graphics g, JComponent c)
+  {
+    Color saved = g.getColor();
+    int space = getCellSpacing();
+    int len = getCellLength();
+    int max = progressBar.getMaximum();
+    int min = progressBar.getMinimum();
+    int value = progressBar.getValue();
+
+    Rectangle vr = new Rectangle();
+    SwingUtilities.calculateInnerArea(c, vr);
+
+    Rectangle or = c.getBounds();
+
+    Insets insets = c.getInsets();
+
+    int amountFull = getAmountFull(insets, or.width, or.height);
+
+    g.setColor(c.getBackground());
+    g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
+
+    if (max != min && len != 0 && value > min)
+      {
+	int iterations = value / (space + len);
+
+	if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
+	  {
+	    double spaceInUnits = space * (double) vr.width / (max - min);
+	    double lenInUnits = len * (double) vr.width / (max - min);
+	    double currX = vr.x;
+
+	    g.setColor(c.getForeground());
+	    g.fill3DRect(vr.x, vr.y, amountFull, vr.height, true);
+
+	    g.setColor(c.getBackground());
+	    if (spaceInUnits != 0)
+	      {
+		for (int i = 0; i < iterations; i++)
+		  {
+		    currX += lenInUnits;
+		    g.fill3DRect((int) currX, vr.y, (int) spaceInUnits,
+		                 vr.height, true);
+		    currX += spaceInUnits;
+		  }
+	      }
+	  }
+	else
+	  {
+	    double currY = vr.y;
+	    double spaceInUnits = space * (double) vr.height / (max - min);
+	    double lenInUnits = len * (double) vr.height / (max - min);
+
+	    g.setColor(c.getForeground());
+	    g.fill3DRect(vr.x, vr.y + vr.height - amountFull, vr.width,
+	                 amountFull, true);
+
+	    g.setColor(c.getBackground());
+
+	    if (spaceInUnits != 0)
+	      {
+		for (int i = 0; i < iterations; i++)
+		  {
+		    currY -= lenInUnits + spaceInUnits;
+		    g.fill3DRect(vr.x, (int) currY, vr.width,
+		                 (int) spaceInUnits, true);
+		  }
+	      }
+	  }
+      }
+
+    if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
+      paintString(g, 0, 0, or.width, or.height, amountFull, insets);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method is called if the painting to be done is for
+   * an indeterminate progressBar.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  protected void paintIndeterminate(Graphics g, JComponent c)
+  {
+    //need to paint the box at it's current position. no text is painted since
+    //all we're doing is bouncing back and forth
+    Color saved = g.getColor();
+    Insets insets = c.getInsets();
+
+    Rectangle or = c.getBounds();
+    Rectangle vr = new Rectangle();
+    SwingUtilities.calculateInnerArea(c, vr);
+
+    g.setColor(c.getBackground());
+    g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
+
+    Rectangle box = new Rectangle();
+    getBox(box);
+
+    g.setColor(c.getForeground());
+    g.fill3DRect(box.x, box.y, box.width, box.height, true);
+
+    if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
+      paintString(g, 0, 0, or.width, or.height,
+                  getAmountFull(insets, or.width, or.height), insets);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the string for the progressBar.
+   *
+   * @param g The Graphics object to paint with.
+   * @param x The x coordinate of the progressBar.
+   * @param y The y coordinate of the progressBar.
+   * @param width The width of the progressBar.
+   * @param height The height of the progressBar.
+   * @param amountFull The amount of the progressBar that has its bar filled.
+   * @param b The insets of the progressBar.
+   */
+  protected void paintString(Graphics g, int x, int y, int width, int height,
+                             int amountFull, Insets b)
+  {
+    // We want to place in the exact center of the bar.
+    Point placement = getStringPlacement(g, progressBar.getString(),
+                                         x + b.left, y + b.top,
+                                         width - b.left - b.right,
+                                         height - b.top - b.bottom);
+    Color saved = g.getColor();
+
+    // FIXME: The Color of the text should use selectionForeground and selectionBackground
+    // but that can't be done right now, so we'll use white in the mean time.
+    g.setColor(Color.WHITE);
+
+    FontMetrics fm = g.getFontMetrics(progressBar.getFont());
+
+    g.drawString(progressBar.getString(), placement.x,
+                 placement.y + fm.getAscent());
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method sets the current animation index. If the index
+   * is greater than the number of frames, it resets to 0.
+   *
+   * @param newValue The new animation index.
+   */
+  protected void setAnimationIndex(int newValue)
+  {
+    animationIndex = (newValue <= numFrames) ? newValue : 0;
+    progressBar.repaint();
+  }
+
+  /**
+   * This method sets the cell length.
+   *
+   * @param cellLen The cell length.
+   */
+  protected void setCellLength(int cellLen)
+  {
+    cellLength = cellLen;
+  }
+
+  /**
+   * This method sets the cell spacing.
+   *
+   * @param cellSpace The cell spacing.
+   */
+  protected void setCellSpacing(int cellSpace)
+  {
+    cellSpacing = cellSpace;
+  }
+
+  /**
+   * This method starts the animation timer. It is called
+   * when the propertyChangeListener detects that the progressBar
+   * has changed to indeterminate mode.
+   *
+   * @since 1.4
+   */
+  protected void startAnimationTimer()
+  {
+    if (animationTimer != null)
+      animationTimer.start();
+  }
+
+  /**
+   * This method stops the animation timer. It is called when
+   * the propertyChangeListener detects that the progressBar
+   * has changed to determinate mode.
+   *
+   * @since 1.4
+   */
+  protected void stopAnimationTimer()
+  {
+    if (animationTimer != null)
+      animationTimer.stop();
+    setAnimationIndex(0);
+  }
+
+  /**
+   * This method changes the settings for the progressBar to
+   * the defaults provided by the current Look and Feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    progressBar.setFont(defaults.getFont("ProgressBar.font"));
+    progressBar.setForeground(defaults.getColor("ProgressBar.foreground"));
+    progressBar.setBackground(defaults.getColor("ProgressBar.background"));
+    progressBar.setBorder(defaults.getBorder("ProgressBar.border"));
+    progressBar.setOpaque(true);
+
+    selectionForeground = defaults.getColor("ProgressBar.selectionForeground");
+    selectionBackground = defaults.getColor("ProgressBar.selectionBackground");
+    cellLength = defaults.getInt("ProgressBar.cellLength");
+    cellSpacing = defaults.getInt("ProgressBar.cellSpacing");
+
+    int repaintInterval = defaults.getInt("ProgressBar.repaintInterval");
+    int cycleTime = defaults.getInt("ProgressBar.cycleTime");
+
+    if (cycleTime % repaintInterval != 0
+        && (cycleTime / repaintInterval) % 2 != 0)
+      {
+	int div = (cycleTime / repaintInterval) + 2;
+	div /= 2;
+	div *= 2;
+	cycleTime = div * repaintInterval;
+      }
+    setAnimationIndex(0);
+    numFrames = cycleTime / repaintInterval;
+    animationTimer.setDelay(repaintInterval);
+  }
+
+  /**
+   * The method uninstalls any defaults that were
+   * set by the current Look and Feel.
+   */
+  protected void uninstallDefaults()
+  {
+    progressBar.setFont(null);
+    progressBar.setForeground(null);
+    progressBar.setBackground(null);
+
+    selectionForeground = null;
+    selectionBackground = null;
+  }
+
+  /**
+   * This method registers listeners to all the 
+   * components that this UI delegate needs to listen to.
+   */
+  protected void installListeners()
+  {
+    changeListener = new ChangeHandler();
+    propertyListener = new PropertyChangeHandler();
+    animation = new Animator();
+
+    progressBar.addChangeListener(changeListener);
+    progressBar.addPropertyChangeListener(propertyListener);
+    animationTimer.addActionListener(animation);
+  }
+
+  /**
+   * This method unregisters listeners to all the 
+   * components that were listened to.
+   */
+  protected void uninstallListeners()
+  {
+    progressBar.removeChangeListener(changeListener);
+    progressBar.removePropertyChangeListener(propertyListener);
+    animationTimer.removeActionListener(animation);
+
+    changeListener = null;
+    propertyListener = null;
+    animation = null;
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   * This includes setting up defaults and listeners as
+   * well as initializing any values or objects that
+   * the UI may need.
+   *
+   * @param c The JComponent that is having this UI installed.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    if (c instanceof JProgressBar)
+      {
+	progressBar = (JProgressBar) c;
+
+	animationTimer = new Timer(200, null);
+	animationTimer.setRepeats(true);
+
+	installDefaults();
+	installListeners();
+      }
+  }
+
+  /**
+   * This method removes the UI for the given JComponent.
+   * This includes removing any listeners or defaults
+   * that the installUI may have set up.
+   *
+   * @param c The JComponent that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    super.uninstallUI(c);
+    uninstallListeners();
+    uninstallDefaults();
+
+    animationTimer = null;
+    progressBar = null;
+  }
+}
Index: javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
diff -N javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,101 @@
+/* BasicRadioButtonMenuItemUI.java
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.MouseEvent;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+
+
+/**
+ * UI Delegator for JRadioButtonMenuItem
+ */
+public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
+{
+  /**
+   * Creates a new BasicRadioButtonMenuItemUI object.
+   */
+  public BasicRadioButtonMenuItemUI()
+  {
+    super();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    checkIcon = defaults.getIcon("RadioButtonMenuItem.checkIcon");
+  }
+
+  /**
+    * Factory method to create a BasicRadioButtonMenuItemUI for the given {@link
+    * JComponent}, which should be a JRadioButtonMenuItem.
+   *
+    * @param b The {@link JComponent} a UI is being created for.
+   *
+    * @return A BasicRadioButtonMenuItemUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent b)
+  {
+    return new BasicRadioButtonMenuItemUI();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return $returnType$ DOCUMENT ME!
+   */
+  protected String getPropertyPrefix()
+  {
+    return null;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param item DOCUMENT ME!
+   * @param e DOCUMENT ME!
+   * @param path DOCUMENT ME!
+   * @param manager DOCUMENT ME!
+   */
+  public void processMouseEvent(JMenuItem item, MouseEvent e,
+                                MenuElement[] path,
+                         MenuSelectionManager manager)
+  {
+  }
+}
Index: javax/swing/plaf/basic/BasicRadioButtonUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicRadioButtonUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicRadioButtonUI.java
--- javax/swing/plaf/basic/BasicRadioButtonUI.java	10 Jan 2004 21:59:30 -0000	1.4
+++ javax/swing/plaf/basic/BasicRadioButtonUI.java	6 Sep 2004 16:36:06 -0000
@@ -38,116 +38,42 @@
 
 package javax.swing.plaf.basic;
 
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Rectangle;
 import javax.swing.AbstractButton;
+import javax.swing.Icon;
 import javax.swing.JComponent;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 
 public class BasicRadioButtonUI extends BasicToggleButtonUI
 {
-  int large_circle_width = 20;
-  int circle_width = large_circle_width - 8; // FIXME: sun == ?
-  
-    public static ComponentUI createUI(final JComponent c)  {
-	return new BasicRadioButtonUI();
-    }
 
+  protected Icon icon;
+
+  public static ComponentUI createUI(final JComponent c)  {
+    return new BasicRadioButtonUI();
+  }
+
+  public BasicRadioButtonUI()
+  {
+    icon = getDefaultIcon();
+  }
+
+  public void installUI(final JComponent c)  {
+    super.installUI(c);
+    if (c instanceof AbstractButton)
+      {
+        AbstractButton b = (AbstractButton) c;        
+        b.setIcon(icon);
+      }
+  }
+
+  public Icon getDefaultIcon()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    return defaults.getIcon("RadioButton.icon");
+  }
     
-    public void installUI(final JComponent c)  {
-	super.installUI(c);
-    }
-    
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	AbstractButton b = (AbstractButton)c;
-	Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
-	
-	// and add a little something for the circles:
-
-	d.width += large_circle_width;
-	d.height = Math.max(large_circle_width, d.height);
-	
-	//System.out.println("^^^^^^^^^^^^^^^^^^^^^^   BASIC-PREF="+d + ",T="+b.text);
-	return d;
-    }
-    
-    protected void paintFocus(Graphics g, 
-			      JComponent c,
-			      Rectangle vr,
-			      Rectangle tr,
-			      Rectangle ir)
-    {
-    }
-
-    protected void paintIcon(Graphics g, 
-			     JComponent c, 
-			     Rectangle iconRect)
-    {
-    }
-
-    protected void paintButtonPressed(Graphics g,
-				      JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	paintButtonNormal(g, b);
-
-	int x = gap;
-	int y = gap;
-
-	int diffp = 2;
-	int diff = 3;
-	
-	g.setColor(textColor);
-	g.fillArc(x+diffp, y+diffp, 
-		  circle_width-diff, circle_width-diff,
-		  0, 360);
-    }
-    
-    protected void paintButtonNormal(Graphics g,
-				     JComponent c)
-    {
-	AbstractButton b = (AbstractButton) c;
-	
-	Dimension size = b.getSize();
-	
-	g.setColor(normalBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);  
-	
-	int x = gap;
-	int y = gap;
-	
-	g.setColor(pressedBackgroundColor);
-	g.drawArc(x, y,
-		  circle_width, circle_width,
-		  0, 360);
-
-	g.setColor(new Color(255,255,255));
-	g.drawArc(x, y,
-		  circle_width+1, circle_width+1,
-		  145, 160);
-    }
-    
-    protected void paintText(Graphics g,
-			     JComponent c,
-			     Rectangle textRect,
-			     String text) 
-    {
-	//        AbstractButton b = (AbstractButton) c;
-	
-	//System.out.println("drawing string: " + text + ", " + c.isEnabled());
-	
-	g.setColor(c.isEnabled() ? textColor : disabledTextColor);
-	
-	BasicGraphicsUtils.drawString(g,
-				      text, 
-				      0,
-				      textRect.x + circle_width + gap, 
-				      textRect.y);
-    } 
 }
 
 
Index: javax/swing/plaf/basic/BasicRootPaneUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicRootPaneUI.java
diff -N javax/swing/plaf/basic/BasicRootPaneUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicRootPaneUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,67 @@
+/* BasicPanelUI.java
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.plaf.basic;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JComponent;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.RootPaneUI;
+
+
+public class BasicRootPaneUI extends RootPaneUI
+  implements PropertyChangeListener
+{
+    public static ComponentUI createUI(JComponent x) 
+    {
+        return new BasicRootPaneUI();
+    }
+
+    public void installUI(JComponent c)
+    {
+      c.setOpaque(true);
+    c.setBackground(UIManager.getColor("control"));
+      super.installUI(c);
+    }
+
+  public void propertyChange(PropertyChangeEvent event)
+  {
+  }
+}
Index: javax/swing/plaf/basic/BasicScrollBarUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicScrollBarUI.java
diff -N javax/swing/plaf/basic/BasicScrollBarUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicScrollBarUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,1405 @@
+/* BasicScrollBarUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.BoundedRangeModel;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JScrollBar;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.ScrollBarUI;
+
+
+/**
+ * The Basic Look and Feel UI delegate for JScrollBar.
+ */
+public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
+                                                             SwingConstants
+{
+  /**
+   * A helper class that listens to the two JButtons on each end
+   * of the JScrollBar.
+   */
+  protected class ArrowButtonListener extends MouseAdapter
+  {
+    /**
+     * Move the thumb in the direction specified by the 
+     * button's arrow. If this button is held down, then
+     * it should keep moving the thumb.
+     *
+     * @param e The MouseEvent fired by the JButton.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      scrollTimer.stop();
+      scrollListener.setScrollByBlock(false);
+      if (e.getSource() == incrButton)
+	scrollListener.setDirection(POSITIVE_SCROLL);
+      else
+	scrollListener.setDirection(NEGATIVE_SCROLL);
+      scrollTimer.start();
+    }
+
+    /**
+     * Stops the thumb when the JButton is released.
+     *
+     * @param e The MouseEvent fired by the JButton.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      scrollTimer.stop();
+    }
+  }
+
+  /**
+   * A helper class that listens to the ScrollBar's model
+   * for ChangeEvents.
+   */
+  protected class ModelListener implements ChangeListener
+  {
+    /**
+     * Called when the model changes.
+     *
+     * @param e The ChangeEvent fired by the model.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      //       System.err.println(this + ".stateChanged()");
+      calculatePreferredSize();
+      layoutContainer(scrollbar);		  
+      getThumbBounds();
+      scrollbar.repaint();
+    }
+  }
+
+  /**
+   * A helper class that listens to the ScrollBar's properties.
+   */
+  public class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * Called when one of the ScrollBar's properties change.
+     *
+     * @param e The PropertyChangeEvent fired by the ScrollBar.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JScrollBar.MODEL_CHANGED_PROPERTY))
+        {
+	  ((BoundedRangeModel) e.getOldValue()).removeChangeListener(modelListener);
+	  scrollbar.getModel().addChangeListener(modelListener);
+	  getThumbBounds();
+        }
+      else if (e.getPropertyName().equals(JScrollBar.ORIENTATION_CHANGED_PROPERTY))
+        {
+	  incrButton.removeMouseListener(buttonListener);
+	  decrButton.removeMouseListener(buttonListener);
+	  incrButton = createIncreaseButton(scrollbar.getOrientation());
+	  decrButton = createDecreaseButton(scrollbar.getOrientation());
+          incrButton.addMouseListener(buttonListener);
+          decrButton.addMouseListener(buttonListener);	  
+          calculatePreferredSize();
+          layoutContainer(scrollbar);		  
+	}
+      layoutContainer(scrollbar);
+      scrollbar.repaint();
+    }
+  }
+
+  /**
+   * A helper class that listens for events from
+   * the timer that is used to move the thumb.
+   */
+  protected class ScrollListener implements ActionListener
+  {
+    /** The direction the thumb moves in. */
+    private transient int direction;
+
+    /** Whether movement will be in blocks. */
+    private transient boolean block;
+
+    /**
+     * Creates a new ScrollListener object.
+     * The default is scrolling positively with block movement.
+     */
+    public ScrollListener()
+    {
+      direction = POSITIVE_SCROLL;
+      block = true;
+    }
+
+    /**
+     * Creates a new ScrollListener object using
+     * the given direction and block.
+     *
+     * @param dir The direction to move in.
+     * @param block Whether movement will be in blocks.
+     */
+    public ScrollListener(int dir, boolean block)
+    {
+      direction = dir;
+      this.block = block;
+    }
+
+    /**
+     * Sets the direction to scroll in.
+     *
+     * @param direction The direction to scroll in.
+     */
+    public void setDirection(int direction)
+    {
+      this.direction = direction;
+    }
+
+    /**
+     * Sets whether scrolling will be done in blocks.
+     *
+     * @param block Whether scrolling will be in blocks.
+     */
+    public void setScrollByBlock(boolean block)
+    {
+      this.block = block;
+    }
+
+    /**
+     * Called every time the timer reaches its interval.
+     *
+     * @param e The ActionEvent fired by the timer.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (block)
+        {
+	  // Only need to check it if it's block scrolling
+	  // We only block scroll if the click occurs
+	  // in the track.
+	  
+	  if (!trackListener.shouldScroll(direction))
+	    {
+	      trackHighlight = NO_HIGHLIGHT;
+	      scrollbar.repaint();
+	      return;
+	    }
+	  scrollByBlock(direction);
+        }
+      else
+	scrollByUnit(direction);
+    }
+  }
+
+  /**
+   * Helper class that listens for movement on the track.
+   */
+  protected class TrackListener extends MouseAdapter
+    implements MouseMotionListener
+  {
+    /** The current X coordinate of the mouse. */
+    protected int currentMouseX;
+
+    /** The current Y coordinate of the mouse. */
+    protected int currentMouseY;
+
+    /** The offset between the current mouse cursor and the 
+        current value of the scrollbar. */
+    protected int offset;
+
+    /**
+     * This method is called when the mouse is being
+     * dragged.
+     *
+     * @param e The MouseEvent given.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      currentMouseX = e.getX();
+      currentMouseY = e.getY();
+      if (scrollbar.getValueIsAdjusting())
+      {
+        int value;
+        if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
+	  value = valueForXPosition(currentMouseX) - offset;
+	else
+	  value = valueForYPosition(currentMouseY) - offset;
+	
+	scrollbar.setValue(value);
+      }
+    }
+
+    /**
+     * This method is called when the mouse is moved.
+     *
+     * @param e The MouseEvent given.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // Not interested in where the mouse
+      // is unless it is being dragged.
+    }
+
+    /**
+     * This method is called when the mouse is
+     * pressed. When it is pressed, the thumb should
+     * move in blocks towards the cursor.
+     *
+     * @param e The MouseEvent given.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      currentMouseX = e.getX();
+      currentMouseY = e.getY();
+
+      int value;
+      if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
+	value = valueForXPosition(currentMouseX);
+      else
+	value = valueForYPosition(currentMouseY);
+
+      if (value == scrollbar.getValue())
+	return;
+
+      if (!thumbRect.contains(e.getPoint()))
+        {
+	  scrollTimer.stop();
+	  scrollListener.setScrollByBlock(true);
+	  if (value > scrollbar.getValue())
+	    {
+	      trackHighlight = INCREASE_HIGHLIGHT;
+	      scrollListener.setDirection(POSITIVE_SCROLL);
+	    }
+	  else
+	    {
+	      trackHighlight = DECREASE_HIGHLIGHT;
+	      scrollListener.setDirection(NEGATIVE_SCROLL);
+	    }
+	  scrollTimer.start();
+        }
+      else
+        {
+	  // We'd like to keep track of where the cursor
+	  // is inside the thumb.
+	  // This works because the scrollbar's value represents 
+	  // "lower" edge of the thumb. The value at which
+	  // the cursor is at must be greater or equal
+	  // to that value.
+	  scrollbar.setValueIsAdjusting(true);
+	  offset = value - scrollbar.getValue();
+	}
+      scrollbar.repaint();      
+    }
+
+    /**
+     * This method is called when the mouse is released.
+     * It should stop movement on the thumb
+     *
+     * @param e The MouseEvent given.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      trackHighlight = NO_HIGHLIGHT;
+      scrollTimer.stop();
+      
+      if (scrollbar.getValueIsAdjusting())
+        scrollbar.setValueIsAdjusting(false);
+      scrollbar.repaint();
+    }
+    
+    /**
+     * A helper method that decides whether we should
+     * keep scrolling in the given direction.
+     *
+     * @param direction The direction to check for.
+     *
+     * @return Whether the thumb should keep scrolling.
+     */
+    public boolean shouldScroll (int direction)
+    {
+      int value;
+      if (scrollbar.getOrientation() == HORIZONTAL)
+        value = valueForXPosition(currentMouseX);
+      else
+        value = valueForYPosition(currentMouseY);
+
+      if (direction == POSITIVE_SCROLL)
+        return (value > scrollbar.getValue());
+      else
+        return (value < scrollbar.getValue());
+    }
+  }
+
+  /** The listener that listens to the JButtons. */
+  protected ArrowButtonListener buttonListener;
+
+  /** The listener that listens to the model. */
+  protected ModelListener modelListener;
+
+  /** The listener that listens to the scrollbar for property
+      changes. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The listener that listens to the timer. */
+  protected ScrollListener scrollListener;
+
+  /** The listener that listens for MouseEvents on the track. */
+  protected TrackListener trackListener;
+
+  /** The JButton that decrements the scrollbar's value. */
+  protected JButton decrButton;
+
+  /** The JButton that increments the scrollbar's value. */
+  protected JButton incrButton;
+
+  /** The dimensions of the maximum thumb size. */
+  protected static Dimension maximumThumbSize;
+
+  /** The dimensions of the minimum thumb size. */
+  protected static Dimension minimumThumbSize;
+
+  /** The color of the thumb. */
+  protected Color thumbColor;
+
+  /** The outer shadow of the thumb. */
+  protected Color thumbDarkShadowColor;
+
+  /** The top and left edge color for the thumb. */
+  protected Color thumbHighlightColor;
+
+  /** The outer light shadow for the thumb. */
+  protected Color thumbLightShadowColor;
+
+  /** The color that is used when the mouse press
+      occurs in the track. */
+  protected Color trackHighlightColor;
+
+  /** The color of the track. */
+  protected Color trackColor;
+
+  /** The size and position of the track. */
+  protected Rectangle trackRect;
+
+  /** The size and position of the thumb. */
+  protected Rectangle thumbRect;
+
+  /** Indicates that the decrease highlight should be painted. */
+  protected static int DECREASE_HIGHLIGHT = 1;
+
+  /** Indicates that the increase highlight should be painted. */
+  protected static int INCREASE_HIGHLIGHT = 2;
+
+  /** Indicates that no highlight should be painted. */
+  protected static int NO_HIGHLIGHT = 0;
+
+  /** Indicates that the scrolling direction is positive. */
+  private static int POSITIVE_SCROLL = 1;
+
+  /** Indicates that the scrolling direction is negative. */
+  private static int NEGATIVE_SCROLL = -1;
+
+  /** The cached preferred size for the scrollbar. */
+  private transient Dimension preferredSize;
+
+  /** The current highlight status. */
+  protected int trackHighlight;
+
+  /** FIXME: Use this for something (presumably mouseDragged) */
+  protected boolean isDragging;
+
+  /** The timer used to move the thumb when the mouse is held. */
+  protected Timer scrollTimer;
+
+  /** The scrollbar this UI is acting for. */
+  protected JScrollBar scrollbar;
+
+  /**
+   * A helper class that allows us to draw icons for 
+   * the JButton.
+   */
+  private static class arrowIcon implements Icon
+  {
+    /** The polygon that describes the icon. */
+    private Polygon arrow;
+
+    /**
+     * Creates a new arrowIcon object.
+     *
+     * @param arrow The polygon that describes the arrow.
+     */
+    public arrowIcon(Polygon arrow)
+    {
+      this.arrow = arrow;
+    }
+
+    /**
+     * Returns the height of the icon.
+     *
+     * @return The height of the icon.
+     */
+    public int getIconHeight()
+    {
+      return 10;
+    }
+
+    /**
+     * Returns the width of the icon.
+     *
+     * @return The width of the icon.
+     */
+    public int getIconWidth()
+    {
+      return 10;
+    }
+
+    /**
+     * Paints the icon.
+     *
+     * @param c The Component to paint for.
+     * @param g The Graphics object to draw with.
+     * @param x The X coordinate to draw at.
+     * @param y The Y coordinate to draw at.
+     */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+      g.translate(x, y);
+
+      Color saved = g.getColor();
+
+      g.setColor(Color.BLACK);
+
+      g.fillPolygon(arrow);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The Icon that points up. */
+  private static Icon upIcon = new arrowIcon(new Polygon(new int[] { 2, 5, 8 },
+                                                            new int[] { 7, 3, 7 },
+                                                            3));
+
+  /** The Icon that points down. */
+  private static Icon downIcon = new arrowIcon(new Polygon(new int[] { 2, 5, 8 },
+                                                              new int[] { 3, 7, 3 },
+                                                              3));
+
+  /** The Icon that points left. */
+  private static Icon leftIcon = new arrowIcon(new Polygon(new int[] { 7, 3, 7 },
+                                                              new int[] { 2, 5, 8 },
+                                                              3));
+
+  /** The Icon that points right. */
+  private static Icon rightIcon = new arrowIcon(new Polygon(new int[] { 3, 7, 3},
+                                                            new int[] { 2, 5, 8}, 
+                                                            3));
+
+  /**
+   * This method adds a component to the layout.
+   *
+   * @param name The name to associate with the component that is added.
+   * @param child The Component to add.
+   */
+  public void addLayoutComponent(String name, Component child)
+  {
+    // You should not be adding stuff to this component.
+    // The contents are fixed.
+  }
+
+  /**
+   * This method configures the scrollbar's colors. This can be 
+   * done by looking up the standard colors from the Look and Feel defaults.
+   */
+  protected void configureScrollBarColors()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+  
+    trackColor = defaults.getColor("ScrollBar.track");
+    trackHighlightColor = defaults.getColor("ScrollBar.trackHighlight");
+    thumbColor = defaults.getColor("ScrollBar.thumb");
+    thumbHighlightColor = defaults.getColor("ScrollBar.thumbHighlight");
+    thumbDarkShadowColor = defaults.getColor("ScrollBar.thumbDarkShadow");
+    thumbLightShadowColor = defaults.getColor("ScrollBar.thumbLightShadow");  
+  }
+
+  /**
+   * This method creates an ArrowButtonListener.
+   *
+   * @return A new ArrowButtonListener.
+   */
+  protected ArrowButtonListener createArrowButtonListener()
+  {
+    return new ArrowButtonListener();
+  }
+
+  /** 
+   * This method creates a new JButton with the appropriate
+   * icon for the orientation.
+   *
+   * @param orientation The orientation this JButton uses.
+   *
+   * @return The increase JButton.
+   */
+  protected JButton createIncreaseButton(int orientation)
+  {
+    if (incrButton == null)
+      {
+      incrButton = new JButton();
+        incrButton.setMargin(new Insets(0,0,0,0));
+        incrButton.setHorizontalAlignment(SwingConstants.CENTER);
+        incrButton.setHorizontalTextPosition(SwingConstants.CENTER);
+        incrButton.setVerticalAlignment(SwingConstants.CENTER);
+        incrButton.setVerticalTextPosition(SwingConstants.CENTER);
+      }
+    
+    if (orientation == SwingConstants.HORIZONTAL)
+      incrButton.setIcon(rightIcon);
+    else
+      incrButton.setIcon(downIcon);
+
+    return incrButton;
+  }
+
+  /**
+   * This method creates a new JButton with the appropriate
+   * icon for the orientation.
+   *
+   * @param orientation The orientation this JButton uses.
+   *
+   * @return The decrease JButton.
+   */
+  protected JButton createDecreaseButton(int orientation)
+  {
+    if (decrButton == null)
+      {
+      decrButton = new JButton();
+        decrButton.setMargin(new Insets(0,0,0,0));
+        decrButton.setHorizontalAlignment(SwingConstants.CENTER);
+        decrButton.setHorizontalTextPosition(SwingConstants.CENTER);
+        decrButton.setVerticalAlignment(SwingConstants.CENTER);
+        decrButton.setVerticalTextPosition(SwingConstants.CENTER);
+      }
+
+    if (orientation == SwingConstants.HORIZONTAL)
+      decrButton.setIcon(leftIcon);
+    else
+      decrButton.setIcon(upIcon);
+
+    return decrButton;
+  }
+
+  /**
+   * This method creates a new ModelListener.
+   *
+   * @return A new ModelListener.
+   */
+  protected ModelListener createModelListener()
+  {
+    return new ModelListener();
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener.
+   *
+   * @return A new PropertyChangeListener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method creates a new ScrollListener.
+   *
+   * @return A new ScrollListener.
+   */
+  protected ScrollListener createScrollListener()
+  {
+    return new ScrollListener();
+  }
+
+  /**
+   * This method creates a new TrackListener.
+   *
+   * @return A new TrackListener.
+   */
+  protected TrackListener createTrackListener()
+  {
+    return new TrackListener();
+  }
+
+  /**
+   * This method returns a new BasicScrollBarUI.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicScrollBarUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicScrollBarUI();
+  }
+
+  /**
+   * This method returns the maximum size for this JComponent.
+   *
+   * @param c The JComponent to measure the maximum size for.
+   *
+   * @return The maximum size for the component.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the maximum thumb size.
+   *
+   * @return The maximum thumb size.
+   */
+  protected Dimension getMaximumThumbSize()
+  {
+    return maximumThumbSize;
+  }
+
+  /**
+   * This method returns the minimum size for this JComponent.
+   *
+   * @param c The JComponent to measure the minimum size for.
+   *
+   * @return The minimum size for the component.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the minimum thumb size.
+   *
+   * @return The minimum thumb size.
+   */
+  protected Dimension getMinimumThumbSize()
+  {
+    return minimumThumbSize;
+  }
+
+  /**
+   * This method calculates the preferred size since
+   * calling getPreferredSize() returns a cached value.
+   */
+  private void calculatePreferredSize()
+  {
+    // System.err.println(this + ".calculatePreferredSize()");
+
+    int height;
+    int width;
+    height = width = 0;
+
+    if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
+      {
+	width += incrButton.getPreferredSize().getWidth();
+	width += decrButton.getPreferredSize().getWidth();
+
+	width += (scrollbar.getMaximum() - scrollbar.getMinimum());
+
+	height = Math.max(incrButton.getPreferredSize().height,
+	                  decrButton.getPreferredSize().height);
+	height = Math.max(getMinimumThumbSize().height, height);
+	height = Math.max(20, height);
+	height = Math.min(getMaximumThumbSize().height, height);
+      }
+    else
+      {
+	height += incrButton.getPreferredSize().getHeight();
+	height += decrButton.getPreferredSize().getHeight();
+
+	height += (scrollbar.getMaximum() - scrollbar.getMinimum());
+
+	width = Math.max(incrButton.getPreferredSize().width,
+	                 decrButton.getPreferredSize().width);
+	width = Math.max(getMinimumThumbSize().width, width);
+	width = Math.max(20, width);
+	width = Math.min(getMaximumThumbSize().width, width);
+      }
+
+    Insets insets = scrollbar.getInsets();
+
+    height += insets.top + insets.bottom;
+    width += insets.left + insets.right;
+
+    preferredSize = new Dimension(width, height);
+  }
+
+  /**
+   * This method returns a cached value of the preferredSize.
+   * The only restrictions are: If the scrollbar is horizontal, the
+   * height should be the maximum of the height of the JButtons and 
+   * the minimum width of the thumb. For vertical scrollbars, the 
+   * calculation is similar (swap width for height and vice versa).
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The preferredSize.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    calculatePreferredSize();
+    return preferredSize;
+  }
+
+  /**
+   * This method returns the thumb's bounds based on the 
+   * current value of the scrollbar. This method updates the
+   * cached value and returns that.
+   *
+   * @return The thumb bounds.
+   */
+  protected Rectangle getThumbBounds()
+  {
+    int max = scrollbar.getMaximum();
+    int min = scrollbar.getMinimum();
+    int value = scrollbar.getValue();
+    int extent = scrollbar.getVisibleAmount();
+
+    // System.err.println(this + ".getThumbBounds()");
+
+    if (max == min)
+    {
+      thumbRect.x = trackRect.x;
+      thumbRect.y = trackRect.y;
+      if (scrollbar.getOrientation() == HORIZONTAL)
+      {
+	thumbRect.width = getMinimumThumbSize().width;
+	thumbRect.height = trackRect.height;
+      }
+      else
+      {
+        thumbRect.width = trackRect.width;
+	thumbRect.height = getMinimumThumbSize().height;
+      }
+      return thumbRect;
+    }
+               
+
+    if (scrollbar.getOrientation() == HORIZONTAL)
+      {
+	thumbRect.x = trackRect.x;
+	thumbRect.x += (value - min) * trackRect.width / (max - min);
+	thumbRect.y = trackRect.y;
+
+	thumbRect.width = extent * trackRect.width / (max - min);
+	thumbRect.height = trackRect.height;
+      }
+    else
+      {
+	thumbRect.x = trackRect.x;
+	thumbRect.y = trackRect.y
+	              + value * trackRect.height / (max - min);
+
+	thumbRect.width = trackRect.width;
+	thumbRect.height = extent * trackRect.height / (max - min);
+      }
+    return thumbRect;
+  }
+
+  /**
+   * This method calculates the bounds of the track. This method
+   * updates the cached value and returns it.
+   *
+   * @return The track's bounds.
+   */
+  protected Rectangle getTrackBounds()
+  {
+    SwingUtilities.calculateInnerArea(scrollbar, trackRect);
+
+    if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
+      {
+	trackRect.width -= incrButton.getPreferredSize().getWidth();
+	trackRect.width -= decrButton.getPreferredSize().getWidth();
+
+	trackRect.x += decrButton.getPreferredSize().getWidth();
+      }
+    else
+      {
+	trackRect.height -= incrButton.getPreferredSize().getHeight();
+	trackRect.height -= decrButton.getPreferredSize().getHeight();
+
+	trackRect.y += incrButton.getPreferredSize().getHeight();
+      }
+    return trackRect;
+  }
+
+  /**
+   * This method installs any addition Components that 
+   * are a part of or related to this scrollbar.
+   */
+  protected void installComponents()
+  {
+    incrButton = createIncreaseButton(scrollbar.getOrientation());
+    scrollbar.add(incrButton);
+    decrButton = createDecreaseButton(scrollbar.getOrientation());
+    scrollbar.add(decrButton);
+  }
+
+  /**
+   * This method installs the defaults for the scrollbar specified
+   * by the Basic Look and Feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    scrollbar.setForeground(defaults.getColor("ScrollBar.foreground"));
+    scrollbar.setBackground(defaults.getColor("ScrollBar.background"));
+    scrollbar.setBorder(defaults.getBorder("ScrollBar.border"));
+    scrollbar.setOpaque(true);
+
+    maximumThumbSize = defaults.getDimension("ScrollBar.maximumThumbSize");
+    minimumThumbSize = defaults.getDimension("ScrollBar.minimumThumbSize");
+  }
+
+  /**
+   * This method installs the keyboard actions for the scrollbar.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: implement.
+  }
+
+  /**
+   * This method installs any listeners for the scrollbar.
+   * This method also installs listeners for things such as
+   * the JButtons and the timer.
+   */
+  protected void installListeners()
+  {
+    scrollListener = createScrollListener();
+    trackListener = createTrackListener();
+    buttonListener = createArrowButtonListener();
+    modelListener = createModelListener();
+    propertyChangeListener = createPropertyChangeListener();
+
+    scrollbar.addMouseMotionListener(trackListener);
+    scrollbar.addMouseListener(trackListener);
+
+    incrButton.addMouseListener(buttonListener);
+    decrButton.addMouseListener(buttonListener);
+
+    scrollbar.addPropertyChangeListener(propertyChangeListener);
+    scrollbar.getModel().addChangeListener(modelListener);
+
+    scrollTimer.addActionListener(scrollListener);
+  }
+
+  /**
+   * This method installs the UI for the component.
+   * This can include setting up listeners, defaults, 
+   * and components. This also includes initializing any data
+   * objects.
+   *
+   * @param c The JComponent to install.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    if (c instanceof JScrollBar)
+      {
+	scrollbar = (JScrollBar) c;
+
+	trackRect = new Rectangle();
+	thumbRect = new Rectangle();
+
+	scrollTimer = new Timer(200, null);
+	scrollTimer.setRepeats(true);
+
+	installComponents();
+	installListeners();
+	installDefaults();
+	configureScrollBarColors();
+
+	calculatePreferredSize();
+        layoutContainer(scrollbar);	
+      }
+  }
+
+  /**
+   * This method lays out the scrollbar.
+   *
+   * @param scrollbarContainer The Container to layout.
+   */
+  public void layoutContainer(Container scrollbarContainer)
+  {
+    if (scrollbarContainer instanceof JScrollBar)
+      {
+	if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
+	  layoutHScrollbar((JScrollBar) scrollbarContainer);
+	else
+	  layoutVScrollbar((JScrollBar) scrollbarContainer);
+      }
+  }
+
+  /**
+   * This method lays out the scrollbar horizontally.
+   *
+   * @param sb The JScrollBar to layout.
+   */
+  protected void layoutHScrollbar(JScrollBar sb)
+  {
+    // All we have to do is layout the 2 buttons?
+    Rectangle vr = new Rectangle();
+    SwingUtilities.calculateInnerArea(scrollbar, vr);
+
+    // Update the rectangles.
+    getTrackBounds();
+    getThumbBounds();
+
+    Dimension incrDims = incrButton.getPreferredSize();
+    Dimension decrDims = decrButton.getPreferredSize();
+
+    decrButton.setBounds(vr.x, vr.y, decrDims.width, trackRect.height);
+    incrButton.setBounds(trackRect.x + trackRect.width, vr.y, incrDims.width,
+                         trackRect.height);
+  }
+
+  /**
+   * This method lays out the scrollbar vertically.
+   *
+   * @param sb The JScrollBar to layout.
+   */
+  protected void layoutVScrollbar(JScrollBar sb)
+  {
+    Rectangle vr = new Rectangle();
+    SwingUtilities.calculateInnerArea(scrollbar, vr);
+
+    // Update rectangles
+    getTrackBounds();
+    getThumbBounds();
+
+    Dimension incrDims = incrButton.getPreferredSize();
+    Dimension decrDims = decrButton.getPreferredSize();
+
+    decrButton.setBounds(vr.x, vr.y, trackRect.width, decrDims.height);
+    incrButton.setBounds(vr.x, trackRect.y + trackRect.height,
+                         trackRect.width, incrDims.height);
+  }
+
+  /**
+   * This method returns the minimum size required for the layout.
+   *
+   * @param scrollbarContainer The Container that is laid out.
+   *
+   * @return The minimum size.
+   */
+  public Dimension minimumLayoutSize(Container scrollbarContainer)
+  {
+    return preferredLayoutSize(scrollbarContainer);
+  }
+
+  /**
+   * This method is called when the component is painted.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    layoutContainer(scrollbar);
+    paintTrack(g, c, getTrackBounds());
+    paintThumb(g, c, getThumbBounds());
+
+    if (trackHighlight == INCREASE_HIGHLIGHT)
+      paintIncreaseHighlight(g);
+    else if (trackHighlight == DECREASE_HIGHLIGHT)
+      paintDecreaseHighlight(g);
+  }
+
+  /**
+   * This method is called when repainting and the mouse is 
+   * pressed in the track. It paints the track below the thumb
+   * with the trackHighlight color.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintDecreaseHighlight(Graphics g)
+  {
+    Color saved = g.getColor();
+
+    g.setColor(trackHighlightColor);
+    if (scrollbar.getOrientation() == HORIZONTAL)
+      g.fillRect(trackRect.x, trackRect.y, thumbRect.x - trackRect.x,
+                 trackRect.height);
+    else
+      g.fillRect(trackRect.x, trackRect.y, trackRect.width, 
+                 thumbRect.y - trackRect.y);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method is called when repainting and the mouse is 
+   * pressed in the track. It paints the track above the thumb
+   * with the trackHighlight color.
+   *
+   * @param g The Graphics objet to paint with.
+   */
+  protected void paintIncreaseHighlight(Graphics g)
+  {
+    Color saved = g.getColor();
+
+    g.setColor(trackHighlightColor);
+    if (scrollbar.getOrientation() == HORIZONTAL)
+      g.fillRect(thumbRect.x + thumbRect.width, trackRect.y,
+                 trackRect.x + trackRect.width - thumbRect.x - thumbRect.width,
+                 trackRect.height);
+    else   
+      g.fillRect(trackRect.x, thumbRect.y + thumbRect.height, 
+                 trackRect.width,
+                 trackRect.y + trackRect.height - thumbRect.y - 
+		 thumbRect.height);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the thumb.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The Component that is being painted.
+   * @param thumbBounds The thumb bounds.
+   */
+  protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds)
+  {
+    Color saved = g.getColor();
+    Point x;
+    Point y;
+    Point z;
+    Polygon lines;
+
+    g.setColor(thumbHighlightColor);
+    x = new Point(thumbBounds.x + 1, thumbBounds.y + 1);
+    y = new Point(x);
+    y.translate(thumbBounds.width - 2, 0);
+    z = new Point(x);
+    z.translate(0, thumbBounds.height - 2);
+
+    lines = new Polygon(new int[] { x.x, y.x, z.x },
+                        new int[] { x.y, y.y, z.y }, 3);
+
+    g.drawPolygon(lines);
+
+    g.setColor(thumbLightShadowColor);
+    x = new Point(thumbBounds.x + thumbBounds.width - 1,
+                  thumbBounds.y + thumbBounds.height - 1);
+    y = new Point(x);
+    y.translate(-(thumbBounds.width - 2), 0);
+    z = new Point(x);
+    z.translate(0, -(thumbBounds.height - 2));
+
+    lines = new Polygon(new int[] { x.x, y.x, z.x },
+                        new int[] { x.y, y.y, z.y }, 3);
+    g.drawPolygon(lines);
+
+    g.setColor(thumbDarkShadowColor);
+    x = new Point(thumbBounds.x + thumbBounds.width,
+                  thumbBounds.y + thumbBounds.height);
+    y = new Point(x);
+    y.translate(-thumbBounds.width, 0);
+    z = new Point(x);
+    z.translate(0, -thumbBounds.height);
+
+    lines = new Polygon(new int[] { x.x, y.x, z.x },
+                        new int[] { x.y, y.y, z.y }, 3);
+    g.drawPolygon(lines);
+
+    g.setColor(thumbColor);
+    g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width,
+               thumbBounds.height);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the track.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent being painted.
+   * @param trackBounds The track's bounds.
+   */
+  protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds)
+  {
+    Color saved = g.getColor();
+    g.setColor(trackColor);
+    g.fill3DRect(trackBounds.x, trackBounds.y, trackBounds.width,
+                 trackBounds.height, false);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method returns the preferred size for the layout.
+   *
+   * @param scrollbarContainer The Container to find a size for.
+   *
+   * @return The preferred size for the layout.
+   */
+  public Dimension preferredLayoutSize(Container scrollbarContainer)
+  {
+    if (scrollbarContainer instanceof JComponent)
+      return getPreferredSize((JComponent) scrollbarContainer);
+    else
+      return null;
+  }
+
+  /**
+   * This method removes a child component from the layout.
+   *
+   * @param child The child to remove.
+   */
+  public void removeLayoutComponent(Component child)
+  {
+    // You should not be removing stuff from this component.
+  }
+
+  /**
+   * The method scrolls the thumb by a block in the 
+   * direction specified.
+   *
+   * @param direction The direction to scroll.
+   */
+  protected void scrollByBlock(int direction)
+  {
+    scrollbar.setValue(scrollbar.getValue() + scrollbar.getBlockIncrement(direction));
+  }
+
+  /**
+   * The method scrolls the thumb by a unit in the
+   * direction specified.
+   *
+   * @param direction The direction to scroll.
+   */
+  protected void scrollByUnit(int direction)
+  {
+    scrollbar.setValue(scrollbar.getValue() + scrollbar.getUnitIncrement(direction));
+  }
+
+  /**
+   * This method sets the thumb's bounds.
+   *
+   * @param x The X position of the thumb.
+   * @param y The Y position of the thumb.
+   * @param width The width of the thumb.
+   * @param height The height of the thumb.
+   */
+  protected void setThumbBounds(int x, int y, int width, int height)
+  {
+    thumbRect.x = x;
+    thumbRect.y = y;
+    thumbRect.width = width;
+    thumbRect.height = height;
+  }
+
+  /**
+   * This method uninstalls any components that 
+   * are a part of or related to this scrollbar.
+   */
+  protected void uninstallComponents()
+  {
+    scrollbar.remove(incrButton);
+    scrollbar.remove(decrButton);
+    incrButton = null;
+    decrButton = null;
+  }
+
+  /**
+   * This method uninstalls any defaults that this
+   * scrollbar acquired from the Basic Look and Feel defaults.
+   */
+  protected void uninstallDefaults()
+  {
+    scrollbar.setForeground(null);
+    scrollbar.setBackground(null);
+    scrollbar.setBorder(null);
+  }
+
+  /**
+   * This method uninstalls any keyboard
+   * actions this scrollbar acquired during install.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: implement.
+  }
+
+  /**
+   * This method uninstalls any listeners that
+   * were registered during install.
+   */
+  protected void uninstallListeners()
+  {
+    scrollTimer.removeActionListener(scrollListener);
+    
+    scrollbar.getModel().removeChangeListener(modelListener);
+    scrollbar.removePropertyChangeListener(propertyChangeListener);
+    
+    decrButton.removeMouseListener(buttonListener);
+    incrButton.removeMouseListener(buttonListener);
+    
+    scrollbar.removeMouseListener(trackListener);
+    scrollbar.removeMouseMotionListener(trackListener);
+    
+    propertyChangeListener = null;
+    modelListener = null;
+    buttonListener = null;
+    trackListener = null;
+    scrollListener = null;
+  }
+
+  /**
+   * This method uninstalls the UI. This includes
+   * removing any defaults, listeners, and components
+   * that this UI may have initialized. It also nulls
+   * any instance data.
+   *
+   * @param c The Component to uninstall for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallDefaults();
+    uninstallListeners();
+    uninstallComponents();
+    
+    scrollTimer = null;
+    
+    thumbRect = null;
+    trackRect = null;
+    
+    trackColor = null;
+    trackHighlightColor = null;
+    thumbColor = null;
+    thumbHighlightColor = null;
+    thumbDarkShadowColor = null;
+    thumbLightShadowColor = null;
+    
+    scrollbar = null;
+  }
+
+  /**
+   * This method returns the value in the scrollbar's range given the y
+   * coordinate. If the value is out of range, it will return the closest
+   * legal value.
+   *
+   * @param yPos The y coordinate to calculate a value for.
+   *
+   * @return The value for the y coordinate.
+   */
+  private int valueForYPosition(int yPos)
+  {
+    int min = scrollbar.getMinimum();
+    int max = scrollbar.getMaximum();
+    int len = trackRect.height;
+
+    int value;
+
+    // If the length is 0, you shouldn't be able to even see where the thumb is.
+    // This really shouldn't ever happen, but just in case, we'll return the middle.
+    if (len == 0)
+      return ((max - min) / 2);
+
+    value = ((yPos - trackRect.y) * (max - min) / len + min);
+
+    // If this isn't a legal value, then we'll have to move to one now.
+    if (value > max)
+      value = max;
+    else if (value < min)
+      value = min;
+    return value;
+  }
+
+  /**
+   * This method returns the value in the scrollbar's range given the x
+   * coordinate. If the value is out of range, it will return the closest
+   * legal value.
+   *
+   * @param xPos The x coordinate to calculate a value for.
+   *
+   * @return The value for the x coordinate.
+   */
+  private int valueForXPosition(int xPos)
+  {
+    int min = scrollbar.getMinimum();
+    int max = scrollbar.getMaximum();
+    int len = trackRect.width;
+
+    int value;
+
+    // If the length is 0, you shouldn't be able to even see where the slider is.
+    // This really shouldn't ever happen, but just in case, we'll return the middle.
+    if (len == 0)
+      return ((max - min) / 2);
+
+    value = ((xPos - trackRect.x) * (max - min) / len + min);
+
+    // If this isn't a legal value, then we'll have to move to one now.
+    if (value > max)
+      value = max;
+    else if (value < min)
+      value = min;
+    return value;
+  }
+}
Index: javax/swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.3
diff -u -r1.3 BasicScrollPaneUI.java
--- javax/swing/plaf/basic/BasicScrollPaneUI.java	10 Jan 2004 21:59:30 -0000	1.3
+++ javax/swing/plaf/basic/BasicScrollPaneUI.java	6 Sep 2004 16:36:06 -0000
@@ -40,54 +40,75 @@
 
 import java.awt.Dimension;
 import java.awt.Graphics;
+
 import javax.swing.JComponent;
 import javax.swing.JScrollPane;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.ScrollPaneLayout;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.ScrollPaneUI;
 
 public class BasicScrollPaneUI extends ScrollPaneUI
+  implements ScrollPaneConstants
 {
-    int min_w = 50;
-    int min_h = 50;
 
     public static ComponentUI createUI(final JComponent c) 
     {
 	return new BasicScrollPaneUI();
     }
 
+  protected void installDefaults(JScrollPane p)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    p.setForeground(defaults.getColor("ScrollPane.foreground"));
+    p.setBackground(defaults.getColor("ScrollPane.background"));
+    p.setFont(defaults.getFont("ScrollPane.font"));
+    p.setBorder(defaults.getBorder("ScrollPane.border"));
+    p.setOpaque(true);
+  }
+
+  protected void uninstallDefaults(JScrollPane p)
+  {
+    p.setForeground(null);
+    p.setBackground(null);
+    p.setFont(null);
+    p.setBorder(null);
+  }
     
     public void installUI(final JComponent c) 
     {
 	super.installUI(c);
+    this.installDefaults((JScrollPane)c);
+  }
+
+  public void uninstallUI(final JComponent c) 
+  {
+    super.uninstallUI(c);
+    this.uninstallDefaults((JScrollPane)c);
     }
     
+    
+    public Dimension getMinimumSize(JComponent c) 
+    {
+	JScrollPane p = (JScrollPane ) c;
+        ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
+        return sl.minimumLayoutSize(c);
+    }
 
     public Dimension getPreferredSize(JComponent c) 
     {
 	JScrollPane p = (JScrollPane ) c;
-	
-	Dimension d = new Dimension(min_w,
-				    min_h);
-	
-	Dimension a = p.getViewport().getPreferredSize();
-
-	if (a != null)
-	    {
-		d.width = Math.max(d.width, a.width);
-		d.height = Math.max(d.height, a.height);
-	    }
-			   
-
-	System.out.println("BasicScrollPaneUI->preff->"+d);
-	return d;
+        ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
+        return sl.preferredLayoutSize(c);
     }
 
+
     public void paint(Graphics g, JComponent c)
     {      
-	System.out.println("BasicScrollPaneUI->paint()->"+c);
-
-	JScrollPane p = (JScrollPane ) c;
-	p.getViewport().paint(g);
+      // do nothing; the normal painting-of-children algorithm, along with
+      // ScrollPaneLayout, does all the relevant work.
     }
 }
 
Index: javax/swing/plaf/basic/BasicSeparatorUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicSeparatorUI.java
diff -N javax/swing/plaf/basic/BasicSeparatorUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicSeparatorUI.java	6 Sep 2004 16:36:06 -0000
@@ -0,0 +1,267 @@
+/* BasicSeparatorUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Dimension;
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Insets;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.SeparatorUI;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.JComponent;
+import javax.swing.JSeparator;
+import javax.swing.SwingUtilities;
+
+/**
+ * The Basic Look and Feel UI delegate for JSeparator.
+ */
+public class BasicSeparatorUI extends SeparatorUI
+{
+  /** The shadow color. */
+  protected Color shadow;
+
+  /** The highlight color. */
+  protected Color highlight;
+
+  /**
+   * Creates a new UI delegate for the given JComponent.
+   *
+   * @param c The JComponent to create a delegate for.
+   *
+   * @return A new BasicSeparatorUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicSeparatorUI();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   * This can include installing defaults, listeners, and
+   * initializing any instance data.
+   *
+   * @param c The JComponent that is having this UI installed.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+
+    if (c instanceof JSeparator)
+      {
+	JSeparator s = (JSeparator) c;
+
+	installDefaults(s);
+	installListeners(s);
+      }
+  }
+
+  /**
+   * Uninstalls the UI for the given JComponent. This
+   * method reverses what was done when installing
+   * the UI on the JComponent.
+   *
+   * @param c The JComponent that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    if (c instanceof JSeparator)
+      {
+	JSeparator s = (JSeparator) c;
+
+	uninstallListeners(s);
+	uninstallDefaults(s);
+      }
+  }
+
+  /**
+   * This method installs the defaults that are given by
+   * the Basic Look and Feel.
+   *
+   * @param s The JSeparator that is being installed.
+   */
+  protected void installDefaults(JSeparator s)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    shadow = defaults.getColor("Separator.shadow");
+    highlight = defaults.getColor("Separator.highlight");
+    s.setOpaque(true);
+  }
+
+  /**
+   * This method removes the defaults that were given
+   * by the Basic Look and Feel.
+   *
+   * @param s The JSeparator that is being uninstalled.
+   */
+  protected void uninstallDefaults(JSeparator s)
+  {
+    shadow = null;
+    highlight = null;
+  }
+
+  /**
+   * This method installs any listeners that need
+   * to be attached to the JSeparator or any of its 
+   * components.
+   *
+   * @param s The JSeparator that is being installed.
+   */
+  protected void installListeners(JSeparator s)
+  {
+    // Separators don't receive events.
+  }
+
+  /**
+   * This method uninstalls any listeners that
+   * were installed during the install UI process.
+   *
+   * @param s The JSeparator that is being uninstalled.
+   */
+  protected void uninstallListeners(JSeparator s)
+  {
+    // Separators don't receive events.  
+  }
+
+  /**
+   * The separator is made of two lines. The top line will be 
+   * the highlight color (or left line if it's vertical). The bottom 
+   * or right line will be the shadow color. The two lines will 
+   * be centered inside the bounds box. If the separator is horizontal, 
+   * then it will be vertically centered, or if it's vertical, it will 
+   * be horizontally centered.
+   *
+   * @param g The Graphics object to paint with
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    Rectangle r = new Rectangle();
+    SwingUtilities.calculateInnerArea(c, r);
+    Color saved = g.getColor();
+    
+    int midAB = r.width / 2 + r.x;
+    int midAD = r.height / 2 + r.y;
+  
+    JSeparator s;
+    if (c instanceof JSeparator)
+      s = (JSeparator) c;
+    else
+      return;
+      
+    if (s.getOrientation() == JSeparator.HORIZONTAL)
+    {    
+      g.setColor(highlight);
+      g.drawLine(r.x, midAD, r.x + r.width, midAD);
+      
+      g.setColor(shadow);
+      g.drawLine(r.x, midAD + 1, r.x + r.width, midAD + 1);
+    }
+    else
+    {
+      g.setColor(highlight);
+      g.drawLine(midAB, r.y, midAB, r.y + r.height);
+      
+      g.setColor(shadow);
+      g.drawLine(midAB + 1, r.y, midAB + 1, r.y + r.height);
+    }
+  }
+
+  /**
+   * This method returns the preferred size of the 
+   * JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    Dimension dims = new Dimension(0, 0);
+    Insets insets = c.getInsets();
+
+    if (c instanceof JSeparator)
+      {
+	JSeparator s = (JSeparator) c;
+
+	if (s.getOrientation() == JSeparator.HORIZONTAL)
+	{
+	  dims.height = 2;
+	  dims.width = 40;
+	}
+	else
+	{
+	  dims.width = 2;
+	  dims.height = 40;
+	}
+      }
+    dims.width += insets.left + insets.right;
+    dims.height += insets.top + insets.bottom;
+    
+    return dims;
+  }
+
+  /**
+   * This method returns the minimum size of the
+   * JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the maximum size of the
+   * JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+}
Index: javax/swing/plaf/basic/BasicSliderUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicSliderUI.java
diff -N javax/swing/plaf/basic/BasicSliderUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicSliderUI.java	6 Sep 2004 16:36:07 -0000
@@ -0,0 +1,2217 @@
+/* BasicSliderUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import javax.swing.BoundedRangeModel;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JSlider;
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.SliderUI;
+
+
+/**
+ * <p>
+ * BasicSliderUI.java This is the UI delegate in the Basic look and feel that
+ * paints JSliders.
+ * </p>
+ * 
+ * <p>
+ * The UI delegate keeps track of 6 rectangles that place the various parts of
+ * the JSlider inside the component.
+ * </p>
+ * 
+ * <p>
+ * The rectangles are organized as follows:
+ * </p>
+ * <pre>
+ *     +-------------------------------------------------------+ <-- focusRect
+ *     |                                                       |
+ *     |  +==+-------------------+==+--------------------+==+<------ contentRect
+ *     |  |  |                   |  |<---thumbRect       |  |  |
+ *     |  |  |    TRACK          |  |                    |<--------- trackRect
+ *     |  |  +-------------------+==+--------------------+  |  |
+ *     |  |  |                                           |  |  |
+ *     |  |  |          TICKS GO HERE                    |<-------- tickRect
+ *     |  |  |                                           |  |  |
+ *     |  +==+-------------------------------------------+==+  |
+ *     |  |  |                                           |  |  |
+ *     |  |  |                                           |  |<----- labelRect
+ *     |  |  |                 LABELS GO HERE            |  |  |
+ *     |  |  |                                           |  |  |
+ *     |  |  |                                           |  |  |
+ *     |  |  |                                           |  |  |
+ *     |  |  |                                           |  |  |
+ *     |  |                                              |  |  |
+ * </pre>
+ * 
+ * <p>
+ * The space between the contentRect and the focusRect are the FocusInsets.
+ * </p>
+ * 
+ * <p>
+ * The space between the focusRect and the component bounds is the insetCache
+ * which are the component's insets.
+ * </p>
+ * 
+ * <p>
+ * The top of the thumb is the top of the contentRect. The trackRect has to be
+ * as tall as the thumb.
+ * </p>
+ * 
+ * <p>
+ * The trackRect and tickRect do not start from the left edge of the
+ * focusRect. They are trackBuffer away from each side of the focusRect. This
+ * is so that the thumb has room to move.
+ * </p>
+ * 
+ * <p>
+ * The labelRect does start right against the contentRect's left and right
+ * edges and it gets all remaining space.
+ * </p>
+ */
+public class BasicSliderUI extends SliderUI
+{
+  /**
+   * Helper class that listens to the {@link JSlider}'s model for changes.
+   */
+  protected class ChangeHandler implements ChangeListener
+  {
+    /**
+     * Called when the slider's model has been altered. The UI delegate should
+     * recalculate any rectangles that are dependent on the model for their
+     * positions and repaint.
+     *
+     * @param e A static {@link ChangeEvent} passed from the model.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      // Maximum, minimum, and extent values will be taken
+      // care of automatically when the slider is repainted.
+      // Only thing that needs recalculation is the thumb.
+      calculateThumbLocation();
+      slider.repaint();
+    }
+  }
+
+  /**
+   * Helper class that listens for resize events.
+   */
+  protected class ComponentHandler extends ComponentAdapter
+  {
+    /**
+     * Called when the size of the component changes. The UI delegate should
+     * recalculate any rectangles that are dependent on the model for their
+     * positions and repaint.
+     *
+     * @param e A {@link ComponentEvent}.
+     */
+    public void componentResized(ComponentEvent e)
+    {
+      calculateGeometry();
+
+      slider.revalidate();
+      slider.repaint();
+    }
+  }
+
+  /**
+   * Helper class that listens for focus events.
+   */
+  protected class FocusHandler implements FocusListener
+  {
+    /**
+     * Called when the {@link JSlider} has gained focus.  It should repaint
+     * the slider with the focus drawn.
+     *
+     * @param e A {@link FocusEvent}.
+     */
+    public void focusGained(FocusEvent e)
+    {
+      // FIXME: implement.
+    }
+
+    /**
+     * Called when the {@link JSlider} has lost focus. It  should repaint the
+     * slider without the focus drawn.
+     *
+     * @param e A {@link FocusEvent}.
+     */
+    public void focusLost(FocusEvent e)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * Helper class that listens for changes to the properties of the {@link
+   * JSlider}.
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * Called when one of the properties change. The UI should recalculate any
+     * rectangles if necessary and repaint.
+     *
+     * @param e A {@link PropertyChangeEvent}.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      // Check for orientation changes.
+      if (e.getPropertyName().equals(JSlider.ORIENTATION_CHANGED_PROPERTY))
+	recalculateIfOrientationChanged();
+      else if (e.getPropertyName().equals(JSlider.MODEL_CHANGED_PROPERTY))
+      {
+        BoundedRangeModel oldModel = (BoundedRangeModel) e.getOldValue();
+	oldModel.removeChangeListener(changeListener);
+	slider.getModel().addChangeListener(changeListener);
+	calculateThumbLocation();
+      }
+
+      // elif the componentOrientation changes (this is a bound property,
+      // just undocumented) we change leftToRightCache. In Sun's 
+      // implementation, the LTR cache changes on a repaint. This is strange
+      // since there is no need to do so. We could events here and 
+      // update the cache. 
+      // elif the border/insets change, we recalculateInsets.
+      slider.repaint();
+    }
+  }
+
+  /**
+   * Helper class that listens to our swing timer. This class is responsible
+   * for listening to the timer and moving the thumb in the proper direction
+   * every interval.
+   */
+  protected class ScrollListener implements ActionListener
+  {
+    /** Indicates which direction the thumb should scroll. */
+    private transient int direction;
+
+    /** Indicates whether we should scroll in blocks or in units. */
+    private transient boolean block;
+
+    /**
+     * Creates a new ScrollListener object.
+     */
+    public ScrollListener()
+    {
+      direction = POSITIVE_SCROLL;
+      block = false;
+    }
+
+    /**
+     * Creates a new ScrollListener object.
+     *
+     * @param dir The direction to scroll in.
+     * @param block If movement will be in blocks.
+     */
+    public ScrollListener(int dir, boolean block)
+    {
+      direction = dir;
+      this.block = block;
+    }
+
+    /**
+     * Called every time the swing timer reaches its interval. If the thumb
+     * needs to move, then this method will move the thumb one block or  unit
+     * in the direction desired. Otherwise, the timer can be stopped.
+     *
+     * @param e An {@link ActionEvent}.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (! trackListener.shouldScroll(direction))
+        {
+	  scrollTimer.stop();
+	  return;
+        }
+
+      if (block)
+	scrollByBlock(direction);
+      else
+	scrollByUnit(direction);
+    }
+
+    /**
+     * Sets the direction to scroll in.
+     *
+     * @param direction The direction to scroll in.
+     */
+    public void setDirection(int direction)
+    {
+      this.direction = direction;
+    }
+
+    /**
+     * Sets whether movement will be in blocks.
+     *
+     * @param block If movement will be in blocks.
+     */
+    public void setScrollByBlock(boolean block)
+    {
+      this.block = block;
+    }
+  }
+
+  /**
+   * Helper class that listens for mouse events.
+   */
+  protected class TrackListener extends MouseInputAdapter
+  {
+    /** The current X position of the mouse. */
+    protected int currentMouseX;
+
+    /** The current Y position of the mouse. */
+    protected int currentMouseY;
+
+    /**
+     * The offset between the current slider value and the cursor's position.
+     */
+    protected int offset;
+
+    /**
+     * Called when the mouse has been dragged. This should find the mouse's
+     * current position and adjust the value of the {@link JSlider}
+     * accordingly.
+     *
+     * @param e A {@link MouseEvent}
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      currentMouseX = e.getX();
+      currentMouseY = e.getY();
+      if (slider.getValueIsAdjusting())
+      {
+        int value;
+        if (slider.getOrientation() == JSlider.HORIZONTAL)
+	  value = valueForXPosition(currentMouseX) - offset;
+	else
+	  value = valueForYPosition(currentMouseY) - offset;
+	
+	slider.setValue(value);
+      }
+    }
+
+    /**
+     * Called when the mouse has moved over a component but no buttons have
+     * been pressed yet.
+     *
+     * @param e A {@link MouseEvent}
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // Don't care that we're moved unless we're dragging.
+    }
+
+    /**
+     * Called when the mouse is pressed. When the press occurs on the thumb
+     * itself, the {@link JSlider} should have its value set to where the
+     * mouse was pressed. If the press occurs on the track, then the thumb
+     * should move one block towards the direction of the mouse.
+     *
+     * @param e A {@link MouseEvent}
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      currentMouseX = e.getX();
+      currentMouseY = e.getY();
+
+      int value;
+      if (slider.getOrientation() == JSlider.HORIZONTAL)
+	value = valueForXPosition(currentMouseX);
+      else
+	value = valueForYPosition(currentMouseY);
+
+      if (slider.getSnapToTicks())
+	value = findClosestTick(value);
+
+      // If the thumb is hit, then we don't need to set the timers to move it. 
+      if (!thumbRect.contains(e.getPoint()))
+        {
+	  // The mouse has hit some other part of the slider.
+	  // The value moves no matter where in the slider you hit.
+	  if (value > slider.getValue())
+	    scrollDueToClickInTrack(POSITIVE_SCROLL);
+	  else
+	    scrollDueToClickInTrack(NEGATIVE_SCROLL);
+        }
+      else
+        {
+	  slider.setValueIsAdjusting(true);
+          offset = value - slider.getValue();
+	}
+    }
+
+    /**
+     * Called when the mouse is released.  This should stop the timer that
+     * scrolls the thumb.
+     *
+     * @param e A {@link MouseEvent}
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      currentMouseX = e.getX();
+      currentMouseY = e.getY();
+
+      if (slider.getValueIsAdjusting())
+      {
+        slider.setValueIsAdjusting(false);
+	if (slider.getSnapToTicks())
+	  slider.setValue(findClosestTick(slider.getValue()));
+      }
+      if (scrollTimer != null)
+	scrollTimer.stop();
+    }
+
+    /**
+     * Indicates whether the thumb should scroll in the given direction.
+     *
+     * @param direction The direction to check.
+     *
+     * @return True if the thumb should move in that direction.
+     */
+    public boolean shouldScroll(int direction)
+    {
+      int value;
+      if (slider.getOrientation() == JSlider.HORIZONTAL)
+	value = valueForXPosition(currentMouseX);
+      else
+	value = valueForYPosition(currentMouseY);
+
+      if (direction == POSITIVE_SCROLL)
+	return (value > slider.getValue());
+      else
+	return (value < slider.getValue());
+    }
+  }
+
+  /** The preferred height of the thumb. */
+  private transient int thumbHeight;
+
+  /** The preferred width of the thumb. */
+  private transient int thumbWidth;
+
+  /** The preferred height of the tick rectangle. */
+  private transient int tickHeight;
+
+  /** Listener for changes from the model. */
+  protected ChangeListener changeListener;
+
+  /** Listener for changes to the {@link JSlider}. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** Listener for the scrollTimer. */
+  protected ScrollListener scrollListener;
+
+  /** Listener for component resizing. */
+  protected ComponentListener componentListener;
+
+  /** Listener for focus handling. */
+  protected FocusListener focusListener;
+
+  /** Listener for mouse events. */
+  protected TrackListener trackListener;
+
+  /** The insets between the FocusRectangle and the ContentRectangle. */
+  protected Insets focusInsets;
+
+  /** The {@link JSlider}'s insets. */
+  protected Insets insetCache;
+
+  /** Rectangle describing content bounds. See diagram above. */
+  protected Rectangle contentRect;
+
+  /** Rectangle describing focus bounds. See diagram above. */
+  protected Rectangle focusRect;
+
+  /** Rectangle describing the thumb's bounds. See diagram above. */
+  protected Rectangle thumbRect;
+
+  /** Rectangle describing the tick bounds. See diagram above. */
+  protected Rectangle tickRect;
+
+  /** Rectangle describing the label bounds. See diagram above. */
+  protected Rectangle labelRect;
+
+  /** Rectangle describing the track bounds. See diagram above. */
+  protected Rectangle trackRect;
+
+  /** FIXME: use this somewhere. */
+  public static final int MAX_SCROLL = 2;
+
+  /** FIXME: use this somewhere. */
+  public static final int MIN_SCROLL = -2;
+
+  /** A constant describing scrolling towards the minimum. */
+  public static final int NEGATIVE_SCROLL = -1;
+
+  /** A constant describing scrolling towards the maximum. */
+  public static final int POSITIVE_SCROLL = 1;
+
+  /** The gap between the edges of the contentRect and trackRect. */
+  protected int trackBuffer;
+
+  /** Whether this slider is actually drawn left to right. */
+  protected boolean leftToRightCache;
+
+  /** A timer that periodically moves the thumb. */
+  protected Timer scrollTimer;
+
+  /** A reference to the {@link JSlider} that this UI was created for. */
+  protected JSlider slider;
+
+  /** The shadow color. */
+  private transient Color shadowColor;
+
+  /** The highlight color. */
+  private transient Color highlightColor;
+
+  /** The focus color. */
+  private transient Color focusColor;
+
+  /**
+   * Creates a new Basic look and feel Slider UI.
+   *
+   * @param b The {@link JSlider} that this UI was created for.
+   */
+  public BasicSliderUI(JSlider b)
+  {
+    super();
+  }
+
+  /**
+   * Gets the shadow color to be used for this slider. The shadow color is the
+   * color used for drawing the top and left edges of the track.
+   *
+   * @return The shadow color.
+   */
+  protected Color getShadowColor()
+  {
+    return shadowColor;
+  }
+
+  /**
+   * Gets the highlight color to be used for this slider. The highlight color
+   * is the color used for drawing the bottom and right edges of the track.
+   *
+   * @return The highlight color.
+   */
+  protected Color getHighlightColor()
+  {
+    return highlightColor;
+  }
+
+  /**
+   * Gets the focus color to be used for this slider. The focus color is the
+   * color used for drawing the focus rectangle when the component gains
+   * focus.
+   *
+   * @return The focus color.
+   */
+  protected Color getFocusColor()
+  {
+    return focusColor;
+  }
+
+  /**
+   * Factory method to create a BasicSliderUI for the given {@link
+   * JComponent}, which should be a {@link JSlider}.
+   *
+   * @param b The {@link JComponent} a UI is being created for.
+   *
+   * @return A BasicSliderUI for the {@link JComponent}.
+   */
+  public static ComponentUI createUI(JComponent b)
+  {
+    return new BasicSliderUI((JSlider) b);
+  }
+
+  /**
+   * Installs and initializes all fields for this UI delegate. Any properties
+   * of the UI that need to be initialized and/or set to defaults will be
+   * done now. It will also install any listeners necessary.
+   *
+   * @param c The {@link JComponent} that is having this UI installed.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    if (c instanceof JSlider)
+      {
+	slider = (JSlider) c;
+
+	focusRect = new Rectangle();
+	contentRect = new Rectangle();
+	thumbRect = new Rectangle();
+	trackRect = new Rectangle();
+	tickRect = new Rectangle();
+	labelRect = new Rectangle();
+
+	insetCache = slider.getInsets();
+	leftToRightCache = ! slider.getInverted();
+
+	scrollTimer = new Timer(200, null);
+	scrollTimer.setRepeats(true);
+
+	installDefaults(slider);
+	installListeners(slider);
+	installKeyboardActions(slider);
+
+	calculateFocusRect();
+
+	calculateContentRect();
+	calculateThumbSize();
+	calculateTrackBuffer();
+	calculateTrackRect();
+	calculateThumbLocation();
+
+	calculateTickRect();
+	calculateLabelRect();
+      }
+  }
+
+  /**
+   * Performs the opposite of installUI. Any properties or resources that need
+   * to be cleaned up will be done now. It will also uninstall any listeners
+   * it has. In addition, any properties of this UI will be nulled.
+   *
+   * @param c The {@link JComponent} that is having this UI uninstalled.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    super.uninstallUI(c);
+
+    uninstallKeyboardActions(slider);
+    uninstallListeners(slider);
+
+    scrollTimer = null;
+
+    focusRect = null;
+    contentRect = null;
+    thumbRect = null;
+    trackRect = null;
+    tickRect = null;
+    labelRect = null;
+
+    focusInsets = null;
+  }
+
+  /**
+   * Initializes any default properties that this UI has from the defaults for
+   * the Basic look and feel.
+   *
+   * @param slider The {@link JSlider} that is having this UI installed.
+   */
+  protected void installDefaults(JSlider slider)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    slider.setForeground(defaults.getColor("Slider.foreground"));
+    slider.setBackground(defaults.getColor("Slider.background"));
+    shadowColor = defaults.getColor("Slider.shadow");
+    highlightColor = defaults.getColor("Slider.highlight");
+    focusColor = defaults.getColor("Slider.focus");
+    slider.setBorder(defaults.getBorder("Slider.border"));
+    slider.setOpaque(true);
+
+    thumbHeight = defaults.getInt("Slider.thumbHeight");
+    thumbWidth = defaults.getInt("Slider.thumbWidth");
+    tickHeight = defaults.getInt("Slider.tickHeight");
+
+    focusInsets = defaults.getInsets("Slider.focusInsets");
+  }
+
+  /**
+   * Creates a new {@link TrackListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link TrackListener} is
+   *        created for.
+   *
+   * @return A new {@link TrackListener}.
+   */
+  protected TrackListener createTrackListener(JSlider slider)
+  {
+    return new TrackListener();
+  }
+
+  /**
+   * Creates a new {@link ChangeListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link ChangeListener} is
+   *        created for.
+   *
+   * @return A new {@link ChangeListener}.
+   */
+  protected ChangeListener createChangeListener(JSlider slider)
+  {
+    return new ChangeHandler();
+  }
+
+  /**
+   * Creates a new {@link ComponentListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link ComponentListener} is
+   *        created for.
+   *
+   * @return A new {@link ComponentListener}.
+   */
+  protected ComponentListener createComponentListener(JSlider slider)
+  {
+    return new ComponentHandler();
+  }
+
+  /**
+   * Creates a new {@link FocusListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link FocusListener} is
+   *        created for.
+   *
+   * @return A new {@link FocusListener}.
+   */
+  protected FocusListener createFocusListener(JSlider slider)
+  {
+    return new FocusHandler();
+  }
+
+  /**
+   * Creates a new {@link ScrollListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link ScrollListener} is
+   *        created for.
+   *
+   * @return A new {@link ScrollListener}.
+   */
+  protected ScrollListener createScrollListener(JSlider slider)
+  {
+    return new ScrollListener();
+  }
+
+  /**
+   * Creates a new {@link PropertyChangeListener}.
+   *
+   * @param slider The {@link JSlider} that this {@link
+   *        PropertyChangeListener} is created for.
+   *
+   * @return A new {@link PropertyChangeListener}.
+   */
+  protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * Creates and registers all the listeners for this UI delegate. This
+   * includes creating the ScrollListener and registering it to the timer.
+   *
+   * @param slider The {@link JSlider} is having listeners installed.
+   */
+  protected void installListeners(JSlider slider)
+  {
+    propertyChangeListener = createPropertyChangeListener(slider);
+    componentListener = createComponentListener(slider);
+    trackListener = createTrackListener(slider);
+    focusListener = createFocusListener(slider);
+    changeListener = createChangeListener(slider);
+    scrollListener = createScrollListener(slider);
+
+    slider.addPropertyChangeListener(propertyChangeListener);
+    slider.addComponentListener(componentListener);
+    slider.addMouseListener(trackListener);
+    slider.addMouseMotionListener(trackListener);
+    slider.addFocusListener(focusListener);
+    slider.getModel().addChangeListener(changeListener);
+
+    scrollTimer.addActionListener(scrollListener);
+  }
+
+  /**
+   * Unregisters all the listeners that this UI delegate was using. In
+   * addition, it will also null any listeners that it was using.
+   *
+   * @param slider The {@link JSlider} that is having listeners removed.
+   */
+  protected void uninstallListeners(JSlider slider)
+  {
+    slider.removePropertyChangeListener(propertyChangeListener);
+    slider.removeComponentListener(componentListener);
+    slider.removeMouseListener(trackListener);
+    slider.removeMouseMotionListener(trackListener);
+    slider.removeFocusListener(focusListener);
+    slider.getModel().removeChangeListener(changeListener);
+
+    scrollTimer.removeActionListener(scrollListener);
+
+    propertyChangeListener = null;
+    componentListener = null;
+    trackListener = null;
+    focusListener = null;
+    changeListener = null;
+    scrollListener = null;
+  }
+
+  /**
+   * Installs any keyboard actions. The list of keys that need to be bound are
+   * listed in Basic look and feel's defaults.
+   *
+   * @param slider The {@link JSlider} that is having keyboard actions
+   *        installed.
+   */
+  protected void installKeyboardActions(JSlider slider)
+  {
+    // FIXME: implement.
+  }
+
+  /**
+   * Uninstalls any keyboard actions. The list of keys used  are listed in
+   * Basic look and feel's defaults.
+   *
+   * @param slider The {@link JSlider} that is having keyboard actions
+   *        uninstalled.
+   */
+  protected void uninstallKeyboardActions(JSlider slider)
+  {
+    // FIXME: implement.
+  }
+
+  /* XXX: This is all after experimentation with SUN's implementation.
+
+     PreferredHorizontalSize seems to be 200x21.
+     PreferredVerticalSize seems to be 21x200.
+
+     MinimumHorizontalSize seems to be 36x21.
+     MinimumVerticalSize seems to be 21x36.
+
+     PreferredSize seems to be 200x63. Or Components.getBounds?
+
+     MinimumSize seems to be 36x63.
+
+     MaximumSize seems to be 32767x63.
+   */
+
+  /**
+   * This method returns the preferred size when the slider is horizontally
+   * oriented.
+   *
+   * @return The dimensions of the preferred horizontal size.
+   */
+  public Dimension getPreferredHorizontalSize()
+  {
+    Insets insets = slider.getInsets();
+    
+    // The width should cover all the labels (which are usually the
+    // deciding factor of the width)
+    int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? 0
+                                                                          : slider.getLabelTable()
+                                                                                  .size());
+    
+    // If there are not enough labels.
+    // This number is pretty much arbitrary, but it looks nice.
+    if (width < 200)
+      width = 200;
+    
+    // We can only draw inside of the focusRectangle, so we have to
+    // pad it with insets.
+    width += insets.left + insets.right + focusInsets.left + focusInsets.right;
+      
+    // Height is determined by the thumb, the ticks and the labels.
+    int height = thumbHeight;
+
+    if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+        || slider.getMinorTickSpacing() > 0)
+      height += tickHeight;
+
+    if (slider.getPaintLabels())
+      height += getHeightOfTallestLabel();
+    
+    height += insets.top + insets.bottom + focusInsets.top
+    + focusInsets.bottom;
+	      
+    return new Dimension(width, height);
+  }
+
+  /**
+   * This method returns the preferred size when the slider is vertically
+   * oriented.
+   *
+   * @return The dimensions of the preferred vertical size.
+   */
+  public Dimension getPreferredVerticalSize()
+  {
+    Insets insets = slider.getInsets();
+    
+    int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null
+                                              ? 0 : slider.getLabelTable()
+                                                          .size());
+    
+    if (height < 200)
+      height = 200;
+      
+    height += insets.top + insets.bottom + focusInsets.top
+    + focusInsets.bottom;
+
+    int width = thumbHeight;
+    
+    if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
+        || slider.getMinorTickSpacing() > 0)
+      width += tickHeight;
+
+    if (slider.getPaintLabels())
+      width += getWidthOfWidestLabel();
+
+    width += insets.left + insets.right + focusInsets.left + focusInsets.right;
+	     
+    return new Dimension(width, height);
+  }
+
+  /**
+   * This method returns the minimum size when the slider is horizontally
+   * oriented.
+   *
+   * @return The dimensions of the minimum horizontal size.
+   */
+  public Dimension getMinimumHorizontalSize()
+  {
+    return getPreferredHorizontalSize();
+  }
+
+  /**
+   * This method returns the minimum size of the slider when it  is vertically
+   * oriented.
+   *
+   * @return The dimensions of the minimum vertical size.
+   */
+  public Dimension getMinimumVerticalSize()
+  {
+    return getPreferredVerticalSize();
+  }
+
+  /**
+   * This method returns the preferred size of the component. If it returns
+   * null, then it is up to the Layout Manager to give the {@link JComponent}
+   * a size.
+   *
+   * @param c The {@link JComponent} to find the preferred size for.
+   *
+   * @return The dimensions of the preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {   
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      return getPreferredHorizontalSize();
+    else
+      return getPreferredVerticalSize();
+  }
+
+  /**
+   * This method returns the minimum size for this {@link JSlider}  for this
+   * look and feel. If it returns null, then it is up to the Layout Manager
+   * to give the {@link JComponent} a size.
+   *
+   * @param c The {@link JComponent} to find the minimum size for.
+   *
+   * @return The dimensions of the minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      return getPreferredHorizontalSize();
+    else
+      return getPreferredVerticalSize();
+  }
+
+  /**
+   * This method returns the maximum size for this {@link JSlider} for this
+   * look and feel. If it returns null, then it is up to the Layout Manager
+   * to give the {@link JComponent} a size.
+   *
+   * @param c The {@link JComponent} to find a maximum size for.
+   *
+   * @return The dimensions of the maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      return getPreferredHorizontalSize();
+    else
+      return getPreferredVerticalSize();
+  }
+  
+  /**
+   * This method calculates all the sizes of the rectangles by delegating to
+   * the helper methods calculateXXXRect.
+   */
+   protected void calculateGeometry()
+   {
+     calculateFocusRect();
+     calculateContentRect();
+     calculateThumbSize();
+     calculateTrackBuffer();
+     calculateTrackRect();
+     calculateTickRect();
+     calculateLabelRect();
+     calculateThumbLocation();
+   }
+
+  /**
+   * This method calculates the size and position of the focusRect. This
+   * method does not need to be called if the orientation changes.
+   */
+  protected void calculateFocusRect()
+  {
+    insetCache = slider.getInsets();
+    focusRect = SwingUtilities.calculateInnerArea(slider, focusRect);
+
+    if (focusRect.width < 0)
+      focusRect.width = 0;
+    if (focusRect.height < 0)
+      focusRect.height = 0;
+  }
+
+  /**
+   * This method calculates the size but not the position of the thumbRect. It
+   * must take into account the orientation of the slider.
+   */
+  protected void calculateThumbSize()
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	if (thumbWidth > contentRect.width)
+	  thumbRect.width = contentRect.width / 4;
+	else
+	  thumbRect.width = thumbWidth;
+	if (thumbHeight > contentRect.height)
+	  thumbRect.height = contentRect.height;
+	else
+	  thumbRect.height = thumbHeight;
+      }
+    else
+      {
+	// The thumb gets flipped when inverted, so thumbWidth 
+	// actually is the height and vice versa.
+	if (thumbWidth > contentRect.height)
+	  thumbRect.height = contentRect.height / 4;
+	else
+	  thumbRect.height = thumbWidth;
+	if (thumbHeight > contentRect.width)
+	  thumbRect.width = contentRect.width;
+	else
+	  thumbRect.width = thumbHeight;
+      }
+  }
+
+  /**
+   * This method calculates the size and position of the contentRect. This
+   * method does not need to be  called if the orientation changes.
+   */
+  protected void calculateContentRect()
+  {
+    contentRect.x = focusRect.x + focusInsets.left;
+    contentRect.y = focusRect.y + focusInsets.top;
+    contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
+    contentRect.height = focusRect.height - focusInsets.top
+                         - focusInsets.bottom;
+
+    if (contentRect.width < 0)
+      contentRect.width = 0;
+    if (contentRect.height < 0)
+      contentRect.height = 0;
+  }
+
+  /**
+   * Calculates the position of the thumbRect based on the current value of
+   * the slider. It must take into  account the orientation of the slider.
+   */
+  protected void calculateThumbLocation()
+  {
+    int value = slider.getValue();
+
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	thumbRect.x = xPositionForValue(value) - thumbRect.width / 2;
+	thumbRect.y = contentRect.y;
+      }
+    else
+      {
+	thumbRect.x = contentRect.x;
+	thumbRect.y = yPositionForValue(value) - thumbRect.height / 2;
+      }
+  }
+
+  /**
+   * Calculates the gap size between the left edge of the contentRect and the
+   * left edge of the trackRect.
+   */
+  protected void calculateTrackBuffer()
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      trackBuffer = thumbRect.width;
+    else
+      trackBuffer = thumbRect.height;
+  }
+
+  /**
+   * This method returns the size of the thumbRect.
+   *
+   * @return The dimensions of the thumb.
+   */
+  protected Dimension getThumbSize()
+  {
+    // This is really just the bounds box for the thumb.
+    // The thumb will actually be pointed (like a rectangle + triangle at bottom)
+    return thumbRect.getSize();
+  }
+
+  /**
+   * Calculates the size and position of the trackRect. It must take into
+   * account the orientation of the slider.
+   */
+  protected void calculateTrackRect()
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	trackRect.x = contentRect.x + trackBuffer;
+	trackRect.y = contentRect.y;
+	trackRect.width = contentRect.width - 2 * trackBuffer;
+	trackRect.height = thumbRect.height;
+      }
+    else
+      {
+	trackRect.x = contentRect.x;
+	trackRect.y = contentRect.y + trackBuffer;
+	trackRect.width = thumbRect.width;
+	trackRect.height = contentRect.height - 2 * trackBuffer;
+      }
+  }
+
+  /**
+   * This method returns the height of the tick area box if the slider  is
+   * horizontal and the width of the tick area box is the slider is vertical.
+   * It not necessarily how long the ticks will be. If a gap between the edge
+   * of tick box and the actual tick is desired, then that will need to be
+   * handled in the tick painting methods.
+   *
+   * @return The height (or width if the slider is vertical) of the tick
+   *         rectangle.
+   */
+  protected int getTickLength()
+  {
+    return tickHeight;
+  }
+
+  /**
+   * This method calculates the size and position of the tickRect. It must
+   * take into account the orientation of the slider.
+   */
+  protected void calculateTickRect()
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	tickRect.x = trackRect.x;
+	tickRect.y = trackRect.y + trackRect.height;
+	tickRect.width = trackRect.width;
+	tickRect.height = getTickLength();
+
+	if (tickRect.y + tickRect.height > contentRect.y + contentRect.height)
+	  tickRect.height = contentRect.y + contentRect.height - tickRect.y;
+      }
+    else
+      {
+	tickRect.x = trackRect.x + trackRect.width;
+	tickRect.y = trackRect.y;
+	tickRect.width = getTickLength();
+	tickRect.height = trackRect.height;
+
+	if (tickRect.x + tickRect.width > contentRect.x + contentRect.width)
+	  tickRect.width = contentRect.x + contentRect.width - tickRect.x;
+      }
+  }
+
+  /**
+   * This method calculates the size and position of the labelRect. It must
+   * take into account the orientation of the slider.
+   */
+  protected void calculateLabelRect()
+  {
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	labelRect.x = contentRect.x;
+	labelRect.y = tickRect.y + tickRect.height;
+	labelRect.width = contentRect.width;
+	labelRect.height = contentRect.height - labelRect.y;
+      }
+    else
+      {
+	labelRect.x = tickRect.x + tickRect.width;
+	labelRect.y = contentRect.y;
+	labelRect.width = contentRect.width - labelRect.x;
+	labelRect.height = contentRect.height;
+      }
+  }
+
+  /**
+   * This method returns the width of the widest label  in the slider's label
+   * table.
+   *
+   * @return The width of the widest label or 0 if no label table exists.
+   */
+  protected int getWidthOfWidestLabel()
+  {
+    int widest = 0;
+    Component label;
+
+    if (slider.getLabelTable() == null)
+      return 0;
+
+    Dimension pref;
+    for (Enumeration list = slider.getLabelTable().elements();
+         list.hasMoreElements();)
+      {
+	Object comp = list.nextElement();
+	if (! (comp instanceof Component))
+	  continue;
+	label = (Component) comp;
+	pref = label.getPreferredSize();
+	if (pref != null && pref.width > widest)
+	  widest = pref.width;
+      }
+    return widest;
+  }
+
+  /**
+   * This method returns the height of the tallest label in the slider's label
+   * table.
+   *
+   * @return The height of the tallest label or 0 if no label table exists.
+   */
+  protected int getHeightOfTallestLabel()
+  {
+    int tallest = 0;
+    Component label;
+
+    if (slider.getLabelTable() == null)
+      return 0;
+    Dimension pref;
+    for (Enumeration list = slider.getLabelTable().elements();
+         list.hasMoreElements();)
+      {
+	Object comp = list.nextElement();
+	if (! (comp instanceof Component))
+	  continue;
+	label = (Component) comp;
+	pref = label.getPreferredSize();
+	if (pref != null && pref.height > tallest)
+	  tallest = pref.height;
+      }
+    return tallest;
+  }
+
+  /**
+   * This method returns the width of the label whose key has the highest
+   * value.
+   *
+   * @return The width of the high value label or 0 if no label table exists.
+   */
+  protected int getWidthOfHighValueLabel()
+  {
+    Component highValueLabel = getHighestValueLabel();
+    if (highValueLabel != null)
+      return highValueLabel.getWidth();
+    else
+      return 0;
+  }
+
+  /**
+   * This method returns the width of the label whose key has the lowest
+   * value.
+   *
+   * @return The width of the low value label or 0 if no label table exists.
+   */
+  protected int getWidthOfLowValueLabel()
+  {
+    Component lowValueLabel = getLowestValueLabel();
+    if (lowValueLabel != null)
+      return lowValueLabel.getWidth();
+    else
+      return 0;
+  }
+
+  /**
+   * This method returns the height of the label whose key has the highest
+   * value.
+   *
+   * @return The height of the high value label or 0 if no label table exists.
+   */
+  protected int getHeightOfHighValueLabel()
+  {
+    Component highValueLabel = getHighestValueLabel();
+    if (highValueLabel != null)
+      return highValueLabel.getHeight();
+    else
+      return 0;
+  }
+
+  /**
+   * This method returns the height of the label whose key has the lowest
+   * value.
+   *
+   * @return The height of the low value label or 0 if no label table exists.
+   */
+  protected int getHeightOfLowValueLabel()
+  {
+    Component lowValueLabel = getLowestValueLabel();
+    if (lowValueLabel != null)
+      return lowValueLabel.getHeight();
+    else
+      return 0;
+  }
+
+  /**
+   * This method returns whether the slider is to be drawn inverted.
+   *
+   * @return True is the slider is to be drawn inverted.
+   */
+  protected boolean drawInverted()
+  {
+    return ! (slider.getInverted() ^ leftToRightCache);
+  }
+
+  /**
+   * This method returns the label whose key has the lowest value.
+   *
+   * @return The low value label or null if no label table exists.
+   */
+  protected Component getLowestValueLabel()
+  {
+    Integer key = new Integer(Integer.MAX_VALUE);
+    Integer tmpKey;
+    Dictionary labelTable = slider.getLabelTable();
+
+    if (labelTable == null)
+      return null;
+
+    for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
+      {
+	Object value = list.nextElement();
+	if (! (value instanceof Integer))
+	  continue;
+	tmpKey = (Integer) value;
+	if (tmpKey.intValue() < key.intValue())
+	  key = tmpKey;
+      }
+    Object comp = labelTable.get(key);
+    if (! (comp instanceof Component))
+      return null;
+    return (Component) comp;
+  }
+
+  /**
+   * This method returns the label whose  key has the highest value.
+   *
+   * @return The high value label or null if no label table exists.
+   */
+  protected Component getHighestValueLabel()
+  {
+    Integer key = new Integer(Integer.MIN_VALUE);
+    Integer tmpKey;
+    Dictionary labelTable = slider.getLabelTable();
+
+    if (labelTable == null)
+      return null;
+
+    for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
+      {
+	Object value = list.nextElement();
+	if (! (value instanceof Integer))
+	  continue;
+	tmpKey = (Integer) value;
+	if (tmpKey.intValue() > key.intValue())
+	  key = tmpKey;
+      }
+    Object comp = labelTable.get(key);
+    if (! (comp instanceof Component))
+      return null;
+    return (Component) comp;
+  }
+
+  /**
+   * This method is used to paint the {@link JSlider}. It delegates all its
+   * duties to the various paint methods like paintTicks(),  paintTrack(),
+   * paintThumb(), etc.
+   *
+   * @param g The {@link Graphics} object to paint with.
+   * @param c The {@link JComponent} that is being painted.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    // FIXME: Move this to propertyChangeEvent handler, when we get those.
+    leftToRightCache = slider.getComponentOrientation() != ComponentOrientation.RIGHT_TO_LEFT;
+    // FIXME: This next line is only here because the above line is here.
+    calculateThumbLocation();
+    
+    if (slider.getPaintTrack())
+      paintTrack(g);
+    if (slider.getPaintTicks())
+      paintTicks(g);
+    if (slider.getPaintLabels())
+      paintLabels(g);
+
+    //FIXME: Paint focus.
+    paintThumb(g);
+  }
+
+  /**
+   * This method recalculates any rectangles that need to be recalculated
+   * after the insets of the component have changed.
+   */
+  protected void recalculateIfInsetsChanged()
+  {
+    // Examining a test program shows that either Sun calls private
+    // methods that we don't know about, or these don't do anything.
+    calculateFocusRect();
+
+    calculateContentRect();
+    calculateThumbSize();
+    calculateTrackBuffer();
+    calculateTrackRect();
+    calculateThumbLocation();
+
+    calculateTickRect();
+    calculateLabelRect();
+  }
+
+  /**
+   * This method recalculates any rectangles that need to be recalculated
+   * after the orientation of the slider changes.
+   */
+  protected void recalculateIfOrientationChanged()
+  {
+    // Examining a test program shows that either Sun calls private
+    // methods that we don't know about, or these don't do anything.  
+    calculateThumbSize();
+    calculateTrackBuffer();
+    calculateTrackRect();
+    calculateThumbLocation();
+
+    calculateTickRect();
+    calculateLabelRect();
+  }
+
+  /**
+   * This method is called during a repaint if the slider has focus. It draws
+   * an outline of the  focusRect using the color returned by
+   * getFocusColor().
+   *
+   * @param g The {@link Graphics} object to draw with.
+   */
+  public void paintFocus(Graphics g)
+  {
+    Color saved_color = g.getColor();
+
+    g.setColor(getFocusColor());
+
+    g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
+
+    g.setColor(saved_color);
+  }
+
+  /**
+   * <p>
+   * This method is called during a repaint if the  track is to be drawn. It
+   * draws a 3D rectangle to  represent the track. The track is not the size
+   * of the trackRect. The top and left edges of the track should be outlined
+   * with the shadow color. The bottom and right edges should be outlined
+   * with the highlight color.
+   * </p>
+   * <pre>
+   *    a---d   
+   *    |   |   
+   *    |   |   a------------------------d
+   *    |   |   |                        |
+   *    |   |   b------------------------c
+   *    |   |
+   *    |   |   
+   *    b---c
+   * </pre>
+   * 
+   * <p>
+   * The b-a-d path needs to be drawn with the shadow color and the b-c-d path
+   * needs to be drawn with the highlight color.
+   * </p>
+   *
+   * @param g The {@link Graphics} object to draw with.
+   */
+  public void paintTrack(Graphics g)
+  {
+    Color saved_color = g.getColor();
+    int width;
+    int height;
+
+    Point a = new Point(trackRect.x, trackRect.y);
+    Point b = new Point(a);
+    Point c = new Point(a);
+    Point d = new Point(a);
+
+    Polygon high;
+    Polygon shadow;
+
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	width = trackRect.width;
+	height = (thumbRect.height / 4 == 0) ? 1 : thumbRect.height / 4;
+
+	a.translate(0, (trackRect.height / 2) - (height / 2));
+	b.translate(0, (trackRect.height / 2) + (height / 2));
+	c.translate(trackRect.width, (trackRect.height / 2) + (height / 2));
+	d.translate(trackRect.width, (trackRect.height / 2) - (height / 2));
+      }
+    else
+      {
+	width = (thumbRect.width / 4 == 0) ? 1 : thumbRect.width / 4;
+	height = trackRect.height;
+
+	a.translate((trackRect.width / 2) - (width / 2), 0);
+	b.translate((trackRect.width / 2) - (width / 2), trackRect.height);
+	c.translate((trackRect.width / 2) + (width / 2), trackRect.height);
+	d.translate((trackRect.width / 2) + (width / 2), 0);
+      }
+    g.setColor(Color.GRAY);
+    g.fillRect(a.x, a.y, width, height);
+
+    g.setColor(getHighlightColor());
+    g.drawLine(b.x, b.y, c.x, c.y);
+    g.drawLine(c.x, c.y, d.x, d.y);
+
+    g.setColor(getShadowColor());
+    g.drawLine(b.x, b.y, a.x, a.y);
+    g.drawLine(a.x, a.y, d.x, d.y);
+
+    g.setColor(saved_color);
+  }
+
+  /**
+   * This method is called during a repaint if the ticks are to be drawn. This
+   * method must still verify that the majorTickSpacing and minorTickSpacing
+   * are greater than zero before drawing the ticks.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   */
+  public void paintTicks(Graphics g)
+  {
+    int max = slider.getMaximum();
+    int min = slider.getMinimum();
+    int majorSpace = slider.getMajorTickSpacing();
+    int minorSpace = slider.getMinorTickSpacing();
+
+    if (majorSpace > 0)
+      {
+	if (slider.getOrientation() == JSlider.HORIZONTAL)
+	  {
+	    double loc = tickRect.x;
+	    double increment = (max == min) ? 0
+	                                 : majorSpace * (double) tickRect.width / (max
+	                                 - min);
+	    if (drawInverted())
+	      {
+		loc += tickRect.width;
+		increment *= -1;
+	      }
+	    for (int i = min; i <= max; i += majorSpace)
+	      {
+		paintMajorTickForHorizSlider(g, tickRect, (int) loc);
+		loc += increment;
+	      }
+	  }
+	else
+	  {
+	    double loc = tickRect.height + tickRect.y;
+	    double increment = (max == min) ? 0
+	                                 : -majorSpace * (double) tickRect.height / (max
+	                                 - min);
+	    if (drawInverted())
+	      {
+		loc = tickRect.y;
+		increment *= -1;
+	      }
+	    for (int i = min; i <= max; i += majorSpace)
+	      {
+		paintMajorTickForVertSlider(g, tickRect, (int) loc);
+		loc += increment;
+	      }
+	  }
+      }
+    if (minorSpace > 0)
+      {
+	if (slider.getOrientation() == JSlider.HORIZONTAL)
+	  {
+	    double loc = tickRect.x;
+	    double increment = (max == min) ? 0
+	                                 : minorSpace * (double) tickRect.width / (max
+	                                 - min);
+	    if (drawInverted())
+	      {
+		loc += tickRect.width;
+		increment *= -1;
+	      }
+	    for (int i = min; i <= max; i += minorSpace)
+	      {
+		paintMinorTickForHorizSlider(g, tickRect, (int) loc);
+		loc += increment;
+	      }
+	  }
+	else
+	  {
+	    double loc = tickRect.height + tickRect.y;
+	    double increment = (max == min) ? 0
+	                                 : -minorSpace * (double) tickRect.height / (max
+	                                 - min);
+	    if (drawInverted())
+	      {
+		loc = tickRect.y;
+		increment *= -1;
+	      }
+	    for (int i = min; i <= max; i += minorSpace)
+	      {
+		paintMinorTickForVertSlider(g, tickRect, (int) loc);
+		loc += increment;
+	      }
+	  }
+      }
+  }
+
+  /* Minor ticks start at 1/4 of the height (or width) of the tickRect and extend
+     to 1/2 of the tickRect.
+
+     Major ticks start at 1/4 of the height and extend to 3/4.
+   */
+
+  /**
+   * This method paints a minor tick for a horizontal slider at the given x
+   * value. x represents the x coordinate to paint at.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param tickBounds The tickRect rectangle.
+   * @param x The x coordinate to draw the tick at.
+   */
+  protected void paintMinorTickForHorizSlider(Graphics g,
+                                              Rectangle tickBounds, int x)
+  {
+    int y = tickRect.y + tickRect.height / 4;
+    Color saved = g.getColor();
+    g.setColor(Color.BLACK);
+
+    g.drawLine(x, y, x, y + tickRect.height / 4);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints a major tick for a horizontal slider at the given x
+   * value. x represents the x coordinate to paint at.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param tickBounds The tickRect rectangle.
+   * @param x The x coordinate to draw the tick at.
+   */
+  protected void paintMajorTickForHorizSlider(Graphics g,
+                                              Rectangle tickBounds, int x)
+  {
+    int y = tickRect.y + tickRect.height / 4;
+    Color saved = g.getColor();
+    g.setColor(Color.BLACK);
+
+    g.drawLine(x, y, x, y + tickRect.height / 2);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints a minor tick for a vertical slider at the given y
+   * value. y represents the y coordinate to paint at.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param tickBounds The tickRect rectangle.
+   * @param y The y coordinate to draw the tick at.
+   */
+  protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
+                                             int y)
+  {
+    int x = tickRect.x + tickRect.width / 4;
+    Color saved = g.getColor();
+    g.setColor(Color.BLACK);
+
+    g.drawLine(x, y, x + tickRect.width / 4, y);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints a major tick for a vertical slider at the given y
+   * value. y represents the y coordinate to paint at.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param tickBounds The tickRect rectangle.
+   * @param y The y coordinate to draw the tick at.
+   */
+  protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
+                                             int y)
+  {
+    int x = tickRect.x + tickRect.width / 4;
+    Color saved = g.getColor();
+    g.setColor(Color.BLACK);
+
+    g.drawLine(x, y, x + tickRect.width / 2, y);
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints all the labels from the slider's label table. This
+   * method must make sure that the label table is not null before painting
+   * the labels. Each entry in the label table is a (integer, component)
+   * pair. Every label is painted at the value of the integer.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   */
+  public void paintLabels(Graphics g)
+  {
+    if (slider.getLabelTable() != null)
+      {
+	Dictionary table = slider.getLabelTable();
+	Integer tmpKey;
+	Object key;
+	Object element;
+	Component label;
+	if (slider.getOrientation() == JSlider.HORIZONTAL)
+	  {
+	    for (Enumeration list = table.keys(); list.hasMoreElements();)
+	      {
+		key = list.nextElement();
+		if (! (key instanceof Integer))
+		  continue;
+		tmpKey = (Integer) key;
+		element = table.get(tmpKey);
+		// We won't paint them if they're not
+		// JLabels so continue anyway
+		if (! (element instanceof JLabel))
+		  continue;
+		label = (Component) element;
+		paintHorizontalLabel(g, tmpKey.intValue(), label);
+	      }
+	  }
+	else
+	  {
+	    for (Enumeration list = table.keys(); list.hasMoreElements();)
+	      {
+		key = list.nextElement();
+		if (! (key instanceof Integer))
+		  continue;
+		tmpKey = (Integer) key;
+		element = table.get(tmpKey);
+		// We won't paint them if they're not
+		// JLabels so continue anyway
+		if (! (element instanceof JLabel))
+		  continue;
+		label = (Component) element;
+		paintVerticalLabel(g, tmpKey.intValue(), label);
+	      }
+	  }
+      }
+  }
+
+  /**
+   * This method paints the label on the horizontal slider at the value
+   * specified. The value is not a coordinate. It is a value within the range
+   * of the  slider. If the value is not within the range of the slider, this
+   * method will do nothing. This method should not paint outside the
+   * boundaries of the labelRect.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param value The value to paint at.
+   * @param label The label to paint.
+   */
+  protected void paintHorizontalLabel(Graphics g, int value, Component label)
+  {
+    // This relies on clipping working properly or we'll end up
+    // painting all over the place. If our preferred size is ignored, then
+    // the labels may not fit inside the slider's bounds. Rather than mucking 
+    // with font sizes and possible icon sizes, we'll set the bounds for
+    // the label and let it get clipped.
+    Dimension dim = label.getPreferredSize();
+    int w = (int) dim.getWidth();
+    int h = (int) dim.getHeight();
+    
+    int max = slider.getMaximum();
+    int min = slider.getMinimum();
+
+    if (value > max || value < min)
+      return;
+    
+    //           value
+    //             |
+    //        ------------
+    //        |          |
+    //        |          |
+    //        |          |
+    //  The label must move w/2 to the right to fit directly under the value.
+    int xpos = xPositionForValue(value) - w / 2;
+    int ypos = labelRect.y;
+
+    // We want to center the label around the xPositionForValue
+    // So we use xpos - w / 2. However, if value is min and the label 
+    // is large, we run the risk of going out of bounds. So we bring it back
+    // to 0 if it becomes negative.
+    if (xpos < 0)
+      xpos = 0;
+
+    // If the label + starting x position is greater than
+    // the x space in the label rectangle, we reset it to the largest
+    // amount possible in the rectangle. This means ugliness.
+    if (xpos + w > labelRect.x + labelRect.width)
+      w = labelRect.x + labelRect.width - xpos;
+
+    // If the label is too tall. We reset it to the height of the label
+    // rectangle.
+    if (h > labelRect.height)
+      h = labelRect.height;
+
+    label.setBounds(xpos, ypos, w, h);
+    javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
+  }
+
+  /**
+   * This method paints the label on the vertical slider at the value
+   * specified. The value is not a coordinate. It is a value within the range
+   * of the  slider. If the value is not within the range of the slider, this
+   * method will do nothing. This method should not paint outside the
+   * boundaries of the labelRect.
+   *
+   * @param g The {@link Graphics} object to draw with.
+   * @param value The value to paint at.
+   * @param label The label to paint.
+   */
+  protected void paintVerticalLabel(Graphics g, int value, Component label)
+  {
+    Dimension dim = label.getPreferredSize();
+    int w = (int) dim.getWidth();
+    int h = (int) dim.getHeight();
+
+    int max = slider.getMaximum();
+    int min = slider.getMinimum();
+
+    if (value > max || value < min)
+      return;
+
+    int xpos = labelRect.x;
+    int ypos = yPositionForValue(value) - h / 2;
+
+    if (ypos < 0)
+      ypos = 0;
+
+    if (ypos + h > labelRect.y + labelRect.height)
+      h = labelRect.y + labelRect.height - ypos;
+
+    if (w > labelRect.width)
+      w = labelRect.width;
+
+    label.setBounds(xpos, ypos, w, h);
+    javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
+  }
+
+  /**
+   * <p>
+   * This method paints a thumb. There are two types of thumb:
+   * </p>
+   * <pre>
+   *   Vertical         Horizontal
+   *    a---b            a-----b
+   *    |   |            |      \
+   *    e   c            |       c
+   *     \ /             |      /
+   *      d              e-----d
+   *  </pre>
+   * 
+   * <p>
+   * In the case of vertical thumbs, we highlight the path b-a-e-d and shadow
+   * the path b-c-d. In the case of horizontal thumbs, we highlight the path
+   * c-b-a-e and shadow the path c-d-e. In both cases we fill the path
+   * a-b-c-d-e before shadows and highlights are drawn.
+   * </p>
+   *
+   * @param g The graphics object to paint with
+   */
+  public void paintThumb(Graphics g)
+  {
+    Color saved_color = g.getColor();
+
+    Polygon thumb = new Polygon();
+
+    Point a = new Point(thumbRect.x, thumbRect.y);
+    Point b = new Point(a);
+    Point c = new Point(a);
+    Point d = new Point(a);
+    Point e = new Point(a);
+
+    Polygon bright;
+    Polygon dark;
+    Polygon all;
+
+    // This will be in X-dimension if the slider is inverted and y if it isn't.	  	  
+    int turnPoint;
+
+    if (slider.getOrientation() == JSlider.HORIZONTAL)
+      {
+	turnPoint = thumbRect.height * 3 / 4;
+
+	b.translate(thumbRect.width, 0);
+	c.translate(thumbRect.width, turnPoint);
+	d.translate(thumbRect.width / 2, thumbRect.height);
+	e.translate(0, turnPoint);
+
+	bright = new Polygon(new int[] { b.x, a.x, e.x, d.x },
+	                     new int[] { b.y, a.y, e.y, d.y }, 4);
+
+	dark = new Polygon(new int[] { b.x, c.x, d.x },
+	                   new int[] { b.y, c.y, d.y }, 3);
+	all = new Polygon(new int[] { a.x + 1, b.x, c.x, d.x, e.x + 1 },
+	                  new int[] { a.y + 1, b.y + 1, c.y, d.y + 1, e.y }, 5);
+      }
+    else
+      {
+	turnPoint = thumbRect.width * 3 / 4;
+
+	b.translate(turnPoint, 0);
+	c.translate(thumbRect.width, thumbRect.height / 2);
+	d.translate(turnPoint, thumbRect.height);
+	e.translate(0, thumbRect.height);
+
+	bright = new Polygon(new int[] { c.x, b.x, a.x, e.x },
+	                     new int[] { c.y, b.y, a.y, e.y }, 4);
+
+	dark = new Polygon(new int[] { c.x, d.x, e.x + 1 },
+	                   new int[] { c.y, d.y, e.y }, 3);
+
+	all = new Polygon(new int[] { a.x + 1, b.x, c.x - 1, d.x, e.x + 1 },
+	                  new int[] { a.y + 1, b.y + 1, c.y, d.y, e.y }, 5);
+      }
+
+    g.setColor(Color.WHITE);
+    g.drawPolygon(bright);
+
+    g.setColor(Color.BLACK);
+    g.drawPolygon(dark);
+
+    g.setColor(Color.GRAY);
+    g.fillPolygon(all);
+
+    g.setColor(saved_color);
+  }
+
+  /**
+   * This method sets the position of the thumbRect.
+   *
+   * @param x The new x position.
+   * @param y The new y position.
+   */
+  public void setThumbLocation(int x, int y)
+  {
+    thumbRect.x = x;
+    thumbRect.y = y;
+  }
+
+  /**
+   * 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.
+   *
+   * @param direction The direction to move in.
+   */
+  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;
+
+    if (slider.getSnapToTicks())
+      moveTo = findClosestTick(moveTo);
+
+    slider.setValue(moveTo);
+  }
+
+  /**
+   * 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.
+   *
+   * @param direction The direction to move in.
+   */
+  public void scrollByUnit(int direction)
+  {
+    // The direction is -1 for backwards and 1 for forwards.
+    int moveTo = slider.getValue() + direction;
+
+    if (slider.getSnapToTicks())
+      moveTo = findClosestTick(moveTo);
+
+    slider.setValue(moveTo);
+  }
+
+  /**
+   * This method is called when there has been a click in the track and the
+   * thumb needs to be scrolled  on regular intervals. This method is only
+   * responsible  for starting the timer and not for stopping it.
+   *
+   * @param dir The direction to move in.
+   */
+  protected void scrollDueToClickInTrack(int dir)
+  {
+    scrollTimer.stop();
+  
+    scrollListener.setDirection(dir);
+    scrollListener.setScrollByBlock(true);
+
+    scrollTimer.start();
+  }
+
+  /**
+   * This method returns the X coordinate for the value passed in.
+   *
+   * @param value The value to calculate an x coordinate for.
+   *
+   * @return The x coordinate for the value.
+   */
+  protected int xPositionForValue(int value)
+  {
+    int min = slider.getMinimum();
+    int max = slider.getMaximum();
+    int extent = slider.getExtent();
+    int len = trackRect.width;
+
+    int xPos = (max == min) ? 0 : (value - min) * len / (max - min);
+
+    if (! drawInverted())
+      xPos += trackRect.x;
+    else
+      {
+	xPos = trackRect.width - xPos;
+	xPos += trackRect.x;
+      }
+    return xPos;
+  }
+
+  /**
+   * This method returns the y coordinate for the value passed in.
+   *
+   * @param value The value to calculate a y coordinate for.
+   *
+   * @return The y coordinate for the value.
+   */
+  protected int yPositionForValue(int value)
+  {
+    int min = slider.getMinimum();
+    int max = slider.getMaximum();
+    int extent = slider.getExtent();
+    int len = trackRect.height;
+
+    int yPos = (max == min) ? 0 : (value - min) * len / (max - min);
+
+    if (! drawInverted())
+      {
+	yPos = trackRect.height - yPos;
+	yPos += trackRect.y;
+      }
+    else
+      yPos += trackRect.y;
+    return yPos;
+  }
+
+  /**
+   * This method returns the value in the slider's range given the y
+   * coordinate. If the value is out of range, it will  return the closest
+   * legal value.
+   *
+   * @param yPos The y coordinate to calculate a value for.
+   *
+   * @return The value for the y coordinate.
+   */
+  public int valueForYPosition(int yPos)
+  {
+    int min = slider.getMinimum();
+    int max = slider.getMaximum();
+    int len = trackRect.height;
+
+    int value;
+
+    // If the length is 0, you shouldn't be able to even see where the slider is.
+    // This really shouldn't ever happen, but just in case, we'll return the middle.
+    if (len == 0)
+      return ((max - min) / 2);
+
+    if (! drawInverted())
+      value = ((len - (yPos - trackRect.y)) * (max - min) / len + min);
+    else
+      value = ((yPos - trackRect.y) * (max - min) / len + min);
+
+    // If this isn't a legal value, then we'll have to move to one now.
+    if (value > max)
+      value = max;
+    else if (value < min)
+      value = min;
+    return value;
+  }
+
+  /**
+   * This method returns the value in the slider's range given the x
+   * coordinate. If the value is out of range, it will return the closest
+   * legal value.
+   *
+   * @param xPos The x coordinate to calculate a value for.
+   *
+   * @return The value for the x coordinate.
+   */
+  public int valueForXPosition(int xPos)
+  {
+    int min = slider.getMinimum();
+    int max = slider.getMaximum();
+    int len = trackRect.width;
+
+    int value;
+
+    // If the length is 0, you shouldn't be able to even see where the slider is.
+    // This really shouldn't ever happen, but just in case, we'll return the middle.
+    if (len == 0)
+      return ((max - min) / 2);
+
+    if (! drawInverted())
+      value = ((xPos - trackRect.x) * (max - min) / len + min);
+    else
+      value = ((len - (xPos - trackRect.x)) * (max - min) / len + min);
+
+    // If this isn't a legal value, then we'll have to move to one now.
+    if (value > max)
+      value = max;
+    else if (value < min)
+      value = min;
+    return value;
+  }
+
+  /**
+   * This method finds the closest value that has a tick associated with it.
+   *
+   * @param value The value to search from.
+   *
+   * @return The closest value that has a tick associated with it.
+   */
+  private int findClosestTick(int value)
+  {
+    int min = slider.getMinimum();
+    int max = slider.getMaximum();
+    int majorSpace = slider.getMajorTickSpacing();
+    int minorSpace = slider.getMinorTickSpacing();
+
+    // The default value to return is value + minor or
+    // value + major. 
+    // Initializing at min - value leaves us with a default
+    // return value of min, which always has tick marks
+    // (if ticks are painted).
+    int minor = min - value;
+    int major = min - value;
+
+    // If there are no major tick marks or minor tick marks 
+    // e.g. snap is set to true but no ticks are set, then
+    // we can just return the value.
+    if (majorSpace <= 0 && minorSpace <= 0)
+      return value;
+
+    // First check the major ticks.
+    if (majorSpace > 0)
+      {
+	int lowerBound = (value - min) / majorSpace;
+	int majLower = majorSpace * lowerBound + min;
+	int majHigher = majorSpace * (lowerBound + 1) + min;
+
+	if (majHigher <= max && majHigher - value <= value - majLower)
+	  major = majHigher - value;
+	else
+	  major = majLower - value;
+      }
+
+    if (minorSpace > 0)
+      {
+	int lowerBound = value / minorSpace;
+	int minLower = minorSpace * lowerBound;
+	int minHigher = minorSpace * (lowerBound + 1);
+
+	if (minHigher <= max && minHigher - value <= value - minLower)
+	  minor = minHigher - value;
+	else
+	  minor = minLower - value;
+      }
+
+    // Give preference to minor ticks
+    if (Math.abs(minor) > Math.abs(major))
+      return value + major;
+    else
+      return value + minor;
+  }
+}
Index: javax/swing/plaf/basic/BasicSpinnerUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicSpinnerUI.java
diff -N javax/swing/plaf/basic/BasicSpinnerUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicSpinnerUI.java	6 Sep 2004 16:36:07 -0000
@@ -0,0 +1,572 @@
+/* SpinnerUI.java --
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JSpinner;
+import javax.swing.Timer;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.SpinnerUI;
+
+
+/**
+ * DOCUMENT ME!
+ *
+ * @author Ka-Hing Cheung
+ *
+ * @see javax.swing.JSpinner
+ * @since 1.4
+ */
+public class BasicSpinnerUI extends SpinnerUI
+{
+  /**
+   * Creates a new <code>ComponentUI</code> for the specified
+   * <code>JComponent</code>
+   *
+   * @param c DOCUMENT ME!
+   *
+   * @return a ComponentUI
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicSpinnerUI();
+  }
+
+  /**
+   * Creates an editor component. Really, it just returns
+   * <code>JSpinner.getEditor()</code>
+   *
+   * @return a JComponent as an editor
+   *
+   * @see javax.swing.JSpinner#getEditor
+   */
+  protected JComponent createEditor()
+  {
+    return spinner.getEditor();
+  }
+
+  /**
+   * Creates a <code>LayoutManager</code> that layouts the sub components. The
+   * subcomponents are identifies by the constraint "Next", "Previous" and
+   * "Editor"
+   *
+   * @return a LayoutManager
+   *
+   * @see java.awt.LayoutManager
+   */
+  protected LayoutManager createLayout()
+  {
+    return new DefaultLayoutManager();
+  }
+
+  /**
+   * Creates the "Next" button
+   *
+   * @return the next button component
+   */
+  protected Component createNextButton()
+  {
+    JButton button = new BasicArrowButton(BasicArrowButton.NORTH);
+    return button;
+  }
+
+  /**
+   * Creates the "Previous" button
+   *
+   * @return the previous button component
+   */
+  protected Component createPreviousButton()
+  {
+    JButton button = new BasicArrowButton(BasicArrowButton.SOUTH);
+    return button;
+  }
+
+  /**
+   * Creates the <code>PropertyChangeListener</code> that will be attached by
+   * <code>installListeners</code>. It should watch for the "editor"
+   * property, when it's changed, replace the old editor with the new one,
+   * probably by calling <code>replaceEditor</code>
+   *
+   * @return a PropertyChangeListener
+   *
+   * @see #replaceEditor
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeListener()
+      {
+	public void propertyChange(PropertyChangeEvent evt)
+	{
+	  // FIXME: Add check for enabled property change. Need to
+	  // disable the buttons.
+	  if ("editor".equals(evt.getPropertyName()))
+	    BasicSpinnerUI.this.replaceEditor((JComponent) evt.getOldValue(),
+	                                      (JComponent) evt.getNewValue());
+	}
+      };
+  }
+
+  /**
+   * Called by <code>installUI</code>. This should set various defaults
+   * obtained from <code>UIManager.getLookAndFeelDefaults</code>, as well as
+   * set the layout obtained from <code>createLayout</code>
+   *
+   * @see #javax.swing.UIManager#getLookAndFeelDefaults
+   * @see #createLayout
+   * @see #installUI
+   */
+  protected void installDefaults()
+  {
+    /* most of it copied from BasicLabelUI, I don't know what keys are
+       available, so someone may want to update this. Hence: TODO
+    */
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    /*
+    spinner.setForeground(defaults.getColor("Spinner.foreground"));
+    spinner.setBackground(defaults.getColor("Spinner.background"));
+    spinner.setFont(defaults.getFont("Spinner.font"));
+    spinner.setBorder(defaults.getBorder("Spinner.border"));
+    */
+    spinner.setLayout(createLayout());
+  }
+
+  /*
+   * Called by <code>installUI</code>, which basically adds the
+   * <code>PropertyChangeListener</code> created by
+   * <code>createPropertyChangeListener</code>
+   *
+   * @see #createPropertyChangeListener
+   * @see #installUI
+   */
+  protected void installListeners()
+  {
+    spinner.addPropertyChangeListener(listener);
+  }
+
+  /*
+   * Install listeners to the next button so that it increments the model
+   */
+  protected void installNextButtonListeners(Component c)
+  {
+    c.addMouseListener(new MouseAdapter()
+        {
+	  public void mousePressed(MouseEvent evt)
+	  {
+	    if (! spinner.isEnabled())
+	      return;
+	    increment();
+	    timer.setInitialDelay(500);
+	    timer.start();
+	  }
+
+	  public void mouseReleased(MouseEvent evt)
+	  {
+	    timer.stop();
+	  }
+
+	  void increment()
+	  {
+	    Object next = BasicSpinnerUI.this.spinner.getNextValue();
+	    if (next != null)
+	      BasicSpinnerUI.this.spinner.getModel().setValue(next);
+	  }
+
+	  volatile boolean mouseDown = false;
+	  Timer timer = new Timer(50,
+	                          new ActionListener()
+	      {
+		public void actionPerformed(ActionEvent event)
+		{
+		  increment();
+		}
+	      });
+        });
+  }
+
+  /*
+   * Install listeners to the previous button so that it decrements the model
+   */
+  protected void installPreviousButtonListeners(Component c)
+  {
+    c.addMouseListener(new MouseAdapter()
+        {
+	  public void mousePressed(MouseEvent evt)
+	  {
+	    if (! spinner.isEnabled())
+	      return;
+	    decrement();
+	    timer.setInitialDelay(500);
+	    timer.start();
+	  }
+
+	  public void mouseReleased(MouseEvent evt)
+	  {
+	    timer.stop();
+	  }
+
+	  void decrement()
+	  {
+	    Object prev = BasicSpinnerUI.this.spinner.getPreviousValue();
+	    if (prev != null)
+	      BasicSpinnerUI.this.spinner.getModel().setValue(prev);
+	  }
+
+	  volatile boolean mouseDown = false;
+	  Timer timer = new Timer(50,
+	                          new ActionListener()
+	      {
+		public void actionPerformed(ActionEvent event)
+		{
+		  decrement();
+		}
+	      });
+        });
+  }
+
+  /**
+   * Install this UI to the <code>JComponent</code>, which in reality, is a
+   * <code>JSpinner</code>. Calls <code>installDefaults</code>,
+   * <code>installListeners</code>, and also adds the buttons and editor.
+   *
+   * @param c DOCUMENT ME!
+   *
+   * @see #installDefaults
+   * @see #installListeners
+   * @see #createNextButton
+   * @see #createPreviousButton
+   * @see #createEditor
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+
+    spinner = (JSpinner) c;
+
+    installDefaults();
+    installListeners();
+
+    Component next = createNextButton();
+    Component previous = createPreviousButton();
+
+    installNextButtonListeners(next);
+    installPreviousButtonListeners(previous);
+
+    c.add(createEditor(), "Editor");
+    c.add(next, "Next");
+    c.add(previous, "Previous");
+  }
+
+  /**
+   * Replace the old editor with the new one
+   *
+   * @param oldEditor the old editor
+   * @param newEditor the new one to replace with
+   */
+  protected void replaceEditor(JComponent oldEditor, JComponent newEditor)
+  {
+    spinner.remove(oldEditor);
+    spinner.add(newEditor);
+  }
+
+  /**
+   * The reverse of <code>installDefaults</code>. Called by
+   * <code>uninstallUI</code>
+   */
+  protected void uninstallDefaults()
+  {
+    spinner.setLayout(null);
+  }
+
+  /**
+   * The reverse of <code>installListeners</code>, called by
+   * <code>uninstallUI</code>
+   */
+  protected void uninstallListeners()
+  {
+    spinner.removePropertyChangeListener(listener);
+  }
+
+  /**
+   * Called when the current L&F is replaced with another one, should call
+   * <code>uninstallDefaults</code> and <code>uninstallListeners</code> as
+   * well as remove the next/previous buttons and the editor
+   *
+   * @param c DOCUMENT ME!
+   */
+  public void uninstallUI(JComponent c)
+  {
+    super.uninstallUI(c);
+
+    uninstallDefaults();
+    uninstallListeners();
+    c.removeAll();
+  }
+
+  /** The spinner for this UI */
+  protected JSpinner spinner;
+
+  /** DOCUMENT ME! */
+  private PropertyChangeListener listener = createPropertyChangeListener();
+
+  /**
+   * DOCUMENT ME!
+   */
+  private class DefaultLayoutManager implements LayoutManager
+  {
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     */
+    public void layoutContainer(Container parent)
+    {
+      synchronized (parent.getTreeLock())
+        {
+	  Insets i = parent.getInsets();
+	  boolean l2r = parent.getComponentOrientation().isLeftToRight();
+	  /*
+	    --------------    --------------
+	    |        | n |    | n |        |
+	    |   e    | - | or | - |   e    |
+	    |        | p |    | p |        |
+	    --------------    --------------
+	  */
+	  Dimension e = minSize(editor);
+	  Dimension n = minSize(next);
+	  Dimension p = minSize(previous);
+	  Dimension s = spinner.getPreferredSize();
+
+	  int x = l2r ? i.left : i.right;
+	  int y = i.top;
+	  int w = Math.max(p.width, n.width);
+	  int h = Math.max(p.height, n.height);
+	  h = Math.max(h, e.height / 2);
+	  int e_width = s.width - w;
+
+	  if (l2r)
+	    {
+	      setBounds(editor, x, y + (s.height - e.height) / 2, e_width,
+	                e.height);
+	      x += e_width;
+
+	      setBounds(next, x, y, w, h);
+	      y += h;
+
+	      setBounds(previous, x, y, w, h);
+	    }
+	  else
+	    {
+	      setBounds(next, x, y + (s.height - e.height) / 2, w, h);
+	      y += h;
+
+	      setBounds(previous, x, y, w, h);
+	      x += w;
+	      y -= h;
+
+	      setBounds(editor, x, y, e_width, e.height);
+	    }
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      Dimension d = new Dimension();
+
+      if (editor != null)
+        {
+	  Dimension tmp = editor.getMinimumSize();
+	  d.width += tmp.width;
+	  d.height = tmp.height;
+        }
+
+      int nextWidth = 0;
+      int previousWidth = 0;
+      int otherHeight = 0;
+
+      if (next != null)
+        {
+	  Dimension tmp = next.getMinimumSize();
+	  nextWidth = tmp.width;
+	  otherHeight += tmp.height;
+        }
+      if (previous != null)
+        {
+	  Dimension tmp = previous.getMinimumSize();
+	  previousWidth = tmp.width;
+	  otherHeight += tmp.height;
+        }
+
+      d.height = Math.max(d.height, otherHeight);
+      d.width += Math.max(nextWidth, previousWidth);
+
+      return d;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param parent DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      Dimension d = new Dimension();
+
+      if (editor != null)
+        {
+	  Dimension tmp = editor.getPreferredSize();
+	  d.width += Math.max(tmp.width, 40);
+	  d.height = tmp.height;
+        }
+
+      int nextWidth = 0;
+      int previousWidth = 0;
+      int otherHeight = 0;
+
+      if (next != null)
+        {
+	  Dimension tmp = next.getPreferredSize();
+	  nextWidth = tmp.width;
+	  otherHeight += tmp.height;
+        }
+      if (previous != null)
+        {
+	  Dimension tmp = previous.getPreferredSize();
+	  previousWidth = tmp.width;
+	  otherHeight += tmp.height;
+        }
+
+      d.height = Math.max(d.height, otherHeight);
+      d.width += Math.max(nextWidth, previousWidth);
+
+      return d;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param child DOCUMENT ME!
+     */
+    public void removeLayoutComponent(Component child)
+    {
+      if (child == editor)
+	editor = null;
+      else if (child == next)
+	next = null;
+      else if (previous == child)
+	previous = null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     * @param child DOCUMENT ME!
+     */
+    public void addLayoutComponent(String name, Component child)
+    {
+      if ("Editor".equals(name))
+	editor = child;
+      else if ("Next".equals(name))
+	next = child;
+      else if ("Previous".equals(name))
+	previous = child;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private Dimension minSize(Component c)
+    {
+      if (c == null)
+	return new Dimension();
+      else
+	return c.getMinimumSize();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     * @param x DOCUMENT ME!
+     * @param y DOCUMENT ME!
+     * @param w DOCUMENT ME!
+     * @param h DOCUMENT ME!
+     */
+    private void setBounds(Component c, int x, int y, int w, int h)
+    {
+      if (c != null)
+	c.setBounds(x, y, w, h);
+    }
+
+    /** DOCUMENT ME! */
+    private Component editor;
+
+    /** DOCUMENT ME! */
+    private Component next;
+
+    /** DOCUMENT ME! */
+    private Component previous;
+  }
+}
Index: javax/swing/plaf/basic/BasicSplitPaneDivider.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicSplitPaneDivider.java,v
retrieving revision 1.1
diff -u -r1.1 BasicSplitPaneDivider.java
--- javax/swing/plaf/basic/BasicSplitPaneDivider.java	24 Jun 2003 09:48:42 -0000	1.1
+++ javax/swing/plaf/basic/BasicSplitPaneDivider.java	6 Sep 2004 16:36:07 -0000
@@ -1,5 +1,5 @@
 /* BasicSplitPaneDivider.java
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,14 +35,15 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Insets;
+import java.awt.LayoutManager;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseMotionListener;
@@ -50,173 +51,197 @@
 import java.beans.PropertyChangeListener;
 import javax.swing.JButton;
 import javax.swing.JSplitPane;
+import javax.swing.SwingConstants;
 import javax.swing.border.Border;
 
 
 /**
- * The divider that separates the two parts of a JSplitPane in the
- * Basic look and feel.
- *
- * <p>Implementation status: We do not have a real implementation yet.
- * Currently, it is mostly a stub to allow compiling other parts of
- * the javax.swing.plaf.basic package, although some parts are already
+ * The divider that separates the two parts of a JSplitPane in the Basic look
+ * and feel.
+ * 
+ * <p>
+ * Implementation status: We do not have a real implementation yet. Currently,
+ * it is mostly a stub to allow compiling other parts of the
+ * javax.swing.plaf.basic package, although some parts are already
  * functional.
+ * </p>
  *
- * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Sascha Brawer (brawer_AT_dandelis.ch)
  */
-public class BasicSplitPaneDivider
-  extends Container
+public class BasicSplitPaneDivider extends Container
   implements PropertyChangeListener
 {
   /**
-   * Determined using the <code>serialver</code> tool
-   * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
+   * Determined using the <code>serialver</code> tool of Apple/Sun JDK 1.3.1
+   * on MacOS X 10.1.5.
    */
   static final long serialVersionUID = 1463404307042803342L;
 
-
   /**
-   * The width and height of the little buttons for showing and
-   * hiding parts of a JSplitPane in a single mouse click.
+   * The width and height of the little buttons for showing and hiding parts
+   * of a JSplitPane in a single mouse click.
    */
   protected static final int ONE_TOUCH_SIZE = 6;
 
-
-  // FIXME: Javadoc.
+  /** The distance the one touch buttons will sit from the divider's edges. */
   protected static final int ONE_TOUCH_OFFSET = 2;
 
-
   /**
    * An object that performs the tasks associated with an ongoing drag
-   * operation, or <code>null</code> if the user is currently not
-   * dragging the divider.
+   * operation, or <code>null</code> if the user is currently not dragging
+   * the divider.
    */
   protected DragController dragger;
 
-
   /**
    * The delegate object that is responsible for the UI of the
    * <code>JSplitPane</code> that contains this divider.
    */
   protected BasicSplitPaneUI splitPaneUI;
 
-
-  /**
-   * The thickness of the divider in pixels.
-   */
+  /** The thickness of the divider in pixels. */
   protected int dividerSize;
-  
 
-  /**
-   * A divider that is used for layout purposes.
-   */
+  /** A divider that is used for layout purposes. */
   protected Component hiddenDivider;
 
-
-  /**
-   * The JSplitPane containing this divider.
-   */
+  /** The JSplitPane containing this divider. */
   protected JSplitPane splitPane;
 
-
   /**
-   * The listener for handling mouse events from both the divider
-   * and the containing <code>JSplitPane</code>.
-   *
-   * <p>The reason for also handling MouseEvents from the containing
-   * <code>JSplitPane</code> is that users should be able to start
-   * a drag gesture from inside the JSplitPane, but slightly outisde
-   * the divider.
+   * The listener for handling mouse events from both the divider and the
+   * containing <code>JSplitPane</code>.
+   * 
+   * <p>
+   * The reason for also handling MouseEvents from the containing
+   * <code>JSplitPane</code> is that users should be able to start a drag
+   * gesture from inside the JSplitPane, but slightly outisde the divider.
+   * </p>
    */
   protected MouseHandler mouseHandler = new MouseHandler();
 
-
   /**
-   * The current orientation of the containing <code>JSplitPane</code>,
-   * which is either {@link javax.swing.JSplitPane#HORIZONTAL_SPLIT}
-   * or {@link javax.swing.JSplitPane#VERTICAL_SPLIT}.
+   * The current orientation of the containing <code>JSplitPane</code>, which
+   * is either {@link javax.swing.JSplitPane#HORIZONTAL_SPLIT} or {@link
+   * javax.swing.JSplitPane#VERTICAL_SPLIT}.
    */
   protected int orientation;
 
-
   /**
-   * The button for showing and hiding the left (or top) component
-   * of the <code>JSplitPane</code>.
+   * The button for showing and hiding the left (or top) component of the
+   * <code>JSplitPane</code>.
    */
   protected JButton leftButton;
 
-
   /**
-   * The button for showing and hiding the right (or bottom) component
-   * of the <code>JSplitPane</code>.
+   * The button for showing and hiding the right (or bottom) component of the
+   * <code>JSplitPane</code>.
    */
   protected JButton rightButton;
 
-
   /**
-   * The border of this divider. Typically, this will be an instance of
-   * {@link javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}.
+   * The border of this divider. Typically, this will be an instance of {@link
+   * javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}.
    *
    * @see #getBorder()
    * @see #setBorder(javax.swing.border.Border)
    */
   private Border border;
 
+  // This is not a pixel count.
+  // This int should be able to take 3 values.
+  // left (top), middle, right(bottom)
+  //    0          1          2
+
+  /** Keeps track of where the divider should be placed when using one touch expand
+   * buttons. */
+  private transient int currentDividerLocation = 1;
+
+  private transient Border tmpBorder = new Border()
+  {
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(2, 2, 2, 2);
+    }
+    
+    public boolean isBorderOpaque()
+    {
+      return false;
+    }
+    
+    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
+    {
+      Color saved = g.getColor();
+      g.setColor(Color.BLACK);
+      
+      g.drawRect(x + 2, y + 2, width - 4, height - 4);
+      
+      g.setColor(saved);
+    }
+  };
 
   /**
    * Constructs a new divider.
    *
-   * @param ui the UI delegate of the enclosing
-   *           <code>JSplitPane</code>.
+   * @param ui the UI delegate of the enclosing <code>JSplitPane</code>.
    */
   public BasicSplitPaneDivider(BasicSplitPaneUI ui)
   {
+    setLayout(new DividerLayout());
     setBasicSplitPaneUI(ui);
+    setDividerSize(splitPane.getDividerSize());
+    setBorder(tmpBorder);
   }
 
-
   /**
-   * Sets the delegate object that is responsible for the UI of the
-   * {@link javax.swing.JSplitPane} containing this divider.
+   * Sets the delegate object that is responsible for the UI of the {@link
+   * javax.swing.JSplitPane} containing this divider.
    *
-   * @param newUI the UI delegate, or <code>null</code> to release
-   *        the connection to the current delegate.
+   * @param newUI the UI delegate, or <code>null</code> to release the
+   *        connection to the current delegate.
    */
   public void setBasicSplitPaneUI(BasicSplitPaneUI newUI)
   {
     /* Remove the connection to the existing JSplitPane. */
     if (splitPane != null)
-    {
-      splitPane.removePropertyChangeListener(this);
-      splitPane.removeMouseListener(mouseHandler);
-      splitPane.removeMouseMotionListener(mouseHandler);
-      splitPane = null;
-    }
-    
+      {
+	splitPane.removePropertyChangeListener(this);
+	splitPane.removeMouseListener(mouseHandler);
+	splitPane.removeMouseMotionListener(mouseHandler);
+	removeMouseListener(mouseHandler);
+	removeMouseMotionListener(mouseHandler);
+	splitPane = null;
+	hiddenDivider = null;
+      }
+
     /* Establish the connection to the new JSplitPane. */
     splitPaneUI = newUI;
     if (splitPaneUI != null)
       splitPane = newUI.getSplitPane();
     if (splitPane != null)
-    {
-      splitPane.addPropertyChangeListener(this);
-      splitPane.addMouseListener(mouseHandler);
-      splitPane.addMouseMotionListener(mouseHandler);
-      orientation = splitPane.getOrientation();
-    }
+      {
+	splitPane.addPropertyChangeListener(this);
+	splitPane.addMouseListener(mouseHandler);
+	splitPane.addMouseMotionListener(mouseHandler);
+	addMouseListener(mouseHandler);
+	addMouseMotionListener(mouseHandler);
+	hiddenDivider = splitPaneUI.getNonContinuousLayoutDivider();
+	orientation = splitPane.getOrientation();
+	oneTouchExpandableChanged();
+      }
   }
-  
 
   /**
-   * Returns the delegate object that is responsible for the UI of the
-   * {@link javax.swing.JSplitPane} containing this divider.
+   * Returns the delegate object that is responsible for the UI of the {@link
+   * javax.swing.JSplitPane} containing this divider.
+   *
+   * @return The UI for the JSplitPane.
    */
   public BasicSplitPaneUI getBasicSplitPaneUI()
   {
     return splitPaneUI;
   }
 
-
   /**
    * Sets the thickness of the divider.
    *
@@ -227,37 +252,40 @@
     this.dividerSize = newSize;
   }
 
-
   /**
    * Retrieves the thickness of the divider.
+   *
+   * @return The thickness of the divider.
    */
   public int getDividerSize()
   {
     return dividerSize;
   }
-  
-  
+
   /**
    * Sets the border of this divider.
    *
    * @param border the new border. Typically, this will be an instance of
-   * {@link javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}.
+   *        {@link
+   *        javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}.
    *
    * @since 1.3
    */
   public void setBorder(Border border)
   {
-    Border oldValue = this.border;
-    this.border = border;
-    firePropertyChange("border", oldValue, border);
+    if (border != this.border)
+      {
+	Border oldValue = this.border;
+	this.border = border;
+	firePropertyChange("border", oldValue, border);
+      }
   }
 
-
   /**
    * Retrieves the border of this divider.
    *
-   * @return the current border, or <code>null</code> if no border
-   *         has been set.
+   * @return the current border, or <code>null</code> if no border has been
+   *         set.
    *
    * @since 1.3
    */
@@ -265,13 +293,12 @@
   {
     return border;
   }
-  
 
   /**
-   * Retrieves the insets of the divider. If a border has been
-   * installed on the divider, the result of calling its
-   * <code>getBorderInsets</code> method is returned. Otherwise,
-   * the inherited implementation will be invoked.
+   * Retrieves the insets of the divider. If a border has been installed on
+   * the divider, the result of calling its <code>getBorderInsets</code>
+   * method is returned. Otherwise, the inherited implementation will be
+   * invoked.
    *
    * @see javax.swing.border.Border#getBorderInsets(java.awt.Component)
    */
@@ -282,42 +309,56 @@
     else
       return super.getInsets();
   }
-  
-  
+
   /**
    * Returns the preferred size of this divider, which is
-   * <code>dividerSize</code> by <code>dividerSize</code>
-   * pixels.
+   * <code>dividerSize</code> by <code>dividerSize</code> pixels.
+   *
+   * @return The preferred size of the divider.
    */
   public Dimension getPreferredSize()
   {
-    return new Dimension(dividerSize, dividerSize);
+    return getLayout().preferredLayoutSize(this);
   }
 
-
   /**
    * Returns the minimal size of this divider, which is
-   * <code>dividerSize</code> by <code>dividerSize</code>
-   * pixels.
+   * <code>dividerSize</code> by <code>dividerSize</code> pixels.
+   *
+   * @return The minimal size of the divider.
    */
   public Dimension getMinimumSize()
   {
     return getPreferredSize();
   }
-  
-  
+
   /**
-   * Processes events from the <code>JSplitPane</code> that contains
-   * this divider.
+   * Processes events from the <code>JSplitPane</code> that contains this
+   * divider.
+   *
+   * @param e The PropertyChangeEvent.
    */
   public void propertyChange(PropertyChangeEvent e)
   {
-    // FIXME: Not yet implemented.
+    if (e.getPropertyName().equals(JSplitPane.ONE_TOUCH_EXPANDABLE_PROPERTY))
+      oneTouchExpandableChanged();
+    else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
+      {
+	orientation = splitPane.getOrientation();
+	if (splitPane.isOneTouchExpandable())
+	  {
+	    layout();
+	    repaint();
+	  }
+      }
+    else if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
+      dividerSize = splitPane.getDividerSize();
   }
 
-
   /**
    * Paints the divider by painting its border.
+   *
+   * @param g The Graphics Object to paint with.
    */
   public void paint(Graphics g)
   {
@@ -325,50 +366,85 @@
 
     super.paint(g);
     if (border != null)
-    {
-      dividerSize = getSize();
-      border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height);
-      //System.out.println(dividerSize);
-      //g.setColor(java.awt.Color.white);
-      //g.drawRect(0, 0, 5, 5);
-    }
+      {
+	dividerSize = getSize();
+	border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height);
+      }
   }
 
-
   /**
-   * Reacts to changes of the <code>oneToughExpandable</code>
-   * property of the containing <code>JSplitPane</code>.
+   * Reacts to changes of the <code>oneToughExpandable</code> property of the
+   * containing <code>JSplitPane</code>.
    */
   protected void oneTouchExpandableChanged()
   {
-    // FIXME: Not yet implemented.
+    if (splitPane.isOneTouchExpandable())
+      {
+	leftButton = createLeftOneTouchButton();
+	rightButton = createRightOneTouchButton();
+	add(leftButton);
+	add(rightButton);
+
+	leftButton.addMouseListener(mouseHandler);
+	rightButton.addMouseListener(mouseHandler);
+
+	// Set it to 1.
+	currentDividerLocation = 1;
+      }
+    else
+      {
+	if (leftButton != null && rightButton != null)
+	  {
+	    leftButton.removeMouseListener(mouseHandler);
+	    rightButton.removeMouseListener(mouseHandler);
+
+	    remove(leftButton);
+	    remove(rightButton);
+	    leftButton = null;
+	    rightButton = null;
+	  }
+      }
+    layout();
+    repaint();
   }
 
-
   /**
-   * Creates a button for showing and hiding the left (or top)
-   * part of a <code>JSplitPane</code>.
+   * Creates a button for showing and hiding the left (or top) part of a
+   * <code>JSplitPane</code>.
+   *
+   * @return The left one touch button.
    */
   protected JButton createLeftOneTouchButton()
   {
-    return new OneTouchButton(/* left */ true);
-  }
+    int dir = SwingConstants.WEST;
+    if (orientation == JSplitPane.VERTICAL_SPLIT)
+      dir = SwingConstants.NORTH;
+    JButton button = new BasicArrowButton(dir);
+    button.setBorderPainted(false);
 
+    return button;
+  }
 
   /**
-   * Creates a button for showing and hiding the right (or bottom)
-   * part of a <code>JSplitPane</code>.
+   * Creates a button for showing and hiding the right (or bottom) part of a
+   * <code>JSplitPane</code>.
+   *
+   * @return The right one touch button.
    */
   protected JButton createRightOneTouchButton()
   {
-    return new OneTouchButton(/* left */ false);
+    int dir = SwingConstants.EAST;
+    if (orientation == JSplitPane.VERTICAL_SPLIT)
+      dir = SwingConstants.SOUTH;
+    JButton button = new BasicArrowButton(dir);
+    button.setBorderPainted(false);
+    return button;
   }
-  
 
   /**
    * Prepares the divider for dragging by calling the
-   * <code>startDragging</code> method of the UI delegate of the
-   * enclosing <code>JSplitPane</code>.
+   * <code>startDragging</code> method of the UI delegate of the enclosing
+   * <code>JSplitPane</code>.
    *
    * @see BasicSplitPaneUI#startDragging()
    */
@@ -378,15 +454,14 @@
       splitPaneUI.startDragging();
   }
 
-
   /**
    * Drags the divider to a given location by calling the
-   * <code>dragDividerTo</code> method of the UI delegate of the
-   * enclosing <code>JSplitPane</code>.
+   * <code>dragDividerTo</code> method of the UI delegate of the enclosing
+   * <code>JSplitPane</code>.
    *
    * @param location the new location of the divider.
    *
-   * @see BasicSplitPaneUI#dragDividerTo(int location) 
+   * @see BasicSplitPaneUI#dragDividerTo(int location)
    */
   protected void dragDividerTo(int location)
   {
@@ -394,11 +469,9 @@
       splitPaneUI.dragDividerTo(location);
   }
 
-
   /**
-   * Finishes a dragging gesture by calling the
-   * <code>finishDraggingTo</code> method of the UI delegate of the
-   * enclosing <code>JSplitPane</code>.
+   * Finishes a dragging gesture by calling the <code>finishDraggingTo</code>
+   * method of the UI delegate of the enclosing <code>JSplitPane</code>.
    *
    * @param location the new, final location of the divider.
    *
@@ -410,125 +483,424 @@
       splitPaneUI.finishDraggingTo(location);
   }
 
+  /**
+   * This helper method moves the divider to one of the 
+   * three locations when using one touch expand buttons.
+   * Location 0 is the left (or top) most location.
+   * Location 1 is the middle.
+   * Location 2 is the right (or bottom) most location.
+   *
+   * @param locationIndex The location to move to.
+   */
+  private void moveDividerTo(int locationIndex)
+  {
+    Insets insets = splitPane.getInsets();
+    switch (locationIndex)
+      {
+      case 1:
+	splitPane.setDividerLocation(splitPane.getLastDividerLocation());
+	break;
+      case 0:
+	int top = (orientation == JSplitPane.HORIZONTAL_SPLIT) ? insets.left
+	                                                       : insets.top;
+	splitPane.setDividerLocation(top);
+	break;
+      case 2:
+	int bottom;
+	if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+	  bottom = splitPane.getBounds().width - insets.right - dividerSize;
+	else
+	  bottom = splitPane.getBounds().height - insets.bottom - dividerSize;
+	splitPane.setDividerLocation(bottom);
+	break;
+      }
+  }
 
   /**
-   * The listener for handling mouse events from both the divider
-   * and the containing <code>JSplitPane</code>.
-   *
-   * <p>The reason for also handling MouseEvents from the containing
-   * <code>JSplitPane</code> is that users should be able to start
-   * a drag gesture from inside the JSplitPane, but slightly outisde
-   * the divider. 
+   * The listener for handling mouse events from both the divider and the
+   * containing <code>JSplitPane</code>.
+   * 
+   * <p>
+   * The reason for also handling MouseEvents from the containing
+   * <code>JSplitPane</code> is that users should be able to start a drag
+   * gesture from inside the JSplitPane, but slightly outisde the divider.
+   * </p>
    *
-   * @author Sascha Brawer (brawer@dandelis.ch)
+   * @author Sascha Brawer (brawer_AT_dandelis.ch)
    */
-  protected class MouseHandler
-    extends MouseAdapter
+  protected class MouseHandler extends MouseAdapter
     implements MouseMotionListener
   {
-    
+    /** Keeps track of whether a drag is occurring. */
+    private transient boolean isDragging;
+
+    /**
+     * This method is called when the mouse is pressed.
+     *
+     * @param e The MouseEvent.
+     */
     public void mousePressed(MouseEvent e)
     {
-      // FIXME: Not yet implemented.
+      if (splitPane.isOneTouchExpandable())
+        {
+	  if (e.getSource() == leftButton)
+	    {
+	      currentDividerLocation--;
+	      if (currentDividerLocation < 0)
+		currentDividerLocation = 0;
+	      moveDividerTo(currentDividerLocation);
+	      return;
+	    }
+	  else if (e.getSource() == rightButton)
+	    {
+	      currentDividerLocation++;
+	      if (currentDividerLocation > 2)
+		currentDividerLocation = 2;
+	      moveDividerTo(currentDividerLocation);
+	      return;
+	    }
+        }
+      isDragging = true;
+      currentDividerLocation = 1;
+      if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+	dragger = new DragController(e);
+      else
+	dragger = new VerticalDragController(e);
+      prepareForDragging();
     }
 
-
+    /**
+     * This method is called when the mouse is released.
+     *
+     * @param e The MouseEvent.
+     */
     public void mouseReleased(MouseEvent e)
     {
-      // FIXME: Not yet implemented.
+      if (isDragging)
+	dragger.completeDrag(e);
+      isDragging = false;
     }
 
-
     /**
-     * Repeatedly invoked when the user is dragging the mouse cursor
-     * while having pressed a mouse button.
+     * Repeatedly invoked when the user is dragging the mouse cursor while
+     * having pressed a mouse button.
+     *
+     * @param e The MouseEvent.
      */
     public void mouseDragged(MouseEvent e)
     {
-      // FIXME: Not yet implemented.
+      if (dragger != null)
+	dragger.continueDrag(e);
     }
 
-
     /**
-     * Repeatedly invoked when the user is dragging the mouse cursor
-     * without having pressed a mouse button.
+     * Repeatedly invoked when the user is dragging the mouse cursor without
+     * having pressed a mouse button.
+     *
+     * @param e The MouseEvent.
      */
     public void mouseMoved(MouseEvent e)
     {
-      // FIXME: Not yet implemented.
+      // Do nothing.
     }
   }
 
-
   /**
-   * A small button for showing and hiding parts of a
-   * <code>JSplitPane</code> with a single mouse click.
+   * Performs the tasks associated with an ongoing drag operation.
    *
-   * @author Sascha Brawer (brawer@dandelis.ch)
+   * @author Sascha Brawer (brawer_AT_dandelis.ch)
    */
-  private static class OneTouchButton
-    extends JButton
+  protected class DragController
   {
-    OneTouchButton(boolean left)
+    /** The difference between where the mouse is clicked and the 
+     * initial divider location. */
+    transient int offset;
+
+    /**
+     * Creates a new DragController object.
+     *
+     * @param e The MouseEvent to initialize with.
+     */
+    protected DragController(MouseEvent e)
     {
-      // FIXME: Set various properties of the button.
-      // Make  sure it looks identical to the small
-      // buttons of the Sun reference implementation.
-      // The size should also be the same.
-      if (left)
-        setText("<");
-      else
-        setText(">");
+      offset = e.getX();
+    }
+
+    /**
+     * This method returns true if the divider can move.
+     *
+     * @return True if dragging is allowed.
+     */
+    protected boolean isValid()
+    {
+      // Views can always be resized?
+      return true;
+    }
 
-      Dimension butSize = new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE);
-      setMinimumSize(butSize);
-      setMaximumSize(butSize);
-      setPreferredSize(butSize);
+    /**
+     * Returns a position for the divider given the MouseEvent.
+     *
+     * @param e MouseEvent.
+     *
+     * @return The position for the divider to move to.
+     */
+    protected int positionForMouseEvent(MouseEvent e)
+    {
+      return e.getX() + getX() - offset;
+    }
 
-      setBorderPainted(false);
+    /**
+     * This method returns one of the two paramters
+     * for the orientation. In this case, it returns x.
+     *
+     * @param x The x coordinate.
+     * @param y The y coordinate.
+     *
+     * @return The x coordinate.
+     */
+    protected int getNeededLocation(int x, int y)
+    {
+      return x;
+    }
+
+    /**
+     * This method is called to pass on the drag information
+     * to the UI through dragDividerTo.
+     *
+     * @param newX The x coordinate of the MouseEvent.
+     * @param newY The y coordinate of the MouseEvent.
+     */
+    protected void continueDrag(int newX, int newY)
+    {
+      if (isValid())
+	dragDividerTo(adjust(newX, newY));
     }
-  }
 
+    /**
+     * This method is called to pass on the drag information 
+     * to the UI through dragDividerTo.
+     *
+     * @param e The MouseEvent.
+     */
+    protected void continueDrag(MouseEvent e)
+    {
+      if (isValid())
+	dragDividerTo(positionForMouseEvent(e));
+    }
+
+    /**
+     * This method is called to finish the drag session 
+     * by calling finishDraggingTo.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     */
+    protected void completeDrag(int x, int y)
+    {
+      finishDraggingTo(adjust(x, y));
+    }
+
+    /**
+     * This method is called to finish the drag session 
+     * by calling finishDraggingTo.
+     *
+     * @param e The MouseEvent.
+     */
+    protected void completeDrag(MouseEvent e)
+    {
+      finishDraggingTo(positionForMouseEvent(e));
+    }
+    
+    /**
+     * This is a helper method that includes the offset
+     * in the needed location.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     *
+     * @return The needed location adjusted by the offsets.
+     */
+    int adjust(int x, int y)
+    {
+      return getNeededLocation(x, y) + getX() - offset;
+    }
+  }
 
   /**
-   * Performs the tasks associated with an ongoing drag
-   * operation.
-   *
-   * @author Sascha Brawer (brawer@dandelis.ch)
+   * This is a helper class that controls dragging when 
+   * the orientation is VERTICAL_SPLIT.
    */
-  protected class DragController
+  protected class VerticalDragController extends DragController
   {
-    // FIXME: Not yet implemented.
-    protected DragController(MouseEvent e)
+    /**
+     * Creates a new VerticalDragController object.
+     *
+     * @param e The MouseEvent to initialize with.
+     */
+    protected VerticalDragController(MouseEvent e)
     {
+      super(e);
+      offset = e.getY();
     }
 
-    protected boolean isValid()
+    /**
+     * This method returns one of the two parameters given
+     * the orientation. In this case, it returns y.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     *
+     * @return The y coordinate.
+     */
+    protected int getNeededLocation(int x, int y)
     {
-      // FIXME: Not yet implemented.
-      return true;
+      return y;
     }
 
+    /**
+     * This method returns the new location of the divider
+     * given a MouseEvent.
+     *
+     * @param e The MouseEvent.
+     *
+     * @return The new location of the divider.
+     */
     protected int positionForMouseEvent(MouseEvent e)
     {
-      return 0;
+      return e.getY() + getY() - offset;
     }
 
-    protected int getNeededLocation(int x, int y)
+    /**
+     * This is a helper method that includes the offset
+     * in the needed location.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     *
+     * @return The needed location adjusted by the offsets.
+     */
+    int adjust(int x, int y)
+    {
+      return getNeededLocation(x, y) + getY() - offset;
+    }        
+  }
+
+  /**
+   * This helper class acts as the Layout Manager for
+   * the divider.
+   */
+  protected class DividerLayout implements LayoutManager
+  {
+    /**
+     * Creates a new DividerLayout object.
+     */
+    protected DividerLayout()
     {
-      return 0;
     }
 
-    protected void continueDrag(int newX, int newY)
+    /**
+     * This method is called when a Component is added.
+     *
+     * @param string The constraints string.
+     * @param c The Component to add.
+     */
+    public void addLayoutComponent(String string, Component c)
     {
+      // Do nothing.
     }
 
-    protected void completeDrag(int x, int y)
+    /**
+     * This method is called to lay out the container.
+     *
+     * @param c The container to lay out.
+     */
+    public void layoutContainer(Container c)
     {
+      if (splitPane.isOneTouchExpandable())
+        {
+	  changeButtonOrientation();
+	  positionButtons();
+        }
     }
 
-    protected void completeDrag(MouseEvent e)
+    /**
+     * This method returns the minimum layout size.
+     *
+     * @param c The container to calculate for.
+     *
+     * @return The minimum layout size.
+     */
+    public Dimension minimumLayoutSize(Container c)
+    {
+      return preferredLayoutSize(c);
+    }
+
+    /**
+     * This method returns the preferred layout size.
+     *
+     * @param c The container to calculate for.
+     *
+     * @return The preferred layout size.
+     */
+    public Dimension preferredLayoutSize(Container c)
     {
+      return new Dimension(dividerSize, dividerSize);
+    }
+
+    /**
+     * This method is called when a component is removed.
+     *
+     * @param c The component to remove.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method changes the button orientation when
+     * the orientation of the SplitPane changes.
+     */
+    private void changeButtonOrientation()
+    {
+      if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+        {
+	  ((BasicArrowButton) rightButton).setDirection(SwingConstants.EAST);
+	  ((BasicArrowButton) leftButton).setDirection(SwingConstants.WEST);
+        }
+      else
+        {
+	  ((BasicArrowButton) rightButton).setDirection(SwingConstants.SOUTH);
+	  ((BasicArrowButton) leftButton).setDirection(SwingConstants.NORTH);
+        }
+    }
+
+    /**
+     * This method sizes and positions the buttons.
+     */
+    private void positionButtons()
+    {
+      int w = 0;
+      int h = 0;
+      if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+        {
+	  rightButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET);
+	  leftButton.setLocation(ONE_TOUCH_OFFSET,
+	                         ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE);
+	  w = dividerSize - 2 * ONE_TOUCH_OFFSET;
+	  h = 2 * ONE_TOUCH_SIZE;
+        }
+      else
+        {
+	  leftButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET);
+	  rightButton.setLocation(ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE,
+	                          ONE_TOUCH_OFFSET);
+	  h = dividerSize - 2 * ONE_TOUCH_OFFSET;
+	  w = 2 * ONE_TOUCH_SIZE;
+        }
+      Dimension dims = new Dimension(w, h);
+      leftButton.setSize(dims);
+      rightButton.setSize(dims);
     }
   }
 }
Index: javax/swing/plaf/basic/BasicSplitPaneUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicSplitPaneUI.java,v
retrieving revision 1.1
diff -u -r1.1 BasicSplitPaneUI.java
--- javax/swing/plaf/basic/BasicSplitPaneUI.java	24 Jun 2003 09:48:42 -0000	1.1
+++ javax/swing/plaf/basic/BasicSplitPaneUI.java	6 Sep 2004 16:36:08 -0000
@@ -1,5 +1,5 @@
 /* BasicSplitPaneUI.java
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,273 +37,1478 @@
 
 package javax.swing.plaf.basic;
 
+import java.awt.Canvas;
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Insets;
+import java.awt.LayoutManager2;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import javax.swing.JButton;
 import javax.swing.JComponent;
 import javax.swing.JSplitPane;
 import javax.swing.KeyStroke;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.SplitPaneUI;
 
+
 /**
- * FIXME: Stubbed to allow compiling other classes,
- * no real implementation.
+ * This is the Basic Look and Feel implementation of the SplitPaneUI  class.
  */
-public class BasicSplitPaneUI
-  extends SplitPaneUI
+public class BasicSplitPaneUI extends SplitPaneUI
 {
-  protected static final String NON_CONTINUOUS_DIVIDER
-    = "nonContinuousDivider";
+  /**
+   * This Layout Manager controls the position and size of the components when
+   * the JSplitPane's orientation is HORIZONTAL_SPLIT.
+   */
+  protected class BasicHorizontalLayoutManager implements LayoutManager2
+  {
+    // 3 components at a time.
+    // LEFT/TOP = 0
+    // RIGHT/BOTTOM = 1
+    // DIVIDER = 2    
+
+    /**
+     * This array contains the components in the JSplitPane. The  left/top
+     * component is at index 0, the right/bottom is at 1, and the divider is
+     * at 2.
+     */
+    protected Component[] components = new Component[3];
+
+    // These are the _current_ widths of the associated component.
+
+    /**
+     * This array contains the current width (for HORIZONTAL_SPLIT) or height
+     * (for VERTICAL_SPLIT) of the components. The indices are the same as
+     * for components.
+     */
+    protected int[] sizes = new int[3];
+
+    /**
+     * This method adds the component given to the JSplitPane. The position of
+     * the component is given by the constraints object.
+     *
+     * @param comp The Component to add.
+     * @param constraints The constraints that bind the object.
+     */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+      addLayoutComponent((String) constraints, comp);
+    }
+
+    /**
+     * This method is called to add a Component to the JSplitPane. The
+     * placement string determines where the Component will be placed. The
+     * string should be one of LEFT, RIGHT, TOP, BOTTOM or null (signals that
+     * the component is the divider).
+     *
+     * @param place The placement of the Component.
+     * @param component The Component to add.
+     *
+     * @throws IllegalArgumentException DOCUMENT ME!
+     */
+    public void addLayoutComponent(String place, Component component)
+    {
+      int i = 0;
+      if (place == null)
+	i = 2;
+      else if (place.equals(JSplitPane.TOP) || place.equals(JSplitPane.LEFT))
+	i = 0;
+      else if (place.equals(JSplitPane.BOTTOM)
+               || place.equals(JSplitPane.RIGHT))
+	i = 1;
+      else
+	throw new IllegalArgumentException("Illegal placement in JSplitPane");
+      components[i] = component;
+      resetSizeAt(i);
+      splitPane.revalidate();
+      splitPane.repaint();
+    }
+
+    /**
+     * This method returns the width of the JSplitPane minus the insets.
+     *
+     * @param containerSize The Dimensions of the JSplitPane.
+     * @param insets The Insets of the JSplitPane.
+     *
+     * @return The width of the JSplitPane minus the insets.
+     */
+    protected int getAvailableSize(Dimension containerSize, Insets insets)
+    {
+      return containerSize.width - insets.left - insets.right;
+    }
+
+    /**
+     * This method returns the given insets left value. If the  given inset is
+     * null, then 0 is returned.
+     *
+     * @param insets The Insets to use with the JSplitPane.
+     *
+     * @return The inset's left value.
+     */
+    protected int getInitialLocation(Insets insets)
+    {
+      if (insets != null)
+	return insets.left;
+      return 0;
+    }
+
+    /**
+     * This specifies how a component is aligned with respect to  other
+     * components in the x fdirection.
+     *
+     * @param target The container.
+     *
+     * @return The component's alignment.
+     */
+    public float getLayoutAlignmentX(Container target)
+    {
+      return target.getAlignmentX();
+    }
+
+    /**
+     * This specifies how a component is aligned with respect to  other
+     * components in the y direction.
+     *
+     * @param target The container.
+     *
+     * @return The component's alignment.
+     */
+    public float getLayoutAlignmentY(Container target)
+    {
+      return target.getAlignmentY();
+    }
+
+    /**
+     * This method returns the preferred width of the component.
+     *
+     * @param c The component to measure.
+     *
+     * @return The preferred width of the component.
+     */
+    protected int getPreferredSizeOfComponent(Component c)
+    {
+      Dimension dims = c.getPreferredSize();
+      if (dims != null)
+	return dims.width;
+      return 0;
+    }
+
+    /**
+     * This method returns the current width of the component.
+     *
+     * @param c The component to measure.
+     *
+     * @return The width of the component.
+     */
+    protected int getSizeOfComponent(Component c)
+    {
+      return c.getWidth();
+    }
+
+    /**
+     * This method returns the sizes array.
+     *
+     * @return The sizes array.
+     */
+    protected int[] getSizes()
+    {
+      return sizes;
+    }
+
+    /**
+     * This method invalidates the layout. It does nothing.
+     *
+     * @param c The container to invalidate.
+     */
+    public void invalidateLayout(Container c)
+    {
+      // DO NOTHING
+    }
+
+    /**
+     * This method lays out the components in the container.
+     *
+     * @param container The container to lay out.
+     */
+    public void layoutContainer(Container container)
+    {
+      if (container instanceof JSplitPane)
+        {
+	  JSplitPane split = (JSplitPane) container;
+	  distributeExtraSpace();
+	  Insets insets = split.getInsets();
+	  int width = getInitialLocation(insets);
+	  Dimension dims = split.getSize();
+	  for (int i = 0; i < components.length; i += 2)
+	    {
+	      if (components[i] == null)
+		continue;
+	      setComponentToSize(components[i], sizes[i], width, insets, dims);
+	      width += sizes[i];
+	    }
+	  if (components[1] != null)
+	    {
+	      setComponentToSize(components[1], sizes[1], width, insets, dims);
+	      width += sizes[1];
+	    }
+        }
+    }
+
+    /**
+     * This method returns the maximum size for the container given the
+     * components. It returns a new Dimension object that has width and
+     * height equal to Integer.MAX_VALUE.
+     *
+     * @param target The container to measure.
+     *
+     * @return The maximum size.
+     */
+    public Dimension maximumLayoutSize(Container target)
+    {
+      return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+
+    /**
+     * This method returns the container's minimum size. The  minimum width is
+     * the sum of all the component's minimum widths. The minimum height is
+     * the maximum of  all the components' minimum heights.
+     *
+     * @param target The container to measure.
+     *
+     * @return The minimum size.
+     */
+    public Dimension minimumLayoutSize(Container target)
+    {
+      if (target instanceof JSplitPane)
+        {
+	  JSplitPane split = (JSplitPane) target;
+	  Insets insets = target.getInsets();
+
+	  int height = 0;
+	  int width = 0;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] == null)
+		continue;
+	      Dimension dims = components[i].getMinimumSize();
+	      if (dims != null)
+	        {
+		  width += dims.width;
+		  height = Math.max(height, dims.height);
+	        }
+	    }
+	  return new Dimension(width, height);
+        }
+      return null;
+    }
+
+    /**
+     * This method returns the container's preferred size. The preferred width
+     * is the sum of all the component's preferred widths. The preferred
+     * height is the maximum of all the components' preferred heights.
+     *
+     * @param target The container to measure.
+     *
+     * @return The preferred size.
+     */
+    public Dimension preferredLayoutSize(Container target)
+    {
+      if (target instanceof JSplitPane)
+        {
+	  JSplitPane split = (JSplitPane) target;
+	  Insets insets = target.getInsets();
+
+	  int height = 0;
+	  int width = 0;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] == null)
+		continue;
+	      Dimension dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  width += dims.width;
+		  if (! (components[i] instanceof BasicSplitPaneDivider))
+		    height = Math.max(height, dims.height);
+	        }
+	    }
+	  return new Dimension(500, 500); //width, height);	
+        }
+      return null;
+    }
+
+    /**
+     * This method removes the component from the layout.
+     *
+     * @param component The component to remove from the layout.
+     */
+    public void removeLayoutComponent(Component component)
+    {
+      for (int i = 0; i < components.length; i++)
+        {
+	  if (component == components[i])
+	    {
+	      components[i] = null;
+	      sizes[i] = 0;
+	    }
+        }
+    }
+
+    /**
+     * This method resets the size of Component to the preferred size.
+     *
+     * @param index The index of the component to reset.
+     */
+    protected void resetSizeAt(int index)
+    {
+      if (components[index] != null)
+	sizes[index] = getPreferredSizeOfComponent(components[index]);
+    }
+
+    /**
+     * This method resets the sizes of all the components.
+     */
+    public void resetToPreferredSizes()
+    {
+      for (int i = 0; i < components.length; i++)
+	resetSizeAt(i);
+    }
+
+    /**
+     * This methods sets the bounds of the given component. The width is the
+     * size. The height is the container size minus the  top and bottom
+     * inset. The x coordinate is the location given.  The y coordinate is
+     * the top inset.
+     *
+     * @param c The component to set.
+     * @param size The width of the component.
+     * @param location The x coordinate.
+     * @param insets The insets to use.
+     * @param containerSize The height of the container.
+     */
+    protected void setComponentToSize(Component c, int size, int location,
+                                      Insets insets, Dimension containerSize)
+    {
+      int w = size;
+      int h = containerSize.height - insets.top - insets.bottom;
+      int x = location;
+      int y = insets.top;
+      c.setBounds(x, y, w, h);
+    }
+
+    /**
+     * This method stores the given int array as the new sizes array.
+     *
+     * @param newSizes The array to use as sizes.
+     */
+    protected void setSizes(int[] newSizes)
+    {
+      sizes = newSizes;
+    }
+
+    /**
+     * This method determines the size of each  component. It should be called
+     * when a new Layout Manager is created for an existing JSplitPane.
+     */
+    protected void updateComponents()
+    {
+      Component left = splitPane.getLeftComponent();
+      Component right = splitPane.getRightComponent();
+
+      if (left != null)
+        {
+	  components[0] = left;
+	  resetSizeAt(0);
+        }
+      if (right != null)
+        {
+	  components[1] = right;
+	  resetSizeAt(1);
+        }
+      components[2] = divider;
+      resetSizeAt(2);
+    }
+
+    /**
+     * This method resizes the left and right components to fit inside the
+     * JSplitPane when there is extra space.
+     */
+    void distributeExtraSpace()
+    {
+      int availSize = getAvailableSize(splitPane.getSize(),
+                                       splitPane.getInsets());
+      int[] newSizes = new int[3];
+      double weight = splitPane.getResizeWeight();
+
+      int oldLen = sizes[0] + sizes[1];
+
+      // dividers don't change size.
+      availSize -= sizes[2] + oldLen;
+
+      int rightAlloc = (int) (availSize * (1 - weight));
+      int leftAlloc = availSize - rightAlloc;
+
+      sizes[0] += leftAlloc;
+      sizes[1] += rightAlloc;
+    }
+
+    /**
+     * This method returns the minimum width of the  component at the given
+     * index.
+     *
+     * @param index The index to check.
+     *
+     * @return The minimum width.
+     */
+    int minimumSizeOfComponent(int index)
+    {
+      Dimension dims = components[index].getMinimumSize();
+      if (dims != null)
+	return dims.width;
+      else
+	return 0;
+    }
+  } //end BasicHorizontalLayoutManager
+
+  /**
+   * This class is the Layout Manager for the JSplitPane when the orientation
+   * is VERTICAL_SPLIT.
+   */
+  protected class BasicVerticalLayoutManager
+    extends BasicHorizontalLayoutManager
+  {
+    /**
+     * This method returns the height of the container minus the top and
+     * bottom inset.
+     *
+     * @param containerSize The size of the container.
+     * @param insets The insets of the container.
+     *
+     * @return The height minus top and bottom inset.
+     */
+    protected int getAvailableSize(Dimension containerSize, Insets insets)
+    {
+      return containerSize.height - insets.top - insets.bottom;
+    }
+
+    /**
+     * This method returns the top inset.
+     *
+     * @param insets The Insets to use.
+     *
+     * @return The top inset.
+     */
+    protected int getInitialLocation(Insets insets)
+    {
+      return insets.top;
+    }
+
+    /**
+     * This method returns the preferred height of the component.
+     *
+     * @param c The component to measure.
+     *
+     * @return The preferred height of the component.
+     */
+    protected int getPreferredSizeOfComponent(Component c)
+    {
+      Dimension dims = c.getPreferredSize();
+      if (dims != null)
+	return dims.height;
+      return 0;
+    }
+
+    /**
+     * This method returns the current height of the component.
+     *
+     * @param c The component to measure.
+     *
+     * @return The current height of the component.
+     */
+    protected int getSizeOfComponent(Component c)
+    {
+      return c.getHeight();
+    }
+
+    /**
+     * This method returns the minimum layout size. The minimum height is the
+     * sum of all the components' minimum heights. The minimum width is the
+     * maximum of all the  components' minimum widths.
+     *
+     * @param container The container to measure.
+     *
+     * @return The minimum size.
+     */
+    public Dimension minimumLayoutSize(Container container)
+    {
+      if (container instanceof JSplitPane)
+        {
+	  JSplitPane split = (JSplitPane) container;
+	  Insets insets = container.getInsets();
+
+	  int height = 0;
+	  int width = 0;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] == null)
+		continue;
+	      Dimension dims = components[i].getMinimumSize();
+	      if (dims != null)
+	        {
+		  height += dims.height;
+		  width = Math.max(width, dims.width);
+	        }
+	    }
+	  return new Dimension(width, height);
+        }
+      return null;
+    }
+
+    /**
+     * This method returns the preferred layout size. The preferred height is
+     * the sum of all the components'  preferred heights. The preferred width
+     * is the maximum of  all the components' preferred widths.
+     *
+     * @param container The container to measure.
+     *
+     * @return The preferred size.
+     */
+    public Dimension preferredLayoutSize(Container container)
+    {
+      if (container instanceof JSplitPane)
+        {
+	  JSplitPane split = (JSplitPane) container;
+	  Insets insets = container.getInsets();
+
+	  int height = 0;
+	  int width = 0;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] == null)
+		continue;
+	      Dimension dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  height += dims.height;
+		  width = Math.max(width, dims.width);
+	        }
+	    }
+	  return new Dimension(500, 500); //width, height);
+        }
+      return null;
+    }
+
+    /**
+     * This method sets the bounds of the given component. The y coordinate is
+     * the location given. The x coordinate is the left inset. The height is
+     * the size given. The width is the container size minus the left and
+     * right inset.
+     *
+     * @param c The component to set bounds for.
+     * @param size The height.
+     * @param location The y coordinate.
+     * @param insets The insets to use.
+     * @param containerSize The container's size.
+     */
+    protected void setComponentToSize(Component c, int size, int location,
+                                      Insets insets, Dimension containerSize)
+    {
+      int y = location;
+      int x = insets.left;
+      int h = size;
+      int w = containerSize.width - insets.left - insets.right;
+
+      c.setBounds(x, y, w, h);
+    }
+
+    /**
+     * This method returns the minimum height of the component at the given
+     * index.
+     *
+     * @param index The index of the component to check.
+     *
+     * @return The minimum height of the given component.
+     */
+    int minimumSizeOfComponent(int index)
+    {
+      Dimension dims = components[index].getMinimumSize();
+      if (dims != null)
+	return dims.height;
+      else
+	return 0;
+    }
+  }
+
+  /**
+   * This class handles FocusEvents from the JComponent.
+   */
+  protected class FocusHandler extends FocusAdapter
+  {
+    /**
+     * This method is called when the JSplitPane gains focus.
+     *
+     * @param ev The FocusEvent.
+     */
+    public void focusGained(FocusEvent ev)
+    {
+      // FIXME: implement.
+    }
+
+    /**
+     * This method is called when the JSplitPane loses focus.
+     *
+     * @param ev The FocusEvent.
+     */
+    public void focusLost(FocusEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This is a deprecated class. It is supposed to be used for handling down
+   * and right key presses.
+   */
+  protected class KeyboardDownRightHandler implements ActionListener
+  {
+    /**
+     * This method is called when the down or right keys are pressed.
+     *
+     * @param ev The ActionEvent
+     */
+    public void actionPerformed(ActionEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This is a deprecated class. It is supposed to be used for handling end
+   * key presses.
+   */
+  protected class KeyboardEndHandler implements ActionListener
+  {
+    /**
+     * This method is called when the end key is pressed.
+     *
+     * @param ev The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This is a deprecated class. It is supposed to be used for handling home
+   * key presses.
+   */
+  protected class KeyboardHomeHandler implements ActionListener
+  {
+    /**
+     * This method is called when the home key is pressed.
+     *
+     * @param ev The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This is a deprecated class. It is supposed to be used for handling resize
+   * toggles.
+   */
+  protected class KeyboardResizeToggleHandler implements ActionListener
+  {
+    /**
+     * This method is called when a resize is toggled.
+     *
+     * @param ev The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This is a deprecated class. It is supposed to be used for handler up and
+   * left key presses.
+   */
+  protected class KeyboardUpLeftHandler implements ActionListener
+  {
+    /**
+     * This method is called when the left or up keys are pressed.
+     *
+     * @param ev The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent ev)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This helper class handles PropertyChangeEvents from the JSplitPane. When
+   * a property changes, this will update the UI accordingly.
+   */
+  protected class PropertyHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called whenever one of the JSplitPane's properties
+     * change.
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
+        {
+	  int newSize = splitPane.getDividerSize();
+	  int[] tmpSizes = layoutManager.getSizes();
+	  dividerSize = tmpSizes[2];
+	  Component left = splitPane.getLeftComponent();
+	  Component right = splitPane.getRightComponent();
+	  int newSpace = newSize - tmpSizes[2];
+
+	  tmpSizes[2] = newSize;
+
+	  tmpSizes[0] += newSpace / 2;
+	  tmpSizes[1] += newSpace / 2;
+
+	  layoutManager.setSizes(tmpSizes);
+        }
+      else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
+        {
+	  int max = layoutManager.getAvailableSize(splitPane.getSize(),
+	                                           splitPane.getInsets());
+	  int dividerLoc = getDividerLocation(splitPane);
+	  double prop = ((double) dividerLoc) / max;
+
+	  resetLayoutManager();
+	  if (prop <= 1 && prop >= 0)
+	    splitPane.setDividerLocation(prop);
+        }
+      layoutManager.layoutContainer(splitPane);
+      splitPane.repaint();
+      // Don't have to deal with continuous_layout - only
+      // necessary in dragging modes (and it's checked
+      // every time you drag there)
+      // Don't have to deal with resize_weight (as there
+      // will be no extra space associated with this
+      // event - the changes to the weighting will
+      // be taken into account the next time the 
+      // sizes change.)
+      // Don't have to deal with divider_location 
+      // The method in JSplitPane calls our setDividerLocation
+      // so we'll know about those anyway.
+      // Don't have to deal with last_divider_location
+      // Although I'm not sure why, it doesn't seem to 
+      // have any effect on Sun's JSplitPane.
+      // one_touch_expandable changes are dealt with
+      // by our divider.
+    }
+  }
+
+  /** The location of the divider when dragging began. */
+  protected int beginDragDividerLocation;
+
+  /** The size of the divider while dragging. */
+  protected int dividerSize;
 
+  /** The location where the last drag location ended. */
+  transient int lastDragLocation = -1;
+
+  /** The distance the divider is moved when moved by keyboard actions. */
   protected static int KEYBOARD_DIVIDER_MOVE_OFFSET;
 
-  protected JSplitPane splitPane;
+  /** The divider that divides this JSplitPane. */
   protected BasicSplitPaneDivider divider;
+
+  /** The listener that listens for PropertyChangeEvents from the JSplitPane. */
   protected PropertyChangeListener propertyChangeListener;
+
+  /** The JSplitPane's focus handler. */
   protected FocusListener focusListener;
-  protected int dividerSize;
-  protected Component nonContinuousLayoutDivider;
-  protected boolean draggingHW;
-  protected int beginDragDividerLocation;
-  protected KeyStroke upKey;
-  protected KeyStroke downKey;
-  protected KeyStroke leftKey;
-  protected KeyStroke rightKey;
-  protected KeyStroke homeKey;
-  protected KeyStroke endKey;
-  protected KeyStroke dividerResizeToggleKey;
-  protected ActionListener keyboardUpLeftListener;
+
+  /** Deprecated. The handler for down and right key presses. */
   protected ActionListener keyboardDownRightListener;
-  protected ActionListener keyboardHomeListener;
+
+  /** Deprecated. The handler for end key presses. */
   protected ActionListener keyboardEndListener;
+
+  /** Deprecated. The handler for home key presses. */
+  protected ActionListener keyboardHomeListener;
+
+  /** Deprecated. The handler for toggling resizes. */
   protected ActionListener keyboardResizeToggleListener;
 
-  public static ComponentUI createUI(JComponent c)
-  {
-    BasicSplitPaneUI newUI;
+  /** Deprecated. The handler for up and left key presses. */
+  protected ActionListener keyboardUpLeftListener;
 
-    newUI = new BasicSplitPaneUI();
-    newUI.installUI(c);
-    return newUI;
-  }
+  /** The JSplitPane's current layout manager. */
+  protected BasicHorizontalLayoutManager layoutManager;
+
+  /** Deprecated. The divider resize toggle key. */
+  protected KeyStroke dividerResizeToggleKey;
+
+  /** Deprecated. The down key. */
+  protected KeyStroke downKey;
+
+  /** Deprecated. The end key. */
+  protected KeyStroke endKey;
+
+  /** Deprecated. The home key. */
+  protected KeyStroke homeKey;
+
+  /** Deprecated. The left key. */
+  protected KeyStroke leftKey;
+
+  /** Deprecated. The right key. */
+  protected KeyStroke rightKey;
+
+  /** Deprecated. The up key. */
+  protected KeyStroke upKey;
+
+  /** Set to true when dragging heavy weight components. */
+  protected boolean draggingHW;
+
+  /**
+   * The constraints object used when adding the non-continuous divider to the
+   * JSplitPane.
+   */
+  protected static String NON_CONTINUOUS_DIVIDER;
+
+  /** The dark divider used when dragging in non-continuous layout mode. */
+  protected Component nonContinuousLayoutDivider;
 
+  /** The JSplitPane that this UI draws. */
+  protected JSplitPane splitPane;
+
+  /**
+   * Creates a new BasicSplitPaneUI object.
+   */
   public BasicSplitPaneUI()
   {
-    propertyChangeListener = createPropertyChangeListener();
-    focusListener = createFocusListener();
   }
 
+  /**
+   * This method creates a new BasicSplitPaneUI for the given JComponent.
+   *
+   * @param x The JComponent to create a UI for.
+   *
+   * @return A new BasicSplitPaneUI.
+   */
+  public static ComponentUI createUI(JComponent x)
+  {
+    return new BasicSplitPaneUI();
+  }
+
+  /**
+   * This method installs the BasicSplitPaneUI for the given JComponent.
+   *
+   * @param c The JComponent to install the UI for.
+   */
   public void installUI(JComponent c)
   {
+    if (c instanceof JSplitPane)
+      {
+	splitPane = (JSplitPane) c;
+	installDefaults();
+	installListeners();
+	installKeyboardActions();
+      }
   }
 
-  protected void installDefaults()
+  /**
+   * This method uninstalls the BasicSplitPaneUI for the given JComponent.
+   *
+   * @param c The JComponent to uninstall the UI for.
+   */
+  public void uninstallUI(JComponent c)
   {
-  }
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallDefaults();
 
-  protected void installListeners()
-  {
+    splitPane = null;
   }
 
-  protected void installKeyboardListeners()
+  /**
+   * This method installs the defaults given by the Look and Feel.
+   */
+  protected void installDefaults()
   {
-  }
-
-  protected void installKeyboardActions()
+    resetLayoutManager();
+    divider = createDefaultDivider();
+    nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
+    splitPane.add(divider, JSplitPane.DIVIDER);
+
+    // There is no need to add the nonContinuousLayoutDivider
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    splitPane.setBackground(defaults.getColor("SplitPane.background"));
+    splitPane.setBorder(defaults.getBorder("SplitPane.border"));
+    splitPane.setDividerSize(defaults.getInt("SplitPane.dividerSize"));
+  }
+
+  /**
+   * This method uninstalls the defaults and nulls any objects created during
+   * install.
+   */
+  protected void uninstallDefaults()
   {
+    layoutManager = null;
+    splitPane.remove(divider);
+    divider = null;
+    nonContinuousLayoutDivider = null;
+
+    splitPane.setBackground(null);
+    splitPane.setBorder(null);
   }
 
-  public void uninstallUI(JComponent c)
+  /**
+   * This method installs the listeners needed for this UI to function.
+   */
+  protected void installListeners()
   {
+    propertyChangeListener = createPropertyChangeListener();
+    focusListener = createFocusListener();
+
+    splitPane.addPropertyChangeListener(propertyChangeListener);
+    splitPane.addFocusListener(focusListener);
   }
 
-  protected void uninstallDefaults()
+  /**
+   * This method uninstalls all listeners registered for the UI.
+   */
+  protected void uninstallListeners()
   {
+    splitPane.removePropertyChangeListener(propertyChangeListener);
+    splitPane.removeFocusListener(focusListener);
+
+    focusListener = null;
+    propertyChangeListener = null;
   }
 
-  protected void uninstallListeners()
+  /**
+   * This method installs the keyboard actions for the JSplitPane.
+   */
+  protected void installKeyboardActions()
   {
+    // FIXME: implement.
   }
 
+  /**
+   * This method reverses the work done in installKeyboardActions.
+   */
   protected void uninstallKeyboardActions()
   {
+    // FIXME: implement.
   }
 
+  /**
+   * This method creates a new PropertyChangeListener.
+   *
+   * @return A new PropertyChangeListener.
+   */
   protected PropertyChangeListener createPropertyChangeListener()
   {
-    return null;
+    return new PropertyHandler();
   }
 
+  /**
+   * This method creates a new FocusListener.
+   *
+   * @return A new FocusListener.
+   */
   protected FocusListener createFocusListener()
   {
-    return null;
+    return new FocusHandler();
   }
 
+  /**
+   * Deprecated. This method creates a new ActionListener for up and left key
+   * presses.
+   *
+   * @return A new ActionListener for up and left keys.
+   */
   protected ActionListener createKeyboardUpLeftListener()
   {
-    return null;
+    return new KeyboardUpLeftHandler();
   }
 
+  /**
+   * Deprecated. This method creates a new ActionListener for down and right
+   * key presses.
+   *
+   * @return A new ActionListener for down and right keys.
+   */
   protected ActionListener createKeyboardDownRightListener()
   {
-    return null;
+    return new KeyboardDownRightHandler();
   }
 
+  /**
+   * Deprecated. This method creates a new ActionListener for home key
+   * presses.
+   *
+   * @return A new ActionListener for home keys.
+   */
   protected ActionListener createKeyboardHomeListener()
   {
-    return null;
+    return new KeyboardHomeHandler();
   }
 
+  /**
+   * Deprecated. This method creates a new ActionListener for end key presses.
+   *
+   * @return A new ActionListener for end keys.
+   */
   protected ActionListener createKeyboardEndListener()
   {
-    return null;
+    return new KeyboardEndHandler();
   }
 
+  /**
+   * Depcreated. This method creates a new ActionListener for resize toggle
+   * key events.
+   *
+   * @return A new ActionListener for resize toggle keys.
+   */
   protected ActionListener createKeyboardResizeToggleListener()
   {
-    return null;
+    return new KeyboardResizeToggleHandler();
   }
 
+  /**
+   * This method returns the orientation of the JSplitPane.
+   *
+   * @return The orientation of the JSplitPane.
+   */
   public int getOrientation()
   {
     return splitPane.getOrientation();
   }
 
+  /**
+   * This method sets the orientation of the JSplitPane.
+   *
+   * @param orientation The new orientation of the JSplitPane.
+   */
   public void setOrientation(int orientation)
   {
+    splitPane.setOrientation(orientation);
   }
 
-
+  /**
+   * This method returns true if the JSplitPane is using continuous layout.
+   *
+   * @return True if the JSplitPane is using continuous layout.
+   */
   public boolean isContinuousLayout()
   {
-    return false;
+    return splitPane.isContinuousLayout();
   }
 
+  /**
+   * This method sets the continuous layout property of the JSplitPane.
+   *
+   * @param b True if the JsplitPane is to use continuous layout.
+   */
   public void setContinuousLayout(boolean b)
   {
+    splitPane.setContinuousLayout(b);
   }
 
+  /**
+   * This method returns the last location the divider was dragged to.
+   *
+   * @return The last location the divider was dragged to.
+   */
   public int getLastDragLocation()
   {
-    return 0;
+    return lastDragLocation;
   }
 
+  /**
+   * This method sets the last location the divider was dragged to.
+   *
+   * @param l The last location the divider was dragged to.
+   */
   public void setLastDragLocation(int l)
   {
+    lastDragLocation = l;
   }
 
-
+  /**
+   * This method returns the BasicSplitPaneDivider that divides this
+   * JSplitPane.
+   *
+   * @return The divider for the JSplitPane.
+   */
   public BasicSplitPaneDivider getDivider()
   {
     return divider;
   }
 
-
+  /**
+   * This method creates a nonContinuousLayoutDivider for use with the
+   * JSplitPane in nonContinousLayout mode. The default divider is a gray
+   * Canvas.
+   *
+   * @return The default nonContinousLayoutDivider.
+   */
   protected Component createDefaultNonContinuousLayoutDivider()
   {
-    return null;
+    if (nonContinuousLayoutDivider == null)
+      {
+	nonContinuousLayoutDivider = new Canvas();
+	nonContinuousLayoutDivider.setBackground(Color.DARK_GRAY);
+      }
+    return nonContinuousLayoutDivider;
   }
 
+  /**
+   * This method sets the component to use as the nonContinuousLayoutDivider.
+   *
+   * @param newDivider The component to use as the nonContinuousLayoutDivider.
+   */
   protected void setNonContinuousLayoutDivider(Component newDivider)
   {
-    setNonContinuousLayoutDivider(newDivider, true /* false? */);
+    setNonContinuousLayoutDivider(newDivider, true);
   }
 
+  /**
+   * This method sets the component to use as the nonContinuousLayoutDivider.
+   *
+   * @param newDivider The component to use as the nonContinuousLayoutDivider.
+   * @param rememberSizes FIXME: document.
+   */
   protected void setNonContinuousLayoutDivider(Component newDivider,
                                                boolean rememberSizes)
   {
+    // FIXME: use rememberSizes for something
     nonContinuousLayoutDivider = newDivider;
   }
 
+  /**
+   * This method returns the nonContinuousLayoutDivider.
+   *
+   * @return The nonContinuousLayoutDivider.
+   */
   public Component getNonContinuousLayoutDivider()
   {
     return nonContinuousLayoutDivider;
   }
 
+  /**
+   * This method returns the JSplitPane that this BasicSplitPaneUI draws.
+   *
+   * @return The JSplitPane.
+   */
   public JSplitPane getSplitPane()
   {
     return splitPane;
   }
 
+  /**
+   * This method creates the divider used normally with the JSplitPane.
+   *
+   * @return The default divider.
+   */
   public BasicSplitPaneDivider createDefaultDivider()
   {
-    return null;
+    if (divider == null)
+      divider = new BasicSplitPaneDivider(this);
+    return divider;
   }
 
+  /**
+   * This method is called when JSplitPane's resetToPreferredSizes is called.
+   * It resets the sizes of all components in the JSplitPane.
+   *
+   * @param jc The JSplitPane to reset.
+   */
   public void resetToPreferredSizes(JSplitPane jc)
   {
+    layoutManager.resetToPreferredSizes();
   }
 
+  /**
+   * This method sets the location of the divider.
+   *
+   * @param jc The JSplitPane to set the divider location in.
+   * @param location The new location of the divider.
+   */
   public void setDividerLocation(JSplitPane jc, int location)
   {
-  }
-
+    setLastDragLocation(getDividerLocation(splitPane));
+    splitPane.setLastDividerLocation(getDividerLocation(splitPane));
+    int[] tmpSizes = layoutManager.getSizes();
+    tmpSizes[0] = location
+                  - layoutManager.getInitialLocation(splitPane.getInsets());
+    tmpSizes[1] = layoutManager.getAvailableSize(splitPane.getSize(),
+                                                 splitPane.getInsets())
+                  - tmpSizes[0] - tmpSizes[1];
+
+    layoutManager.setSizes(tmpSizes);
+    splitPane.revalidate();
+    splitPane.repaint();
+  }
+
+  /**
+   * This method returns the location of the divider.
+   *
+   * @param jc The JSplitPane to retrieve the location for.
+   *
+   * @return The location of the divider.
+   */
   public int getDividerLocation(JSplitPane jc)
   {
-    return 0;
+    return layoutManager.sizes[0]
+           + layoutManager.getInitialLocation(splitPane.getInsets());
   }
 
+  /**
+   * This method returns the smallest value possible for the location of the
+   * divider.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The minimum divider location.
+   */
   public int getMinimumDividerLocation(JSplitPane jc)
   {
-    return 0;
+    int value = layoutManager.getInitialLocation(jc.getInsets());
+    if (layoutManager.components[0] != null)
+      value += layoutManager.minimumSizeOfComponent(0);
+    return value;
   }
 
+  /**
+   * This method returns the largest value possible for the location of the
+   * divider.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The maximum divider location.
+   */
   public int getMaximumDividerLocation(JSplitPane jc)
   {
-    return 0;
+    int value = layoutManager.getInitialLocation(jc.getInsets())
+                + layoutManager.getAvailableSize(jc.getSize(), jc.getInsets())
+                - splitPane.getDividerSize();
+    if (layoutManager.components[1] != null)
+      value -= layoutManager.minimumSizeOfComponent(1);
+    return value;
   }
 
+  /**
+   * This method is called after the children of the JSplitPane are painted.
+   *
+   * @param jc The JSplitPane.
+   * @param g The Graphics object to paint with.
+   */
   public void finishedPaintingChildren(JSplitPane jc, Graphics g)
   {
+    if (! splitPane.isContinuousLayout() && nonContinuousLayoutDivider != null
+        && nonContinuousLayoutDivider.isVisible())
+      javax.swing.SwingUtilities.paintComponent(g, nonContinuousLayoutDivider,
+                                                null,
+                                                nonContinuousLayoutDivider
+                                                .getBounds());
   }
 
+  /**
+   * This method is called to paint the JSplitPane.
+   *
+   * @param g The Graphics object to paint with.
+   * @param jc The JSplitPane to paint.
+   */
   public void paint(Graphics g, JComponent jc)
   {
+    // Do nothing. All the painting is handled by children.
   }
 
+  /**
+   * This method returns the preferred size of the JSplitPane.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The preferred size of the JSplitPane.
+   */
   public Dimension getPreferredSize(JComponent jc)
   {
-    return null;
+    return layoutManager.preferredLayoutSize((Container) jc);
   }
 
+  /**
+   * This method returns the minimum size of the JSplitPane.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The minimum size of the JSplitPane.
+   */
   public Dimension getMinimumSize(JComponent jc)
   {
-    return null;
+    return layoutManager.minimumLayoutSize((Container) jc);
   }
 
+  /**
+   * This method returns the maximum size of the JSplitPane.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The maximum size of the JSplitPane.
+   */
   public Dimension getMaximumSize(JComponent jc)
   {
-    return null;
+    return layoutManager.maximumLayoutSize((Container) jc);
   }
 
+  /**
+   * This method returns the border insets of the current border.
+   *
+   * @param jc The JSplitPane.
+   *
+   * @return The current border insets.
+   */
   public Insets getInsets(JComponent jc)
   {
-    return new Insets(0, 0, 0, 0);
+    return splitPane.getBorder().getBorderInsets(splitPane);
   }
 
+  /**
+   * This method resets the current layout manager. The type of layout manager
+   * is dependent on the current orientation.
+   */
   protected void resetLayoutManager()
   {
-  }
-
+    if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+      layoutManager = new BasicHorizontalLayoutManager();
+    else
+      layoutManager = new BasicVerticalLayoutManager();
+    layoutManager.invalidateLayout(splitPane);
+    layoutManager.updateComponents();
+    getSplitPane().setLayout(layoutManager);
+
+    // invalidating by itself does not invalidate the layout.
+    getSplitPane().revalidate();
+  }
+
+  /**
+   * This method is called when dragging starts. It resets lastDragLocation
+   * and dividerSize.
+   */
   protected void startDragging()
   {
-  }
+    dividerSize = divider.getDividerSize();
+    setLastDragLocation(-1);
 
+    if (! splitPane.getLeftComponent().isLightweight()
+        || ! splitPane.getRightComponent().isLightweight())
+      draggingHW = true;
+
+    if (splitPane.isContinuousLayout())
+      nonContinuousLayoutDivider.setVisible(false);
+    else
+      {
+	nonContinuousLayoutDivider.setVisible(true);
+	nonContinuousLayoutDivider.setBounds(divider.getBounds());
+      }
+    splitPane.revalidate();
+    splitPane.repaint();
+  }
+
+  /**
+   * This method is called whenever the divider is dragged. If the JSplitPane
+   * is in continuousLayout mode, the divider needs to be moved and the
+   * JSplitPane needs to be laid out.
+   *
+   * @param location The new location of the divider.
+   */
   protected void dragDividerTo(int location)
   {
-  }
-
+    location = validLocation(location);
+    if (beginDragDividerLocation == -1)
+      beginDragDividerLocation = location;
+
+    if (splitPane.isContinuousLayout())
+      splitPane.setDividerLocation(location);
+    else
+      {
+	Point p = nonContinuousLayoutDivider.getLocation();
+	if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+	  p.x = location;
+	else
+	  p.y = location;
+	nonContinuousLayoutDivider.setLocation(p);
+      }
+    setLastDragLocation(location);
+    splitPane.repaint();
+  }
+
+  /**
+   * This method is called when the dragging is finished.
+   *
+   * @param location The location where the drag finished.
+   */
   protected void finishDraggingTo(int location)
   {
-  }
-
+    if (nonContinuousLayoutDivider != null)
+      nonContinuousLayoutDivider.setVisible(false);
+    draggingHW = false;
+    location = validLocation(location);
+    dragDividerTo(location);
+    splitPane.setDividerLocation(location);
+    splitPane.setLastDividerLocation(beginDragDividerLocation);
+    beginDragDividerLocation = -1;
+    splitPane.repaint();
+  }
+
+  /**
+   * Deprecated. This method returns the width of one of the sides of the
+   * divider's border.
+   *
+   * @return The width of one side of the divider's border.
+   */
   protected int getDividerBorderSize()
   {
-    return 0;
+    if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+      return divider.getBorder().getBorderInsets(divider).left;
+    else
+      return divider.getBorder().getBorderInsets(divider).top;
+  }
+
+  /**
+   * This is a helper method that returns a valid location for the divider
+   * when dragging.
+   *
+   * @param location The location to check.
+   *
+   * @return A valid location.
+   */
+  private int validLocation(int location)
+  {
+    if (location < getMinimumDividerLocation(splitPane))
+      return getMinimumDividerLocation(splitPane);
+    if (location > getMaximumDividerLocation(splitPane))
+      return getMaximumDividerLocation(splitPane);
+    return location;
   }
 }
Index: javax/swing/plaf/basic/BasicTabbedPaneUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java,v
retrieving revision 1.3
diff -u -r1.3 BasicTabbedPaneUI.java
--- javax/swing/plaf/basic/BasicTabbedPaneUI.java	13 Jul 2003 15:29:11 -0000	1.3
+++ javax/swing/plaf/basic/BasicTabbedPaneUI.java	6 Sep 2004 16:36:08 -0000
@@ -1,5 +1,5 @@
 /* BasicTabbedPaneUI.java
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -28,82 +28,2985 @@
 executable, regardless of the license terms of these independent
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
+independent module, the terms and conditions of7 the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.plaf.basic;
 
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Container;
 import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
 import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.Icon;
 import javax.swing.JComponent;
+import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
+import javax.swing.JViewport;
+import javax.swing.KeyStroke;
 import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.PanelUI;
 import javax.swing.plaf.TabbedPaneUI;
+import javax.swing.plaf.UIResource;
+import javax.swing.text.View;
 
-public class BasicTabbedPaneUI extends TabbedPaneUI
-  implements SwingConstants
+
+/**
+ * This is the Basic Look and Feel's UI delegate for JTabbedPane.
+ */
+public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
 {
-    public static ComponentUI createUI(final JComponent c) 
+  /**
+   * A helper class that handles focus.
+   */
+  protected class FocusHandler extends FocusAdapter
+  {
+    /**
+     * This method is called when the component gains focus.
+     *
+     * @param e The FocusEvent.
+     */
+    public void focusGained(FocusEvent e)
     {
-	return new BasicTabbedPaneUI();
+      // FIXME: Implement.
     }
-    
-    public void installUI(final JComponent c) 
+
+    /**
+     * This method is called when the component loses focus.
+     *
+     * @param e The FocusEvent.
+     */
+    public void focusLost(FocusEvent e)
     {
-	super.installUI(c);
+      // FIXME: Implement.
     }
-    
-    public Dimension getPreferredSize(JComponent c) 
+  }
+
+  /**
+   * A helper class for determining if mouse presses occur inside tabs and
+   * sets the index appropriately. In SCROLL_TAB_MODE, this class also
+   * handles the mouse clicks on the scrolling buttons.
+   */
+  protected class MouseHandler extends MouseAdapter
+  {
+    /**
+     * This method is called when the mouse is pressed. The index cannot
+     * change to a tab that is  not enabled.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
     {
-	JTabbedPane p = (JTabbedPane) c;
+      int x = e.getX();
+      int y = e.getY();
+      int tabCount = tabPane.getTabCount();
 
-	Dimension d = new Dimension(50,50);
-	
-	for (int i=0;i<p.getTabCount();i++)
+      if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+        {
+	  if (e.getSource() == incrButton)
 	    {
-		Component comp = p.getComponentAt(i);
-		
-		Dimension pr = comp.getPreferredSize();
+	      if (++currentScrollLocation >= tabCount)
+		currentScrollLocation = tabCount - 1;
+	      if (currentScrollLocation == tabCount - 1)
+		incrButton.setEnabled(false);
+	      else if (! decrButton.isEnabled())
+		decrButton.setEnabled(true);
+	      tabPane.layout();
+	      tabPane.repaint();
+	      return;
+	    }
+	  else if (e.getSource() == decrButton)
+	    {
+	      if (--currentScrollLocation < 0)
+		currentScrollLocation = 0;
+	      if (currentScrollLocation == 0)
+		decrButton.setEnabled(false);
+	      else if (! incrButton.isEnabled())
+		incrButton.setEnabled(true);
+	      tabPane.layout();
+	      tabPane.repaint();
+	      return;
+	    }
+        }
+
+      int index = tabForCoordinate(tabPane, x, y);
+
+      // We need to check since there are areas where tabs cannot be
+      // e.g. in the inset area.
+      if (index != -1 && tabPane.isEnabledAt(index))
+	tabPane.setSelectedIndex(index);
+      tabPane.layout();
+      tabPane.repaint();
+    }
+  }
 
-		d.width = Math.max(d.width, comp.getWidth());
-		d.height = Math.max(d.height, comp.getHeight());
+  /**
+   * This class handles PropertyChangeEvents fired from the JTabbedPane.
+   */
+  protected class PropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * This method is called whenever one of the properties of the JTabbedPane
+     * changes.
+     *
+     * @param e The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(JTabbedPane.TAB_LAYOUT_POLICY_CHANGED_PROPERTY))
+        {
+	  layoutManager = createLayoutManager();
+
+	  tabPane.setLayout(layoutManager);
+        }
+      else if (e.getPropertyName().equals(JTabbedPane.TAB_PLACEMENT_CHANGED_PROPERTY)
+               && tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+        {
+	  incrButton = createIncreaseButton();
+	  decrButton = createDecreaseButton();
+        }
+      tabPane.layout();
+      tabPane.repaint();
+    }
+  }
+
+  /**
+   * A LayoutManager responsible for placing all the tabs and the visible
+   * component inside the JTabbedPane. This class is only used for
+   * WRAP_TAB_LAYOUT.
+   */
+  protected class TabbedPaneLayout implements LayoutManager
+  {
+    /**
+     * This method is called when a component is added to the JTabbedPane.
+     *
+     * @param name The name of the component.
+     * @param comp The component being added.
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called when the rectangles need to be calculated. It
+     * also fixes the size of the visible component.
+     */
+    public void calculateLayoutInfo()
+    {
+      calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount());
+
+      if (tabPane.getSelectedIndex() != -1)
+        {
+	  Component visible = getVisibleComponent();
+	  Insets insets = getContentBorderInsets(tabPane.getTabPlacement());
+	  if (visible != null)
+	    visible.setBounds(contentRect.x + insets.left,
+	                      contentRect.y + insets.top,
+	                      contentRect.width - insets.left - insets.right,
+	                      contentRect.height - insets.top - insets.bottom);
+        }
+    }
+
+    /**
+     * This method calculates the size of the the JTabbedPane.
+     *
+     * @param minimum Whether the JTabbedPane will try to be as small as it
+     *        can.
+     *
+     * @return The desired size of the JTabbedPane.
+     */
+    protected Dimension calculateSize(boolean minimum)
+    {
+      int tabPlacement = tabPane.getTabPlacement();
+      int width = 0;
+      int height = 0;
+
+      int componentHeight = 0;
+      int componentWidth = 0;
+      Component c;
+      Dimension dims;
+      for (int i = 0; i < tabPane.getTabCount(); i++)
+        {
+	  c = tabPane.getComponentAt(i);
+	  if (c == null)
+	    continue;
+	  calcRect = c.getBounds();
+	  dims = c.getPreferredSize();
+	  if (dims != null)
+	    {
+	      componentHeight = Math.max(componentHeight, dims.height);
+	      componentWidth = Math.max(componentWidth, dims.width);
 	    }
-	
-	Insets i = p.getInsets();
-	
-	d.width  += i.left + i.right;
-	d.height += i.top + i.bottom;
+        }
+      Insets insets = tabPane.getInsets();
+
+      if (tabPlacement == SwingConstants.TOP
+          || tabPlacement == SwingConstants.BOTTOM)
+        {
+	  width = calculateMaxTabWidth(tabPlacement) * tabPane.getTabCount();
+	  calcRect = tabPane.getParent().getBounds();
+	  width = Math.max(width, componentWidth);
 
-	int height_of_tabs = 25;
+	  int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width);
+	  height = tabAreaHeight + componentHeight;
+        }
+      else
+        {
+	  height = calculateMaxTabHeight(tabPlacement) * tabPane.getTabCount();
+	  calcRect = tabPane.getParent().getBounds();
+	  height = Math.max(height, componentHeight);
 
-	d.height += height_of_tabs;
+	  int tabAreaWidth = preferredTabAreaWidth(tabPlacement, height);
+	  width = tabAreaWidth + componentWidth;
+        }
 
-	// FIXME: should be max of panes in p
-	return d;
+      return new Dimension(width, height);
+    }
+
+    // if tab placement is LEFT OR RIGHT, they share width.
+    // if tab placement is TOP OR BOTTOM, they share height
+    // PRE STEP: finds the default sizes for the labels as well as their locations.
+    // AND where they will be placed within the run system.
+    // 1. calls normalizeTab Runs.
+    // 2. calls rotate tab runs.
+    // 3. pads the tab runs.
+    // 4. pads the selected tab.
+
+    /**
+     * This method is called to calculate the tab rectangles.  This method
+     * will calculate the size and position of all  rectangles (taking into
+     * account which ones should be in which tab run). It will pad them and
+     * normalize them  as necessary.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param tabCount The run the current selection is in.
+     */
+    protected void calculateTabRects(int tabPlacement, int tabCount)
+    {
+      if (tabCount == 0)
+	return;
+      assureRectsCreated(tabCount);
+
+      FontMetrics fm = getFontMetrics();
+      SwingUtilities.calculateInnerArea(tabPane, calcRect);
+      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+      Insets insets = tabPane.getInsets();
+      int max = 0;
+      int runs = 0;
+      int start = getTabRunIndent(tabPlacement, 1);
+      if (tabPlacement == SwingConstants.TOP
+          || tabPlacement == SwingConstants.BOTTOM)
+        {
+	  int maxHeight = calculateMaxTabHeight(tabPlacement);
+
+	  calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
+	  max = calcRect.width + tabAreaInsets.left + insets.left;
+	  start += tabAreaInsets.left + insets.left;
+	  int width = 0;
+	  int runWidth = start;
+
+	  for (int i = 0; i < tabCount; i++)
+	    {
+	      width = calculateTabWidth(tabPlacement, i, fm);
+
+	      if (runWidth + width > max)
+	        {
+		  runWidth = tabAreaInsets.left + insets.left
+		             + getTabRunIndent(tabPlacement, ++runs);
+		  rects[i] = new Rectangle(runWidth,
+		                           insets.top + tabAreaInsets.top,
+		                           width, maxHeight);
+		  runWidth += width;
+		  if (runs > tabRuns.length - 1)
+		    expandTabRunsArray();
+		  tabRuns[runs] = i;
+	        }
+	      else
+	        {
+		  rects[i] = new Rectangle(runWidth,
+		                           insets.top + tabAreaInsets.top,
+		                           width, maxHeight);
+		  runWidth += width;
+	        }
+	    }
+	  runs++;
+	  tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
+	  tabAreaRect.height = runs * maxTabHeight
+	                       - (runs - 1) * tabRunOverlay
+	                       + tabAreaInsets.top + tabAreaInsets.bottom;
+	  contentRect.width = tabAreaRect.width;
+	  contentRect.height = tabPane.getHeight() - insets.top
+	                       - insets.bottom - tabAreaRect.height;
+	  contentRect.x = insets.left;
+	  tabAreaRect.x = insets.left;
+	  if (tabPlacement == SwingConstants.BOTTOM)
+	    {
+	      contentRect.y = insets.top;
+	      tabAreaRect.y = contentRect.y + contentRect.height;
+	    }
+	  else
+	    {
+	      tabAreaRect.y = insets.top;
+	      contentRect.y = tabAreaRect.y + tabAreaRect.height;
+	    }
+        }
+      else
+        {
+	  int maxWidth = calculateMaxTabWidth(tabPlacement);
+	  calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
+	  max = calcRect.height + tabAreaInsets.top + insets.top;
+
+	  int height = 0;
+	  start += tabAreaInsets.top + insets.top;
+	  int runHeight = start;
+
+	  int fontHeight = fm.getHeight();
+
+	  for (int i = 0; i < tabCount; i++)
+	    {
+	      height = calculateTabHeight(tabPlacement, i, fontHeight);
+	      if (runHeight + height > max)
+	        {
+		  runHeight = tabAreaInsets.top + insets.top
+		              + getTabRunIndent(tabPlacement, ++runs);
+		  rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
+		                           runHeight, maxWidth, height);
+		  runHeight += height;
+		  if (runs > tabRuns.length - 1)
+		    expandTabRunsArray();
+		  tabRuns[runs] = i;
+	        }
+	      else
+	        {
+		  rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
+		                           runHeight, maxWidth, height);
+		  runHeight += height;
+	        }
+	    }
+	  runs++;
+
+	  tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
+	                      + tabAreaInsets.left + tabAreaInsets.right;
+	  tabAreaRect.height = tabPane.getHeight() - insets.top
+	                       - insets.bottom;
+	  tabAreaRect.y = insets.top;
+	  contentRect.width = tabPane.getWidth() - insets.left - insets.right
+	                      - tabAreaRect.width;
+	  contentRect.height = tabAreaRect.height;
+	  contentRect.y = insets.top;
+	  if (tabPlacement == SwingConstants.LEFT)
+	    {
+	      tabAreaRect.x = insets.left;
+	      contentRect.x = tabAreaRect.x + tabAreaRect.width;
+	    }
+	  else
+	    {
+	      contentRect.x = insets.left;
+	      tabAreaRect.x = contentRect.x + contentRect.width;
+	    }
+        }
+      runCount = runs;
+
+      tabRuns[0] = 0;
+      normalizeTabRuns(tabPlacement, tabCount, start, max);
+      selectedRun = getRunForTab(tabCount, tabPane.getSelectedIndex());
+      if (shouldRotateTabRuns(tabPlacement))
+	rotateTabRuns(tabPlacement, selectedRun);
+
+      // Need to pad the runs and move them to the correct location.
+      for (int i = 0; i < runCount; i++)
+        {
+	  int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
+	  if (first == tabCount)
+	    first = 0;
+	  int last = lastTabInRun(tabCount, i);
+	  if (shouldPadTabRun(tabPlacement, i))
+	    padTabRun(tabPlacement, first, last, max);
+
+	  // Done padding, now need to move it.
+	  if (tabPlacement == SwingConstants.TOP && i > 0)
+	    {
+	      for (int j = first; j <= last; j++)
+		rects[j].y += (runCount - i) * maxTabHeight
+		+ (runCount - i) * tabRunOverlay;
+	    }
+
+	  if (tabPlacement == SwingConstants.BOTTOM)
+	    {
+	      int height = tabPane.getBounds().height - insets.bottom
+	                   - tabAreaInsets.bottom;
+	      int adjustment;
+	      if (i == 0)
+		adjustment = height - maxTabHeight;
+	      else
+		adjustment = height - (runCount - i + 1) * maxTabHeight
+		             - (runCount - i) * tabRunOverlay;
+
+	      for (int j = first; j <= last; j++)
+		rects[j].y = adjustment;
+	    }
+
+	  if (tabPlacement == SwingConstants.LEFT && i > 0)
+	    {
+	      for (int j = first; j <= last; j++)
+		rects[j].x += (runCount - i) * maxTabWidth
+		- (runCount - i) * tabRunOverlay;
+	    }
+
+	  if (tabPlacement == SwingConstants.RIGHT)
+	    {
+	      int width = tabPane.getBounds().width - insets.right
+	                  - tabAreaInsets.right;
+	      int adjustment;
+	      if (i == 0)
+		adjustment = width - maxTabWidth;
+	      else
+		adjustment = width - (runCount - i + 1) * maxTabWidth
+		             + (runCount - i) * tabRunOverlay;
+
+	      for (int j = first; j <= last; j++)
+		rects[j].x = adjustment;
+	    }
+        }
+      padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+    }
+
+    /**
+     * This method is called when the JTabbedPane is laid out in
+     * WRAP_TAB_LAYOUT. It calls calculateLayoutInfo to  find the positions
+     * of all its components.
+     *
+     * @param parent The Container to lay out.
+     */
+    public void layoutContainer(Container parent)
+    {
+      calculateLayoutInfo();
+    }
+
+    /**
+     * This method returns the minimum layout size for the given container.
+     *
+     * @param parent The container that is being sized.
+     *
+     * @return The minimum size.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return calculateSize(false);
+    }
+
+    // If there is more free space in an adjacent run AND the tab in the run can fit in the 
+    // adjacent run, move it. This method is not perfect, it is merely an approximation.
+    // If you play around with Sun's JTabbedPane, you'll see that 
+    // it does do some pretty strange things with regards to not moving tabs 
+    // that should be moved. 
+    // start = the x position where the tabs will begin
+    // max = the maximum position of where the tabs can go to (tabAreaInsets.left + the width of the tab area)
+
+    /**
+     * This method tries to "even out" the number of tabs in each run based on
+     * their widths.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param tabCount The number of tabs.
+     * @param start The x position where the tabs will begin.
+     * @param max The maximum x position where the tab can run to.
+     */
+    protected void normalizeTabRuns(int tabPlacement, int tabCount, int start,
+                                    int max)
+    {
+      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+      if (tabPlacement == SwingUtilities.TOP
+          || tabPlacement == SwingUtilities.BOTTOM)
+        {
+	  // We should only do this for runCount - 1, cause we can only shift that many times between
+	  // runs.
+	  for (int i = 1; i < runCount; i++)
+	    {
+	      Rectangle currRun = rects[lastTabInRun(tabCount, i)];
+	      Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+	      int spaceInCurr = currRun.x + currRun.width;
+	      int spaceInNext = nextRun.x + nextRun.width;
+
+	      int diffNow = spaceInCurr - spaceInNext;
+	      int diffLater = (spaceInCurr - currRun.width)
+	                      - (spaceInNext + currRun.width);
+	      while (Math.abs(diffLater) < Math.abs(diffNow)
+	             && spaceInNext + currRun.width < max)
+	        {
+		  tabRuns[i]--;
+		  spaceInNext += currRun.width;
+		  spaceInCurr -= currRun.width;
+		  currRun = rects[lastTabInRun(tabCount, i)];
+		  diffNow = spaceInCurr - spaceInNext;
+		  diffLater = (spaceInCurr - currRun.width)
+		              - (spaceInNext + currRun.width);
+	        }
+
+	      // Fix the bounds.
+	      int first = lastTabInRun(tabCount, i) + 1;
+	      int last = lastTabInRun(tabCount, getNextTabRun(i));
+	      int currX = tabAreaInsets.left;
+	      for (int j = first; j <= last; j++)
+	        {
+		  rects[j].x = currX;
+		  currX += rects[j].width;
+	        }
+	    }
+        }
+      else
+        {
+	  for (int i = 1; i < runCount; i++)
+	    {
+	      Rectangle currRun = rects[lastTabInRun(tabCount, i)];
+	      Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+	      int spaceInCurr = currRun.y + currRun.height;
+	      int spaceInNext = nextRun.y + nextRun.height;
+
+	      int diffNow = spaceInCurr - spaceInNext;
+	      int diffLater = (spaceInCurr - currRun.height)
+	                      - (spaceInNext + currRun.height);
+	      while (Math.abs(diffLater) < Math.abs(diffNow)
+	             && spaceInNext + currRun.height < max)
+	        {
+		  tabRuns[i]--;
+		  spaceInNext += currRun.height;
+		  spaceInCurr -= currRun.height;
+		  currRun = rects[lastTabInRun(tabCount, i)];
+		  diffNow = spaceInCurr - spaceInNext;
+		  diffLater = (spaceInCurr - currRun.height)
+		              - (spaceInNext + currRun.height);
+	        }
+
+	      int first = lastTabInRun(tabCount, i) + 1;
+	      int last = lastTabInRun(tabCount, getNextTabRun(i));
+	      int currY = tabAreaInsets.top;
+	      for (int j = first; j <= last; j++)
+	        {
+		  rects[j].y = currY;
+		  currY += rects[j].height;
+	        }
+	    }
+        }
+    }
+
+    /**
+     * This method pads the tab at the selected index by the  selected tab pad
+     * insets (so that it looks larger).
+     *
+     * @param tabPlacement The placement of the tabs.
+     * @param selectedIndex The selected index.
+     */
+    protected void padSelectedTab(int tabPlacement, int selectedIndex)
+    {
+      Insets insets = getSelectedTabPadInsets(tabPlacement);
+      rects[selectedIndex].x -= insets.left;
+      rects[selectedIndex].y -= insets.top;
+      rects[selectedIndex].width += insets.left + insets.right;
+      rects[selectedIndex].height += insets.top + insets.bottom;
+    }
+
+    // If the tabs on the run don't fill the width of the window, make it fit now.
+    // start = starting index of the run
+    // end = last index of the run
+    // max = tabAreaInsets.left + width (or equivalent)
+    // assert start <= end.
+
+    /**
+     * This method makes each tab in the run larger so that the  tabs expand
+     * to fill the runs width/height (depending on tabPlacement).
+     *
+     * @param tabPlacement The placement of the tabs.
+     * @param start The index of the first tab.
+     * @param end The last index of the tab
+     * @param max The amount of space in the run (width for TOP and BOTTOM
+     *        tabPlacement).
+     */
+    protected void padTabRun(int tabPlacement, int start, int end, int max)
+    {
+      if (tabPlacement == SwingConstants.TOP
+          || tabPlacement == SwingConstants.BOTTOM)
+        {
+	  int runWidth = rects[end].x + rects[end].width;
+	  int spaceRemaining = max - runWidth;
+	  int numTabs = end - start + 1;
+
+	  // now divvy up the space.
+	  int spaceAllocated = spaceRemaining / numTabs;
+	  int currX = rects[start].x;
+	  for (int i = start; i <= end; i++)
+	    {
+	      rects[i].x = currX;
+	      rects[i].width += spaceAllocated;
+	      currX += rects[i].width;
+	      // This is used because since the spaceAllocated 
+	      // variable is an int, it rounds down. Sometimes,
+	      // we don't fill an entire row, so we make it do
+	      // so now.
+	      if (i == end && rects[i].x + rects[i].width != max)
+		rects[i].width = max - rects[i].x;
+	    }
+        }
+      else
+        {
+	  int runHeight = rects[end].y + rects[end].height;
+	  int spaceRemaining = max - runHeight;
+	  int numTabs = end - start + 1;
+
+	  int spaceAllocated = spaceRemaining / numTabs;
+	  int currY = rects[start].y;
+	  for (int i = start; i <= end; i++)
+	    {
+	      rects[i].y = currY;
+	      rects[i].height += spaceAllocated;
+	      currY += rects[i].height;
+	      if (i == end && rects[i].y + rects[i].height != max)
+		rects[i].height = max - rects[i].y;
+	    }
+        }
     }
-    
 
-    public Rectangle getTabBounds(JTabbedPane pane, int index)
+    /**
+     * This method returns the preferred layout size for the given container.
+     *
+     * @param parent The container to size.
+     *
+     * @return The preferred layout size.
+     */
+    public Dimension preferredLayoutSize(Container parent)
     {
-	return null;
+      return calculateSize(false);
     }
 
-    public int getTabRunCount(JTabbedPane pane)
+    /**
+     * This method returns the preferred tab height given a tabPlacement and
+     * width.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param width The expected width.
+     *
+     * @return The preferred tab area height.
+     */
+    protected int preferredTabAreaHeight(int tabPlacement, int width)
     {
-	return 0;
+      if (tabPane.getTabCount() == 0)
+	return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+      int runs = 0;
+      int runWidth = 0;
+      int tabWidth = 0;
+
+      FontMetrics fm = getFontMetrics();
+
+      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+      Insets insets = tabPane.getInsets();
+
+      // Only interested in width, this is a messed up rectangle now.
+      width -= tabAreaInsets.left + tabAreaInsets.right + insets.left
+      + insets.right;
+
+      // The reason why we can't use runCount:
+      // This method is only called to calculate the size request
+      // for the tabbedPane. However, this size request is dependent on 
+      // our desired width. We need to find out what the height would
+      // be IF we got our desired width.
+      for (int i = 0; i < tabPane.getTabCount(); i++)
+        {
+	  tabWidth = calculateTabWidth(tabPlacement, i, fm);
+	  if (runWidth + tabWidth > width)
+	    {
+	      runWidth = tabWidth;
+	      runs++;
+	    }
+	  else
+	    runWidth += tabWidth;
+        }
+      runs++;
+
+      int maxTabHeight = calculateMaxTabHeight(tabPlacement);
+      int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
+                                                 maxTabHeight);
+      return tabAreaHeight;
     }
 
-    public int tabForCoordinate(JTabbedPane pane, int x, int y)
+    /**
+     * This method calculates the preferred tab area width given a tab
+     * placement and height.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param height The expected height.
+     *
+     * @return The preferred tab area width.
+     */
+    protected int preferredTabAreaWidth(int tabPlacement, int height)
     {
-	return 0;
+      if (tabPane.getTabCount() == 0)
+	return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+      int runs = 0;
+      int runHeight = 0;
+      int tabHeight = 0;
+
+      FontMetrics fm = getFontMetrics();
+
+      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+      Insets insets = tabPane.getInsets();
+
+      height -= tabAreaInsets.top + tabAreaInsets.bottom + insets.top
+      + insets.bottom;
+      int fontHeight = fm.getHeight();
+
+      for (int i = 0; i < tabPane.getTabCount(); i++)
+        {
+	  tabHeight = calculateTabHeight(tabPlacement, i, fontHeight);
+	  if (runHeight + tabHeight > height)
+	    {
+	      runHeight = tabHeight;
+	      runs++;
+	    }
+	  else
+	    runHeight += tabHeight;
+        }
+      runs++;
+
+      int maxTabWidth = calculateMaxTabWidth(tabPlacement);
+      int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
+      return tabAreaWidth;
     }
+
+    /**
+     * This method rotates the places each run in the correct place  the
+     * tabRuns array. See the comment for tabRuns for how the runs are placed
+     * in the array.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param selectedRun The run the current selection is in.
+     */
+    protected void rotateTabRuns(int tabPlacement, int selectedRun)
+    {
+      if (selectedRun == 1 || selectedRun == -1)
+	return;
+      int[] newTabRuns = new int[tabRuns.length];
+      int currentRun = selectedRun;
+      int i = 1;
+      do
+        {
+	  newTabRuns[i] = tabRuns[currentRun];
+	  currentRun = getNextTabRun(currentRun);
+	  i++;
+        }
+      while (i < runCount);
+      if (runCount > 1)
+	newTabRuns[0] = tabRuns[currentRun];
+
+      tabRuns = newTabRuns;
+      BasicTabbedPaneUI.this.selectedRun = 1;
+    }
+
+    /**
+     * This method is called when a component is removed  from the
+     * JTabbedPane.
+     *
+     * @param comp The component removed.
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+      // Do nothing.
+    }
+  }
+
+  /**
+   * This class acts as the LayoutManager for the JTabbedPane in
+   * SCROLL_TAB_MODE.
+   */
+  private class TabbedPaneScrollLayout extends TabbedPaneLayout
+  {
+    /**
+     * This method returns the preferred layout size for the given container.
+     *
+     * @param parent The container to calculate a size for.
+     *
+     * @return The preferred layout size.
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      return super.calculateSize(true);
+    }
+
+    /**
+     * This method returns the minimum layout size for the given container.
+     *
+     * @param parent The container to calculate a size for.
+     *
+     * @return The minimum layout size.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return super.calculateSize(true);
+    }
+
+    /**
+     * This method calculates the tab area height given  a desired width.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param width The expected width.
+     *
+     * @return The tab area height given the width.
+     */
+    protected int preferredTabAreaHeight(int tabPlacement, int width)
+    {
+      if (tabPane.getTabCount() == 0)
+	return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+      int runs = 1;
+
+      int maxTabHeight = calculateMaxTabHeight(tabPlacement);
+      int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
+                                                 maxTabHeight);
+      return tabAreaHeight;
+    }
+
+    /**
+     * This method calculates the tab area width given a desired height.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param height The expected height.
+     *
+     * @return The tab area width given the height.
+     */
+    protected int preferredTabAreaWidth(int tabPlacement, int height)
+    {
+      if (tabPane.getTabCount() == 0)
+	return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+      int runs = 1;
+
+      int maxTabWidth = calculateMaxTabWidth(tabPlacement);
+      int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
+      return tabAreaWidth;
+    }
+
+    /**
+     * This method is called to calculate the tab rectangles.  This method
+     * will calculate the size and position of all  rectangles (taking into
+     * account which ones should be in which tab run). It will pad them and
+     * normalize them  as necessary.
+     *
+     * @param tabPlacement The JTabbedPane's tab placement.
+     * @param tabCount The number of tabs.
+     */
+    protected void calculateTabRects(int tabPlacement, int tabCount)
+    {
+      if (tabCount == 0)
+	return;
+      assureRectsCreated(tabCount);
+
+      FontMetrics fm = getFontMetrics();
+      SwingUtilities.calculateInnerArea(tabPane, calcRect);
+      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+      Insets insets = tabPane.getInsets();
+      int max = 0;
+      int runs = 1;
+      int start = 0;
+      int top = 0;
+      if (tabPlacement == SwingConstants.TOP
+          || tabPlacement == SwingConstants.BOTTOM)
+        {
+	  int maxHeight = calculateMaxTabHeight(tabPlacement);
+	  calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
+	  max = calcRect.width + tabAreaInsets.left + insets.left;
+	  start = tabAreaInsets.left + insets.left;
+	  int width = 0;
+	  int runWidth = start;
+	  top = insets.top + tabAreaInsets.top;
+	  for (int i = 0; i < tabCount; i++)
+	    {
+	      width = calculateTabWidth(tabPlacement, i, fm);
+
+	      rects[i] = new Rectangle(runWidth, top, width, maxHeight);
+	      runWidth += width;
+	    }
+	  tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
+	  tabAreaRect.height = runs * maxTabHeight
+	                       - (runs - 1) * tabRunOverlay
+	                       + tabAreaInsets.top + tabAreaInsets.bottom;
+	  contentRect.width = tabAreaRect.width;
+	  contentRect.height = tabPane.getHeight() - insets.top
+	                       - insets.bottom - tabAreaRect.height;
+	  contentRect.x = insets.left;
+	  tabAreaRect.x = insets.left;
+	  if (tabPlacement == SwingConstants.BOTTOM)
+	    {
+	      contentRect.y = insets.top;
+	      tabAreaRect.y = contentRect.y + contentRect.height;
+	    }
+	  else
+	    {
+	      tabAreaRect.y = insets.top;
+	      contentRect.y = tabAreaRect.y + tabAreaRect.height;
+	    }
+        }
+      else
+        {
+	  int maxWidth = calculateMaxTabWidth(tabPlacement);
+
+	  calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
+	  max = calcRect.height + tabAreaInsets.top;
+	  int height = 0;
+	  start = tabAreaInsets.top + insets.top;
+	  int runHeight = start;
+	  int fontHeight = fm.getHeight();
+	  top = insets.left + tabAreaInsets.left;
+	  for (int i = 0; i < tabCount; i++)
+	    {
+	      height = calculateTabHeight(tabPlacement, i, fontHeight);
+	      rects[i] = new Rectangle(top, runHeight, maxWidth, height);
+	      runHeight += height;
+	    }
+	  tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
+	                      + tabAreaInsets.left + tabAreaInsets.right;
+	  tabAreaRect.height = tabPane.getHeight() - insets.top
+	                       - insets.bottom;
+	  tabAreaRect.y = insets.top;
+	  contentRect.width = tabPane.getWidth() - insets.left - insets.right
+	                      - tabAreaRect.width;
+	  contentRect.height = tabAreaRect.height;
+	  contentRect.y = insets.top;
+	  if (tabPlacement == SwingConstants.LEFT)
+	    {
+	      tabAreaRect.x = insets.left;
+	      contentRect.x = tabAreaRect.x + tabAreaRect.width;
+	    }
+	  else
+	    {
+	      contentRect.x = insets.left;
+	      tabAreaRect.x = contentRect.x + contentRect.width;
+	    }
+        }
+      runCount = runs;
+
+      padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+    }
+
+    /**
+     * This method is called when the JTabbedPane is laid out in
+     * SCROLL_TAB_LAYOUT. It finds the position for all components in the
+     * JTabbedPane.
+     *
+     * @param pane The JTabbedPane to be laid out.
+     */
+    public void layoutContainer(Container pane)
+    {
+      super.layoutContainer(pane);
+      int tabCount = tabPane.getTabCount();
+      if (tabCount == 0)
+	return;
+      int tabPlacement = tabPane.getTabPlacement();
+      incrButton.hide();
+      decrButton.hide();
+      if (tabPlacement == SwingConstants.TOP
+          || tabPlacement == SwingConstants.BOTTOM)
+        {
+	  if (tabAreaRect.x + tabAreaRect.width < rects[tabCount - 1].x
+	      + rects[tabCount - 1].width)
+	    {
+	      Dimension incrDims = incrButton.getPreferredSize();
+	      Dimension decrDims = decrButton.getPreferredSize();
+
+	      decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+	                           - incrDims.width - decrDims.width,
+	                           tabAreaRect.y, decrDims.width,
+	                           tabAreaRect.height);
+	      incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+	                           - incrDims.width, tabAreaRect.y,
+	                           decrDims.width, tabAreaRect.height);
+
+	      tabAreaRect.width -= decrDims.width + incrDims.width;
+	      incrButton.show();
+	      decrButton.show();
+	    }
+        }
+
+      if (tabPlacement == SwingConstants.LEFT
+          || tabPlacement == SwingConstants.RIGHT)
+        {
+	  if (tabAreaRect.y + tabAreaRect.height < rects[tabCount - 1].y
+	      + rects[tabCount - 1].height)
+	    {
+	      Dimension incrDims = incrButton.getPreferredSize();
+	      Dimension decrDims = decrButton.getPreferredSize();
+
+	      decrButton.setBounds(tabAreaRect.x,
+	                           tabAreaRect.y + tabAreaRect.height
+	                           - incrDims.height - decrDims.height,
+	                           tabAreaRect.width, decrDims.height);
+	      incrButton.setBounds(tabAreaRect.x,
+	                           tabAreaRect.y + tabAreaRect.height
+	                           - incrDims.height, tabAreaRect.width,
+	                           incrDims.height);
+
+	      tabAreaRect.height -= decrDims.height + incrDims.height;
+	      incrButton.show();
+	      decrButton.show();
+	    }
+        }
+      viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width,
+                         tabAreaRect.height);
+      int tabC = tabPane.getTabCount() - 1;
+      if (tabCount > 0)
+        {
+	  int w = Math.max(rects[tabC].width + rects[tabC].x, tabAreaRect.width);
+	  int h = Math.max(rects[tabC].height, tabAreaRect.height);
+	  Point p = findPointForIndex(currentScrollLocation);
+
+	  // we want to cover that entire space so that borders that run under
+	  // the tab area don't show up when we move the viewport around.
+	  panel.setSize(w + p.x, h + p.y);
+        }
+      viewport.setViewPosition(findPointForIndex(currentScrollLocation));
+    }
+  }
+
+  /**
+   * This class handles ChangeEvents from the JTabbedPane.
+   */
+  protected class TabSelectionHandler implements ChangeListener
+  {
+    /**
+     * This method is called whenever a ChangeEvent is fired from the
+     * JTabbedPane.
+     *
+     * @param e The ChangeEvent fired.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      selectedRun = getRunForTab(tabPane.getTabCount(),
+                                 tabPane.getSelectedIndex());
+      tabPane.revalidate();
+      tabPane.repaint();
+    }
+  }
+
+  /**
+   * This helper class is a JPanel that fits inside the ScrollViewport. This
+   * panel's sole job is to paint the tab rectangles inside the  viewport so
+   * that it's clipped correctly.
+   */
+  private class ScrollingPanel extends JPanel
+  {
+    /**
+     * This is a private UI class for our panel.
+     */
+    private class ScrollingPanelUI extends BasicPanelUI
+    {
+      /**
+       * This method overrides the default paint method. It paints the tab
+       * rectangles for the JTabbedPane in the panel.
+       *
+       * @param g The Graphics object to paint with.
+       * @param c The JComponent to paint.
+       */
+      public void paint(Graphics g, JComponent c)
+      {
+	paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+      }
+    }
+
+    /**
+     * This method overrides the updateUI method. It makes the default UI for
+     * this ScrollingPanel to be  a ScrollingPanelUI.
+     */
+    public void updateUI()
+    {
+      setUI((PanelUI) new ScrollingPanelUI());
+    }
+  }
+
+  /**
+   * This is a helper class that paints the panel that paints tabs. This
+   * custom JViewport is used so that the tabs painted in the panel will be
+   * clipped. This class implements UIResource so tabs are not added when
+   * this objects of this class are added to the  JTabbedPane.
+   */
+  private class ScrollingViewport extends JViewport implements UIResource
+  {
+  }
+
+  /**
+   * This is a helper class that implements UIResource so it is not added as a
+   * tab when an object of this class is added to the JTabbedPane.
+   */
+  private static class ScrollingButton extends BasicArrowButton
+    implements UIResource
+  {
+    /**
+     * Creates a ScrollingButton given the direction.
+     *
+     * @param dir The direction to point in.
+     */
+    public ScrollingButton(int dir)
+    {
+      super(dir);
+    }
+  }
+
+  /** The button that increments the current scroll location. */
+  private transient ScrollingButton incrButton;
+
+  /** The button that decrements the current scroll location. */
+  private transient ScrollingButton decrButton;
+
+  /** The viewport used to display the tabs. */
+  private transient ScrollingViewport viewport;
+
+  /** The panel inside the viewport that paints the tabs. */
+  private transient ScrollingPanel panel;
+
+  /** The starting visible tab in the run in SCROLL_TAB_MODE. */
+  private transient int currentScrollLocation;
+
+  /** A reusable rectangle. */
+  protected Rectangle calcRect;
+
+  /** An array of Rectangles keeping track of the tabs' area and position. */
+  protected Rectangle[] rects;
+
+  /** The insets around the content area. */
+  protected Insets contentBorderInsets;
+
+  /** The extra insets around the selected tab. */
+  protected Insets selectedTabPadInsets;
+
+  /** The insets around the tab area. */
+  protected Insets tabAreaInsets;
+
+  /** The insets around each and every tab. */
+  protected Insets tabInsets;
+
+  /**
+   * The outer bottom and right edge color for both the tab and content
+   * border.
+   */
+  protected Color darkShadow;
+
+  /** The color of the focus outline on the selected tab. */
+  protected Color focus;
+
+  /** FIXME: find a use for this. */
+  protected Color highlight;
+
+  /** The top and left edge color for both the tab and content border. */
+  protected Color lightHighlight;
+
+  /** The inner bottom and right edge color for the tab and content border. */
+  protected Color shadow;
+
+  /** The maximum tab height. */
+  protected int maxTabHeight;
+
+  /** The maximum tab width. */
+  protected int maxTabWidth;
+
+  /** The number of runs in the JTabbedPane. */
+  protected int runCount;
+
+  /** The index of the run that the selected index is in. */
+  protected int selectedRun;
+
+  /** The amount of space each run overlaps the previous by. */
+  protected int tabRunOverlay;
+
+  /** The gap between text and label */
+  protected int textIconGap;
+
+  // Keeps track of tab runs.
+  // The organization of this array is as follows (lots of experimentation to
+  // figure this out)
+  // index 0 = furthest away from the component area (aka outer run)
+  // index 1 = closest to component area (aka selected run)
+  // index > 1 = listed in order leading from selected run to outer run.
+  // each int in the array is the tab index + 1 (counting starts at 1)
+  // for the last tab in the run. (same as the rects array)
+
+  /** This array keeps track of which tabs are in which run. See above. */
+  protected int[] tabRuns;
+
+  /** Deprecated. This is the keystroke for moving down. */
+  protected KeyStroke downKey;
+
+  /** Deprecated. This is the keystroke for moving left. */
+  protected KeyStroke leftKey;
+
+  /** Deprecated. This is the keystroke for moving right. */
+  protected KeyStroke rightKey;
+
+  /** Deprecated. This is the keystroke for moving up. */
+  protected KeyStroke upKey;
+
+  /** The listener that listens for focus events. */
+  protected FocusListener focusListener;
+
+  /** The listener that listens for mouse events. */
+  protected MouseListener mouseListener;
+
+  /** The listener that listens for property change events. */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The listener that listens for change events. */
+  protected ChangeListener tabChangeListener;
+
+  /** The tab pane that this UI paints. */
+  protected JTabbedPane tabPane;
+
+  /** The current layout manager for the tabPane. */
+  private transient LayoutManager layoutManager;
+
+  /** The rectangle that describes the tab area's position and size. */
+  private transient Rectangle tabAreaRect;
+
+  /** The rectangle that describes the content area's position and size. */
+  private transient Rectangle contentRect;
+
+  /**
+   * Creates a new BasicTabbedPaneUI object.
+   */
+  public BasicTabbedPaneUI()
+  {
+    super();
+  }
+
+  /**
+   * This method creates a ScrollingButton that  points in the appropriate
+   * direction for an increasing button.
+   *
+   * @return The increase ScrollingButton.
+   */
+  private ScrollingButton createIncreaseButton()
+  {
+    if (incrButton == null)
+      incrButton = new ScrollingButton(SwingConstants.NORTH);
+    if (tabPane.getTabPlacement() == SwingConstants.TOP
+        || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
+      incrButton.setDirection(SwingConstants.EAST);
+    else
+      incrButton.setDirection(SwingConstants.SOUTH);
+    return incrButton;
+  }
+
+  /**
+   * This method creates a ScrollingButton that points in the appropriate
+   * direction for a decreasing button.
+   *
+   * @return The decrease ScrollingButton.
+   */
+  private ScrollingButton createDecreaseButton()
+  {
+    if (decrButton == null)
+      decrButton = new ScrollingButton(SwingConstants.SOUTH);
+    if (tabPane.getTabPlacement() == SwingConstants.TOP
+        || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
+      decrButton.setDirection(SwingConstants.WEST);
+    else
+      decrButton.setDirection(SwingConstants.NORTH);
+    return decrButton;
+  }
+
+  /**
+   * This method finds the point to set the view  position at given the index
+   * of a tab. The tab will be the first visible tab in the run.
+   *
+   * @param index The index of the first visible tab.
+   *
+   * @return The position of the first visible tab.
+   */
+  private Point findPointForIndex(int index)
+  {
+    int tabPlacement = tabPane.getTabPlacement();
+    int selectedIndex = tabPane.getSelectedIndex();
+    Insets insets = getSelectedTabPadInsets(tabPlacement);
+    int w = 0;
+    int h = 0;
+
+    if (tabPlacement == TOP || tabPlacement == BOTTOM)
+      {
+	if (index > 0)
+	  {
+	    w += rects[index - 1].x + rects[index - 1].width;
+	    if (index > selectedIndex)
+	      w -= insets.left + insets.right;
+	  }
+      }
+
+    else
+      {
+	if (index > 0)
+	  {
+	    h += rects[index - 1].y + rects[index - 1].height;
+	    if (index > selectedIndex)
+	      h -= insets.top + insets.bottom;
+	  }
+      }
+
+    Point p = new Point(w, h);
+    return p;
+  }
+
+  /**
+   * This method creates a new BasicTabbedPaneUI.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicTabbedPaneUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicTabbedPaneUI();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install the UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+    if (c instanceof JTabbedPane)
+      {
+	tabPane = (JTabbedPane) c;
+
+	installComponents();
+	installDefaults();
+	installListeners();
+	installKeyboardActions();
+
+	layoutManager = createLayoutManager();
+	tabPane.setLayout(layoutManager);
+	tabPane.layout();
+      }
+  }
+
+  /**
+   * This method uninstalls the UI for the  given JComponent.
+   *
+   * @param c The JComponent to uninstall the UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    layoutManager = null;
+
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallDefaults();
+    uninstallComponents();
+
+    tabPane = null;
+  }
+
+  /**
+   * This method creates the appropriate layout manager for the JTabbedPane's
+   * current tab layout policy. If the tab layout policy is
+   * SCROLL_TAB_LAYOUT, then all the associated components that need to be
+   * created will be done so now.
+   *
+   * @return A layout manager given the tab layout policy.
+   */
+  public LayoutManager createLayoutManager()
+  {
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+      return new TabbedPaneLayout();
+    else
+      {
+	incrButton = createIncreaseButton();
+	decrButton = createDecreaseButton();
+	viewport = new ScrollingViewport();
+	panel = new ScrollingPanel();
+	viewport.setView(panel);
+	tabPane.add(incrButton);
+	tabPane.add(decrButton);
+	tabPane.add(viewport);
+	currentScrollLocation = 0;
+	decrButton.setEnabled(false);
+	panel.addMouseListener(mouseListener);
+	incrButton.addMouseListener(mouseListener);
+	decrButton.addMouseListener(mouseListener);
+	viewport.setBackground(Color.LIGHT_GRAY);
+
+	return new TabbedPaneScrollLayout();
+      }
+  }
+
+  /**
+   * This method installs components for this JTabbedPane.
+   */
+  protected void installComponents()
+  {
+    // Nothing to be done.
+  }
+
+  /**
+   * This method uninstalls components for this JTabbedPane.
+   */
+  protected void uninstallComponents()
+  {
+    // Nothing to be done.
+  }
+
+  /**
+   * This method installs defaults for the Look and Feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    tabPane.setFont(defaults.getFont("TabbedPane.font"));
+    tabPane.setForeground(defaults.getColor("TabbedPane.foreground"));
+    tabPane.setBackground(defaults.getColor("TabbedPane.background"));
+    tabPane.setOpaque(true);
+
+    highlight = defaults.getColor("TabbedPane.highlight");
+    lightHighlight = defaults.getColor("TabbedPane.lightHighlight");
+
+    shadow = defaults.getColor("TabbedPane.shadow");
+    darkShadow = defaults.getColor("TabbedPane.darkShadow");
+
+    focus = defaults.getColor("TabbedPane.focus");
+
+    textIconGap = defaults.getInt("TabbedPane.textIconGap");
+    tabRunOverlay = defaults.getInt("TabbedPane.tabRunOverlay");
+
+    tabInsets = defaults.getInsets("TabbedPane.tabbedPaneTabInsets");
+    selectedTabPadInsets = defaults.getInsets("TabbedPane.tabbedPaneTabPadInsets");
+    tabAreaInsets = defaults.getInsets("TabbedPane.tabbedPaneTabAreaInsets");
+    contentBorderInsets = defaults.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
+
+    calcRect = new Rectangle();
+    tabRuns = new int[10];
+    tabAreaRect = new Rectangle();
+    contentRect = new Rectangle();
+  }
+
+  /**
+   * This method uninstalls defaults for the Look and Feel.
+   */
+  protected void uninstallDefaults()
+  {
+    calcRect = null;
+    tabAreaRect = null;
+    contentRect = null;
+    tabRuns = null;
+
+    contentBorderInsets = null;
+    tabAreaInsets = null;
+    selectedTabPadInsets = null;
+    tabInsets = null;
+
+    focus = null;
+    darkShadow = null;
+    shadow = null;
+    lightHighlight = null;
+    highlight = null;
+
+    tabPane.setBackground(null);
+    tabPane.setForeground(null);
+    tabPane.setFont(null);
+  }
+
+  /**
+   * This method creates and installs the listeners for this UI.
+   */
+  protected void installListeners()
+  {
+    mouseListener = createMouseListener();
+    tabChangeListener = createChangeListener();
+    propertyChangeListener = createPropertyChangeListener();
+    focusListener = createFocusListener();
+
+    tabPane.addMouseListener(mouseListener);
+    tabPane.addChangeListener(tabChangeListener);
+    tabPane.addPropertyChangeListener(propertyChangeListener);
+    tabPane.addFocusListener(focusListener);
+  }
+
+  /**
+   * This method removes and nulls the listeners for this UI.
+   */
+  protected void uninstallListeners()
+  {
+    tabPane.removeFocusListener(focusListener);
+    tabPane.removePropertyChangeListener(propertyChangeListener);
+    tabPane.removeChangeListener(tabChangeListener);
+    tabPane.removeMouseListener(mouseListener);
+
+    focusListener = null;
+    propertyChangeListener = null;
+    tabChangeListener = null;
+    mouseListener = null;
+  }
+
+  /**
+   * This method creates a new MouseListener.
+   *
+   * @return A new MouseListener.
+   */
+  protected MouseListener createMouseListener()
+  {
+    return new MouseHandler();
+  }
+
+  /**
+   * This method creates a new FocusListener.
+   *
+   * @return A new FocusListener.
+   */
+  protected FocusListener createFocusListener()
+  {
+    return new FocusHandler();
+  }
+
+  /**
+   * This method creates a new ChangeListener.
+   *
+   * @return A new ChangeListener.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new TabSelectionHandler();
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener.
+   *
+   * @return A new PropertyChangeListener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new PropertyChangeHandler();
+  }
+
+  /**
+   * This method installs keyboard actions for the JTabbedPane.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method uninstalls keyboard actions for the JTabbedPane.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method returns the preferred size of the JTabbedPane.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return layoutManager.preferredLayoutSize(tabPane);
+  }
+
+  /**
+   * This method returns the minimum size of the JTabbedPane.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return layoutManager.minimumLayoutSize(tabPane);
+  }
+
+  /**
+   * This method returns the maximum size of the JTabbedPane.
+   *
+   * @param c The JComponent to find a size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method paints the JTabbedPane.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    if (tabPane.getTabCount() == 0)
+      return;
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+      paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+    paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+  }
+
+  /**
+   * This method paints the tab area. This includes painting the rectangles
+   * that make up the tabs.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The selected index.
+   */
+  protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex)
+  {
+    Rectangle ir = new Rectangle();
+    Rectangle tr = new Rectangle();
+
+    // Please note: the ordering of the painting is important. 
+    // we WANT to paint the outermost run first and then work our way in.
+    int tabCount = tabPane.getTabCount();
+    int currRun = 1;
+    if (tabCount < 1)
+      return;
+
+    if (runCount > 1)
+      currRun = 0;
+    for (int i = 0; i < runCount; i++)
+      {
+	int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
+	if (first == tabCount)
+	  first = 0;
+	int last = lastTabInRun(tabCount, currRun);
+	for (int j = first; j <= last; j++)
+	  {
+	    if (j != selectedIndex)
+	      paintTab(g, tabPlacement, rects, j, ir, tr);
+	  }
+	currRun = getNextTabRun(currRun);
+      }
+    paintTab(g, tabPlacement, rects, selectedIndex, ir, tr);
+  }
+
+  /**
+   * This method paints an individual tab.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param rects The array of rectangles that keep the size and position of
+   *        the tabs.
+   * @param tabIndex The tab index to paint.
+   * @param iconRect The rectangle to use for the icon.
+   * @param textRect The rectangle to use for the text.
+   */
+  protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
+                          int tabIndex, Rectangle iconRect, Rectangle textRect)
+  {
+    FontMetrics fm = getFontMetrics();
+    Icon icon = getIconForTab(tabIndex);
+    String title = tabPane.getTitleAt(tabIndex);
+    boolean isSelected = tabIndex == tabPane.getSelectedIndex();
+    calcRect = getTabBounds(tabPane, tabIndex);
+
+    int x = calcRect.x;
+    int y = calcRect.y;
+    int w = calcRect.width;
+    int h = calcRect.height;
+    if (getRunForTab(tabPane.getTabCount(), tabIndex) == 1)
+      {
+	Insets insets = getTabAreaInsets(tabPlacement);
+	switch (tabPlacement)
+	  {
+	  case TOP:
+	    h += insets.bottom;
+	    break;
+	  case LEFT:
+	    w += insets.right;
+	    break;
+	  case BOTTOM:
+	    y -= insets.top;
+	    h += insets.top;
+	    break;
+	  case RIGHT:
+	    x -= insets.left;
+	    w += insets.left;
+	    break;
+	  }
+      }
+
+    layoutLabel(tabPlacement, fm, tabIndex, title, icon, calcRect, iconRect,
+                textRect, isSelected);
+    paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+    paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+
+    // FIXME: Paint little folding corner and jagged edge clipped tab.
+    if (icon != null)
+      paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
+    if (title != null && ! title.equals(""))
+      paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title,
+                textRect, isSelected);
+  }
+
+  /**
+   * This method lays out the tab and finds the location to paint the  icon
+   * and text.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param metrics The font metrics for the font to paint with.
+   * @param tabIndex The tab index to paint.
+   * @param title The string painted.
+   * @param icon The icon painted.
+   * @param tabRect The tab bounds.
+   * @param iconRect The calculated icon bounds.
+   * @param textRect The calculated text bounds.
+   * @param isSelected Whether this tab is selected.
+   */
+  protected void layoutLabel(int tabPlacement, FontMetrics metrics,
+                             int tabIndex, String title, Icon icon,
+                             Rectangle tabRect, Rectangle iconRect,
+                             Rectangle textRect, boolean isSelected)
+  {
+    SwingUtilities.layoutCompoundLabel(metrics, title, icon,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER, tabRect,
+                                       iconRect, textRect, textIconGap);
+
+    int shiftX = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
+    int shiftY = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
+
+    iconRect.x += shiftX;
+    iconRect.y += shiftY;
+
+    textRect.x += shiftX;
+    textRect.y += shiftY;
+  }
+
+  /**
+   * This method paints the icon.
+   *
+   * @param g The Graphics object to paint.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index to paint.
+   * @param icon The icon to paint.
+   * @param iconRect The bounds of the icon.
+   * @param isSelected Whether this tab is selected.
+   */
+  protected void paintIcon(Graphics g, int tabPlacement, int tabIndex,
+                           Icon icon, Rectangle iconRect, boolean isSelected)
+  {
+    icon.paintIcon(tabPane, g, iconRect.x, iconRect.y);
+  }
+
+  /**
+   * This method paints the text for the given tab.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param font The font to paint with.
+   * @param metrics The fontmetrics of the given font.
+   * @param tabIndex The tab index.
+   * @param title The string to paint.
+   * @param textRect The bounds of the string.
+   * @param isSelected Whether this tab is selected.
+   */
+  protected void paintText(Graphics g, int tabPlacement, Font font,
+                           FontMetrics metrics, int tabIndex, String title,
+                           Rectangle textRect, boolean isSelected)
+  {
+    View textView = getTextViewForTab(tabIndex);
+    if (textView != null)
+      {
+	textView.paint(g, textRect);
+	return;
+      }
+
+    Color fg = tabPane.getForegroundAt(tabIndex);
+    if (fg == null)
+      fg = tabPane.getForeground();
+    Color bg = tabPane.getBackgroundAt(tabIndex);
+    if (bg == null)
+      bg = tabPane.getBackground();
+
+    Color saved_color = g.getColor();
+    Font f = g.getFont();
+    g.setFont(font);
+
+    if (tabPane.isEnabledAt(tabIndex))
+      {
+	g.setColor(fg);
+
+	int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
+
+	if (mnemIndex != -1)
+	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+	                                               textRect.x,
+	                                               textRect.y
+	                                               + metrics.getAscent());
+	else
+	  g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
+      }
+    else
+      {
+	g.setColor(bg.brighter());
+
+	int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
+
+	if (mnemIndex != -1)
+	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+	                                               textRect.x, textRect.y);
+	else
+	  g.drawString(title, textRect.x, textRect.y);
+
+	g.setColor(bg.darker());
+	if (mnemIndex != -1)
+	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+	                                               textRect.x + 1,
+	                                               textRect.y + 1);
+	else
+	  g.drawString(title, textRect.x + 1, textRect.y + 1);
+      }
+
+    g.setColor(saved_color);
+    g.setFont(f);
+  }
+
+  /**
+   * This method returns how much the label for the tab should shift in the X
+   * direction.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index being painted.
+   * @param isSelected Whether this tab is selected.
+   *
+   * @return The amount the label should shift by in the X direction.
+   */
+  protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
+                                  boolean isSelected)
+  {
+    // No reason to shift.
+    return 0;
+  }
+
+  /**
+   * This method returns how much the label for the tab should shift in the Y
+   * direction.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index being painted.
+   * @param isSelected Whether this tab is selected.
+   *
+   * @return The amount the label should shift by in the Y direction.
+   */
+  protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
+                                  boolean isSelected)
+  {
+    // No reason to shift.
+    return 0;
+  }
+
+  /**
+   * This method paints the focus rectangle around the selected tab.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param rects The array of rectangles keeping track of size and position.
+   * @param tabIndex The tab index.
+   * @param iconRect The icon bounds.
+   * @param textRect The text bounds.
+   * @param isSelected Whether this tab is selected.
+   */
+  protected void paintFocusIndicator(Graphics g, int tabPlacement,
+                                     Rectangle[] rects, int tabIndex,
+                                     Rectangle iconRect, Rectangle textRect,
+                                     boolean isSelected)
+  {
+    Color saved = g.getColor();
+    calcRect = iconRect.union(textRect);
+
+    g.setColor(focus);
+
+    g.drawRect(calcRect.x, calcRect.y, calcRect.width, calcRect.height);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the border for an individual tab.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index.
+   * @param x The x position of the tab.
+   * @param y The y position of the tab.
+   * @param w The width of the tab.
+   * @param h The height of the tab.
+   * @param isSelected Whether the tab is selected.
+   */
+  protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
+                                int x, int y, int w, int h, boolean isSelected)
+  {
+    Color saved = g.getColor();
+    
+    if (! isSelected || tabPlacement != SwingConstants.TOP)
+      {
+	g.setColor(shadow);
+	g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
+	g.setColor(darkShadow);
+	g.drawLine(x, y + h, x + w, y + h);
+      }
+
+    if (! isSelected || tabPlacement != SwingConstants.LEFT)
+      {
+	g.setColor(darkShadow);
+	g.drawLine(x + w, y, x + w, y + h);
+	g.setColor(shadow);
+	g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
+      }
+
+    if (! isSelected || tabPlacement != SwingConstants.RIGHT)
+      {
+	g.setColor(lightHighlight);
+	g.drawLine(x, y, x, y + h);
+      }
+
+    if (! isSelected || tabPlacement != SwingConstants.BOTTOM)
+      {
+	g.setColor(lightHighlight);
+	g.drawLine(x, y, x + w, y);
+      }
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the background for an individual tab.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index.
+   * @param x The x position of the tab.
+   * @param y The y position of the tab.
+   * @param w The width of the tab.
+   * @param h The height of the tab.
+   * @param isSelected Whether the tab is selected.
+   */
+  protected void paintTabBackground(Graphics g, int tabPlacement,
+                                    int tabIndex, int x, int y, int w, int h,
+                                    boolean isSelected)
+  {
+    Color saved = g.getColor();
+    if (isSelected)
+      g.setColor(Color.LIGHT_GRAY);
+    else
+      {
+	Color bg = tabPane.getBackgroundAt(tabIndex);
+	if (bg == null)
+	  bg = tabPane.getBackground();
+	g.setColor(bg);
+      }
+
+    g.fillRect(x, y, w, h);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the border around the content area.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The index of the selected tab.
+   */
+  protected void paintContentBorder(Graphics g, int tabPlacement,
+                                    int selectedIndex)
+  {
+    Insets insets = getContentBorderInsets(tabPlacement);
+    int x = contentRect.x;
+    int y = contentRect.y;
+    int w = contentRect.width;
+    int h = contentRect.height;
+    paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+    paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+    paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+    paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+  }
+
+  /**
+   * This method paints the top edge of the content border.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The selected tab index.
+   * @param x The x coordinate for the content area.
+   * @param y The y coordinate for the content area.
+   * @param w The width of the content area.
+   * @param h The height of the content area.
+   */
+  protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
+                                           int selectedIndex, int x, int y,
+                                           int w, int h)
+  {
+    Color saved = g.getColor();
+    g.setColor(lightHighlight);
+
+    int startgap = rects[selectedIndex].x;
+    int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
+
+    int diff = 0;
+
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+      {
+	Point p = findPointForIndex(currentScrollLocation);
+	diff = p.x;
+      }
+
+    if (tabPlacement == SwingConstants.TOP)
+      {
+	g.drawLine(x, y, startgap - diff, y);
+	g.drawLine(endgap - diff, y, x + w, y);
+      }
+    else
+      g.drawLine(x, y, x + w, y);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the left edge of the content border.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The selected tab index.
+   * @param x The x coordinate for the content area.
+   * @param y The y coordinate for the content area.
+   * @param w The width of the content area.
+   * @param h The height of the content area.
+   */
+  protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
+                                            int selectedIndex, int x, int y,
+                                            int w, int h)
+  {
+    Color saved = g.getColor();
+    g.setColor(lightHighlight);
+
+    int startgap = rects[selectedIndex].y;
+    int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+
+    int diff = 0;
+
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+      {
+	Point p = findPointForIndex(currentScrollLocation);
+	diff = p.y;
+      }
+
+    if (tabPlacement == SwingConstants.LEFT)
+      {
+	g.drawLine(x, y, x, startgap - diff);
+	g.drawLine(x, endgap - diff, x, y + h);
+      }
+    else
+      g.drawLine(x, y, x, y + h);
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the bottom edge of the content border.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The selected tab index.
+   * @param x The x coordinate for the content area.
+   * @param y The y coordinate for the content area.
+   * @param w The width of the content area.
+   * @param h The height of the content area.
+   */
+  protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
+                                              int selectedIndex, int x, int y,
+                                              int w, int h)
+  {
+    Color saved = g.getColor();
+
+    int startgap = rects[selectedIndex].x;
+    int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
+
+    int diff = 0;
+
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+      {
+	Point p = findPointForIndex(currentScrollLocation);
+	diff = p.x;
+      }
+
+    if (tabPlacement == SwingConstants.BOTTOM)
+      {
+	g.setColor(shadow);
+	g.drawLine(x + 1, y + h - 1, startgap - diff, y + h - 1);
+	g.drawLine(endgap - diff, y + h - 1, x + w - 1, y + h - 1);
+
+	g.setColor(darkShadow);
+	g.drawLine(x, y + h, startgap - diff, y + h);
+	g.drawLine(endgap - diff, y + h, x + w, y + h);
+      }
+    else
+      {
+	g.setColor(shadow);
+	g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
+	g.setColor(darkShadow);
+	g.drawLine(x, y + h, x + w, y + h);
+      }
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method paints the right edge of the content border.
+   *
+   * @param g The Graphics object to paint with.
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param selectedIndex The selected tab index.
+   * @param x The x coordinate for the content area.
+   * @param y The y coordinate for the content area.
+   * @param w The width of the content area.
+   * @param h The height of the content area.
+   */
+  protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
+                                             int selectedIndex, int x, int y,
+                                             int w, int h)
+  {
+    Color saved = g.getColor();
+    int startgap = rects[selectedIndex].y;
+    int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+
+    int diff = 0;
+    if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+      {
+	Point p = findPointForIndex(currentScrollLocation);
+	diff = p.y;
+      }
+
+    if (tabPlacement == SwingConstants.RIGHT)
+      {
+	g.setColor(shadow);
+	g.drawLine(x + w - 1, y + 1, x + w - 1, startgap - diff);
+	g.drawLine(x + w - 1, endgap - diff, x + w - 1, y + h - 1);
+
+	g.setColor(darkShadow);
+	g.drawLine(x + w, y, x + w, startgap - diff);
+	g.drawLine(x + w, endgap - diff, x + w, y + h);
+      }
+    else
+      {
+	g.setColor(shadow);
+	g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
+	g.setColor(darkShadow);
+	g.drawLine(x + w, y, x + w, y + h);
+      }
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method returns the tab bounds for the given index.
+   *
+   * @param pane The JTabbedPane.
+   * @param i The index to look for.
+   *
+   * @return The bounds of the tab with the given index.
+   */
+  public Rectangle getTabBounds(JTabbedPane pane, int i)
+  {
+    return rects[i];
+  }
+
+  /**
+   * This method returns the number of runs.
+   *
+   * @param pane The JTabbedPane.
+   *
+   * @return The number of runs.
+   */
+  public int getTabRunCount(JTabbedPane pane)
+  {
+    return runCount;
+  }
+
+  /**
+   * This method returns the tab index given a coordinate.
+   *
+   * @param pane The JTabbedPane.
+   * @param x The x coordinate.
+   * @param y The y coordinate.
+   *
+   * @return The tab index that the coordinate lands in.
+   */
+  public int tabForCoordinate(JTabbedPane pane, int x, int y)
+  {
+    Point p = new Point(x, y);
+    int tabCount = tabPane.getTabCount();
+    int currRun = 1;
+    for (int i = 0; i < runCount; i++)
+      {
+	int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
+	if (first == tabCount)
+	  first = 0;
+	int last = lastTabInRun(tabCount, currRun);
+	for (int j = first; j <= last; j++)
+	  {
+	    if (getTabBounds(pane, j).contains(p))
+	      return j;
+	  }
+	currRun = getNextTabRun(currRun);
+      }
+    return -1;
+  }
+
+  /**
+   * This method returns the tab bounds in the given rectangle.
+   *
+   * @param tabIndex The index to get bounds for.
+   * @param dest The rectangle to store bounds in.
+   *
+   * @return The rectangle passed in.
+   */
+  protected Rectangle getTabBounds(int tabIndex, Rectangle dest)
+  {
+    dest.setBounds(getTabBounds(tabPane, tabIndex));
+    return dest;
+  }
+
+  /**
+   * This method returns the component that is shown in  the content area.
+   *
+   * @return The component that is shown in the content area.
+   */
+  protected Component getVisibleComponent()
+  {
+    return tabPane.getComponentAt(tabPane.getSelectedIndex());
+  }
+
+  /**
+   * This method sets the visible component.
+   *
+   * @param component The component to be set visible.
+   */
+  protected void setVisibleComponent(Component component)
+  {
+    component.setVisible(true);
+    tabPane.setSelectedComponent(component);
+  }
+
+  /**
+   * This method assures that enough rectangles are created given the
+   * tabCount. The old array is copied to the  new one.
+   *
+   * @param tabCount The number of tabs.
+   */
+  protected void assureRectsCreated(int tabCount)
+  {
+    if (rects == null)
+      rects = new Rectangle[tabCount];
+    if (tabCount == rects.length)
+      return;
+    else
+      {
+	int numToCopy = Math.min(tabCount, rects.length);
+	Rectangle[] tmp = new Rectangle[tabCount];
+	System.arraycopy(rects, 0, tmp, 0, numToCopy);
+	rects = tmp;
+      }
+  }
+
+  /**
+   * This method expands the tabRuns array to give it more room. The old array
+   * is copied to the new one.
+   */
+  protected void expandTabRunsArray()
+  {
+    // This method adds another 10 index positions to the tabRuns array.
+    if (tabRuns == null)
+      tabRuns = new int[10];
+    else
+      {
+	int[] newRuns = new int[tabRuns.length + 10];
+	System.arraycopy(tabRuns, 0, newRuns, 0, tabRuns.length);
+	tabRuns = newRuns;
+      }
+  }
+
+  /**
+   * This method returns which run a particular tab belongs to.
+   *
+   * @param tabCount The number of tabs.
+   * @param tabIndex The tab to find.
+   *
+   * @return The tabRuns index that it belongs to.
+   */
+  protected int getRunForTab(int tabCount, int tabIndex)
+  {
+    if (runCount == 1 && tabIndex < tabCount && tabIndex >= 0)
+      return 1;
+    for (int i = 0; i < runCount; i++)
+      {
+	int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
+	if (first == tabCount)
+	  first = 0;
+	int last = lastTabInRun(tabCount, i);
+	if (last >= tabIndex && first <= tabIndex)
+	  return i;
+      }
+    return -1;
+  }
+
+  /**
+   * This method returns the index of the last tab in  a run.
+   *
+   * @param tabCount The number of tabs.
+   * @param run The run to check.
+   *
+   * @return The last tab in the given run.
+   */
+  protected int lastTabInRun(int tabCount, int run)
+  {
+    if (tabRuns[run] == 0)
+      return tabCount - 1;
+    else
+      return tabRuns[run] - 1;
+  }
+
+  /**
+   * This method returns the tab run overlay.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The tab run overlay.
+   */
+  protected int getTabRunOverlay(int tabPlacement)
+  {
+    return tabRunOverlay;
+  }
+
+  /**
+   * This method returns the tab run indent. It is used in WRAP_TAB_LAYOUT and
+   * makes each tab run start indented by a certain amount.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param run The run to get indent for.
+   *
+   * @return The amount a run should be indented.
+   */
+  protected int getTabRunIndent(int tabPlacement, int run)
+  {
+    return 0;
+  }
+
+  /**
+   * This method returns whether a tab run should be padded.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param run The run to check.
+   *
+   * @return Whether the given run should be padded.
+   */
+  protected boolean shouldPadTabRun(int tabPlacement, int run)
+  {
+    return true;
+  }
+
+  /**
+   * This method returns whether the tab runs should be rotated.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return Whether runs should be rotated.
+   */
+  protected boolean shouldRotateTabRuns(int tabPlacement)
+  {
+    return true;
+  }
+
+  /**
+   * This method returns an icon for the tab. If the tab is disabled, it
+   * should return the disabledIcon. If it is enabled, then it should return
+   * the default icon.
+   *
+   * @param tabIndex The tab index to get an icon for.
+   *
+   * @return The icon for the tab index.
+   */
+  protected Icon getIconForTab(int tabIndex)
+  {
+    if (tabPane.isEnabledAt(tabIndex))
+      return tabPane.getIconAt(tabIndex);
+    else
+      return tabPane.getDisabledIconAt(tabIndex);
+  }
+
+  /**
+   * This method returns a view that can paint the text for the label.
+   *
+   * @param tabIndex The tab index to get a view for.
+   *
+   * @return The view for the tab index.
+   */
+  protected View getTextViewForTab(int tabIndex)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns the tab height, including insets, for the given index
+   * and fontheight.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The index of the tab to calculate.
+   * @param fontHeight The font height.
+   *
+   * @return This tab's height.
+   */
+  protected int calculateTabHeight(int tabPlacement, int tabIndex,
+                                   int fontHeight)
+  {
+    Icon icon = getIconForTab(tabIndex);
+    Insets insets = getTabInsets(tabPlacement, tabIndex);
+
+    if (icon != null)
+      {
+	Rectangle vr = new Rectangle();
+	Rectangle ir = new Rectangle();
+	Rectangle tr = new Rectangle();
+	layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
+	            tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
+	            tabIndex == tabPane.getSelectedIndex());
+	calcRect = tr.union(ir);
+      }
+    else
+      calcRect.height = fontHeight;
+
+    calcRect.height += insets.top + insets.bottom;
+    return calcRect.height;
+  }
+
+  /**
+   * This method returns the max tab height.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The maximum tab height.
+   */
+  protected int calculateMaxTabHeight(int tabPlacement)
+  {
+    maxTabHeight = 0;
+
+    FontMetrics fm = getFontMetrics();
+    int fontHeight = fm.getHeight();
+
+    for (int i = 0; i < tabPane.getTabCount(); i++)
+      maxTabHeight = Math.max(calculateTabHeight(tabPlacement, i, fontHeight),
+                              maxTabHeight);
+
+    return maxTabHeight;
+  }
+
+  /**
+   * This method calculates the tab width, including insets, for the given tab
+   * index and font metrics.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index to calculate for.
+   * @param metrics The font's metrics.
+   *
+   * @return The tab width for the given index.
+   */
+  protected int calculateTabWidth(int tabPlacement, int tabIndex,
+                                  FontMetrics metrics)
+  {
+    Icon icon = getIconForTab(tabIndex);
+    Insets insets = getTabInsets(tabPlacement, tabIndex);
+
+    if (icon != null)
+      {
+	Rectangle vr = new Rectangle();
+	Rectangle ir = new Rectangle();
+	Rectangle tr = new Rectangle();
+	layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
+	            tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
+	            tabIndex == tabPane.getSelectedIndex());
+	calcRect = tr.union(ir);
+      }
+    else
+      calcRect.width = metrics.stringWidth(tabPane.getTitleAt(tabIndex));
+
+    calcRect.width += insets.left + insets.right;
+    return calcRect.width;
+  }
+
+  /**
+   * This method calculates the max tab width.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The maximum tab width.
+   */
+  protected int calculateMaxTabWidth(int tabPlacement)
+  {
+    maxTabWidth = 0;
+
+    FontMetrics fm = getFontMetrics();
+
+    for (int i = 0; i < tabPane.getTabCount(); i++)
+      maxTabWidth = Math.max(calculateTabWidth(tabPlacement, i, fm),
+                             maxTabWidth);
+
+    return maxTabWidth;
+  }
+
+  /**
+   * This method calculates the tab area height, including insets, for the
+   * given amount of runs and tab height.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param horizRunCount The number of runs.
+   * @param maxTabHeight The max tab height.
+   *
+   * @return The tab area height.
+   */
+  protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount,
+                                       int maxTabHeight)
+  {
+    Insets insets = getTabAreaInsets(tabPlacement);
+    int tabAreaHeight = horizRunCount * maxTabHeight
+                        - (horizRunCount - 1) * tabRunOverlay;
+
+    tabAreaHeight += insets.top + insets.bottom;
+
+    return tabAreaHeight;
+  }
+
+  /**
+   * This method calculates the tab area width, including insets, for the
+   * given amount of runs and tab width.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param vertRunCount The number of runs.
+   * @param maxTabWidth The max tab width.
+   *
+   * @return The tab area width.
+   */
+  protected int calculateTabAreaWidth(int tabPlacement, int vertRunCount,
+                                      int maxTabWidth)
+  {
+    Insets insets = getTabAreaInsets(tabPlacement);
+    int tabAreaWidth = vertRunCount * maxTabWidth
+                       - (vertRunCount - 1) * tabRunOverlay;
+
+    tabAreaWidth += insets.left + insets.right;
+
+    return tabAreaWidth;
+  }
+
+  /**
+   * This method returns the tab insets appropriately rotated.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab index.
+   *
+   * @return The tab insets for the given index.
+   */
+  protected Insets getTabInsets(int tabPlacement, int tabIndex)
+  {
+    Insets target = new Insets(0, 0, 0, 0);
+    rotateInsets(tabInsets, target, tabPlacement);
+    return target;
+  }
+
+  /**
+   * This method returns the selected tab pad insets appropriately rotated.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The selected tab pad insets.
+   */
+  protected Insets getSelectedTabPadInsets(int tabPlacement)
+  {
+    Insets target = new Insets(0, 0, 0, 0);
+    rotateInsets(selectedTabPadInsets, target, tabPlacement);
+    return target;
+  }
+
+  /**
+   * This method returns the tab area insets appropriately rotated.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The tab area insets.
+   */
+  protected Insets getTabAreaInsets(int tabPlacement)
+  {
+    Insets target = new Insets(0, 0, 0, 0);
+    rotateInsets(tabAreaInsets, target, tabPlacement);
+    return target;
+  }
+
+  /**
+   * This method returns the content border insets appropriately rotated.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   *
+   * @return The content border insets.
+   */
+  protected Insets getContentBorderInsets(int tabPlacement)
+  {
+    Insets target = new Insets(0, 0, 0, 0);
+    rotateInsets(contentBorderInsets, target, tabPlacement);
+    return target;
+  }
+
+  /**
+   * This method returns the fontmetrics for the font of the JTabbedPane.
+   *
+   * @return The font metrics for the JTabbedPane.
+   */
+  protected FontMetrics getFontMetrics()
+  {
+    FontMetrics fm = tabPane.getToolkit().getFontMetrics(tabPane.getFont());
+    return fm;
+  }
+
+  /**
+   * This method navigates from the selected tab into the given direction. As
+   * a result, a new tab will be selected (if possible).
+   *
+   * @param direction The direction to navigate in.
+   */
+  protected void navigateSelectedTab(int direction)
+  {
+    int tabPlacement = tabPane.getTabPlacement();
+    if (tabPlacement == SwingConstants.TOP
+        || tabPlacement == SwingConstants.BOTTOM)
+      {
+	if (direction == SwingConstants.WEST)
+	  selectPreviousTabInRun(tabPane.getSelectedIndex());
+	else if (direction == SwingConstants.EAST)
+	  selectNextTabInRun(tabPane.getSelectedIndex());
+
+	else
+	  {
+	    int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
+	                                 tabPane.getSelectedIndex(),
+	                                 (tabPlacement == SwingConstants.RIGHT)
+	                                 ? true : false);
+	    selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
+	                         offset);
+	  }
+      }
+    if (tabPlacement == SwingConstants.LEFT
+        || tabPlacement == SwingConstants.RIGHT)
+      {
+	if (direction == SwingConstants.NORTH)
+	  selectPreviousTabInRun(tabPane.getSelectedIndex());
+	else if (direction == SwingConstants.SOUTH)
+	  selectNextTabInRun(tabPane.getSelectedIndex());
+	else
+	  {
+	    int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
+	                                 tabPane.getSelectedIndex(),
+	                                 (tabPlacement == SwingConstants.RIGHT)
+	                                 ? true : false);
+	    selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
+	                         offset);
+	  }
+      }
+  }
+
+  /**
+   * This method selects the next tab in the run.
+   *
+   * @param current The current selected index.
+   */
+  protected void selectNextTabInRun(int current)
+  {
+    tabPane.setSelectedIndex(getNextTabIndexInRun(tabPane.getTabCount(),
+                                                  current));
+  }
+
+  /**
+   * This method selects the previous tab in the run.
+   *
+   * @param current The current selected index.
+   */
+  protected void selectPreviousTabInRun(int current)
+  {
+    tabPane.setSelectedIndex(getPreviousTabIndexInRun(tabPane.getTabCount(),
+                                                      current));
+  }
+
+  /**
+   * This method selects the next tab (regardless of runs).
+   *
+   * @param current The current selected index.
+   */
+  protected void selectNextTab(int current)
+  {
+    tabPane.setSelectedIndex(getNextTabIndex(current));
+  }
+
+  /**
+   * This method selects the previous tab (regardless of runs).
+   *
+   * @param current The current selected index.
+   */
+  protected void selectPreviousTab(int current)
+  {
+    tabPane.setSelectedIndex(getPreviousTabIndex(current));
+  }
+
+  /**
+   * This method selects the correct tab given an offset from the current tab
+   * index. If the tab placement is TOP or BOTTOM, the offset will be in the
+   * y direction, otherwise, it will be in the x direction. A new coordinate
+   * will be found by adding the offset to the current location of the tab.
+   * The tab that the new location will be selected.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabIndex The tab to start from.
+   * @param offset The coordinate offset.
+   */
+  protected void selectAdjacentRunTab(int tabPlacement, int tabIndex,
+                                      int offset)
+  {
+    int x = rects[tabIndex].x + rects[tabIndex].width / 2;
+    int y = rects[tabIndex].y + rects[tabIndex].height / 2;
+
+    switch (tabPlacement)
+      {
+      case SwingConstants.TOP:
+      case SwingConstants.BOTTOM:
+	y += offset;
+	break;
+      case SwingConstants.RIGHT:
+      case SwingConstants.LEFT:
+	x += offset;
+	break;
+      }
+
+    int index = tabForCoordinate(tabPane, x, y);
+    if (index != -1)
+      tabPane.setSelectedIndex(index);
+  }
+
+  // This method is called when you press up/down to cycle through tab runs.
+  // it returns the distance (between the two runs' x/y position.
+  // where one run is the current selected run and the other run is the run in the
+  // direction of the scroll (dictated by the forward flag)
+  // the offset is an absolute value of the difference
+
+  /**
+   * This method calculates the offset distance for use in
+   * selectAdjacentRunTab. The offset returned will be a difference in the y
+   * coordinate between the run in  the desired direction and the current run
+   * (for tabPlacement in TOP or BOTTOM). Use x coordinate for LEFT and
+   * RIGHT.
+   *
+   * @param tabPlacement The JTabbedPane's tab placement.
+   * @param tabCount The number of tabs.
+   * @param tabIndex The starting index.
+   * @param forward If forward, the run in the desired direction will be the
+   *        next run.
+   *
+   * @return The offset between the two runs.
+   */
+  protected int getTabRunOffset(int tabPlacement, int tabCount, int tabIndex,
+                                boolean forward)
+  {
+    int currRun = getRunForTab(tabCount, tabIndex);
+    int offset;
+    int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun);
+    if (tabPlacement == SwingConstants.TOP
+        || tabPlacement == SwingConstants.BOTTOM)
+      offset = rects[lastTabInRun(tabCount, nextRun)].y
+               - rects[lastTabInRun(tabCount, currRun)].y;
+    else
+      offset = rects[lastTabInRun(tabCount, nextRun)].x
+               - rects[lastTabInRun(tabCount, currRun)].x;
+    return offset;
+  }
+
+  /**
+   * This method returns the previous tab index.
+   *
+   * @param base The index to start from.
+   *
+   * @return The previous tab index.
+   */
+  protected int getPreviousTabIndex(int base)
+  {
+    base--;
+    if (base < 0)
+      return tabPane.getTabCount() - 1;
+    return base;
+  }
+
+  /**
+   * This method returns the next tab index.
+   *
+   * @param base The index to start from.
+   *
+   * @return The next tab index.
+   */
+  protected int getNextTabIndex(int base)
+  {
+    base++;
+    if (base == tabPane.getTabCount())
+      return 0;
+    return base;
+  }
+
+  /**
+   * This method returns the next tab index in the run. If the next index is
+   * out of this run, it will return the starting tab index for the run.
+   *
+   * @param tabCount The number of tabs.
+   * @param base The index to start from.
+   *
+   * @return The next tab index in the run.
+   */
+  protected int getNextTabIndexInRun(int tabCount, int base)
+  {
+    int index = getNextTabIndex(base);
+    int run = getRunForTab(tabCount, base);
+    if (index == lastTabInRun(tabCount, run) + 1)
+      index = lastTabInRun(tabCount, getPreviousTabRun(run)) + 1;
+    return getNextTabIndex(base);
+  }
+
+  /**
+   * This method returns the previous tab index in the run. If the previous
+   * index is out of this run, it will return the last index for the run.
+   *
+   * @param tabCount The number of tabs.
+   * @param base The index to start from.
+   *
+   * @return The previous tab index in the run.
+   */
+  protected int getPreviousTabIndexInRun(int tabCount, int base)
+  {
+    int index = getPreviousTabIndex(base);
+    int run = getRunForTab(tabCount, base);
+    if (index == lastTabInRun(tabCount, getPreviousTabRun(run)))
+      index = lastTabInRun(tabCount, run);
+    return getPreviousTabIndex(base);
+  }
+
+  /**
+   * This method returns the index of the previous run.
+   *
+   * @param baseRun The run to start from.
+   *
+   * @return The index of the previous run.
+   */
+  protected int getPreviousTabRun(int baseRun)
+  {
+    if (getTabRunCount(tabPane) == 1)
+      return 1;
+
+    int prevRun = --baseRun;
+    if (prevRun < 0)
+      prevRun = getTabRunCount(tabPane) - 1;
+    return prevRun;
+  }
+
+  /**
+   * This method returns the index of the next run.
+   *
+   * @param baseRun The run to start from.
+   *
+   * @return The index of the next run.
+   */
+  protected int getNextTabRun(int baseRun)
+  {
+    if (getTabRunCount(tabPane) == 1)
+      return 1;
+
+    int nextRun = ++baseRun;
+    if (nextRun == getTabRunCount(tabPane))
+      nextRun = 0;
+    return nextRun;
+  }
+
+  /**
+   * This method rotates the insets given a direction to rotate them in.
+   * Target placement should be one of TOP, LEFT, BOTTOM, RIGHT. The  rotated
+   * insets will be stored in targetInsets. Passing in TOP as  the direction
+   * does nothing. Passing in LEFT switches top and left, right and bottom.
+   * Passing in BOTTOM switches top and bottom. Passing in RIGHT switches top
+   * for left, left for bottom, bottom for right, and right for top.
+   *
+   * @param topInsets The reference insets.
+   * @param targetInsets An Insets object to store the new insets.
+   * @param targetPlacement The rotation direction.
+   */
+  protected static void rotateInsets(Insets topInsets, Insets targetInsets,
+                                     int targetPlacement)
+  {
+    // Sun's version will happily throw an NPE if params are null,
+    // so I won't check it either.
+    switch (targetPlacement)
+      {
+      case SwingConstants.TOP:
+	targetInsets.top = topInsets.top;
+	targetInsets.left = topInsets.left;
+	targetInsets.right = topInsets.right;
+	targetInsets.bottom = topInsets.bottom;
+	break;
+      case SwingConstants.LEFT:
+	targetInsets.left = topInsets.top;
+	targetInsets.top = topInsets.left;
+	targetInsets.right = topInsets.bottom;
+	targetInsets.bottom = topInsets.right;
+	break;
+      case SwingConstants.BOTTOM:
+	targetInsets.top = topInsets.bottom;
+	targetInsets.bottom = topInsets.top;
+	targetInsets.left = topInsets.left;
+	targetInsets.right = topInsets.right;
+	break;
+      case SwingConstants.RIGHT:
+	targetInsets.top = topInsets.left;
+	targetInsets.left = topInsets.bottom;
+	targetInsets.bottom = topInsets.right;
+	targetInsets.right = topInsets.top;
+	break;
+      }
+  }
 }
-                       
Index: javax/swing/plaf/basic/BasicTableHeaderUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicTableHeaderUI.java
diff -N javax/swing/plaf/basic/BasicTableHeaderUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicTableHeaderUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,301 @@
+/* BasicTableHeaderUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import javax.swing.CellRendererPane;
+import javax.swing.JComponent;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.TableHeaderUI;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+
+public class BasicTableHeaderUI
+  extends TableHeaderUI
+{
+
+  public static ComponentUI createUI(JComponent h)
+  {
+    return new BasicTableHeaderUI();
+  }
+
+  protected JTableHeader header;
+  protected MouseInputListener mouseInputListener;
+  protected CellRendererPane rendererPane;
+  protected Border cellBorder;
+
+  class MouseInputHandler
+    implements MouseInputListener
+  {
+    public void mouseClicked(MouseEvent e) {}
+    public void mouseDragged(MouseEvent e) {}
+    public void mouseEntered(MouseEvent e) {}
+    public void mouseExited(MouseEvent e) {}
+    public void mouseMoved(MouseEvent e) {}
+    public void mousePressed(MouseEvent e) {}
+    public void mouseReleased(MouseEvent e) {}
+  }
+
+  protected MouseInputListener createMouseInputListener()
+  {
+    return new MouseInputHandler();
+  }
+
+  public BasicTableHeaderUI()
+  {
+    mouseInputListener = createMouseInputListener();
+  }
+
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    header.setBackground(defaults.getColor("TableHeader.background"));
+    header.setForeground(defaults.getColor("TableHeader.foreground"));
+    header.setFont(defaults.getFont("TableHeader.font"));
+    cellBorder = defaults.getBorder("TableHeader.cellBorder");
+  }
+
+  protected void installKeyboardActions()
+  {
+  }
+
+  protected void installListeners()
+  {
+    header.addMouseListener(mouseInputListener);
+  }
+
+  public void installUI(JComponent c)
+  {
+    header = (JTableHeader) c;
+    installDefaults();
+    installKeyboardActions();
+    installListeners();
+  }
+
+  protected void uninstallDefaults()
+  {
+    header.setBackground(null);
+    header.setForeground(null);
+    header.setFont(null);
+  }
+
+  protected void uninstallKeyboardActions()
+  {
+  }
+
+  protected void uninstallListeners()
+  {
+    header.removeMouseListener(mouseInputListener);
+  }
+
+  public void uninstallUI(JComponent c)
+  {
+    uninstallListeners();
+    uninstallKeyboardActions();
+    uninstallDefaults();
+  }
+
+  public void paint(Graphics gfx, JComponent c)
+  {
+    TableColumnModel cmod = header.getColumnModel();
+    int ncols = cmod.getColumnCount();
+    if (ncols == 0)
+      return;
+    
+    Rectangle clip = gfx.getClipBounds();
+    TableCellRenderer defaultRend = header.getDefaultRenderer();
+
+    for (int i = 0; i < ncols; ++i)
+      {
+        Rectangle bounds = header.getHeaderRect(i);
+        if (bounds.intersects(clip))
+          {
+            TableColumn col = cmod.getColumn(i);
+            TableCellRenderer rend = col.getHeaderRenderer();
+            if (rend == null)
+              rend = defaultRend;
+            Object val = col.getHeaderValue();
+            Component comp = rend.getTableCellRendererComponent(header.getTable(),
+                                                                val,
+                                                                false, // isSelected
+                                                                false, // isFocused
+                                                                -1, i);
+            comp.setFont(header.getFont());
+            comp.setBackground(header.getBackground());
+            comp.setForeground(header.getForeground());
+            if (comp instanceof JComponent)
+              ((JComponent)comp).setBorder(cellBorder);
+            gfx.translate(bounds.x, bounds.y);
+            comp.setSize(bounds.width, bounds.height);
+            comp.setLocation(0,0);
+            comp.paint(gfx);
+            gfx.translate(-bounds.x, -bounds.y);
+          }
+      }
+
+  }
+
+  public Dimension getMaximumSize(JComponent c)
+  {
+    TableColumnModel cmod = header.getColumnModel();
+    TableCellRenderer defaultRend = header.getDefaultRenderer();
+    int ncols = cmod.getColumnCount();    
+    int spacing = 0;
+    Dimension ret = getPreferredSize(c);
+    
+    if (header.getTable() != null 
+        && header.getTable().getInterCellSpacing() != null)
+      spacing = header.getTable().getInterCellSpacing().width;
+
+    ret.width = 0;
+    for (int i = 0; i < ncols; ++i)      
+      {
+        TableColumn col = cmod.getColumn(i);
+        TableCellRenderer rend = col.getHeaderRenderer();
+        if (rend == null)
+          rend = defaultRend;
+        Object val = col.getHeaderValue();
+        Component comp = rend.getTableCellRendererComponent(header.getTable(),
+                                                            val,
+                                                            false, // isSelected
+                                                            false, // isFocused
+                                                            -1, i);
+        comp.setFont(header.getFont());
+        comp.setBackground(header.getBackground());
+        comp.setForeground(header.getForeground());
+        if (comp instanceof JComponent)
+          ((JComponent)comp).setBorder(cellBorder);
+
+        Dimension d = comp.getMaximumSize();
+        ret.width += col.getMaxWidth();
+        ret.height = Math.max(ret.height, d.height);
+        ret.width += spacing;
+      }
+    return ret;
+  }
+
+  public Dimension getMinimumSize(JComponent c)
+  {
+    TableColumnModel cmod = header.getColumnModel();
+    TableCellRenderer defaultRend = header.getDefaultRenderer();
+    int ncols = cmod.getColumnCount();    
+    int spacing = 0;
+    Dimension ret = getPreferredSize(c);
+
+    if (header.getTable() != null 
+        && header.getTable().getInterCellSpacing() != null)
+      spacing = header.getTable().getInterCellSpacing().width;
+
+    ret.width = 0;
+    for (int i = 0; i < ncols; ++i)      
+      {
+        TableColumn col = cmod.getColumn(i);
+        TableCellRenderer rend = col.getHeaderRenderer();
+        if (rend == null)
+          rend = defaultRend;
+        Object val = col.getHeaderValue();
+        Component comp = rend.getTableCellRendererComponent(header.getTable(),
+                                                            val,
+                                                            false, // isSelected
+                                                            false, // isFocused
+                                                            -1, i);
+        comp.setFont(header.getFont());
+        comp.setBackground(header.getBackground());
+        comp.setForeground(header.getForeground());
+        if (comp instanceof JComponent)
+          ((JComponent)comp).setBorder(cellBorder);
+
+        Dimension d = comp.getMinimumSize();
+        ret.width += col.getMinWidth();
+        ret.width += spacing;
+        ret.height = Math.max(ret.height, d.height);
+      }
+    return ret;
+  }
+  
+  public Dimension getPreferredSize(JComponent c)
+  {
+    TableColumnModel cmod = header.getColumnModel();
+    TableCellRenderer defaultRend = header.getDefaultRenderer();
+    int ncols = cmod.getColumnCount();    
+    Dimension ret = new Dimension(0,0);
+    int spacing = 0;
+
+    if (header.getTable() != null 
+        && header.getTable().getInterCellSpacing() != null)
+      spacing = header.getTable().getInterCellSpacing().width;
+    
+    for (int i = 0; i < ncols; ++i)      
+      {
+        TableColumn col = cmod.getColumn(i);
+        TableCellRenderer rend = col.getHeaderRenderer();
+        if (rend == null)
+          rend = defaultRend;
+        Object val = col.getHeaderValue();
+        Component comp = rend.getTableCellRendererComponent(header.getTable(),
+                                                            val,
+                                                            false, // isSelected
+                                                            false, // isFocused
+                                                            -1, i);
+        comp.setFont(header.getFont());
+        comp.setBackground(header.getBackground());
+        comp.setForeground(header.getForeground());
+        if (comp instanceof JComponent)
+          ((JComponent)comp).setBorder(cellBorder);
+
+        Dimension d = comp.getPreferredSize();
+        ret.width += d.width;
+        ret.width += spacing;
+        ret.height = Math.max(d.height, ret.height);        
+      }
+    return ret;
+  }
+  
+  
+}
Index: javax/swing/plaf/basic/BasicTableUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicTableUI.java
diff -N javax/swing/plaf/basic/BasicTableUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicTableUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,374 @@
+/* BasicTableUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import javax.swing.CellRendererPane;
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.TableUI;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+
+
+public class BasicTableUI
+  extends TableUI
+{
+
+  public static ComponentUI createUI(JComponent comp) 
+  {
+    return new BasicTableUI();
+  }
+
+  protected FocusListener focusListener;  
+  protected KeyListener keyListener;   
+  protected MouseInputListener	mouseInputListener;   
+  protected CellRendererPane rendererPane;   
+  protected JTable table;
+
+  class FocusHandler implements FocusListener
+  {
+    public void focusGained(FocusEvent e) 
+    {
+    }
+    public void focusLost(FocusEvent e) 
+    {
+    }
+  }
+
+  class KeyHandler implements KeyListener
+  {
+    public void keyPressed(KeyEvent e) 
+    {
+    }
+    public void keyReleased(KeyEvent e) 
+    {
+    }
+    public void keyTyped(KeyEvent e) 
+    {
+    }
+  }
+
+  class MouseInputHandler implements MouseInputListener
+  {
+    Point begin, curr;
+
+    private int getRowForPoint(Point p)
+    {      
+      int y0 = table.getLocation().y;
+      int nrows = table.getRowCount();
+      Dimension gap = table.getInterCellSpacing();
+      int height = table.getRowHeight() + (gap == null ? 0 : gap.height);
+      int y = p.y;
+      for (int i = 0; i < nrows; ++i)
+        {
+          if (0 <= y && y < height)
+            return i;
+          y -= height;
+        }
+      return -1;
+    }
+
+    private int getColForPoint(Point p)
+    {
+      int x0 = table.getLocation().x;
+      int ncols = table.getColumnCount();
+      Dimension gap = table.getInterCellSpacing();
+      TableColumnModel cols = table.getColumnModel();      
+      int x = p.x;
+      for (int i = 0; i < ncols; ++i)
+        {
+          int width = cols.getColumn(i).getWidth() + (gap == null ? 0 : gap.width);
+          if (0 <= x && x < width)
+            return i;
+          x -= width;
+        }
+      return -1;
+    }
+
+    private void updateSelection()
+    {
+      if (table.getRowSelectionAllowed())
+        {
+          int lo_row = getRowForPoint(begin);
+          int hi_row  = getRowForPoint(curr);
+          ListSelectionModel rowModel = table.getSelectionModel();
+          if (lo_row != -1 && hi_row != -1)
+            rowModel.setSelectionInterval(lo_row, hi_row);
+        }
+
+      if (table.getColumnSelectionAllowed())
+        {
+          int lo_col = getColForPoint(begin);
+          int hi_col = getColForPoint(curr);
+          ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+          if (lo_col != -1 && hi_col != -1)
+            colModel.setSelectionInterval(lo_col, hi_col);
+        }
+    }
+
+    public void mouseClicked(MouseEvent e) 
+    {
+    }
+    public void mouseDragged(MouseEvent e) 
+    {
+      curr = new Point(e.getX(), e.getY());
+      updateSelection();      
+    }
+    public void mouseEntered(MouseEvent e) 
+    {
+    }
+    public void mouseExited(MouseEvent e) 
+    {
+    }
+    public void mouseMoved(MouseEvent e) 
+    {
+    }
+    public void mousePressed(MouseEvent e) 
+    {
+      begin = new Point(e.getX(), e.getY());
+      curr = new Point(e.getX(), e.getY());
+      updateSelection();
+    }
+    public void mouseReleased(MouseEvent e) 
+    {
+      begin = null;
+      curr = null;
+    }
+  }
+
+  protected FocusListener createFocusListener() 
+  {
+    return new FocusHandler();
+  }
+  protected KeyListener createKeyListener() 
+  {
+    return new KeyHandler();
+  }
+  protected MouseInputListener createMouseInputListener() 
+  {
+    return new MouseInputHandler();
+  }
+
+  public Dimension getMaximumSize(JComponent comp) 
+  {
+    return getPreferredSize(comp);
+  }
+
+  public Dimension getMinimumSize(JComponent comp) 
+  {
+    return getPreferredSize(comp);
+  }
+
+  public Dimension getPreferredSize(JComponent comp) 
+  {
+    int width = table.getColumnModel().getTotalColumnWidth();
+    int height = table.getRowCount() * table.getRowHeight();
+    return new Dimension(width, height);
+  }
+
+  protected void installDefaults() 
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    table.setFont(defaults.getFont("Table.font"));
+    table.setGridColor(defaults.getColor("Table.gridColor"));
+    table.setForeground(defaults.getColor("Table.foreground"));
+    table.setBackground(defaults.getColor("Table.background"));
+    table.setSelectionForeground(defaults.getColor("Table.selectionForeground"));
+    table.setSelectionBackground(defaults.getColor("Table.selectionBackground"));
+    table.setOpaque(true);
+  }
+  protected void installKeyboardActions() 
+  {
+  }
+
+  protected void installListeners() 
+  {
+    table.addFocusListener(focusListener);  
+    table.addKeyListener(keyListener);
+    table.addMouseListener(mouseInputListener);    
+  }
+
+  protected void uninstallDefaults() 
+  {
+    table.setFont(null);
+    table.setGridColor(null);
+    table.setForeground(null);
+    table.setBackground(null);
+    table.setSelectionForeground(null);
+    table.setSelectionBackground(null);
+  }
+
+  protected void uninstallKeyboardActions() 
+  {
+  }
+
+  protected void uninstallListeners() 
+  {
+    table.removeFocusListener(focusListener);  
+    table.removeKeyListener(keyListener);
+    table.removeMouseListener(mouseInputListener);    
+  }
+
+  public void installUI(JComponent comp) 
+  {
+    table = (JTable)comp;
+    focusListener = createFocusListener();  
+    keyListener = createKeyListener();
+    mouseInputListener = createMouseInputListener();
+    installDefaults();
+    installKeyboardActions();
+    installListeners();
+  }
+
+  public void uninstallUI(JComponent c) 
+  {
+    uninstallListeners();
+    uninstallKeyboardActions();
+    uninstallDefaults();    
+  }
+
+  public void paint(Graphics gfx, JComponent ignored) 
+  {
+    int ncols = table.getColumnCount();
+    int nrows = table.getRowCount();
+    if (nrows == 0 || ncols == 0)
+      return;
+
+    Rectangle clip = gfx.getClipBounds();
+    TableColumnModel cols = table.getColumnModel();
+
+    int height = table.getRowHeight();
+    int x0 = 0, y0 = 0;
+    int x = x0;
+    int y = y0;
+
+    Dimension gap = table.getInterCellSpacing();
+    int ymax = clip.y + clip.height;
+    int xmax = clip.x + clip.width;
+
+    // paint the cell contents
+    for (int c = 0; c < ncols && x < xmax; ++c)
+      {
+        y = y0;
+        TableColumn col = cols.getColumn(c);
+        int width = col.getWidth();
+        int modelCol = col.getModelIndex();
+
+        for (int r = 0; r < nrows && y < ymax; ++r)
+          {
+            Rectangle bounds = new Rectangle(x, y, width, height);
+              if (bounds.intersects(clip))
+              {
+                TableCellRenderer rend = table.getCellRenderer(r, c);
+                Component comp = table.prepareRenderer(rend, r, c);
+                gfx.translate(x, y);
+                comp.setBounds(new Rectangle(0, 0, width, height));
+                comp.paint(gfx);
+                gfx.translate(-x, -y);
+              }
+              y += height;
+              if (gap != null)
+                y += gap.height;
+          }
+        x += width;
+        if (gap != null)
+          x += gap.width;
+      }
+
+    // tighten up the x and y max bounds
+    ymax = y;
+    xmax = x;
+
+    Color grid = table.getGridColor();    
+
+    // paint vertical grid lines    
+    if (grid != null && table.getShowVerticalLines())
+      {    
+        x = x0;
+        Color save = gfx.getColor();
+        gfx.setColor(grid);
+        boolean paintedLine = false;
+        for (int c = 0; c < ncols && x < xmax; ++c)
+          {
+            x += cols.getColumn(c).getWidth();;
+            if (gap != null)
+              x += gap.width;
+            gfx.drawLine(x, y0, x, ymax);
+            paintedLine = true;
+          }
+        gfx.setColor(save);
+      }
+
+    // paint horizontal grid lines    
+    if (grid != null && table.getShowHorizontalLines())
+      {    
+        y = y0;
+        Color save = gfx.getColor();
+        gfx.setColor(grid);
+        boolean paintedLine = false;
+        for (int r = 0; r < nrows && y < ymax; ++r)
+          {
+            y += height;
+            if (gap != null)
+              y += gap.height;
+            gfx.drawLine(x0, y, xmax, y);
+            paintedLine = true;
+          }
+        gfx.setColor(save);
+      }
+
+  }
+
+}
Index: javax/swing/plaf/basic/BasicTextAreaUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicTextAreaUI.java
diff -N javax/swing/plaf/basic/BasicTextAreaUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicTextAreaUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,69 @@
+/* BasicTextAreaUI.java -- 
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.plaf.basic;
+
+import java.beans.PropertyChangeEvent;
+
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.text.Element;
+import javax.swing.text.PlainView;
+import javax.swing.text.View;
+
+public class BasicTextAreaUI extends BasicTextUI
+{
+  public static ComponentUI createUI(JComponent comp)
+  {
+    return new BasicTextAreaUI();
+  }
+
+  public BasicTextAreaUI()
+  {
+  }
+
+  public View create(Element elem)
+  {
+    return new PlainView(elem);
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "TextArea";
+  }
+}
Index: javax/swing/plaf/basic/BasicTextFieldUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicTextFieldUI.java
diff -N javax/swing/plaf/basic/BasicTextFieldUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicTextFieldUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,82 @@
+/* BasicTextFieldUI.java
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.plaf.basic;
+
+import java.beans.PropertyChangeEvent;
+
+import javax.swing.JComponent;
+import javax.swing.JTextField;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.text.Element;
+import javax.swing.text.FieldView;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.View;
+
+public class BasicTextFieldUI extends BasicTextUI
+{
+  public BasicTextFieldUI()
+  {
+    super();
+  }
+
+  public View create(Element elem)
+  {
+    return new FieldView(elem);
+  }
+  
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicTextFieldUI();
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "TextField";
+  }
+
+  public void installUI(JComponent c)
+  {
+    super.installUI(c);
+  }
+
+  protected void propertyChange(PropertyChangeEvent event)
+  {
+    // Does nothing by default.
+  }
+}
Index: javax/swing/plaf/basic/BasicTextUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicTextUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicTextUI.java
--- javax/swing/plaf/basic/BasicTextUI.java	13 Jul 2003 15:29:11 -0000	1.4
+++ javax/swing/plaf/basic/BasicTextUI.java	6 Sep 2004 16:36:08 -0000
@@ -1,5 +1,5 @@
 /* BasicTextUI.java
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,151 +39,433 @@
 package javax.swing.plaf.basic;
 
 import java.awt.Color;
+import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Graphics;
+import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.Shape;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.TextUI;
+import javax.swing.plaf.UIResource;
 import javax.swing.text.BadLocationException;
+import javax.swing.text.Caret;
+import javax.swing.text.DefaultCaret;
 import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.Document;
 import javax.swing.text.EditorKit;
 import javax.swing.text.Element;
+import javax.swing.text.Highlighter;
 import javax.swing.text.JTextComponent;
+import javax.swing.text.Keymap;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.PlainView;
 import javax.swing.text.Position;
 import javax.swing.text.View;
 import javax.swing.text.ViewFactory;
 
-public class BasicTextUI extends TextUI
+
+public abstract class BasicTextUI extends TextUI
   implements ViewFactory
 {
-    int gap = 3;
-    View view = null; // was: new RootView();
-    Color textColor, disabledTextColor, normalBackgroundColor;
-    EditorKit kit = new DefaultEditorKit();
-    
-    /* *****************************************************************
-     * This View is way too incomplete to be of any use. To avoid errors
-     * when compiling with the Sun JDK, it has been commented out.
-     *                            -- Sascha Brawer (brawer@dandelis.ch)
-     *
-     * (begin of commented out section)
-    class RootView extends View
+  public static class BasicCaret extends DefaultCaret
+    implements UIResource
+  {
+    public BasicCaret()
     {
-	RootView()
-	{
-	    super(null);
-	}
-        public void paint(Graphics g, Shape s)
-	{
-	    if (view != null)
-		{
-		    Rectangle r = s.getBounds();
-
-		    view.setSize((int)r.getWidth(),
-				 (int)r.getHeight());
-		    view.paint(g, s);
-		}
-        }
     }
-    * (end of commented out section)
-    *************************************************************** */
+  }
 
-    public BasicTextUI()
+  public static class BasicHighlighter extends DefaultHighlighter
+    implements UIResource
+  {
+    public BasicHighlighter()
     {
     }
+  }
 
-    public static ComponentUI createUI(final JComponent c) 
+  private class RootView extends View
+  {
+    private View view;
+    
+    public RootView()
     {
-	return new BasicTextUI();
+      super(null);
     }
 
-    
-    public void installUI(final JComponent c) 
+    public ViewFactory getViewFactory()
     {
-	super.installUI(c);
-
-	textColor                = new Color(0,0,0);
-	disabledTextColor        = new Color(130, 130, 130);
-	normalBackgroundColor    = new Color(192,192,192);
+      // FIXME: Handle EditorKit somehow.
+      return BasicTextUI.this;
     }
-    
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	JTextComponent b = (JTextComponent) c;
-
-	View v = getRootView(b);
 
-	float w = v.getPreferredSpan(View.X_AXIS);
-	float h = v.getPreferredSpan(View.Y_AXIS);
+    public void setView(View v)
+      {
+          if (view != null)
+	view.setParent(null);
+      
+      if (v != null)
+	v.setParent(null);
 
-	return new Dimension((int)w, (int) h);
+      view = v;
     }
-    
 
-    public void paint(Graphics g, JComponent c)
-    {      
-	//	view.paint(
+    public Container getContainer()
+              {
+      return textComponent;
     }
 
-    public void damageRange(JTextComponent t, int p0, int p1)
+    public float getPreferredSpan(int axis)
     {
-	damageRange(t, p0, p1, null, null);
-    }    
+      if (view != null)
+	return view.getPreferredSpan(axis);
 
-    public void damageRange(JTextComponent t, 
-		     int p0, int p1, 
-		     Position.Bias firstBias,
-		     Position.Bias secondBias)
-    {
-    }
+      return Integer.MAX_VALUE;
+              }
 
-    public EditorKit getEditorKit(JTextComponent t)
+    public void paint(Graphics g, Shape s)
     {
-	return kit;
+      if (view != null)
+	view.paint(g, s);
     }
-    
-    public int getNextVisualPositionFrom(JTextComponent t, 
-				  int pos,
-				  Position.Bias b, 
-				  int direction,
-				  Position.Bias[] biasRet)
-        throws BadLocationException
+
+    protected Rectangle modelToView(int position, Shape a, Position.Bias bias)
+      throws BadLocationException
     {
-	return 0;
+      return ((PlainView) view).modelToView(position, a, bias).getBounds();
     }
-    
-    public View getRootView(JTextComponent t)
+  }
+
+  class UpdateHandler implements PropertyChangeListener
+  {
+    public void propertyChange(PropertyChangeEvent event)
     {
-	return view;
+      if (event.getPropertyName().equals("document"))
+	{
+          // Document changed.
+	  modelChanged();
+	}
     }
+  }
+  
+  static EditorKit kit = new DefaultEditorKit();
+
+  RootView rootView = new RootView();
+  JTextComponent textComponent;
+  UpdateHandler updateHandler = new UpdateHandler();
+
+  public BasicTextUI()
+  {
+  }
+
+  protected Caret createCaret()
+  {
+    return new BasicCaret();
+  }
+
+  protected Highlighter createHighlighter()
+  {
+    return new BasicHighlighter();
+  }
+  
+  protected final JTextComponent getComponent()
+  {
+    return textComponent;
+  }
+
+  public void installUI(final JComponent c)
+  {
+    super.installUI(c);
+    c.setOpaque(true);
+
+    textComponent = (JTextComponent) c;
+
+    Document doc = textComponent.getDocument();
+    if (doc == null)
+      {
+	doc = getEditorKit(textComponent).createDefaultDocument();
+	textComponent.setDocument(doc);
+      }
     
-    public Rectangle modelToView(JTextComponent t, int pos)
-      throws BadLocationException
-    {
-	return modelToView(t, pos, null);
-    }
+    textComponent.addPropertyChangeListener(updateHandler);
+    modelChanged();
     
-    public Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias)
-      throws BadLocationException
-    {
-	return null;
-    }
+    installDefaults();
+    installListeners();
+    installKeyboardActions();
+  }
+
+  protected void installDefaults()
+  {
+    Caret caret = textComponent.getCaret();
+    if (caret == null)
+      {
+        caret = createCaret();
+        textComponent.setCaret(caret);
+      }
+
+    Highlighter highlighter = textComponent.getHighlighter();
+    if (highlighter == null)
+      textComponent.setHighlighter(createHighlighter());
+
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    textComponent.setBackground(defaults.getColor(prefix + ".background"));
+    textComponent.setForeground(defaults.getColor(prefix + ".foreground"));
+    textComponent.setMargin(defaults.getInsets(prefix + ".margin"));
+    textComponent.setBorder(defaults.getBorder(prefix + ".border"));
+    textComponent.setFont(defaults.getFont(prefix + ".font"));
+
+    caret.setBlinkRate(defaults.getInt(prefix + ".caretBlinkRate"));
+  }
+
+  protected void installListeners()
+  {
+    // Do nothing here.
+  }
+
+  protected String getKeymapName()
+  {
+    return "BasicTextUI";
+  }
+
+  protected Keymap createKeymap()
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    JTextComponent.KeyBinding[] bindings = 
+      (JTextComponent.KeyBinding[]) defaults.get(prefix + ".keyBindings");
+    Keymap km = JTextComponent.addKeymap(getKeymapName(), 
+                                         JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP));    
+    JTextComponent.loadKeymap(km, bindings, textComponent.getActions());
+    return km;    
+  }
+
+  protected void installKeyboardActions()
+  {    
+    // load any bindings for the older Keymap interface
+    Keymap km = JTextComponent.getKeymap(getKeymapName());
+    if (km == null)
+      km = createKeymap();
+    textComponent.setKeymap(km);
+
+    // load any bindings for the newer InputMap / ActionMap interface
+    SwingUtilities.replaceUIInputMap(textComponent, 
+                                     JComponent.WHEN_FOCUSED,
+                                     getInputMap(JComponent.WHEN_FOCUSED));
+    SwingUtilities.replaceUIActionMap(textComponent, getActionMap());
+  }
+
+  InputMap getInputMap(int condition)
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    switch (condition)
+      {
+      case JComponent.WHEN_IN_FOCUSED_WINDOW:
+        // FIXME: is this the right string? nobody seems to use it.
+        return (InputMap) defaults.get(prefix + ".windowInputMap"); 
+      case JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        return (InputMap) defaults.get(prefix + ".ancestorInputMap");
+      default:
+      case JComponent.WHEN_FOCUSED:
+        return (InputMap) defaults.get(prefix + ".focusInputMap");
+      }
+  }
+
+  ActionMap getActionMap()
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();    
+    ActionMap am = (ActionMap) defaults.get(prefix + ".actionMap");
+    if (am == null)
+      {
+        am = createActionMap();
+        defaults.put(prefix + ".actionMap", am);
+      }
+    return am;
+  }
+
+  ActionMap createActionMap()
+  {
+    Action[] actions = textComponent.getActions();
+    ActionMap am = new ActionMap();
+    for (int i = 0; i < actions.length; ++i)
+      {
+        String name = (String) actions[i].getValue(Action.NAME);
+        if (name != null)
+          am.put(name, actions[i]);
+      }
+    return am;
+  }
+  
+  public void uninstallUI(final JComponent component)
+  {
+    super.uninstallUI(component);
+    rootView.setView(null);
+
+    textComponent.removePropertyChangeListener(updateHandler);
+    textComponent = null;
+
+    uninstallDefaults();
+    uninstallListeners();
+    uninstallKeyboardActions();
+  }
+
+  protected void uninstallDefaults()
+  {
+    // Do nothing here.
+  }
+
+  protected void uninstallListeners()
+  {
+    // Do nothing here.
+  }
+
+  protected void uninstallKeyboardActions()
+  {
+    // Do nothing here.
+  }
+  
+  protected abstract String getPropertyPrefix();
+
+  public Dimension getPreferredSize(JComponent c)
+  {
+    View v = getRootView(textComponent);
+
+    float w = v.getPreferredSpan(View.X_AXIS);
+    float h = v.getPreferredSpan(View.Y_AXIS);
+
+    return new Dimension((int) w, (int) h);
+  }
+
+  public final void paint(Graphics g, JComponent c)
+  {
+    paintSafely(g);
+  }
+
+  protected void paintSafely(Graphics g)
+  {
+    Caret caret = textComponent.getCaret();
+    Highlighter highlighter = textComponent.getHighlighter();
     
-    public int viewToModel(JTextComponent t, Point pt)
-    {
-	return viewToModel(t, pt, null);
-    }
+    if (textComponent.isOpaque())
+      paintBackground(g);
     
-    public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn)
-    {
-	return 0;
-    } 
+    if (highlighter != null
+	&& textComponent.getSelectionStart() != textComponent.getSelectionEnd())
+      highlighter.paint(g);
+
+    rootView.paint(g, getVisibleEditorRect());
 
-  public View create (Element elem)
+    if (caret != null)
+      caret.paint(g);
+  }
+
+  protected void paintBackground(Graphics g)
+  {
+    g.setColor(textComponent.getBackground());
+    g.fillRect(0, 0, textComponent.getWidth(), textComponent.getHeight());
+  }
+
+  public void damageRange(JTextComponent t, int p0, int p1)
+  {
+    damageRange(t, p0, p1, null, null);
+  }
+
+  public void damageRange(JTextComponent t, int p0, int p1,
+                          Position.Bias firstBias, Position.Bias secondBias)
+  {
+  }
+
+  public EditorKit getEditorKit(JTextComponent t)
+  {
+    return kit;
+  }
+
+  public int getNextVisualPositionFrom(JTextComponent t, int pos,
+                                       Position.Bias b, int direction,
+                                       Position.Bias[] biasRet)
+    throws BadLocationException
+  {
+    return 0;
+  }
+
+  public View getRootView(JTextComponent t)
+  {
+    return rootView;
+  }
+
+  public Rectangle modelToView(JTextComponent t, int pos)
+    throws BadLocationException
+  {
+    return modelToView(t, pos, Position.Bias.Forward);
+  }
+
+  public Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias)
+    throws BadLocationException
+  {
+    return rootView.modelToView(pos, getVisibleEditorRect(), bias).getBounds();
+  }
+
+  public int viewToModel(JTextComponent t, Point pt)
+  {
+    return viewToModel(t, pt, null);
+  }
+
+  public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn)
+  {
+    return 0;
+  }
+
+  public View create(Element elem)
+  {
+    // subclasses have to implement this to get this functionality
+    return null;
+  }
+
+  public View create(Element elem, int p0, int p1)
   {
     // subclasses have to implement this to get this functionality
     return null;
   }
+  
+  protected Rectangle getVisibleEditorRect()
+  {
+    int width = textComponent.getWidth();
+    int height = textComponent.getHeight();
+
+    if (width <= 0 || height <= 0)
+      return null;
+	
+    Insets insets = textComponent.getInsets();
+    return new Rectangle(insets.left, insets.top,
+			 width - insets.left + insets.right,
+			 height - insets.top + insets.bottom);
+  }
+
+  protected final void setView(View view)
+  {
+    rootView.setView(view);
+    view.setParent(rootView);
+  }
+
+  protected void modelChanged()
+  {
+    ViewFactory factory = rootView.getViewFactory();
+    Element elem = textComponent.getDocument().getDefaultRootElement();
+    setView(factory.create(elem));
+  }
 }
Index: javax/swing/plaf/basic/BasicToggleButtonUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java,v
retrieving revision 1.4
diff -u -r1.4 BasicToggleButtonUI.java
--- javax/swing/plaf/basic/BasicToggleButtonUI.java	10 Jan 2004 21:59:30 -0000	1.4
+++ javax/swing/plaf/basic/BasicToggleButtonUI.java	6 Sep 2004 16:36:08 -0000
@@ -38,86 +38,15 @@
 
 package javax.swing.plaf.basic;
 
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import javax.swing.AbstractButton;
 import javax.swing.JComponent;
 import javax.swing.plaf.ComponentUI;
 
 public class BasicToggleButtonUI extends BasicButtonUI
 {
-  
-    public static ComponentUI createUI(final JComponent c)  {
-	return new BasicToggleButtonUI();
-    }
+  public static ComponentUI createUI(final JComponent component)
+  {
+    return new BasicToggleButtonUI();
+  }    
 
-    
-    public void installUI(final JComponent c)  {
-	super.installUI(c);
-    }
-    
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	AbstractButton b = (AbstractButton)c;
-	Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
-							  
-	//System.out.println("^^^^^^^^^^^^^^^^^^^^^^   BASIC-PREF="+d + ",T="+b.text);
-	return d;
-    }
-    
-    protected void paintFocus(Graphics g, 
-			      JComponent c,
-			      Rectangle vr,
-			      Rectangle tr,
-			      Rectangle ir)
-    {
-    }
-
-    protected void paintIcon(Graphics g, 
-			     JComponent c, 
-			     Rectangle iconRect)
-    {
-    }
-
-    protected void paintButtonPressed(Graphics g,
-				      JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(pressedBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
-    
-    protected void paintButtonNormal(Graphics g,
-				     JComponent b)
-    {
-	Dimension size = b.getSize();
-	
-	g.setColor(normalBackgroundColor);
-	g.fillRect(1,1,size.width-2, size.height-2);                
-
-    }
-    protected void paintText(Graphics g,
-			     JComponent c,
-			     Rectangle textRect,
-			     String text) 
-    {
-	//        AbstractButton b = (AbstractButton) c;
-	
-	//	System.out.println("drawing string: " + text + ", at:" + textRect);
-	
-	g.setColor(textColor);
-
-	BasicGraphicsUtils.drawString(g,
-				      text, 
-				      0,	
-				      textRect.x, 
-				      textRect.y);
-    } 
 }
 
-
-
-
Index: javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
diff -N javax/swing/plaf/basic/BasicToolBarSeparatorUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicToolBarSeparatorUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,132 @@
+/* BasicToolBarSeparatorUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JToolBar.Separator;
+import javax.swing.JSeparator;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.SeparatorUI;
+
+
+/**
+ * The Basic Look and Feel UI delegate for Separator.
+ */
+public class BasicToolBarSeparatorUI extends BasicSeparatorUI
+{
+  private transient Dimension size;
+
+  /**
+   * Creates a new UI delegate for the given JComponent.
+   *
+   * @param c The JComponent to create a delegate for.
+   *
+   * @return A new BasicToolBarSeparatorUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicToolBarSeparatorUI();
+  }
+
+  /**
+   * This method installs the defaults that are given by the Basic L&F.
+   *
+   * @param s The Separator that is being installed.
+   */
+  protected void installDefaults(JSeparator s)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    
+    size = defaults.getDimension("ToolBar.separatorSize");
+  }
+
+  /**
+   * This method does nothing as a Separator is just blank space.
+   *
+   * @param g The Graphics object to paint with
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    // Do nothing.
+  }
+
+  /**
+   * This method returns the preferred size of the  JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return size;
+  }
+
+  /**
+   * This method returns the minimum size of the JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return size;
+  }
+
+  /**
+   * This method returns the maximum size of the JComponent.
+   *
+   * @param c The JComponent to measure.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return size;
+  }
+}
Index: javax/swing/plaf/basic/BasicToolBarUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicToolBarUI.java
diff -N javax/swing/plaf/basic/BasicToolBarUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicToolBarUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,1435 @@
+/* BasicToolBarUI.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Window;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JToolBar;
+import javax.swing.RootPaneContainer;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.BorderUIResource;
+import javax.swing.plaf.BorderUIResource.EtchedBorderUIResource;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.ToolBarUI;
+import javax.swing.plaf.UIResource;
+
+
+/**
+ * This is the Basic Look and Feel UI class for JToolBar.
+ */
+public class BasicToolBarUI extends ToolBarUI implements SwingConstants
+{
+  /** Static owner of all DragWindows. */
+  private static JFrame owner = new JFrame();
+
+  /** The border used when the JToolBar is in nonrollover mode. */
+  private static Border nonRolloverBorder;
+
+  /** The border used when the JToolBar is in rollover mode. */
+  private static Border rolloverBorder;
+
+  /** The last known BorderLayout constraint before floating. */
+    protected String constraintBeforeFloating;
+
+  /** The last known orientation of the JToolBar before floating. */
+  private int lastGoodOrientation;
+
+  /** The color of the border when it is dockable. */
+    protected Color dockingBorderColor;
+
+  /** The background color of the JToolBar when it is dockable. */
+    protected Color dockingColor;
+
+  /** The docking listener responsible for mouse events on the JToolBar. */
+    protected MouseInputListener dockingListener;
+
+  /** The window used for dragging the JToolBar. */
+    protected BasicToolBarUI.DragWindow dragWindow;
+
+  /** The color of the border when it is not dockable. */
+    protected Color floatingBorderColor;
+
+  /** The background color of the JToolBar when it is not dockable. */
+    protected Color floatingColor;
+
+  /** The index of the focused component. */
+    protected int focusedCompIndex;
+
+  /** The PropertyChangeListener for the JToolBar. */
+    protected PropertyChangeListener propertyListener;
+
+  /** The JToolBar this UI delegate is responsible for. */
+    protected JToolBar toolBar;
+
+  /** The Container listener for the JToolBar. */
+    protected ContainerListener toolBarContListener;
+
+  /** The Focus listener for the JToolBar. */
+  protected FocusListener toolBarFocusListener;
+
+  /**
+   * The floating window that is responsible for holding the JToolBar when it
+   * is dragged outside of its original parent.
+   */
+  private transient Window floatFrame;
+
+  /** The original parent of the JToolBar. */
+  private transient Container origParent;
+
+  /** A hashtable of components and their original borders. */
+  private transient Hashtable borders;
+
+  /** A window listener for the floatable frame. */
+  private transient WindowListener windowListener;
+
+  /** A set of cached bounds of the JToolBar. */
+  private transient Dimension cachedBounds;
+
+  /** The cached orientation of the JToolBar. */
+  private transient int cachedOrientation;
+
+  /**
+   * This method creates a new BasicToolBarUI object for the given JToolBar.
+   */
+  public BasicToolBarUI()
+  {
+    super();
+  }
+
+  /**
+   * This method returns whether the JToolBar can dock at the given position.
+   *
+   * @param c The component to try to dock in.
+   * @param p The position of the mouse cursor relative to the given
+   *        component.
+   *
+   * @return Whether the JToolBar can dock.
+   */
+  protected boolean canDock(Component c, Point p)
+    {
+    if (areaOfClick(c, p) != -1)
+      return true;
+
+	return false;
+    }
+
+  /**
+   * This helper method returns the position of the JToolBar if it can dock.
+   *
+   * @param c The component to try to dock in.
+   * @param p The position of the mouse cursor relative to the given
+   *        component.
+   *
+   * @return One of the SwingConstants directions or -1 if the JToolBar can't
+   *         dock.
+   */
+  private int areaOfClick(Component c, Point p)
+  {
+    // Has to dock in immediate parent, not eventual root container.
+    Rectangle pBounds = c.getBounds();
+
+    // XXX: In Sun's implementation, the space the toolbar has to dock is dependent on the size it had last.
+    Dimension d = toolBar.getSize();
+    int limit = Math.min(d.width, d.height);
+
+    // The order of checking is 1. top 2. bottom 3. left 4. right
+    if (! pBounds.contains(p))
+      return -1;
+
+    if (p.y < limit)
+      return SwingConstants.NORTH;
+
+    if (p.y > (pBounds.height - limit))
+      return SwingConstants.SOUTH;
+
+    if (p.x < limit)
+      return SwingConstants.WEST;
+
+    if (p.x > (pBounds.width - limit))
+      return SwingConstants.EAST;
+
+    return -1;
+  }
+
+  /**
+   * This method creates a new DockingListener for the JToolBar.
+   *
+   * @return A new DockingListener for the JToolBar.
+   */
+    protected MouseInputListener createDockingListener()
+    {
+    return new DockingListener(toolBar);
+    }
+
+  /**
+   * This method creates a new DragWindow for the given JToolBar.
+   *
+   * @param toolbar The JToolBar to create a DragWindow for.
+   *
+   * @return A new DragWindow.
+   */
+    protected BasicToolBarUI.DragWindow createDragWindow(JToolBar toolbar)
+    {
+    return new DragWindow();
+    }
+
+  /**
+   * This method creates a new floating frame for the JToolBar. By default,
+   * this UI uses createFloatingWindow instead. This method of creating a
+   * floating frame is deprecated.
+   *
+   * @param toolbar The JToolBar to create a floating frame for.
+   *
+   * @return A new floating frame.
+   */
+    protected JFrame createFloatingFrame(JToolBar toolbar)
+    {
+    // FIXME: Though deprecated, this should still work.
+      return null;
+    }
+
+  /**
+   * This method creates a new floating window for the JToolBar. This is the
+   * method used by default to create a floating container for the JToolBar.
+   *
+   * @param toolbar The JToolBar to create a floating window for.
+   *
+   * @return A new floating window.
+   */
+    protected RootPaneContainer createFloatingWindow(JToolBar toolbar)
+    {
+    // This one is used by default though.
+    return new ToolBarDialog();
+    }
+
+  /**
+   * This method creates a new WindowListener for the JToolBar.
+   *
+   * @return A new WindowListener.
+   */
+    protected WindowListener createFrameListener()
+    {
+    return new FrameListener();
+    }
+
+  /**
+   * This method creates a new nonRolloverBorder for JButtons when the
+   * JToolBar's rollover property is set to false.
+   *
+   * @return A new NonRolloverBorder.
+   */
+    protected Border createNonRolloverBorder()
+    {
+    return new EtchedBorderUIResource();
+    }
+
+  /**
+   * This method creates a new PropertyChangeListener for the JToolBar.
+   *
+   * @return A new PropertyChangeListener.
+   */
+    protected PropertyChangeListener createPropertyListener()
+    {
+    return new PropertyListener();
+    }
+
+  /**
+   * This method creates a new rollover border for JButtons when the
+   * JToolBar's rollover property is set to true.
+   *
+   * @return A new rollover border.
+   */
+    protected Border createRolloverBorder()
+    {
+    return new EtchedBorderUIResource()
+      {
+	public void paintBorder(Component c, Graphics g, int x, int y,
+	                        int width, int height)
+	{
+	  if (c instanceof JButton)
+	    {
+	      if (((JButton) c).getModel().isRollover())
+		super.paintBorder(c, g, x, y, width, height);
+	    }
+	}
+      };
+    }
+
+  /**
+   * This method creates a new Container listener for the JToolBar.
+   *
+   * @return A new Container listener.
+   */
+    protected ContainerListener createToolBarContListener()
+    {
+    return new ToolBarContListener();
+    }
+
+  /**
+   * This method creates a new FocusListener for the JToolBar.
+   *
+   * @return A new FocusListener for the JToolBar.
+   */
+    protected FocusListener createToolBarFocusListener()
+    {
+    return new ToolBarFocusListener();
+    }
+
+  /**
+   * This method creates a new UI delegate for the given JComponent.
+   *
+   * @param c The JComponent to create a UI delegate for.
+   *
+   * @return A new UI delegate.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicToolBarUI();
+  }
+
+  /**
+   * This method is called to drag the DragWindow around when the JToolBar is
+   * being dragged around.
+   *
+   * @param position The mouse cursor coordinates relative to the JToolBar.
+   * @param origin The screen position of the JToolBar.
+   */
+    protected void dragTo(Point position, Point origin)
+    {
+    int loc = areaOfClick(origParent,
+                          SwingUtilities.convertPoint(toolBar, position,
+                                                      origParent));
+
+    if (loc != -1)
+      {
+	dragWindow.setBorderColor(dockingBorderColor);
+	dragWindow.setBackground(dockingColor);
+      }
+    else
+      {
+	dragWindow.setBorderColor(floatingBorderColor);
+	dragWindow.setBackground(floatingColor);
+      }
+
+    int w = 0;
+    int h = 0;
+
+    boolean tmp = ((loc == SwingConstants.NORTH)
+                  || (loc == SwingConstants.SOUTH) || (loc == -1));
+
+    if (((cachedOrientation == SwingConstants.HORIZONTAL) && tmp)
+        || ((cachedOrientation == VERTICAL) && ! tmp))
+      {
+	w = cachedBounds.width;
+	h = cachedBounds.height;
+      }
+    else
+      {
+	w = cachedBounds.height;
+	h = cachedBounds.width;
+    }
+
+    Point p = dragWindow.getOffset();
+    Insets insets = toolBar.getInsets();
+
+    dragWindow.setBounds((origin.x + position.x) - p.x
+                         - ((insets.left + insets.right) / 2),
+                         (origin.y + position.y) - p.y
+                         - ((insets.top + insets.bottom) / 2), w, h);
+
+    if (! dragWindow.isVisible())
+      dragWindow.show();
+  }
+
+  /**
+   * This method is used at the end of a drag session to place the frame in
+   * either its original parent as a docked JToolBar or in its floating
+   * frame.
+   *
+   * @param position The position of the mouse cursor relative to the
+   *        JToolBar.
+   * @param origin The screen position of the JToolBar before the drag session
+   *        started.
+   */
+    protected void floatAt(Point position, Point origin)
+    {
+    Point p = new Point(position);
+    int aoc = areaOfClick(origParent,
+                          SwingUtilities.convertPoint(toolBar, p, origParent));
+
+    Container oldParent = toolBar.getParent();
+
+    oldParent.remove(toolBar);
+    oldParent.doLayout();
+    oldParent.repaint();
+
+    Container newParent;
+
+    if (aoc == -1)
+      newParent = ((RootPaneContainer) floatFrame).getContentPane();
+    else
+      {
+	floatFrame.hide();
+	newParent = origParent;
+    }
+
+    String constraint;
+    switch (aoc)
+      {
+      case SwingConstants.EAST:
+	constraint = BorderLayout.EAST;
+	break;
+      case SwingConstants.NORTH:
+	constraint = BorderLayout.NORTH;
+	break;
+      case SwingConstants.SOUTH:
+	constraint = BorderLayout.SOUTH;
+	break;
+      case SwingConstants.WEST:
+	constraint = BorderLayout.WEST;
+	break;
+      default:
+	constraint = BorderLayout.CENTER;
+	break;
+      }
+
+    int newOrientation = SwingConstants.HORIZONTAL;
+    if ((aoc != -1)
+        && ((aoc == SwingConstants.EAST) || (aoc == SwingConstants.WEST)))
+      newOrientation = SwingConstants.VERTICAL;
+
+    if (aoc != -1)
+      {
+	constraintBeforeFloating = constraint;
+	lastGoodOrientation = newOrientation;
+      }
+
+    newParent.add(toolBar, constraint);
+
+    setFloating(aoc == -1, null);
+    toolBar.setOrientation(newOrientation);
+
+    Insets insets = floatFrame.getInsets();
+    Dimension dims = toolBar.getPreferredSize();
+    p = dragWindow.getOffset();
+    setFloatingLocation((position.x + origin.x) - p.x
+                        - ((insets.left + insets.right) / 2),
+                        (position.y + origin.y) - p.y
+                        - ((insets.top + insets.bottom) / 2));
+
+    if (aoc == -1)
+      {
+	floatFrame.pack();
+	floatFrame.setSize(dims.width + insets.left + insets.right,
+	                   dims.height + insets.top + insets.bottom);
+	floatFrame.show();
+      }
+
+    newParent.invalidate();
+    newParent.validate();
+    newParent.repaint();
+  }
+
+  /**
+   * This method returns the docking color.
+   *
+   * @return The docking color.
+   */
+  public Color getDockingColor()
+    {
+	return dockingColor;
+    }
+
+  /**
+   * This method returns the Color which is displayed when over a floating
+   * area.
+   *
+   * @return The color which is displayed when over a floating area.
+   */
+  public Color getFloatingColor()
+    {
+	return floatingColor;
+    }
+
+  /**
+   * This method returns the maximum size of the given JComponent for this UI.
+   *
+   * @param c The JComponent to find the maximum size for.
+   *
+   * @return The maximum size for this UI.
+   */
+  public Dimension getMaximumSize(JComponent c)
+    {
+    return getPreferredSize(c);
+    }
+
+  /**
+   * This method returns the minimum size of the given JComponent for this UI.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size for this UI.
+   */
+  public Dimension getMinimumSize(JComponent c)
+    {
+    return getPreferredSize(c);
+    }
+
+  /**
+   * This method returns the preferred size of the given JComponent for this
+   * UI.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size for this UI.
+   */
+  public Dimension getPreferredSize(JComponent c)
+    {
+    return toolBar.getLayout().preferredLayoutSize(c);
+    }
+
+  /**
+   * This method installs the needed components for the JToolBar.
+   */
+    protected void installComponents()
+    {
+    floatFrame = (Window) createFloatingWindow(toolBar);
+
+    dragWindow = createDragWindow(toolBar);
+
+    cachedBounds = toolBar.getPreferredSize();
+    cachedOrientation = toolBar.getOrientation();
+
+    nonRolloverBorder = createNonRolloverBorder();
+    rolloverBorder = createRolloverBorder();
+
+    borders = new Hashtable();
+
+    fillHashtable();
+    }
+
+  /**
+   * This method installs the defaults as specified by the look and feel.
+   */
+    protected void installDefaults()
+    {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    toolBar.setBorder(new ToolBarBorder());
+    toolBar.setBackground(defaults.getColor("ToolBar.background"));
+    toolBar.setForeground(defaults.getColor("ToolBar.foreground"));
+    toolBar.setFont(defaults.getFont("ToolBar.font"));
+
+    dockingBorderColor = defaults.getColor("ToolBar.dockingForeground");
+    dockingColor = defaults.getColor("ToolBar.dockingBackground");
+
+    floatingBorderColor = defaults.getColor("ToolBar.floatingForeground");
+    floatingColor = defaults.getColor("ToolBar.floatingBackground");
+    }
+
+  /**
+   * This method installs the keyboard actions for the JToolBar as specified
+   * by the look and feel.
+   */
+    protected void installKeyboardActions()
+    {
+    // FIXME: implement.
+    }
+
+  /**
+   * This method installs listeners for the JToolBar.
+   *
+   * @param toolbar The JToolBar to register listeners for.
+   */
+    protected void installListeners(JToolBar toolbar)
+    {
+    dockingListener = createDockingListener();
+    toolBar.addMouseListener(dockingListener);
+    toolBar.addMouseMotionListener(dockingListener);
+
+    propertyListener = createPropertyListener();
+    toolBar.addPropertyChangeListener(propertyListener);
+
+    toolBarContListener = createToolBarContListener();
+    toolBar.addContainerListener(toolBarContListener);
+
+    windowListener = createFrameListener();
+    floatFrame.addWindowListener(windowListener);
+
+    toolBarFocusListener = createToolBarFocusListener();
+    toolBar.addFocusListener(toolBarFocusListener);
+  }
+
+  /**
+   * This method installs non rollover borders for each component inside the
+   * given JComponent.
+   *
+   * @param c The JComponent whose children need to have non rollover borders
+   *        installed.
+   */
+    protected void installNonRolloverBorders(JComponent c)
+    {
+    Component[] components = toolBar.getComponents();
+
+    for (int i = 0; i < components.length; i++)
+      setBorderToNonRollover(components[i]);
+    }
+
+  /**
+   * This method installs normal (or their original) borders for each
+   * component inside the given JComponent.
+   *
+   * @param c The JComponent whose children need to have their original
+   *        borders installed.
+   */
+    protected void installNormalBorders(JComponent c)
+    {
+    Component[] components = toolBar.getComponents();
+
+    for (int i = 0; i < components.length; i++)
+      setBorderToNormal(components[i]);
+    }
+
+  /**
+   * This method install rollover borders for each component inside the given
+   * JComponent.
+   *
+   * @param c The JComponent whose children need to have rollover borders
+   *        installed.
+   */
+    protected void installRolloverBorders(JComponent c)
+    {
+    Component[] components = toolBar.getComponents();
+
+    for (int i = 0; i < components.length; i++)
+      setBorderToRollover(components[i]);
+    }
+
+  /**
+   * This method fills the borders hashtable with a list of components that
+   * are JButtons and their borders.
+   */
+  private void fillHashtable()
+  {
+    Component[] c = toolBar.getComponents();
+
+    for (int i = 0; i < c.length; i++)
+      {
+	if (c[i] instanceof JButton)
+	  {
+	    // Don't really care about anything other than JButtons
+	    JButton b = (JButton) c[i];
+
+	    if (b.getBorder() != null)
+	      borders.put(b, b.getBorder());
+	  }
+      }
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install a UI for.
+   */
+    public void installUI(JComponent c)
+    {
+	super.installUI(c);
+
+	if (c instanceof JToolBar)
+	{
+	    toolBar = (JToolBar) c;
+	    toolBar.setOpaque(true);
+	installDefaults();
+	installComponents();
+	    installListeners(toolBar);
+	installKeyboardActions();
+	}
+    }
+
+  /**
+   * This method returns whether the JToolBar is floating.
+   *
+   * @return Whether the JToolBar is floating.
+   */
+  public boolean isFloating()
+    {
+    return floatFrame.isVisible();
+    }
+
+  /**
+   * This method returns whether rollover borders have been set.
+   *
+   * @return Whether rollover borders have been set.
+   */
+  public boolean isRolloverBorders()
+    {
+    return toolBar.isRollover();
+    }
+
+  /**
+   * This method navigates in the given direction giving focus to the next
+   * component in the given direction.
+   *
+   * @param direction The direction to give focus to.
+   */
+    protected void navigateFocusedComp(int direction)
+    {
+    // FIXME: Implement.
+    }
+
+  /**
+   * This method sets the border of the given component to a non rollover
+   * border.
+   *
+   * @param c The Component whose border needs to be set.
+   */
+    protected void setBorderToNonRollover(Component c)
+    {
+    if (c instanceof JButton)
+      {
+	JButton b = (JButton) c;
+	b.setRolloverEnabled(false);
+	b.setBorder(nonRolloverBorder);
+      }
+    }
+
+  /**
+   * This method sets the border of the given component to its original value.
+   *
+   * @param c The Component whose border needs to be set.
+   */
+    protected void setBorderToNormal(Component c)
+    {
+    if (c instanceof JButton)
+      {
+	JButton b = (JButton) c;
+	Border border = (Border) borders.get(b);
+	b.setBorder(border);
+      }
+    }
+
+  /**
+   * This method sets the border of the given component to a rollover border.
+   *
+   * @param c The Component whose border needs to be set.
+   */
+    protected void setBorderToRollover(Component c)
+    {
+    if (c instanceof JButton)
+      {
+	JButton b = (JButton) c;
+	b.setRolloverEnabled(true);
+	b.setBorder(rolloverBorder);
+      }
+    }
+
+  /**
+   * This method sets the docking color.
+   *
+   * @param c The docking color.
+   */
+  public void setDockingColor(Color c)
+    {
+	dockingColor = c;
+    }
+
+  /**
+   * This method sets the floating property for the JToolBar.
+   *
+   * @param b Whether the JToolBar is floating.
+   * @param p FIXME
+   */
+  public void setFloating(boolean b, Point p)
+  {
+    // FIXME: use p for something. It's not location
+    // since we already have setFloatingLocation.
+    floatFrame.setVisible(b);
+  }
+
+  /**
+   * This method sets the color displayed when the JToolBar is not in a
+   * dockable area.
+   *
+   * @param c The floating color.
+   */
+  public void setFloatingColor(Color c)
+    {
+    floatingColor = c;
+    }
+
+  /**
+   * This method sets the floating location of the JToolBar.
+   *
+   * @param x The x coordinate for the floating frame.
+   * @param y The y coordinate for the floating frame.
+   */
+  public void setFloatingLocation(int x, int y)
+  {
+    // x,y are the coordinates of the new JFrame created to store the toolbar
+    // XXX: The floating location is bogus is not floating.
+    floatFrame.setLocation(x, y);
+    floatFrame.invalidate();
+    floatFrame.validate();
+    floatFrame.repaint();
+  }
+
+  /**
+   * This is a convenience method for changing the orientation of the
+   * JToolBar.
+   *
+   * @param orientation The new orientation.
+   */
+  public void setOrientation(int orientation)
+  {
+    toolBar.setOrientation(orientation);
+  }
+
+  /**
+   * This method changes the child components to have rollover borders if the
+   * given parameter is true. Otherwise, the components are set to have non
+   * rollover borders.
+   *
+   * @param rollover Whether the children will have rollover borders.
+   */
+  public void setRolloverBorders(boolean rollover)
+  {
+    if (rollover)
+      installRolloverBorders(toolBar);
+    else
+      installNonRolloverBorders(toolBar);
+  }
+
+  /**
+   * This method uninstall UI installed components from the JToolBar.
+   */
+  protected void uninstallComponents()
+    {
+    installNormalBorders(toolBar);
+    borders = null;
+    rolloverBorder = null;
+    nonRolloverBorder = null;
+    cachedBounds = null;
+
+    floatFrame = null;
+    dragWindow = null;
+  }
+
+  /**
+   * This method removes the defaults installed by the Look and Feel.
+   */
+  protected void uninstallDefaults()
+  {
+    toolBar.setBackground(null);
+    toolBar.setForeground(null);
+    toolBar.setFont(null);
+
+    dockingBorderColor = null;
+    dockingColor = null;
+    floatingBorderColor = null;
+    floatingColor = null;
+    }
+
+  /**
+   * This method uninstalls keyboard actions installed by the UI.
+   */
+  protected void uninstallKeyboardActions()
+    {
+    // FIXME: implement.
+    }
+
+  /**
+   * This method uninstalls listeners installed by the UI.
+   */
+  protected void uninstallListeners()
+    {
+    toolBar.removeFocusListener(toolBarFocusListener);
+    toolBarFocusListener = null;
+
+    floatFrame.removeWindowListener(windowListener);
+    windowListener = null;
+
+    toolBar.removeContainerListener(toolBarContListener);
+    toolBarContListener = null;
+
+    toolBar.removeMouseMotionListener(dockingListener);
+    toolBar.removeMouseListener(dockingListener);
+    dockingListener = null;
+    }
+
+  /**
+   * This method uninstalls the UI.
+   *
+   * @param c The JComponent that is having this UI removed.
+   */
+  public void uninstallUI(JComponent c)
+    {
+    uninstallKeyboardActions();
+    uninstallListeners();
+    uninstallComponents();
+    uninstallDefaults();
+    toolBar = null;
+  }
+
+  /**
+   * This is the MouseHandler class that allows the user to drag the JToolBar
+   * in and out of the parent and dock it if it can.
+   */
+  protected class DockingListener implements MouseInputListener
+  {
+    /** Whether the JToolBar is being dragged. */
+    protected boolean isDragging;
+
+    /**
+     * The origin point. This point is saved from the beginning press and is
+     * used until the end of the drag session.
+     */
+    protected Point origin;
+
+    /** The JToolBar being dragged. */
+    protected JToolBar toolBar;
+
+    /**
+     * Creates a new DockingListener object.
+     *
+     * @param t The JToolBar this DockingListener is being used for.
+     */
+    public DockingListener(JToolBar t)
+    {
+      toolBar = t;
+    }
+
+    /**
+     * This method is called when the mouse is clicked.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      // Don't care.
+    }
+
+    /**
+     * This method is called when the mouse is dragged. It delegates the drag
+     * painting to the dragTo method.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      if (isDragging)
+	dragTo(e.getPoint(), origin);
+    }
+
+    /**
+     * This method is called when the mouse enters the JToolBar.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+      // Don't care (yet).
+    }
+
+    /**
+     * This method is called when the mouse exits the JToolBar.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      // Don't care (yet).
+    }
+
+    /**
+     * This method is called when the mouse is moved in the JToolBar.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+    }
+
+    /**
+     * This method is called when the mouse is pressed in the JToolBar. If the
+     * press doesn't occur in a place where it causes the JToolBar to be
+     * dragged, it returns. Otherwise, it starts a drag session.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      if (! toolBar.isFloatable())
+	return;
+
+      Point ssd = e.getPoint();
+      Insets insets = toolBar.getInsets();
+
+      // Verify that this click occurs in the top inset.
+      if (toolBar.getOrientation() == SwingConstants.HORIZONTAL)
+        {
+	  if (e.getX() > insets.left)
+	    return;
+    }
+      else
+        {
+	  if (e.getY() > insets.top)
+	    return;
+        }
+
+      origin = new Point(0, 0);
+      SwingUtilities.convertPointToScreen(ssd, toolBar);
+
+      if (! (SwingUtilities.getAncestorOfClass(Window.class, toolBar) instanceof UIResource))
+	// Need to know who keeps the toolBar if it gets dragged back into it.
+	origParent = toolBar.getParent();
+
+      SwingUtilities.convertPointToScreen(origin, toolBar);
+
+      isDragging = true;
+
+      if (dragWindow != null)
+	dragWindow.setOffset(new Point(e.getX(), e.getY()));
+
+      dragTo(e.getPoint(), origin);
+    }
+
+    /**
+     * This method is called when the mouse is released from the JToolBar.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      if (! isDragging || ! toolBar.isFloatable())
+	return;
+
+      isDragging = false;
+      floatAt(e.getPoint(), origin);
+      dragWindow.hide();
+    }
+  }
+
+  /**
+   * This is the window that appears when the JToolBar is being dragged
+   * around.
+   */
+  protected class DragWindow extends Window
+  {
+    /**
+     * The current border color. It changes depending on whether the JToolBar
+     * is over a place that allows it to dock.
+     */
+    private Color borderColor;
+
+    /** The between the mouse and the top left corner of the window. */
+    private Point offset;
+
+    /**
+     * Creates a new DragWindow object.
+     */
+    private DragWindow()
+    {
+      super(owner);
+    }
+
+    /**
+     * The color that the border should be.
+     *
+     * @return The border color.
+     */
+    public Color getBorderColor()
+    {
+      if (borderColor == null)
+	return Color.BLACK;
+
+      return borderColor;
+    }
+
+    /**
+     * This method returns the insets for the DragWindow.
+     *
+     * @return The insets for the DragWindow.
+     */
+    public Insets getInsets()
+    {
+      // This window has no decorations, so insets are empty.
+      return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * This method returns the mouse offset from the top left corner of the
+     * DragWindow.
+     *
+     * @return The mouse offset.
+     */
+    public Point getOffset()
+    {
+      return offset;
+    }
+
+    /**
+     * This method paints the DragWindow.
+     *
+     * @param g The Graphics object to paint with.
+     */
+    public void paint(Graphics g)
+    {
+      //  No visiting children necessary.
+      Color saved = g.getColor();
+      Rectangle b = getBounds();
+
+      g.setColor(getBorderColor());
+      g.drawRect(0, 0, b.width - 1, b.height - 1);
+
+      g.setColor(saved);
+    }
+
+    /**
+     * This method changes the border color.
+     *
+     * @param c The new border color.
+     */
+    public void setBorderColor(Color c)
+    {
+      borderColor = c;
+    }
+
+    /**
+     * This method changes the mouse offset.
+     *
+     * @param p The new mouse offset.
+     */
+    public void setOffset(Point p)
+    {
+      offset = p;
+    }
+
+    /**
+     * FIXME: Do something.
+     *
+     * @param o DOCUMENT ME!
+     */
+    public void setOrientation(int o)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This helper class listens for Window events from the floatable window and
+   * if it is closed, returns the JToolBar to the last known good location.
+   */
+  protected class FrameListener extends WindowAdapter
+  {
+    /**
+     * This method is called when the floating window is closed.
+     *
+     * @param e The WindowEvent.
+     */
+    public void windowClosing(WindowEvent e)
+    {
+      Container parent = toolBar.getParent();
+      parent.remove(toolBar);
+
+      if (origParent != null)
+        {
+	  origParent.add(toolBar,
+	                 (constraintBeforeFloating != null)
+	                 ? constraintBeforeFloating : BorderLayout.NORTH);
+	  toolBar.setOrientation(lastGoodOrientation);
+        }
+
+      origParent.invalidate();
+      origParent.validate();
+      origParent.repaint();
+    }
+  }
+
+  /**
+   * This helper class listens for PropertyChangeEvents from the JToolBar.
+   */
+  protected class PropertyListener implements PropertyChangeListener
+  {
+    /**
+     * This method is called when a property from the JToolBar is changed.
+     *
+     * @param e The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      // FIXME: need name properties so can change floatFrame title.
+      if (e.getPropertyName().equals(JToolBar.ROLLOVER_CHANGED_PROPERTY))
+	setRolloverBorders(toolBar.isRollover());
+    }
+  }
+
+  /**
+   * This helper class listens for components added to and removed from the
+   * JToolBar.
+   */
+  protected class ToolBarContListener implements ContainerListener
+  {
+    /**
+     * This method is responsible for setting rollover or non rollover for new
+     * buttons added to the JToolBar.
+     *
+     * @param e The ContainerEvent.
+     */
+    public void componentAdded(ContainerEvent e)
+    {
+      if (e.getChild() instanceof JButton)
+        {
+	  JButton b = (JButton) e.getChild();
+
+	  if (b.getBorder() != null)
+	    borders.put(b, b.getBorder());
+        }
+
+      if (isRolloverBorders())
+	setBorderToRollover(e.getChild());
+      else
+	setBorderToNonRollover(e.getChild());
+
+      cachedBounds = toolBar.getPreferredSize();
+      cachedOrientation = toolBar.getOrientation();
+    }
+
+    /**
+     * This method is responsible for giving the child components their
+     * original borders when they are removed.
+     *
+     * @param e The ContainerEvent.
+     */
+    public void componentRemoved(ContainerEvent e)
+    {
+      setBorderToNormal(e.getChild());
+      cachedBounds = toolBar.getPreferredSize();
+      cachedOrientation = toolBar.getOrientation();
+    }
+  }
+
+  /**
+   * This is the floating window that is returned when getFloatingWindow is
+   * called.
+   */
+  private class ToolBarDialog extends JDialog implements UIResource
+  {
+    /**
+     * Creates a new ToolBarDialog object with the name given by the JToolBar.
+     */
+    public ToolBarDialog()
+    {
+      super();
+      setName((toolBar.getName() != null) ? toolBar.getName() : "");
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected class ToolBarFocusListener implements FocusListener
+  {
+    /**
+     * Creates a new ToolBarFocusListener object.
+     */
+    protected ToolBarFocusListener()
+    {
+      // FIXME: implement.
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void focusGained(FocusEvent e)
+    {
+      // FIXME: implement.
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param e DOCUMENT ME!
+     */
+    public void focusLost(FocusEvent e)
+    {
+      // FIXME: implement.
+    }
+  }
+
+  /**
+   * This helper class acts as the border for the JToolBar.
+   */
+  private static class ToolBarBorder implements Border
+  {
+    /** The size of the larger, draggable side of the border. */
+    private static int offset = 10;
+
+    /** The other sides. */
+    private static int regular = 2;
+
+    /**
+     * This method returns the border insets for the JToolBar.
+     *
+     * @param c The Component to find insets for.
+     *
+     * @return The border insets.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      if (c instanceof JToolBar)
+        {
+	  JToolBar tb = (JToolBar) c;
+	  int orientation = tb.getOrientation();
+
+	  if (! tb.isFloatable())
+	    return new Insets(regular, regular, regular, regular);
+	  else if (orientation == SwingConstants.HORIZONTAL)
+	    return new Insets(regular, offset, regular, regular);
+	  else
+	    return new Insets(offset, regular, regular, regular);
+        }
+
+      return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * This method returns whether the border is opaque.
+     *
+     * @return Whether the border is opaque.
+     */
+    public boolean isBorderOpaque()
+    {
+      return false;
+    }
+
+    /**
+     * This method paints the ribbed area of the border.
+     *
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate of the area.
+     * @param y The y coordinate of the area.
+     * @param w The width of the area.
+     * @param h The height of the area.
+     * @param size The size of the bump.
+     * @param c The color of the bumps.
+     */
+    private void paintBumps(Graphics g, int x, int y, int w, int h, int size,
+                            Color c)
+    {
+      Color saved = g.getColor();
+      g.setColor(c);
+
+      int hgap = 2 * size;
+      int vgap = 4 * size;
+      int count = 0;
+
+      for (int i = x; i < (w + x); i += hgap)
+	for (int j = ((count++ % 2) == 0) ? y : (y + (2 * size)); j < (h + y);
+	     j += vgap)
+	  g.fillRect(i, j, size, size);
+
+      g.setColor(saved);
+    }
+
+    /**
+     * This method paints the border around the given Component.
+     *
+     * @param c The Component whose border is being painted.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate of the component.
+     * @param y The y coordinate of the component.
+     * @param width The width of the component.
+     * @param height The height of the component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      if (c instanceof JToolBar)
+        {
+	  JToolBar tb = (JToolBar) c;
+
+	  int orientation = tb.getOrientation();
+
+	  if (orientation == SwingConstants.HORIZONTAL)
+	    {
+	      paintBumps(g, x, y, offset, height, 1, Color.WHITE);
+	      paintBumps(g, x + 1, y + 1, offset - 1, height - 1, 1, Color.GRAY);
+	    }
+	  else
+	    {
+	      paintBumps(g, x, y, width, offset, 1, Color.WHITE);
+	      paintBumps(g, x + 1, y + 1, width - 1, offset - 1, 1, Color.GRAY);
+	    }
+        }
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicToolTipUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicToolTipUI.java
diff -N javax/swing/plaf/basic/BasicToolTipUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicToolTipUI.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,287 @@
+/* BasicToolTipUI.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GNU Classpath.
+
+   GNU Classpath is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GNU Classpath is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Classpath; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   Linking this library statically or dynamically with other modules is
+   making a combined work based on this library.  Thus, the terms and
+   conditions of the GNU General Public License cover the whole
+   combination.
+
+   As a special exception, the copyright holders of this library give you
+   permission to link this library with independent modules to produce an
+   executable, regardless of the license terms of these independent
+   modules, and to copy and distribute the resulting executable under
+   terms of your choice, provided that you also meet, for each linked
+   independent module, the terms and conditions of the license of that
+   module.  An independent module is a module which is not derived from
+   or based on this library.  If you modify this library, you may extend
+   this exception to your version of the library, but you are not
+   obligated to do so.  If you do not wish to do so, delete this
+   exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JToolTip;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.ToolTipUI;
+
+
+/**
+ * This is the Basic Look and Feel UI class for JToolTip.
+ */
+public class BasicToolTipUI extends ToolTipUI
+{
+  /** The default Border around the JToolTip. */
+  private static Border defaultBorder = new Border()
+    {
+      // FIXME: This needs to go into Basic Look and Feel
+      // defaults.
+
+			/**
+			 * This method returns the border insets.
+			 *
+			 * @param c The Component to find Border insets for.
+			 *
+			 * @return The Border insets.
+			 */		 
+      public Insets getBorderInsets(Component c)
+      {
+	return new Insets(4, 4, 4, 4);
+      }
+
+			/**
+			 * This method returns whether the border is opaque.
+			 *
+			 * @return Whether the border is opaque.
+			 */
+      public boolean isBorderOpaque()
+      {
+	return false;
+      }
+
+			/**
+			 * This method paints the border.
+			 *
+			 * @param c The Component to paint this border around.
+			 * @param g The Graphics object to paint with.
+			 * @param x The x coordinate to start painting at.
+			 * @param y The y coordinate to start painting at.
+			 * @param w The width of the Component.
+			 * @param y The height of the Component.
+			 */
+      public void paintBorder(Component c, Graphics g, int x, int y, int w,
+                              int h)
+      {
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	g.drawRect(0, 0, w - 1, h - 1);
+
+	g.setColor(saved);
+      }
+    };
+
+	/** The shared instance of BasicToolTipUI used for all ToolTips. */
+	private static BasicToolTipUI shared;
+
+  /**
+   * Creates a new BasicToolTipUI object.
+   */
+  public BasicToolTipUI()
+  {
+    super();
+  }
+
+  /**
+   * This method creates a new BasicToolTip UI for the given 
+	 * JComponent.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A BasicToolTipUI that can be used by the given JComponent.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+		if (shared == null)
+			shared = new BasicToolTipUI();
+		return shared;
+  }
+
+  /**
+   * This method returns the msximum size of the given JComponent.
+   *
+   * @param c The JComponent to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the minimum size of the given JComponent.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the preferred size of the given JComponent.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    JToolTip tip = (JToolTip) c;
+    Rectangle vr = new Rectangle();
+    Rectangle ir = new Rectangle();
+    Rectangle tr = new Rectangle();
+    Insets insets = tip.getInsets();
+    FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
+    SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER, vr, ir, tr, 0);
+    return new Dimension(insets.left + tr.width + insets.right,
+                         insets.top + tr.height + insets.bottom);
+  }
+
+  /**
+   * This method installs the defaults for the given JComponent.
+   *
+   * @param c The JComponent to install defaults for.
+   */
+  protected void installDefaults(JComponent c)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    c.setBackground(defaults.getColor("ToolTip.background"));
+    c.setForeground(defaults.getColor("ToolTip.foreground"));
+    c.setFont(defaults.getFont("ToolTip.font"));
+    c.setBorder(defaultBorder);
+  }
+
+  /**
+   * This method installs the listeners for the given JComponent.
+   *
+   * @param c The JComponent to install listeners for.
+   */
+  protected void installListeners(JComponent c)
+  {
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install the UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    c.setOpaque(true);
+    installDefaults(c);
+    installListeners(c);
+  }
+
+  /**
+   * This method paints the given JComponent with the given Graphics object.
+   *
+   * @param g The Graphics object to paint with.
+   * @param c The JComponent to paint.
+   */
+  public void paint(Graphics g, JComponent c)
+  {
+    JToolTip tip = (JToolTip) c;
+
+    String text = tip.getTipText();
+    if (text == null)
+      return;
+
+    Rectangle vr = new Rectangle();
+    vr = SwingUtilities.calculateInnerArea(tip, vr);
+    Rectangle ir = new Rectangle();
+    Rectangle tr = new Rectangle();
+    FontMetrics fm = tip.getToolkit().getFontMetrics(tip.getFont());
+    SwingUtilities.layoutCompoundLabel(tip, fm, tip.getTipText(), null,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER,
+                                       SwingConstants.CENTER, vr, ir, tr, 0);
+
+    Color saved = g.getColor();
+    g.setColor(Color.BLACK);
+
+    g.drawString(text, vr.x, vr.y + fm.getAscent());
+
+    g.setColor(saved);
+  }
+
+  /**
+   * This method uninstalls the defaults for the given JComponent.
+   *
+   * @param c The JComponent to uninstall defaults for.
+   */
+  protected void uninstallDefaults(JComponent c)
+  {
+    c.setForeground(null);
+    c.setBackground(null);
+    c.setFont(null);
+    c.setBorder(null);
+  }
+
+  /**
+   * This method uninstalls listeners for the given JComponent.
+   *
+   * @param c The JComponent to uninstall listeners for.
+   */
+  protected void uninstallListeners(JComponent c)
+  {
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent.
+   *
+   * @param c The JComponent to uninstall.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallDefaults(c);
+    uninstallListeners(c);
+  }
+}
Index: javax/swing/plaf/basic/BasicViewportUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicViewportUI.java,v
retrieving revision 1.3
diff -u -r1.3 BasicViewportUI.java
--- javax/swing/plaf/basic/BasicViewportUI.java	10 Jan 2004 21:59:30 -0000	1.3
+++ javax/swing/plaf/basic/BasicViewportUI.java	6 Sep 2004 16:36:08 -0000
@@ -38,36 +38,154 @@
 
 package javax.swing.plaf.basic;
 
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.image.ImageObserver;
 import javax.swing.JComponent;
+import javax.swing.JViewport;
+import javax.swing.ViewportLayout;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.ViewportUI;
 
 public class BasicViewportUI extends ViewportUI 
 {
 
-    public static ComponentUI createUI(final JComponent c)
+  ChangeListener changeListener;
+  Image backingStoreImage;
+  int backingStoreWidth = -1;
+  int backingStoreHeight = -1;
+  
+  class ChangeHandler implements ChangeListener
+  {
+    public void stateChanged(ChangeEvent event)
     {
-	return new BasicViewportUI();
+      JViewport v = (JViewport) event.getSource();
+      v.repaint();
     }
+  }
 
-    
-    public void installUI(final JComponent c) 
-    {
-	super.installUI(c);
-    }
+  void installDefaults(JComponent c)
+  {    
+    c.setOpaque(true);
+  }
+
+  void uninstallDefaults(JComponent c)
+  {
+  }
+
+  void installListeners(JComponent c)
+  {
+    ((JViewport)c).addChangeListener(changeListener);
+  }
+
+  void uninstallListeners(JComponent c)
+  {
+    ((JViewport)c).removeChangeListener(changeListener);
+  }
+
+  public BasicViewportUI()
+  {
+    changeListener = new ChangeHandler();
+  }
+
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicViewportUI();
+  }
+
+  public void installUI(JComponent c) 
+  {
+    super.installUI(c);
+    c.setLayout(new ViewportLayout());
+    installListeners(c);
+  }
+
+  public void uninstallUI(JComponent c) 
+  {
+    uninstallListeners(c);
+  }
     
 
-    public Dimension getPreferredSize(JComponent c) 
-    {
-	Dimension d = new Dimension(100,100);
-	System.out.println("BasicViewportUI->preff->"+d);
-	return d;
-    }
+  public Dimension getPreferredSize(JComponent c) 
+  {
+    // let the ViewportLayout decide
+    return null;
+  }
 
-    public void paint(Graphics g, JComponent c)
-    {      
-	System.out.println("BasicViewportUI->paint->"+c);
-    }
+  public void paint(Graphics g, JComponent c)
+  {      
+
+    JViewport v = (JViewport)c;
+    Component view = v.getView();
+
+    if (view == null)
+      return;
+
+    Point pos = v.getViewPosition();
+    Rectangle viewBounds = view.getBounds();
+    Rectangle portBounds = v.getBounds();
+
+    if (viewBounds.width == 0 
+        || viewBounds.height == 0
+        || portBounds.width == 0
+        || portBounds.height == 0)
+      return;
+
+    if (backingStoreImage == null 
+        || backingStoreWidth != viewBounds.width
+        || backingStoreHeight != viewBounds.height)
+      {
+        backingStoreImage = v.createImage(viewBounds.width, viewBounds.height);
+        backingStoreWidth = viewBounds.width;
+        backingStoreHeight = viewBounds.height;
+      }
+
+    Graphics g2 = backingStoreImage.getGraphics();
+
+
+    if (c.getBackground() != null)
+      {
+        // fill the backing store background
+        java.awt.Color save = g2.getColor();
+        g2.setColor(c.getBackground());
+        g2.fillRect (0, 0, backingStoreWidth, backingStoreHeight);
+        g2.setColor(save);
+
+        // fill the viewport background
+        save = g.getColor();
+        g.setColor(c.getBackground());
+        g.fillRect (0, 0, portBounds.width, portBounds.height);
+        g.setColor(save);
+
+      }
+    else
+      {
+        // clear the backing store background
+        g2.clearRect(0, 0, backingStoreWidth, backingStoreHeight);
+
+        // clear the viewport background
+        g.clearRect(0, 0, portBounds.width, portBounds.height);
+      }
+
+    g2.setClip(g.getClipBounds());
+    g2.translate(-pos.x, -pos.y);
+    try 
+      {
+        view.paint(g2);
+      }
+    finally
+      {
+        g2.translate(pos.x, pos.y);
+      }
+    g2 = null;
+    g.drawImage(backingStoreImage, 
+                0, 0, 
+                (ImageObserver)null);
+  }
 }
Index: javax/swing/plaf/basic/ComboPopup.java
===================================================================
RCS file: javax/swing/plaf/basic/ComboPopup.java
diff -N javax/swing/plaf/basic/ComboPopup.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/ComboPopup.java	6 Sep 2004 16:36:08 -0000
@@ -0,0 +1,103 @@
+/* ComboPopup.java
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import javax.swing.JList;
+
+
+public interface ComboPopup
+{
+  /**
+   * This method display popup menu containing list of JComboBox's items to
+   * the screen
+   */
+  void show();
+
+  /**
+   * This method hides popup menu with list of JComboBox's item from the
+   * screen
+   */
+  void hide();
+
+  /**
+   * Retursn true if popup menu with JComboBOx's item is currently visible on
+   * the screen and false otherwise
+   *
+   * @return true if JComboBox's popup menu with list of items is currently
+   *         visible on the screen and false otherwise.
+   */
+  boolean isVisible();
+
+  /**
+   * Return JList that is used to draw cells of the JComboBox.
+   *
+   * @return JList that is used to draw cells of the JcomboBox
+   */
+  JList getList();
+
+  /**
+   * This method returns MouseListener that listen's to mouse events occuring
+   * in the combo box
+   *
+   * @return MouseListenere
+   */
+  MouseListener getMouseListener();
+
+  /**
+   * This method returns MouseListener that listen's to mouse events occuring
+   * in the combo box.
+   *
+   * @return MouseMotionListener
+   */
+  MouseMotionListener getMouseMotionListener();
+
+  /**
+   * This method returns KeyListener that listen's to key events  occuring in
+   * the combo box.
+   *
+   * @return KeyListener
+   */
+  KeyListener getKeyListener();
+
+  /* This method removes any listeners that were installed */
+  void uninstallingUI();
+}
Index: javax/swing/plaf/metal/MetalLookAndFeel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/metal/MetalLookAndFeel.java,v
retrieving revision 1.4
diff -u -r1.4 MetalLookAndFeel.java
--- javax/swing/plaf/metal/MetalLookAndFeel.java	12 Oct 2003 13:26:01 -0000	1.4
+++ javax/swing/plaf/metal/MetalLookAndFeel.java	6 Sep 2004 16:36:09 -0000
@@ -40,7 +40,6 @@
 package javax.swing.plaf.metal;
 
 import javax.swing.UIDefaults;
-import javax.swing.plaf.basic.BasicDefaults;
 import javax.swing.plaf.basic.BasicLookAndFeel;
 
 public class MetalLookAndFeel extends BasicLookAndFeel
@@ -61,7 +60,7 @@
      public UIDefaults getDefaults()
 	 {
 	   if (LAF_defaults == null)
-	     LAF_defaults = new BasicDefaults();
+	     LAF_defaults = super.getDefaults();
 	     
 	     //      Returns the default values for this look and feel. 
 	     return LAF_defaults;
Index: javax/swing/table/AbstractTableModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/AbstractTableModel.java,v
retrieving revision 1.5
diff -u -r1.5 AbstractTableModel.java
--- javax/swing/table/AbstractTableModel.java	8 Oct 2003 15:29:52 -0000	1.5
+++ javax/swing/table/AbstractTableModel.java	6 Sep 2004 16:36:09 -0000
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.table;
 
 import java.io.Serializable;
@@ -271,25 +270,4 @@
   {
     return listenerList.getListeners (listenerType);
   }
-
-  /**
-   * getValueAt
-   * @param value0 TODO
-   * @param value1 TODO
-   * @return Object
-   */
-  public abstract Object getValueAt (int row, int column);
-
-  /**
-   * getColumnCount
-   * @return int
-   */
-  public abstract int getColumnCount();
-
-  /**
-   * getRowCount
-   * @return int
-   */
-  public abstract int getRowCount();
-
-} // AbstractTableModel
+}
Index: javax/swing/table/DefaultTableCellRenderer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/DefaultTableCellRenderer.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultTableCellRenderer.java
--- javax/swing/table/DefaultTableCellRenderer.java	11 Jun 2003 13:20:41 -0000	1.3
+++ javax/swing/table/DefaultTableCellRenderer.java	6 Sep 2004 16:36:09 -0000
@@ -1,5 +1,5 @@
 /* DefaultTableCellRenderer.java
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,40 +35,194 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.table;
 
+import java.awt.Color;
 import java.awt.Component;
+import java.awt.Rectangle;
 import java.io.Serializable;
 import javax.swing.JLabel;
 import javax.swing.JTable;
 import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
 
 /**
- * STUBBED
+ * Class to display every cells.
  */
 public class DefaultTableCellRenderer extends JLabel
   implements TableCellRenderer, Serializable
 {
   static final long serialVersionUID = 7878911414715528324L;
 
+  protected static Border noFocusBorder = new EmptyBorder(0, 0, 0, 0);
+
   public static class UIResource extends DefaultTableCellRenderer
     implements javax.swing.plaf.UIResource
   {
     public UIResource()
     {
     }
-  } // class UIResource
+  }
 
+  /**
+   * Creates a default table cell renderer with an empty border.
+   */
   public DefaultTableCellRenderer()
   {
+    super();
+  }
+
+  /**
+   * Assign the unselected-foreground.
+   *
+   * @param c the color to assign
+   */
+  public void setForeground(Color c)
+  {
+    super.setForeground(c);
   }
 
+  /**
+   * Assign the unselected-background.
+   *
+   * @param c the color to assign
+   */
+  public void setBackground(Color c)
+  {
+    super.setBackground(c);
+  }
+
+  /**
+   * Look and feel has changed.
+   *
+   * <p>Replaces the current UI object with the  latest version from
+   * the UIManager.</p>
+   */
+  public void updateUI()
+  {
+    super.updateUI();
+  }
+
+  /**
+   * Get the string value of the object and pass it to setText().
+   *
+   * @param table the JTable
+   * @param value the value of the object
+   * @param isSelected is the cell selected?
+   * @param hasFocus has the cell the focus?
+   * @param row the row to render
+   * @param column the cell to render
+   * 
+   * @return this component (the default table cell renderer)
+   */
   public Component getTableCellRendererComponent(JTable table, Object value,
                                                  boolean isSelected,
                                                  boolean hasFocus,
                                                  int row, int column)
   {
-    return null;
+    if (value!=null)
+      super.setText(value.toString());
+
+    setOpaque(true);
+    if (isSelected)
+      {
+        setBackground(table.getSelectionBackground());
+        setForeground(table.getSelectionForeground());
+      }
+    else
+      {
+        setBackground(table.getBackground());
+        setForeground(table.getForeground());
+      }
+
+    setEnabled(table.isEnabled());
+    setFont(table.getFont());
+    return this;    
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   *
+   * @return always true
+   */
+  public boolean isOpaque()
+  {
+    return true;
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   */
+  public void validate()
+  {
+    // Does nothing.
+  }
+
+  public void revalidate()
+  {
+    // Does nothing.
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   */
+  public void repaint(long tm, int x, int y, int width, int height)
+  {
+    // Does nothing.
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   */
+  public void repaint(Rectangle r)
+  {
+    // Does nothing.
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   */
+  public void firePropertyChange(String propertyName, Object oldValue,
+                                 Object newValue)
+  {
+    // Does nothing.
+  }
+
+  /**
+   * Overriden for performance.
+   *
+   * <p>This method needs to be overridden in a subclass to actually
+   * do something.</p>
+   */
+  public void firePropertyChange(String propertyName, boolean oldValue,
+		                 boolean newValue)
+  {
+    // Does nothing.
+  }
+
+  /**
+   * Sets the String for this cell.
+   * 
+   * @param value the string value for this cell; if value is null it
+   * sets the text value to an empty string
+   */
+  protected void setValue(Object value)
+  {
+    super.setText((value!=null) ? value.toString() : "");
   }
-} // class DefaultTableCellRenderer
+}
Index: javax/swing/table/DefaultTableColumnModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/DefaultTableColumnModel.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultTableColumnModel.java
--- javax/swing/table/DefaultTableColumnModel.java	11 Jun 2003 13:20:41 -0000	1.3
+++ javax/swing/table/DefaultTableColumnModel.java	6 Sep 2004 16:36:09 -0000
@@ -1,5 +1,5 @@
 /* DefaultTableColumnModel.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -35,7 +35,6 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.table;
 
 import java.beans.PropertyChangeEvent;
@@ -45,6 +44,7 @@
 import java.util.EventListener;
 import java.util.Vector;
 import javax.swing.ListSelectionModel;
+import javax.swing.DefaultListSelectionModel;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.EventListenerList;
 import javax.swing.event.ListSelectionEvent;
@@ -52,315 +52,361 @@
 import javax.swing.event.TableColumnModelEvent;
 import javax.swing.event.TableColumnModelListener;
 
+
 /**
  * DefaultTableColumnModel
  * @author	Andrew Selkirk
  * @version	1.0
  */
 public class DefaultTableColumnModel
-  implements TableColumnModel, PropertyChangeListener,
-             ListSelectionListener, Serializable
+  implements TableColumnModel, PropertyChangeListener, ListSelectionListener,
+             Serializable
 {
-  static final long serialVersionUID = 6580012493508960512L;
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * tableColumns
-	 */
-	protected Vector tableColumns;
-
-	/**
-	 * selectionModel
-	 */
-	protected ListSelectionModel selectionModel;
-
-	/**
-	 * columnMargin
-	 */
-	protected int columnMargin;
-
-	/**
-	 * listenerList
-	 */
-	protected EventListenerList listenerList;
-
-	/**
-	 * changeEvent
-	 */
-	protected transient ChangeEvent changeEvent;
-
-	/**
-	 * columnSelectionAllowed
-	 */
-	protected boolean columnSelectionAllowed;
-
-	/**
-	 * totalColumnWidth
-	 */
-	protected int totalColumnWidth;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultTableColumnModel
-	 */
-	public DefaultTableColumnModel() {
-		// TODO
-	} // DefaultTableColumnModel()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * addColumn
-	 * @param value0 TODO
-	 */
-	public void addColumn(TableColumn value0) {
-		// TODO
-	} // addColumn()
-
-	/**
-	 * removeColumn
-	 * @param value0 TODO
-	 */
-	public void removeColumn(TableColumn value0) {
-		// TODO
-	} // removeColumn()
-
-	/**
-	 * moveColumn
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void moveColumn(int value0, int value1) {
-		// TODO
-	} // moveColumn()
+  private static final long serialVersionUID = 6580012493508960512L;
 
-	/**
-	 * setColumnMargin
-	 * @param value0 TODO
-	 */
-	public void setColumnMargin(int value0) {
-		// TODO
-	} // setColumnMargin()
+  /**
+   * tableColumns
+   */
+  protected Vector tableColumns;
+
+  /**
+   * selectionModel
+   */
+  protected ListSelectionModel selectionModel;
+
+  /**
+   * columnMargin
+   */
+  protected int columnMargin;
+
+  /**
+   * listenerList
+   */
+  protected EventListenerList listenerList = new EventListenerList();
+
+  /**
+   * changeEvent
+   */
+  protected transient ChangeEvent changeEvent = new ChangeEvent(this);
+
+  /**
+   * columnSelectionAllowed
+   */
+  protected boolean columnSelectionAllowed;
+
+  /**
+   * totalColumnWidth
+   */
+  protected int totalColumnWidth;
+
+  /**
+   * Constructor DefaultTableColumnModel
+   */
+  public DefaultTableColumnModel()
+  {
+    tableColumns = new Vector();
+    setSelectionModel(new DefaultListSelectionModel());
+    columnMargin = 1;
+    columnSelectionAllowed = false;
+  }
+
+  /**
+   * addColumn
+   * @param value0 TODO
+   */
+  public void addColumn(TableColumn col)
+  {
+    tableColumns.add(col);
+    invalidateWidthCache();
+  }
+
+  /**
+   * removeColumn
+   * @param value0 TODO
+   */
+  public void removeColumn(TableColumn col)
+  {
+    tableColumns.remove(col);
+    invalidateWidthCache();
+  }
+
+  /**
+   * moveColumn
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void moveColumn(int i, int j)
+  {
+    Object tmp = tableColumns.get(i);
+    tableColumns.set(i, tableColumns.get(j));
+    tableColumns.set(j, tmp);
+  }
+
+  /**
+   * setColumnMargin
+   * @param value0 TODO
+   */
+  public void setColumnMargin(int m)
+  {
+    columnMargin = m;
+  }
 
 	/**
 	 * getColumnCount
-	 * @returns int
+   * @return int
 	 */
-	public int getColumnCount() {
-		return 0; // TODO
-	} // getColumnCount()
+  public int getColumnCount()
+  {
+    return tableColumns.size();
+  }
 
 	/**
 	 * getColumns
-	 * @returns Enumeration
+   * @return Enumeration
 	 */
-	public Enumeration getColumns() {
-		return null; // TODO
-	} // getColumns()
+  public Enumeration getColumns()
+  {
+    return tableColumns.elements();
+  }
 
 	/**
 	 * getColumnIndex
 	 * @param value0 TODO
-	 * @returns int
-	 */
-	public int getColumnIndex(Object value0) {
-		return 0; // TODO
-	} // getColumnIndex()
+   * @return int
+   */
+  public int getColumnIndex(Object obj)
+  {
+    return tableColumns.indexOf(obj, 0);
+  }
 
 	/**
 	 * getColumn
 	 * @param value0 TODO
-	 * @returns TableColumn
-	 */
-	public TableColumn getColumn(int value0) {
-		return null; // TODO
-	} // getColumn()
+   * @return TableColumn
+   */
+  public TableColumn getColumn(int i)
+  {
+    return (TableColumn) tableColumns.get(i);
+  }
 
 	/**
 	 * getColumnMargin
-	 * @returns int
+   * @return int
 	 */
-	public int getColumnMargin() {
-		return 0; // TODO
-	} // getColumnMargin()
+  public int getColumnMargin()
+  {
+    return columnMargin;
+  }
 
 	/**
 	 * getColumnIndexAtX
 	 * @param value0 TODO
-	 * @returns int
-	 */
-	public int getColumnIndexAtX(int value0) {
-		return 0; // TODO
-	} // getColumnIndexAtX()
+   * @return int
+   */
+  public int getColumnIndexAtX(int x)
+  {    
+    for (int i = 0; i < tableColumns.size(); ++i)
+      {
+        int w = ((TableColumn)tableColumns.get(i)).getWidth();
+        if (0 <= x && x < w)
+          return i;
+        else
+          x -= w;
+      }
+    return -1;
+  }
 
 	/**
 	 * getTotalColumnWidth
-	 * @returns int
+   * @return int
 	 */
-	public int getTotalColumnWidth() {
-		return 0; // TODO
-	} // getTotalColumnWidth()
-
-	/**
-	 * setSelectionModel
-	 * @param value0 TODO
-	 */
-	public void setSelectionModel(ListSelectionModel value0) {
-		// TODO
-	} // setSelectionModel()
+  public int getTotalColumnWidth()
+  {
+    if (totalColumnWidth == -1)
+      recalcWidthCache();
+    return totalColumnWidth;
+  }
+
+  /**
+   * setSelectionModel
+   * @param model TODO
+   * @exception IllegalArgumentException if model is null
+   */
+  public void setSelectionModel(ListSelectionModel model)
+  {
+    if (model == null)
+      throw new IllegalArgumentException();
+    
+    selectionModel = model;
+    selectionModel.addListSelectionListener(this);
+  }
 
 	/**
 	 * getSelectionModel
-	 * @returns ListSelectionModel
+   * @return ListSelectionModel
 	 */
-	public ListSelectionModel getSelectionModel() {
-		return null; // TODO
-	} // getSelectionModel()
-
-	/**
-	 * setColumnSelectionAllowed
-	 * @param value0 TODO
-	 */
-	public void setColumnSelectionAllowed(boolean value0) {
-		// TODO
-	} // setColumnSelectionAllowed()
+  public ListSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * setColumnSelectionAllowed
+   * @param value0 TODO
+   */
+  public void setColumnSelectionAllowed(boolean a)
+  {
+    columnSelectionAllowed = a;
+  }
 
 	/**
 	 * getColumnSelectionAllowed
-	 * @returns boolean
+   * @return boolean
 	 */
-	public boolean getColumnSelectionAllowed() {
-		return false; // TODO
-	} // getColumnSelectionAllowed()
+  public boolean getColumnSelectionAllowed()
+  {
+    return columnSelectionAllowed;
+  }
 
 	/**
 	 * getSelectedColumns
-	 * @returns int[]
+   * @return int[]
 	 */
-	public int[] getSelectedColumns() {
+  public int[] getSelectedColumns()
+  {
 		return null; // TODO
-	} // getSelectedColumns()
+  }
 
 	/**
 	 * getSelectedColumnCount
-	 * @returns int
+   * @return int
 	 */
-	public int getSelectedColumnCount() {
+  public int getSelectedColumnCount()
+  {
 		return 0; // TODO
-	} // getSelectedColumnCount()
+  }
 
-	/**
-	 * addColumnModelListener
-	 * @param value0 TODO
-	 */
-	public void addColumnModelListener(TableColumnModelListener value0) {
-		// TODO
-	} // addColumnModelListener()
+  /**
+   * addColumnModelListener
+   * @param value0 TODO
+   */
+  public void addColumnModelListener(TableColumnModelListener listener)
+  {
+    listenerList.add(TableColumnModelListener.class, listener);
+  }
 
 	/**
 	 * removeColumnModelListener
 	 * @param value0 TODO
 	 */
-	public void removeColumnModelListener(TableColumnModelListener value0) {
+  public void removeColumnModelListener(TableColumnModelListener value0)
+  {
 		// TODO
-	} // removeColumnModelListener()
+  }
 
 	/**
 	 * fireColumnAdded
 	 * @param value0 TODO
 	 */
-	protected void fireColumnAdded(TableColumnModelEvent value0) {
+  protected void fireColumnAdded(TableColumnModelEvent value0)
+  {
 		// TODO
-	} // fireColumnAdded()
+  }
 
 	/**
 	 * fireColumnRemoved
 	 * @param value0 TODO
 	 */
-	protected void fireColumnRemoved(TableColumnModelEvent value0) {
+  protected void fireColumnRemoved(TableColumnModelEvent value0)
+  {
 		// TODO
-	} // fireColumnRemoved()
+  }
 
 	/**
 	 * fireColumnMoved
 	 * @param value0 TODO
 	 */
-	protected void fireColumnMoved(TableColumnModelEvent value0) {
+  protected void fireColumnMoved(TableColumnModelEvent value0)
+  {
 		// TODO
-	} // fireColumnMoved()
+  }
 
-	/**
-	 * fireColumnSelectionChanged
-	 * @param value0 TODO
-	 */
-	protected void fireColumnSelectionChanged(ListSelectionEvent value0) {
-		// TODO
-	} // fireColumnSelectionChanged()
+  /**
+   * fireColumnSelectionChanged
+   * @param value0 TODO
+   */
+  protected void fireColumnSelectionChanged(ListSelectionEvent evt)
+  {
+    EventListener [] listeners = getListeners(TableColumnModelListener.class);
+    for (int i = 0; i < listeners.length; ++i)
+      ((TableColumnModelListener)listeners[i]).columnSelectionChanged(evt);
+  }
 
 	/**
 	 * fireColumnMarginChanged
 	 */
-	protected void fireColumnMarginChanged() {
+  protected void fireColumnMarginChanged()
+  {
 		// TODO
-	} // fireColumnMarginChanged()
+  }
 
 	/**
 	 * getListeners
 	 * @param value0 TODO
-	 * @returns EventListener[]
-	 */
-	public EventListener[] getListeners(Class value0) {
-		return null; // TODO
-	} // getListeners()
+   * @return EventListener[]
+   */
+  public EventListener[] getListeners(Class klass)
+  {
+    return listenerList.getListeners(klass);
+  }
 
 	/**
 	 * propertyChange
 	 * @param value0 TODO
 	 */
-	public void propertyChange(PropertyChangeEvent value0) {
+  public void propertyChange(PropertyChangeEvent value0)
+  {
 		// TODO
-	} // propertyChange()
+  }
 
 	/**
 	 * valueChanged
 	 * @param value0 TODO
 	 */
-	public void valueChanged(ListSelectionEvent value0) {
-		// TODO
-	} // valueChanged()
+  public void valueChanged(ListSelectionEvent value0)
+  {
+    fireColumnSelectionChanged(value0);
+  }
 
 	/**
 	 * createSelectionModel
-	 * @returns ListSelectionModel
+   * @return ListSelectionModel
 	 */
-	protected ListSelectionModel createSelectionModel() {
+  protected ListSelectionModel createSelectionModel()
+  {
 		return null; // TODO
-	} // createSelectionModel()
+  }
 
 	/**
 	 * recalcWidthCache
 	 */
-	protected void recalcWidthCache() {
-		// TODO
-	} // recalcWidthCache()
+  protected void recalcWidthCache()
+  {
+    if (totalColumnWidth == -1)
+      {
+        totalColumnWidth = 0;
+        for (int i = 0; i < tableColumns.size(); ++i)
+          {
+            totalColumnWidth += ((TableColumn)tableColumns.get(i)).getWidth();
+          }
+      }
+  }
 
 	/**
 	 * invalidateWidthCache
 	 */
-	private void invalidateWidthCache() {
-		// TODO
-	} // invalidateWidthCache()
-
-
-} // DefaultTableColumnModel
-
+  private void invalidateWidthCache()
+  {
+    totalColumnWidth = -1;
+  }
+}
Index: javax/swing/table/DefaultTableModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/DefaultTableModel.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultTableModel.java
--- javax/swing/table/DefaultTableModel.java	12 Oct 2003 13:33:31 -0000	1.4
+++ javax/swing/table/DefaultTableModel.java	6 Sep 2004 16:36:09 -0000
@@ -50,445 +50,387 @@
   implements Serializable
 {
   static final long serialVersionUID = 6680042567037222321L;
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * dataVector
-	 */
-	protected Vector dataVector;
-
-	/**
-	 * columnIdentifiers
-	 */
-	protected Vector columnIdentifiers;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultTableModel
-	 */
-	public DefaultTableModel() {
-		this(0, 0);
-	} // DefaultTableModel()
-
-	/**
-	 * Constructor DefaultTableModel
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public DefaultTableModel(int numRows, int numColumns) {
-
-		// Variables
-		int		columnIndex;
-		Vector		defaultNames;
-
-		// Create Column Names
-		defaultNames = new Vector();
-		for (columnIndex = 0; columnIndex < numColumns; columnIndex++) {
-			defaultNames.addElement(super.getColumnName(columnIndex));
-		} // for
-
-		// Setup Data
-//		setDataVector(defaultNames, numRows);
-
-	} // DefaultTableModel()
-
-	/**
-	 * Constructor DefaultTableModel
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public DefaultTableModel(Vector columnNames, int numRows) {
-
-		// Variables
-		Vector		data;
-		Vector		rowData;
-		int		rowIndex;
-		int		numColumns;
-
-		// Create Data
-		data = new Vector();
-		if (columnNames == null) {
-			numColumns = 0;
-		} else {
-			numColumns = columnNames.size();
-		} // if
-		for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
-			rowData = new Vector();
-			rowData.setSize(numColumns);
-			data.addElement(rowData);
-		} // for
-
-		// Setup Data
-		setDataVector(data, columnNames);
-
-	} // DefaultTableModel()
-
-	/**
-	 * Constructor DefaultTableModel
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public DefaultTableModel(Object[] columnNames, int numRows) {
-		this(convertToVector(columnNames), numRows);
-	} // DefaultTableModel()
-
-	/**
-	 * Constructor DefaultTableModel
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public DefaultTableModel(Vector data, Vector columnNames) {
-		setDataVector(data, columnNames);
-	} // DefaultTableModel()
-
-	/**
-	 * Constructor DefaultTableModel
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public DefaultTableModel(Object[][] data, Object[] columnNames) {
-		this(convertToVector(data), convertToVector(columnNames));
-	} // DefaultTableModel()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * getDataVector
-	 * @returns Vector
-	 */
-	public Vector getDataVector() {
-		return dataVector;
-	} // getDataVector()
-
-	/**
-	 * setDataVector
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void setDataVector(Vector data, Vector columnNames) {
-
-		// Variables
-		int	rowIndex;
-		int	numRows;
-		int	numColumns;
-		Vector	columnVector;
-
-		// Set Data
-		dataVector = data;
-		columnIdentifiers = columnNames;
-
-		// Check Data
-		numRows = data.size();
-		numColumns = columnNames.size();
-		for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
-			columnVector = (Vector) dataVector.get(rowIndex);
-			columnVector.setSize(numColumns);
-		} // for
-
-	} // setDataVector()
-
-	/**
-	 * setDataVector
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void setDataVector(Object[][] data, Object[] columnNames) {
-		setDataVector(convertToVector(data), convertToVector(columnNames));
-	} // setDataVector()
-
-	/**
-	 * newDataAvailable
-	 * @param value0 TODO
-	 */
-	public void newDataAvailable(TableModelEvent event) {
-		fireTableChanged(event);
-	} // newDataAvailable()
-
-	/**
-	 * newRowsAdded
-	 * @param value0 TODO
-	 */
-	public void newRowsAdded(TableModelEvent event) {
-		// TODO
-	} // newRowsAdded()
-
-	/**
-	 * rowsRemoved
-	 * @param value0 TODO
-	 */
-	public void rowsRemoved(TableModelEvent event) {
-		fireTableChanged(event);
-	} // rowsRemoved()
-
-	/**
-	 * setColumnIdentifiers
-	 * @param value0 TODO
-	 */
-	public void setColumnIdentifiers(Vector columnIdentifiers) {
-		this.columnIdentifiers = columnIdentifiers;
-		setColumnCount(columnIdentifiers.size());
-	} // setColumnIdentifiers()
-
-	/**
-	 * setColumnIdentifiers
-	 * @param value0 TODO
-	 */
-	public void setColumnIdentifiers(Object[] columnIdentifiers) {
-		setColumnIdentifiers(convertToVector(columnIdentifiers));
-	} // setColumnIdentifiers()
-
-	/**
-	 * setNumRows
-	 * @param value0 TODO
-	 */
-	public void setNumRows(int numRows) {
-		setRowCount(numRows);
-	} // setNumRows()
-
-	/**
-	 * setRowCount
-	 * @param value0 TODO
-	 */
-	public void setRowCount(int rowCount) {
-		// TODO
-	} // setRowCount()
-
-	/**
-	 * setColumnCount
-	 * @param value0 TODO
-	 */
-	public void setColumnCount(int columnCount) {
-		// TODO
-	} // setColumnCount()
-
-	/**
-	 * addColumn
-	 * @param value0 TODO
-	 */
-	public void addColumn(Object columnName) {
-		addColumn(columnName, new Vector(dataVector.size()));
-	} // addColumn()
-
-	/**
-	 * addColumn
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void addColumn(Object columnName, Vector columnData) {
-		// TODO
-	} // addColumn()
-
-	/**
-	 * addColumn
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void addColumn(Object columnName, Object[] columnData) {
-		// TODO
-	} // addColumn()
-
-	/**
-	 * addRow
-	 * @param value0 TODO
-	 */
-	public void addRow(Vector rowData) {
-		// TODO
-	} // addRow()
-
-	/**
-	 * addRow
-	 * @param value0 TODO
-	 */
-	public void addRow(Object[] rowData) {
-		addRow(convertToVector(rowData));
-	} // addRow()
-
-	/**
-	 * insertRow
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void insertRow(int row, Vector rowData) {
-		dataVector.add(row, rowData);
-	} // insertRow()
-
-	/**
-	 * insertRow
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	public void insertRow(int row, Object[] rowData) {
-		insertRow(row, convertToVector(rowData));
-	} // insertRow()
-
-	/**
-	 * moveRow
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @param value2 TODO
-	 */
-	public void moveRow(int startIndex, int endIndex, int toIndex) {
-
-		// Variables
-		int		index;
-		Vector	vector;
-
-		// Move Rows
-		for (index = 0; index < (endIndex - startIndex); index++) {
-			vector = (Vector) dataVector.remove(startIndex);
-			dataVector.add(toIndex, vector);
-		} // for
-
-	} // moveRow()
-
-	/**
-	 * removeRow
-	 * @param value0 TODO
-	 */
-	public void removeRow(int row) {
-		dataVector.remove(row);
-	} // removeRow()
-
-	/**
-	 * getRowCount
-	 * @returns int
-	 */
-	public int getRowCount() {
-		return dataVector.size();
-	} // getRowCount()
-
-	/**
-	 * getColumnCount
-	 * @returns int
-	 */
-	public int getColumnCount() {
-		return columnIdentifiers.size();
-	} // getColumnCount()
-
-	/**
-	 * getColumnName
-	 * @param value0 TODO
-	 * @returns String
-	 */
-	public String getColumnName(int column) {
-
-		// Check for Column
-		if (columnIdentifiers == null || column >= getColumnCount()) {
-			return super.getColumnName(column);
-		} // if
-
-		// Return Column name
-		return (String) columnIdentifiers.get(column);
-
-	} // getColumnName()
-
-	/**
-	 * isCellEditable
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @returns boolean
-	 */
-	public boolean isCellEditable(int row, int column) {
-		return true;
-	} // isCellEditable()
-
-	/**
-	 * getValueAt
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @returns Object
-	 */
-	public Object getValueAt(int row, int column) {
-
-		// Variables
-		Vector	rowVector;
-
-		// Get Row Vector
-		rowVector = (Vector) dataVector.get(row);
-
-		// Get Data
-		return rowVector.get(column);
-
-	} // getValueAt()
-
-	/**
-	 * setValueAt
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 * @param value2 TODO
-	 */
-	public void setValueAt(Object value, int row, int column) {
-
-		// Variables
-		Vector	rowVector;
-
-		// Get Row Vector
-		rowVector = (Vector) dataVector.get(row);
-
-		// Set Data
-		rowVector.remove(column);
-		rowVector.add(column, value);
-
-	} // setValueAt()
-
-	/**
-	 * convertToVector
-	 * @param value0 TODO
-	 * @returns Vector
-	 */
-	protected static Vector convertToVector(Object[] data) {
-
-		// Variables
-		int	index;
-		Vector	vector;
-
-		// Check for null
-		if (data == null) {
-			return null;
-		} // if
-
-		// Process
-		vector = new Vector();
-		for (index = 0; index < data.length; index++) {
-			vector.add(data[index]);
-		} // for: index
-
-		// Return new Vector
-		return vector;
-
-	} // convertToVector()
-
-	/**
-	 * convertToVector
-	 * @param value0 TODO
-	 * @returns Vector
-	 */
-	protected static Vector convertToVector(Object[][] data) {
-
-		// Variables
-		int	index;
-		Vector	vector;
-
-		// Process
-		vector = new Vector();
-		for (index = 0; index < data.length; index++) {
-			vector.add(convertToVector(data[index]));
-		} // for: index
-
-		// Return new Vector
-		return vector;
-
-	} // convertToVector()
-
-
-} // DefaultTableModel
+  /**
+   * dataVector
+   */
+  protected Vector dataVector;
+
+  /**
+   * columnIdentifiers
+   */
+  protected Vector columnIdentifiers;
+
+  /**
+   * Constructor DefaultTableModel
+   */
+  public DefaultTableModel() 
+  {
+    this(0, 0);
+  }
+  
+  /**
+   * Constructor DefaultTableModel
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public DefaultTableModel(int numRows, int numColumns) 
+  {
+    Vector defaultNames = new Vector(numColumns);
+    Vector data = new Vector(numRows);
+    for (int i = 0; i < numColumns; i++) 
+      {
+        defaultNames.add(super.getColumnName(i));
+        Vector tmp = new Vector(numColumns);
+        tmp.setSize(numColumns);
+        data.add(tmp);
+      }          
+    setDataVector(defaultNames, data);
+  }
+  
+  /**
+   * Constructor DefaultTableModel
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public DefaultTableModel(Vector columnNames, int numRows) 
+  {
+    Vector data = new Vector();
+    int numColumns = 0;
+
+    if (columnNames != null)
+      numColumns = columnNames.size();
+    
+    while (0 < numRows--) 
+      {
+        Vector rowData = new Vector();
+        rowData.setSize(numColumns);
+        data.add(rowData);
+      }
+    setDataVector(data, columnNames);
+  }
+
+  /**
+   * Constructor DefaultTableModel
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public DefaultTableModel(Object[] columnNames, int numRows) 
+  {
+    this(convertToVector(columnNames), numRows);
+  }
+  
+  /**
+   * Constructor DefaultTableModel
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public DefaultTableModel(Vector data, Vector columnNames) 
+  {
+    setDataVector(data, columnNames);
+  }
+
+  /**
+   * Constructor DefaultTableModel
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public DefaultTableModel(Object[][] data, Object[] columnNames) 
+  {
+    this(convertToVector(data), convertToVector(columnNames));
+  }
+
+  /**
+   * getDataVector
+   * @returns Vector
+   */
+  public Vector getDataVector() 
+  {
+    return dataVector;
+  }
+
+  /**
+   * setDataVector
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void setDataVector(Vector data, Vector columnNames) 
+  {
+    dataVector = data;
+    columnIdentifiers = columnNames;
+    for (int r = 0; r < data.size(); r++) {
+      ((Vector) dataVector.get(r)).setSize(columnNames.size());
+    }          
+  }
+
+  /**
+   * setDataVector
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void setDataVector(Object[][] data, Object[] columnNames) 
+  {
+    setDataVector(convertToVector(data), 
+                  convertToVector(columnNames));
+  }
+  
+  /**
+   * newDataAvailable
+   * @param value0 TODO
+   */
+  public void newDataAvailable(TableModelEvent event) 
+  {
+    fireTableChanged(event);
+  }
+
+  /**
+   * newRowsAdded
+   * @param value0 TODO
+   */
+  public void newRowsAdded(TableModelEvent event) 
+  {
+    fireTableChanged(event);
+  }
+
+  /**
+   * rowsRemoved
+   * @param value0 TODO
+   */
+  public void rowsRemoved(TableModelEvent event) 
+  {
+    fireTableChanged(event);
+  }
+
+  /**
+   * setColumnIdentifiers
+   * @param value0 TODO
+   */
+  public void setColumnIdentifiers(Vector columnIdentifiers) 
+  {
+    this.columnIdentifiers = columnIdentifiers;
+    setColumnCount(columnIdentifiers.size());
+  }
+  
+  /**
+   * setColumnIdentifiers
+   * @param value0 TODO
+   */
+  public void setColumnIdentifiers(Object[] columnIdentifiers) 
+  {
+    setColumnIdentifiers(convertToVector(columnIdentifiers));
+  }
+
+  /**
+   * setNumRows
+   * @param value0 TODO
+   */
+  public void setNumRows(int numRows) 
+  {
+    setRowCount(numRows);
+  }
+
+  /**
+   * setRowCount
+   * @param value0 TODO
+   */
+  public void setRowCount(int rowCount) 
+  {
+    dataVector.setSize(rowCount);
+    fireTableDataChanged();
+  }
+
+  /**
+   * setColumnCount
+   * @param value0 TODO
+   */
+  public void setColumnCount(int columnCount) 
+  {
+    for (int i = 0; i < dataVector.size(); ++i)
+      {
+        ((Vector) dataVector.get(i)).setSize(columnCount);
+      }
+    columnIdentifiers.setSize(columnCount);
+    fireTableDataChanged();
+  }
+
+  /**
+   * addColumn
+   * @param value0 TODO
+   */
+  public void addColumn(Object columnName) 
+  {
+    addColumn(columnName, (Object[]) null);
+  }
+
+  /**
+   * addColumn
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void addColumn(Object columnName, Vector columnData) 
+  {
+    addColumn(columnName, columnData == null ? null : columnData.toArray());
+  }
+
+  /**
+   * addColumn
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void addColumn(Object columnName, Object[] columnData) {
+    for (int i = 0; i < dataVector.size(); ++i)
+      {
+        ((Vector) dataVector.get(i)).add(columnData == null ? null : columnData[i]);
+      }
+    columnIdentifiers.add(columnName);
+    fireTableDataChanged();
+  }
+
+  /**
+   * addRow
+   * @param value0 TODO
+   */
+  public void addRow(Vector rowData) {
+    dataVector.add(rowData);
+    fireTableDataChanged();
+  }
+
+  /**
+   * addRow
+   * @param value0 TODO
+   */
+  public void addRow(Object[] rowData) {
+    addRow(convertToVector(rowData));
+  }
+
+  /**
+   * insertRow
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void insertRow(int row, Vector rowData) {
+    dataVector.add(row, rowData);
+    fireTableDataChanged();
+  }
+
+  /**
+   * insertRow
+   * @param value0 TODO
+   * @param value1 TODO
+   */
+  public void insertRow(int row, Object[] rowData) {
+    insertRow(row, convertToVector(rowData));
+  }
+
+  /**
+   * moveRow
+   * @param value0 TODO
+   * @param value1 TODO
+   * @param value2 TODO
+   */
+  public void moveRow(int startIndex, int endIndex, int toIndex) {
+    for (int index = 0; index < (endIndex - startIndex); index++) {
+      Vector vector = (Vector) dataVector.remove(startIndex);
+      dataVector.add(toIndex, vector);
+    }
+    fireTableDataChanged();
+  }
+
+  /**
+   * removeRow
+   * @param value0 TODO
+   */
+  public void removeRow(int row) {
+    dataVector.remove(row);
+    fireTableDataChanged();
+  }
+
+  /**
+   * getRowCount
+   * @returns int
+   */
+  public int getRowCount() {
+    return dataVector.size();
+  }
+
+  /**
+   * getColumnCount
+   * @returns int
+   */
+  public int getColumnCount() {
+    return columnIdentifiers.size();
+  }
+
+  /**
+   * getColumnName
+   * @param value0 TODO
+   * @returns String
+   */
+  public String getColumnName(int column) {
+    // Check for Column
+    if (columnIdentifiers == null || column >= getColumnCount()) {
+      return super.getColumnName(column);
+    }
+          
+    // Return Column name
+    return (String) columnIdentifiers.get(column);          
+  }
+
+  /**
+   * isCellEditable
+   * @param value0 TODO
+   * @param value1 TODO
+   * @returns boolean
+   */
+  public boolean isCellEditable(int row, int column) {
+    return true;
+  }
+
+  /**
+   * getValueAt
+   * @param value0 TODO
+   * @param value1 TODO
+   * @returns Object
+   */
+  public Object getValueAt(int row, int column) {
+    return ((Vector) dataVector.get(row)).get(column);
+  }
+
+  /**
+   * setValueAt
+   * @param value0 TODO
+   * @param value1 TODO
+   * @param value2 TODO
+   */
+  public void setValueAt(Object value, int row, int column) {
+    ((Vector) dataVector.get(row)).set(column, value);
+    fireTableDataChanged();
+  }
+
+  /**
+   * convertToVector
+   * @param value0 TODO
+   * @returns Vector
+   */
+  protected static Vector convertToVector(Object[] data) {
+    if (data == null)
+      return null;
+    Vector vector = new Vector(data.length);
+    for (int i = 0; i < data.length; i++) 
+      vector.add(data[i]);
+    return vector;          
+  }
+  
+  /**
+   * convertToVector
+   * @param value0 TODO
+   * @returns Vector
+   */
+  protected static Vector convertToVector(Object[][] data) {
+    if (data == null)
+      return null;
+    Vector vector = new Vector(data.length);
+    for (int i = 0; i < data.length; i++)
+      vector.add(convertToVector(data[i]));
+    return vector;
+  }
+}
Index: javax/swing/table/JTableHeader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/JTableHeader.java,v
retrieving revision 1.1
diff -u -r1.1 JTableHeader.java
--- javax/swing/table/JTableHeader.java	11 Jun 2003 16:36:11 -0000	1.1
+++ javax/swing/table/JTableHeader.java	6 Sep 2004 16:36:09 -0000
@@ -1,5 +1,5 @@
 /* JTableHeader.java
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,6 +38,8 @@
 
 package javax.swing.table;
 
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
 import java.awt.Color;
 import java.awt.Cursor;
 import java.awt.Dimension;
@@ -45,38 +47,527 @@
 import java.awt.FontMetrics;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.event.FocusListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.util.Locale;
+
 import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
 import javax.accessibility.AccessibleComponent;
 import javax.accessibility.AccessibleContext;
-import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
 import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleText;
+import javax.accessibility.AccessibleValue;
 import javax.swing.JComponent;
 import javax.swing.JTable;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.TableColumnModelEvent;
-import javax.swing.event.TableColumnModelListener;
+import javax.swing.UIManager;
 import javax.swing.plaf.TableHeaderUI;
 
-public class JTableHeader
+public class JTableHeader extends JComponent
 {
-  protected class AccessibleJTableHeader
+  protected class AccessibleJTableHeader extends AccessibleJComponent
   {
-    protected class AccessibleJTableHeaderEntry
+    protected class AccessibleJTableHeaderEntry extends AccessibleContext
+      implements Accessible, AccessibleComponent
     {
-    }
+      public void addFocusListener(FocusListener l)
+      {
+        throw new Error("not implemented");
+      }
+      public void addPropertyChangeListener(PropertyChangeListener l)
+      {
+        throw new Error("not implemented");
+      }
+      public boolean contains(Point p)
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleAction getAccessibleAction()
+      {
+        throw new Error("not implemented");
+      }
+      public Accessible getAccessibleAt(Point p)
+      {
+        throw new Error("not implemented");
+      }
+      public Accessible getAccessibleChild(int i)
+      {
+        throw new Error("not implemented");
+      }
+      public int getAccessibleChildrenCount()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleComponent getAccessibleComponent()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleContext getAccessibleContext()
+      {
+        throw new Error("not implemented");
+      }
+      public String getAccessibleDescription()
+      {
+        throw new Error("not implemented");
+      }
+      public int getAccessibleIndexInParent()
+      {
+        throw new Error("not implemented");
+      }
+      public String getAccessibleName()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleRole getAccessibleRole()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleSelection getAccessibleSelection()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleStateSet getAccessibleStateSet()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleText getAccessibleText()
+      {
+        throw new Error("not implemented");
+      }
+      public AccessibleValue getAccessibleValue()
+      {
+        throw new Error("not implemented");
+      }
+      public Color getBackground()
+      {
+        throw new Error("not implemented");
+      }
+      public Rectangle getBounds()
+      {
+        throw new Error("not implemented");
+      }
+      public Cursor getCursor()
+      {
+        throw new Error("not implemented");
+      }
+      public Font getFont()
+      {
+        throw new Error("not implemented");
+      }
+      public FontMetrics getFontMetrics(Font f)
+      {
+        throw new Error("not implemented");
+      }
+      public Color getForeground()
+      {
+        throw new Error("not implemented");
+      }
+      public Locale getLocale()
+      {
+        throw new Error("not implemented");
+      }
+      public Point getLocation()
+      {
+        throw new Error("not implemented");
+      }
+      public Point getLocationOnScreen()
+      {
+        throw new Error("not implemented");
+      }
+      public Dimension getSize()
+      {
+        throw new Error("not implemented");
+      }
+      public boolean isEnabled()
+      {
+        throw new Error("not implemented");
+      }
+      public boolean isFocusTraversable()
+      {
+        throw new Error("not implemented");
+      }
+      public boolean isShowing()
+      {
+        throw new Error("not implemented");
+      }
+      public boolean isVisible()
+      {
+        throw new Error("not implemented");
+      }
+      public void removeFocusListener(FocusListener l)
+      {
+        throw new Error("not implemented");
+      }
+      public void removePropertyChangeListener(PropertyChangeListener l)
+      {
+        throw new Error("not implemented");
+      }
+      public void requestFocus()
+      {
+        throw new Error("not implemented");
+      }
+      public void setAccessibleDescription(String s)
+      {
+        throw new Error("not implemented");
+      }
+      public void setAccessibleName(String s)
+      {
+        throw new Error("not implemented");
+      }
+      public void setBackground(Color c)
+      {
+        throw new Error("not implemented");
+      }
+      public void setBounds(Rectangle r)
+      {
+        throw new Error("not implemented");
+      }
+      public void setCursor(Cursor c)
+      {
+        throw new Error("not implemented");
+      }
+      public void setEnabled(boolean b)
+      {
+        throw new Error("not implemented");
+      }
+      public void setFont(Font f)
+      {
+        throw new Error("not implemented");
+      }
+      public void setForeground(Color c)
+      {
+        throw new Error("not implemented");
+      }
+      public void setLocation(Point p)
+      {
+        throw new Error("not implemented");
+      }
+      public void setSize(Dimension d)
+      {
+        throw new Error("not implemented");
+      }
+      public void setVisible(boolean b)
+      {
+        throw new Error("not implemented");
+      }
+    };
   }
 
   private static final long serialVersionUID = 5144633983372967710L;
 
-  protected TableColumnModel columnModel;
-  protected TableColumn draggedColumn;
-  protected int draggedDistance;
-  protected boolean reorderingAllowed;
-  protected boolean resizingAllowed;
-  protected TableColumn resizingColumn;
-  protected JTable table;
-  protected boolean updateTableInRealTime;
+  /**
+   * The accessibleContext property.
+   */
+  AccessibleContext accessibleContext;
+
+  /**
+   * The columnModel property.
+   */
+  TableColumnModel columnModel;
+
+  /**
+   * The draggedColumn property.
+   */
+  TableColumn draggedColumn;
+
+  /**
+   * The draggedDistance property.
+   */
+  int draggedDistance;
+
+  /**
+   * The opaque property.
+   */
+  boolean opaque;
+
+  /**
+   * The reorderingAllowed property.
+   */
+  boolean reorderingAllowed;
+
+  /**
+   * The resizingAllowed property.
+   */
+  boolean resizingAllowed;
+
+  /**
+   * The resizingColumn property.
+   */
+  TableColumn resizingColumn;
+
+  /**
+   * The table property.
+   */
+  JTable table;
+
+  /**
+   * The updateTableInRealTime property.
+   */
+  boolean updateTableInRealTime;
+
+  TableCellRenderer cellRenderer; 
+
+  public JTableHeader()
+  {
+    this(null);
+  }
+
+  public JTableHeader(TableColumnModel cm)
+  {
+    accessibleContext = new AccessibleJTableHeader();
+    columnModel = cm == null ? createDefaultTableColumnModel() : cm; 
+    draggedColumn = null;
+    draggedDistance = 0;
+    opaque = true;
+    reorderingAllowed = true;
+    resizingAllowed = true;
+    resizingColumn = null;
+    table = null;
+    updateTableInRealTime = true;
+    cellRenderer = createDefaultRenderer();
+    updateUI();
+  }
+
+  protected TableColumnModel createDefaultTableColumnModel()
+  {
+    return new DefaultTableColumnModel();
+  }
+
+
+  /**
+   * Get the value of the {@link #accessibleContext} property.
+   *
+   * @return The current value of the property
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return accessibleContext;
+  }
+
+  /**
+   * Get the value of the {@link #columnModel} property.
+   *
+   * @return The current value of the property
+   */
+  public TableColumnModel getColumnModel()
+  {
+    return columnModel;
+  }
+
+  /**
+   * Get the value of the {@link #draggedColumn} property.
+   *
+   * @return The current value of the property
+   */
+  public TableColumn getDraggedColumn()
+  {
+    return draggedColumn;
+  }
+
+  /**
+   * Get the value of the {@link #draggedDistance} property.
+   *
+   * @return The current value of the property
+   */
+  public int getDraggedDistance()
+  {
+    return draggedDistance;
+  }
+
+  /**
+   * Get the value of the {@link #reorderingAllowed} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getReorderingAllowed()
+  {
+    return reorderingAllowed;
+  }
+
+  /**
+   * Get the value of the {@link #resizingAllowed} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getResizingAllowed()
+  {
+    return resizingAllowed;
+  }
+
+  /**
+   * Get the value of the {@link #resizingColumn} property.
+   *
+   * @return The current value of the property
+   */
+  public TableColumn getResizingColumn()
+  {
+    return resizingColumn;
+  }
+
+  /**
+   * Get the value of the {@link #table} property.
+   *
+   * @return The current value of the property
+   */
+  public JTable getTable()
+  {
+    return table;
+  }
+
+  /**
+   * Get the value of the {@link #updateTableInRealTime} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getUpdateTableInRealTime()
+  {
+    return updateTableInRealTime;
+  }
+
+  /**
+   * Get the value of the {@link #opaque} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean isOpaque()
+  {
+    return opaque;
+  }
+
+  /**
+   * Set the value of the {@link #columnModel} property.
+   *
+   * @param c The new value of the property
+   */ 
+  public void setColumnModel(TableColumnModel c)
+  {
+    columnModel = c;
+  }
+
+  /**
+   * Set the value of the {@link #draggedColumn} property.
+   *
+   * @param d The new value of the property
+   */ 
+  public void setDraggedColumn(TableColumn d)
+  {
+    draggedColumn = d;
+  }
+
+  /**
+   * Set the value of the {@link #draggedDistance} property.
+   *
+   * @param d The new value of the property
+   */ 
+  public void setDraggedDistance(int d)
+  {
+    draggedDistance = d;
+  }
+
+  /**
+   * Set the value of the {@link #opaque} property.
+   *
+   * @param o The new value of the property
+   */ 
+  public void setOpaque(boolean o)
+  {
+    opaque = o;
+  }
+
+  /**
+   * Set the value of the {@link #reorderingAllowed} property.
+   *
+   * @param r The new value of the property
+   */ 
+  public void setReorderingAllowed(boolean r)
+  {
+    reorderingAllowed = r;
+  }
+
+  /**
+   * Set the value of the {@link #resizingAllowed} property.
+   *
+   * @param r The new value of the property
+   */ 
+  public void setResizingAllowed(boolean r)
+  {
+    resizingAllowed = r;
+  }
+
+  /**
+   * Set the value of the {@link #resizingColumn} property.
+   *
+   * @param r The new value of the property
+   */ 
+  public void setResizingColumn(TableColumn r)
+  {
+    resizingColumn = r;
+  }
+
+  /**
+   * Set the value of the {@link #table} property.
+   *
+   * @param t The new value of the property
+   */ 
+  public void setTable(JTable t)
+  {
+    table = t;
+  }
+
+  /**
+   * Set the value of the {@link #updateTableInRealTime} property.
+   *
+   * @param u The new value of the property
+   */ 
+  public void setUpdateTableInRealTime(boolean u)
+  {
+    updateTableInRealTime = u;
+  }
+
+  protected TableCellRenderer createDefaultRenderer()
+  {
+    return new DefaultTableCellRenderer();
+  }
+
+  public TableCellRenderer getDefaultRenderer()
+  {
+    return cellRenderer;
+  }
+
+  public Rectangle getHeaderRect(int column)
+  {
+    Rectangle r = getTable().getCellRect(-1, column, true);
+    r.height = getHeight();
+    return r;
+  }
+
+  protected String paramString()
+  {
+    return "JTableHeader";
+  }
+
+  // UI support
+
+  public String getUIClassID()
+  {
+    return "TableHeaderUI";
+  }
+
+  public TableHeaderUI getUI()
+  {
+    return (TableHeaderUI) ui;
+  }
+
+  public void setUI(TableHeaderUI u)
+  {
+    super.setUI(u);
+  }
+
+  public void updateUI()
+  {
+    setUI((TableHeaderUI) UIManager.getUI(this));
+  }
+
 }
Index: javax/swing/table/TableColumn.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/TableColumn.java,v
retrieving revision 1.3
diff -u -r1.3 TableColumn.java
--- javax/swing/table/TableColumn.java	11 Jun 2003 13:20:41 -0000	1.3
+++ javax/swing/table/TableColumn.java	6 Sep 2004 16:36:09 -0000
@@ -35,26 +35,23 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing.table;
 
 import java.beans.PropertyChangeListener;
 import java.io.Serializable;
 import javax.swing.event.SwingPropertyChangeSupport;
 
+
 /**
  * TableColumn
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public class TableColumn implements Serializable
+public class TableColumn
+  implements Serializable
 {
   static final long serialVersionUID = -6113660025878112608L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * COLUMN_WIDTH_PROPERTY
 	 */
@@ -138,36 +135,35 @@
 	/**
 	 * changeSupport
 	 */
-	private SwingPropertyChangeSupport changeSupport = new SwingPropertyChangeSupport(this);
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
+  private SwingPropertyChangeSupport changeSupport =
+    new SwingPropertyChangeSupport(this);
 
 	/**
 	 * Constructor TableColumn
 	 */
-	public TableColumn() {
+  public TableColumn()
+  {
 		this(0, 75, null, null);
-	} // TableColumn()
+  }
 
 	/**
 	 * Constructor TableColumn
 	 * @param modelIndex TODO
 	 */
-	public TableColumn(int modelIndex) {
+  public TableColumn(int modelIndex)
+  {
 		this(modelIndex, 75, null, null);
-	} // TableColumn()
+  }
 
 	/**
 	 * Constructor TableColumn
 	 * @param modelIndex TODO
 	 * @param width TODO
 	 */
-	public TableColumn(int modelIndex, int width) {
+  public TableColumn(int modelIndex, int width)
+  {
 		this(modelIndex, width, null, null);
-	} // TableColumn()
+  }
 
 	/**
 	 * Constructor TableColumn
@@ -177,7 +173,8 @@
 	 * @param cellEditor TODO
 	 */
 	public TableColumn(int modelIndex, int width,
-			TableCellRenderer cellRenderer, TableCellEditor cellEditor) {
+                     TableCellRenderer cellRenderer, TableCellEditor cellEditor)
+  {
 		this.modelIndex = modelIndex;
 		this.width = width;
 		this.preferredWidth = width;
@@ -185,12 +182,7 @@
 		this.cellEditor = cellEditor;
 		this.headerValue = null;
 		this.identifier = null;
-	} // TableColumn()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  }
 
 	/**
 	 * firePropertyChange
@@ -198,9 +190,11 @@
 	 * @param oldValue TODO
 	 * @param newValue TODO
 	 */
-	private void firePropertyChange(String property, Object oldValue, Object newValue) {
+  private void firePropertyChange(String property, Object oldValue,
+                                  Object newValue)
+  {
 		changeSupport.firePropertyChange(property, oldValue, newValue);
-	} // firePropertyChange()
+  }
 
 	/**
 	 * firePropertyChange
@@ -208,9 +202,10 @@
 	 * @param oldValue TODO
 	 * @param newValue TODO
 	 */
-	private void firePropertyChange(String property, int oldValue, int newValue) {
+  private void firePropertyChange(String property, int oldValue, int newValue)
+  {
 		firePropertyChange(property, new Integer(oldValue), new Integer(newValue));
-	} // firePropertyChange()
+  }
 
 	/**
 	 * firePropertyChange
@@ -218,51 +213,56 @@
 	 * @param oldValue TODO
 	 * @param newValue TODO
 	 */
-	private void firePropertyChange(String property, boolean oldValue, boolean newValue) {
+  private void firePropertyChange(String property, boolean oldValue,
+                                  boolean newValue)
+	{
 		firePropertyChange(property, new Boolean(oldValue), new Boolean(newValue));
-	} // firePropertyChange()
+	}
 
 	/**
 	 * setModelIndex
 	 * @param modelIndex TODO
 	 */
-	public void setModelIndex(int modelIndex) {
+  public void setModelIndex(int modelIndex)
+  {
 		this.modelIndex = modelIndex;
-	} // setModelIndex()
+  }
 
 	/**
 	 * getModelIndex
-	 * @returns int
+   * @return int
 	 */
-	public int getModelIndex() {
+  public int getModelIndex()
+  {
 		return modelIndex;
-	} // getModelIndex()
+  }
 
 	/**
 	 * setIdentifier
 	 * @param identifier TODO
 	 */
-	public void setIdentifier(Object identifier) {
+  public void setIdentifier(Object identifier)
+  {
 		this.identifier = identifier;
-	} // setIdentifier()
+  }
 
 	/**
 	 * getIdentifier
-	 * @returns Object
+   * @return Object
 	 */
-	public Object getIdentifier() {
-		if (identifier == null) {
+  public Object getIdentifier()
+  {
+    if (identifier == null)
 			return getHeaderValue();
-		} // if
 		return identifier;
-	} // getIdentifier()
+  }
 
 	/**
 	 * setHeaderValue
 	 * @param headerValue TODO
 	 */
-	public void setHeaderValue(Object headerValue) {
-
+  public void setHeaderValue(Object headerValue)
+  {
 		// Variables
 		Object	oldValue;
 
@@ -273,245 +273,243 @@
 		this.headerValue = headerValue;
 
 		// Notify Listeners of change
-		firePropertyChange(HEADER_VALUE_PROPERTY, 
-				oldValue, headerValue);
-
-	} // setHeaderValue()
+    firePropertyChange(HEADER_VALUE_PROPERTY, oldValue, headerValue);
+  }
 
 	/**
 	 * getHeaderValue
-	 * @returns Object
+   * @return Object
 	 */
-	public Object getHeaderValue() {
+  public Object getHeaderValue()
+  {
 		return headerValue;
-	} // getHeaderValue()
+  }
 
-	/**
-	 * setHeaderRenderer
-	 * @param headerRenderer TODO
-	 */
-	public void setHeaderRenderer(TableCellRenderer headerRenderer) {
-
-		// Variables
-		TableCellRenderer	oldRenderer;
-
-		// Get Old Renderer
-		oldRenderer = this.headerRenderer;
-
-		// Set Property
-		this.headerRenderer = headerRenderer;
-
-		// Notify Listeners of change
-		firePropertyChange(HEADER_RENDERER_PROPERTY, 
-				oldRenderer, headerRenderer);
-
-	} // setHeaderRenderer()
+  /**
+   * setHeaderRenderer
+   * @param headerRenderer TODO
+   */
+  public void setHeaderRenderer(TableCellRenderer renderer)
+  {
+    if (headerRenderer == renderer)
+      return;
+    
+    TableCellRenderer oldRenderer = headerRenderer;
+    headerRenderer = renderer;
+    firePropertyChange(HEADER_RENDERER_PROPERTY, 
+		       oldRenderer, headerRenderer);
+  }
 
 	/**
 	 * getHeaderRenderer
-	 * @returns TableCellRenderer
+   * @return TableCellRenderer
 	 */
-	public TableCellRenderer getHeaderRenderer() {
+  public TableCellRenderer getHeaderRenderer()
+  {
 		return headerRenderer;
-	} // getHeaderRenderer()
-
-	/**
-	 * setCellRenderer
-	 * @param cellRenderer TODO
-	 */
-	public void setCellRenderer(TableCellRenderer cellRenderer) {
-
-		// Variables
-		TableCellRenderer	oldRenderer;
-
-		// Get Old Renderer
-		oldRenderer = this.cellRenderer;
-
-		// Set Property
-		this.cellRenderer = cellRenderer;
-
-		// Notify Listeners of change
-		firePropertyChange(CELL_RENDERER_PROPERTY, 
-				oldRenderer, cellRenderer);
+  }
 
-	} // setCellRenderer()
+  /**
+   * setCellRenderer
+   * @param cellRenderer TODO
+   */
+  public void setCellRenderer(TableCellRenderer renderer)
+  {
+    if (cellRenderer == renderer)
+      return;
+    
+    TableCellRenderer oldRenderer = cellRenderer;
+    cellRenderer = renderer;
+    firePropertyChange(CELL_RENDERER_PROPERTY, 
+		       oldRenderer, cellRenderer);
+  }
 
 	/**
 	 * getCellRenderer
-	 * @returns TableCellRenderer
+   * @return TableCellRenderer
 	 */
-	public TableCellRenderer getCellRenderer() {
+  public TableCellRenderer getCellRenderer()
+  {
 		return cellRenderer;
-	} // getCellRenderer()
+  }
 
 	/**
 	 * setCellEditor
 	 * @param cellEditor TODO
 	 */
-	public void setCellEditor(TableCellEditor cellEditor) {
+  public void setCellEditor(TableCellEditor cellEditor)
+  {
 		this.cellEditor = cellEditor;
-	} // setCellEditor()
+  }
 
 	/**
 	 * getCellEditor
-	 * @returns TableCellEditor
+   * @return TableCellEditor
 	 */
-	public TableCellEditor getCellEditor() {
+  public TableCellEditor getCellEditor()
+  {
 		return cellEditor;
-	} // getCellEditor()
+  }
 
-	/**
-	 * setWidth
-	 * @param width TODO
-	 */
-	public void setWidth(int width) {
-
-		// Variables
-		int	oldWidth;
+  /**
+   * setWidth
+   * @param newWidth TODO
+   */
+  public void setWidth(int newWidth)
+  {
+    int	oldWidth = width;
+
+    if (newWidth < minWidth)
+      width = minWidth;
+    else if (newWidth > maxWidth)
+      width = maxWidth;
+    else
+      width = newWidth;
 
-		// Get Old Width
-		oldWidth = this.width;
+    if (width == oldWidth)
+      return;
 
-		// Adjust Width within Limits
-		if (width < minWidth) {
-			this.width = minWidth;
-		} else if (width > maxWidth) {
-			this.width = maxWidth;
-		} else {
-			this.width = width;
-		} // if
-
-		// Fire Property Change
-		firePropertyChange(COLUMN_WIDTH_PROPERTY, oldWidth, this.width);
-
-	} // setWidth()
+    firePropertyChange(COLUMN_WIDTH_PROPERTY, oldWidth, width);
+  }
 
 	/**
 	 * getWidth
-	 * @returns int
+   * @return int
 	 */
-	public int getWidth() {
+  public int getWidth()
+  {
 		return width;
-	} // getWidth()
+  }
 
 	/**
 	 * setPreferredWidth
 	 * @param preferredWidth TODO
 	 */
-	public void setPreferredWidth(int preferredWidth) {
-		if (preferredWidth < minWidth) {
+  public void setPreferredWidth(int preferredWidth)
+  {
+    if (preferredWidth < minWidth)
 			this.preferredWidth = minWidth;
-		} else if (preferredWidth > maxWidth) {
+    else if (preferredWidth > maxWidth)
 			this.preferredWidth = maxWidth;
-		} else {
+    else
 			this.preferredWidth = preferredWidth;
-		} // if
-	} // setPreferredWidth()
+  }
 
 	/**
 	 * getPreferredWidth
-	 * @returns int
+   * @return int
 	 */
-	public int getPreferredWidth() {
+  public int getPreferredWidth()
+  {
 		return preferredWidth;
-	} // getPreferredWidth()
+  }
 
 	/**
 	 * setMinWidth
 	 * @param minWidth TODO
 	 */
-	public void setMinWidth(int minWidth) {
+  public void setMinWidth(int minWidth)
+  {
 		this.minWidth = minWidth;
 		setWidth(getWidth());
 		setPreferredWidth(getPreferredWidth());
-	} // setMinWidth()
+  }
 
 	/**
 	 * getMinWidth
-	 * @returns int
+   * @return int
 	 */
-	public int getMinWidth() {
+  public int getMinWidth()
+  {
 		return minWidth;
-	} // getMinWidth()
+  }
 
 	/**
 	 * setMaxWidth
 	 * @param maxWidth TODO
 	 */
-	public void setMaxWidth(int maxWidth) {
+  public void setMaxWidth(int maxWidth)
+  {
 		this.maxWidth = maxWidth;
 		setWidth(getWidth());
 		setPreferredWidth(getPreferredWidth());
-	} // setMaxWidth()
+  }
 
 	/**
 	 * getMaxWidth
-	 * @returns int
+   * @return int
 	 */
-	public int getMaxWidth() {
+  public int getMaxWidth()
+  {
 		return maxWidth;
-	} // getMaxWidth()
+  }
 
 	/**
 	 * setResizable
 	 * @param isResizable TODO
 	 */
-	public void setResizable(boolean isResizable) {
+  public void setResizable(boolean isResizable)
+  {
 		this.isResizable = isResizable;
-	} // setResizable()
+  }
 
 	/**
 	 * getResizable
-	 * @returns boolean
+   * @return boolean
 	 */
-	public boolean getResizable() {
+  public boolean getResizable()
+  {
 		return isResizable;
-	} // getResizable()
+  }
 
 	/**
 	 * sizeWidthToFit
 	 */
-	public void sizeWidthToFit() {
+  public void sizeWidthToFit()
+  {
 		// TODO
-	} // sizeWidthToFit()
+  }
 
 	/**
 	 * disableResizedPosting
 	 */
-	public void disableResizedPosting() {
+  public void disableResizedPosting()
+  {
 		// Does nothing
-	} // disableResizedPosting()
+  }
 
 	/**
 	 * enableResizedPosting
 	 */
-	public void enableResizedPosting() {
+  public void enableResizedPosting()
+  {
 		// Does nothing
-	} // enableResizedPosting()
+  }
 
 	/**
 	 * addPropertyChangeListener
-	 * @param listener TODO
+   * @param listener the listener to all
 	 */
-	public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+  public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
+  {
 		changeSupport.addPropertyChangeListener(listener);
-	} // addPropertyChangeListener()
+  }
 
 	/**
 	 * removePropertyChangeListener
-	 * @param listener TODO
+   * @param listener the listener to remove
 	 */
-	public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+  public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
+  {
 		changeSupport.removePropertyChangeListener(listener);
-	} // removePropertyChangeListener()
+  }
 
 	/**
 	 * createDefaultHeaderRenderer
-	 * @returns TableCellRenderer
+   * @return TableCellRenderer
 	 */
-	protected TableCellRenderer createDefaultHeaderRenderer() {
+  protected TableCellRenderer createDefaultHeaderRenderer()
+  {
 		return new DefaultTableCellRenderer();
-	} // createDefaultHeaderRenderer()
-
-
-} // TableColumn
+  }
+}
Index: javax/swing/table/TableColumnModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/TableColumnModel.java,v
retrieving revision 1.2
diff -u -r1.2 TableColumnModel.java
--- javax/swing/table/TableColumnModel.java	12 Oct 2003 13:33:31 -0000	1.2
+++ javax/swing/table/TableColumnModel.java	6 Sep 2004 16:36:09 -0000
@@ -37,17 +37,17 @@
 
 package javax.swing.table;
 
-// Imports
 import java.util.Enumeration;
 import javax.swing.ListSelectionModel;
 import javax.swing.event.TableColumnModelListener;
 
+
 /**
  * TableColumnModel public interface
  * @author Andrew Selkirk
  */
-public interface TableColumnModel {
-
+public interface TableColumnModel
+{
 	/**
 	 * addColumn
 	 * @param column TableColumn
@@ -75,13 +75,13 @@
 
 	/**
 	 * getColumnCount
-	 * @returns Column count
+   * @return Column count
 	 */
 	int getColumnCount();
 
 	/**
 	 * getColumns
-	 * @returns Enumeration of columns
+   * @return Enumeration of columns
 	 */
 	Enumeration getColumns();
 
@@ -99,19 +99,19 @@
 
 	/**
 	 * getColumnMargin
-	 * @returns Column margin
+   * @return Column margin
 	 */
 	int getColumnMargin();
 
 	/**
 	 * getColumnIndexAtX
-	 * @returns Column index as position x
+   * @return Column index as position x
 	 */
 	int getColumnIndexAtX(int xPosition);
 
 	/**
 	 * getTotalColumnWidth
-	 * @returns Total column width
+   * @return Total column width
 	 */
 	int getTotalColumnWidth();
 
@@ -123,19 +123,19 @@
 
 	/**
 	 * getColumnSelectionAllowed
-	 * @returns true if column selection allowed, false otherwise
+   * @return true if column selection allowed, false otherwise
 	 */
 	boolean getColumnSelectionAllowed();
 
 	/**
 	 * getSelectedColumns
-	 * @returns Selected columns
+   * @return Selected columns
 	 */
 	int[] getSelectedColumns();
 
 	/**
 	 * getSelectedColumnCount
-	 * @returns Count of selected columns
+   * @return Count of selected columns
 	 */
 	int getSelectedColumnCount();
 
@@ -162,6 +162,4 @@
 	 * @param listener TableColumnModelListener
 	 */
 	void removeColumnModelListener(TableColumnModelListener listener);
-
-
-} // TableColumnModel
+}
Index: javax/swing/table/TableModel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/table/TableModel.java,v
retrieving revision 1.2
diff -u -r1.2 TableModel.java
--- javax/swing/table/TableModel.java	12 Oct 2003 13:33:31 -0000	1.2
+++ javax/swing/table/TableModel.java	6 Sep 2004 16:36:09 -0000
@@ -37,38 +37,38 @@
 
 package javax.swing.table;
 
-// Imports
 import javax.swing.event.TableModelListener;
 
+
 /**
  * TableModel public interface
  * @author Andrew Selkirk
  */
-public interface TableModel {
-
+public interface TableModel
+{
 	/**
 	 * getRowCount
-	 * @returns row count
+   * @return row count
 	 */
 	int getRowCount();
 
 	/**
 	 * getColumnCount
-	 * @returns column count
+   * @return column count
 	 */
 	int getColumnCount();
 
 	/**
 	 * getColumnName
 	 * @param columnIndex Column index
-	 * @returns Column name
+   * @return Column name
 	 */
 	String getColumnName(int columnIndex);
 
 	/**
 	 * getColumnClass
 	 * @param columnIndex Column index
-	 * @returns Column class
+   * @return Column class
 	 */
 	Class getColumnClass(int columnIndex);
 
@@ -76,7 +76,7 @@
 	 * isCellEditable
 	 * @param rowIndex Row index
 	 * @param columnIndex Column index
-	 * @returns true if editable, false otherwise
+   * @return true if editable, false otherwise
 	 */
 	boolean isCellEditable(int rowIndex, int columnIndex);
 
@@ -84,7 +84,7 @@
 	 * getValueAt
 	 * @param rowIndex Row index
 	 * @param columnIndex Column index
-	 * @returns Value at specified indices
+   * @return Value at specified indices
 	 */
 	Object getValueAt(int rowIndex, int columnIndex);
 
@@ -107,6 +107,4 @@
 	 * @param listener TableModelListener
 	 */
 	void removeTableModelListener(TableModelListener listener);
-
-
-} // TableModel
+}
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.3
diff -u -r1.3 AbstractDocument.java
--- javax/swing/text/AbstractDocument.java	10 Jan 2004 21:07:44 -0000	1.3
+++ javax/swing/text/AbstractDocument.java	6 Sep 2004 16:36:09 -0000
@@ -1,4 +1,4 @@
-/* AbstractDocument.java -- 
+/* AbstractDocument.java --
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -37,6 +37,8 @@
 
 package javax.swing.text;
 
+import java.io.Serializable;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.EventListener;
@@ -47,321 +49,776 @@
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.event.UndoableEditListener;
 import javax.swing.tree.TreeNode;
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CompoundEdit;
 import javax.swing.undo.UndoableEdit;
 
-public abstract class AbstractDocument implements Document
+
+public abstract class AbstractDocument
+  implements Document, Serializable
 {
-    Vector doc_list = new Vector();
-    Vector undo_list = new Vector();
+  private static final long serialVersionUID = -116069779446114664L;
+  protected static final String BAD_LOCATION = "document location failure";
+  public static final String BidiElementName = "bidi level";
+  public static final String ContentElementName = "content";
+  public static final String ParagraphElementName = "paragraph";
+  public static final String SectionElementName = "section";
+  public static final String ElementNameAttribute = "$ename";
+
+  Content content;
+  AttributeContext context;
+  protected EventListenerList listenerList = new EventListenerList();
+
+  protected AbstractDocument(Content doc)
+  {
+    this(doc, StyleContext.getDefaultStyleContext());
+  }
+
+  protected AbstractDocument(Content doc, AttributeContext ctx)
+  {
+    content = doc;
+    context = ctx;
+  }
+
+  // These still need to be implemented by a derived class:
+  public abstract Element getParagraphElement(int pos);
+
+  public abstract Element getDefaultRootElement();
+
+  protected Element createBranchElement(Element parent,
+					AttributeSet attributes)
+  {
+    return new BranchElement(parent, attributes);
+  }
+
+  protected Element createLeafElement(Element parent, AttributeSet attributes,
+				      int start, int end)
+  {
+    return new LeafElement(parent, attributes, start, end);
+  }
+
+  public Position createPosition(final int offset) throws BadLocationException
+  {
+    if (offset < 0 || offset > getLength())
+      throw new BadLocationException(getText(0, getLength()), offset);
+
+    return new Position()
+      {
+	public int getOffset()
+	{
+	  return offset;
+	}
+      };
+  }
 
-    // these still need to be implemented by a derived class:
-    public abstract  Element getParagraphElement(int pos);
-    public abstract  Element getDefaultRootElement();
-
-    // some inner classes sun says I should have:
-    abstract class AbstractElement implements Element, TreeNode
-    {
-	int count, offset;
-	AttributeSet attr;
-	Vector elts = new Vector();
-	String name;
-	Element parent;
-	Vector kids = new Vector();
-	TreeNode tree_parent;
-	
-	public AbstractElement(Element p, AttributeSet s)
-	{ parent = p; attr = s; }
-
-	public Enumeration children()         { return kids.elements(); }
-	public boolean getAllowsChildren()    { return true; }
-	public TreeNode getChildAt(int index) { return (TreeNode) kids.elementAt(index); }
-	public int getChildCount()            { return kids.size(); }
-	public int getIndex(TreeNode  node)   { return kids.indexOf(node); }
-	public TreeNode getParent()           { return tree_parent; }
-
-	public AttributeSet getAttributes()      { return attr; }
-	public Document getDocument()            { return AbstractDocument.this; }
-	public Element getElement(int index)     { return (Element)elts.elementAt(index); }
-	public String getName()                  { return name; }
-	public Element getParentElement()        { return parent; }
-
-	public abstract boolean isLeaf();
-	public abstract int getEndOffset();
-	public abstract int getElementCount();
-	public abstract int getElementIndex(int offset);
-	public abstract int getStartOffset();
+  protected void fireChangedUpdate(DocumentEvent event)
+  {
+    DocumentListener[] listeners = getDocumentListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].changedUpdate(event);
+  }
+
+  protected void fireInsertUpdate(DocumentEvent event)
+  {
+    DocumentListener[] listeners = getDocumentListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].insertUpdate(event);
+  }
+
+  protected void fireRemoveUpdate(DocumentEvent event)
+  {
+    DocumentListener[] listeners = getDocumentListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].removeUpdate(event);
+  }
+
+  protected void fireUndoableEditUpdate(UndoableEditEvent event)
+  {
+    UndoableEditListener[] listeners = getUndoableEditListeners();
+    
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].undoableEditHappened(event);
+  }
+
+  public int getAsynchronousLoadPriority()
+  {
+    return 0;
+  }
+
+  protected AttributeContext getAttributeContext()
+  {
+    return context;
+  }
+
+  public Element getBidiRootElement()
+  {
+    return null;
+  }
+
+  protected Content getContent()
+  {
+    return content;
+  }
+
+  protected Thread getCurrentWriter()
+  {
+    return null;
+  }
+
+  public Dictionary getDocumentProperties()
+  {
+    return null;
+  }
+
+  public Position getEndPosition()
+  {
+    return new Position() 
+      {        
+        public int getOffset() 
+        { 
+          return getLength(); 
+        } 
+      };
+  }
+
+  public int getLength()
+  {
+    return content.length();
+  }
+
+  public EventListener[] getListeners(Class listenerType)
+  {
+    return listenerList.getListeners(listenerType);
+  }
+
+  public Object getProperty(Object key)
+  {
+    return null;
+  }
+
+  public Element[] getRootElements()
+  {
+    Element[] elements = new Element[1];
+    elements[0] = getDefaultRootElement();
+    return elements;
+  }
+
+  public Position getStartPosition()
+  {
+    return new Position() 
+      {        
+        public int getOffset() 
+        { 
+          return 0; 
+        } 
+      };
+  }
+
+  public String getText(int offset, int length) throws BadLocationException
+      {
+	return content.getString(offset, length);
+      }
+
+  public void getText(int offset, int length, Segment segment)
+    throws BadLocationException
+  {
+    content.getChars(offset, length, segment);
+  }
+
+  public void insertString(int offset, String text, AttributeSet attributes)
+    throws BadLocationException
+  {
+    // Just return when no text to insert was given.
+    if (text == null || text.length() == 0)
+      return;
+    
+    DefaultDocumentEvent event =
+      new DefaultDocumentEvent(offset, text.length(),
+			       DocumentEvent.EventType.INSERT);
+    content.insertString(offset, text);
+    insertUpdate(event, attributes);
+    fireInsertUpdate(event);
+  }
+
+  protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
+  {
+  }
+
+  protected void postRemoveUpdate(DefaultDocumentEvent chng)
+  {
+  }
+
+  public void putProperty(Object key, Object value)
+  {
+  }
+
+  public void readLock()
+  {
+  }
+
+  public void readUnlock()
+  {
+  }
+
+  public void remove(int offset, int length) throws BadLocationException
+  {
+    DefaultDocumentEvent event =
+      new DefaultDocumentEvent(offset, length,
+			       DocumentEvent.EventType.REMOVE);
+    removeUpdate(event);
+    content.remove(offset, length);
+    postRemoveUpdate(event);
+    fireRemoveUpdate(event);
+  }
+
+  /**
+   * Replaces some text in the document.
+   *
+   * @since 1.4
+   */
+  public void replace(int offset, int length, String text,
+		      AttributeSet attributes)
+    throws BadLocationException
+  {
+    remove(offset, length);
+    insertString(offset, text, attributes);
+  }
+
+  /**
+   * Adds a <code>DocumentListener</code> object to this document.
+   *
+   * @param listener the listener to add
+   */
+  public void addDocumentListener(DocumentListener listener)
+  {
+    listenerList.add(DocumentListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>DocumentListener</code> object from this document.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeDocumentListener(DocumentListener listener)
+  {
+    listenerList.remove(DocumentListener.class, listener);
+  }
+
+  /**
+   * Returns add added <code>DocumentListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public DocumentListener[] getDocumentListeners()
+  {
+    return (DocumentListener[]) getListeners(DocumentListener.class);
+  }
+
+  /**
+   * Adds a <code>UndoableEditListener</code> object to this document.
+   *
+   * @param listener the listener to add
+   */
+  public void addUndoableEditListener(UndoableEditListener listener)
+  {
+    listenerList.add(UndoableEditListener.class, listener);
+  }
+
+  /**
+   * Removes a <code>UndoableEditListener</code> object from this document.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeUndoableEditListener(UndoableEditListener listener)
+  {
+    listenerList.remove(UndoableEditListener.class, listener);
+  }
+
+  /**
+   * Returns add added <code>UndoableEditListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public UndoableEditListener[] getUndoableEditListeners()
+  {
+    return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
+  }
+
+  protected void removeUpdate(DefaultDocumentEvent chng)
+  {
+  }
+
+  public void render(Runnable r)
+  {
+  }
+
+  public void setAsynchronousLoadPriority(int p)
+  {
+  }
+
+  public void setDocumentProperties(Dictionary x)
+  {
+  }
+
+  protected void writeLock()
+  {
+  }
+
+  protected void writeUnlock()
+  {
+  }
+
+  public interface AttributeContext
+  {
+    AttributeSet addAttribute(AttributeSet old, Object name, Object value);
+
+    AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
+
+    AttributeSet getEmptySet();
+
+    void reclaim(AttributeSet attributes);
+
+    AttributeSet removeAttribute(AttributeSet old, Object name);
+
+    AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
+
+    AttributeSet removeAttributes(AttributeSet old, Enumeration names);
+  }
+
+  public interface Content
+  {
+    Position createPosition(int offset) throws BadLocationException;
+
+    int length();
+
+    UndoableEdit insertString(int where, String str)
+      throws BadLocationException;
+
+    UndoableEdit remove(int where, int nitems) throws BadLocationException;
+
+    String getString(int where, int len) throws BadLocationException;
+
+    void getChars(int where, int len, Segment txt) throws BadLocationException;
+  }
+
+  public abstract class AbstractElement
+    implements Element, MutableAttributeSet, TreeNode, Serializable
+  {
+    private static final long serialVersionUID = 1265312733007397733L;
+    int count;
+    int offset;
+
+    AttributeSet attributes;
+
+    Element element_parent;
+    Vector element_children;
+
+    TreeNode tree_parent;
+    Vector tree_children;
+
+    public AbstractElement(Element p, AttributeSet s)
+    {
+      element_parent = p;
+      attributes = s;
     }
 
-    interface AttributeContext
+    // TreeNode implementation
+
+    public Enumeration children()
+    {
+      return Collections.enumeration(tree_children);
+    }
+      
+    public boolean getAllowsChildren()
+    {
+      return true;
+    }
+      
+    public TreeNode getChildAt(int index)
     {
+      return (TreeNode) tree_children.get(index);
+    }
+      
+    public int getChildCount()
+    {
+      return tree_children.size();
+    }
+      
+    public int getIndex(TreeNode node)
+    {
+      return tree_children.indexOf(node);
     }
 
-    
-    class BranchElement extends AbstractElement
+    public TreeNode getParent()
     {
-	public BranchElement(Element e, AttributeSet a, int s, int end)
-	{  super(e, a);	}
+      return tree_parent;
+    }
 
-	public boolean isLeaf() { return false; }
-	public int getEndOffset() {  return 0; }
-	public int getElementCount() { return 0; }
-	public int getElementIndex(int offset) { return 0; }
-	public int getStartOffset() { return 0; }
+    public abstract boolean isLeaf();
+
+
+    // MutableAttributeSet support
+
+    public void addAttribute(Object name, Object value)
+    {
+      attributes = getAttributeContext().addAttribute(attributes, name, value);
     }
-    
-    interface Content
+
+    public void addAttributes(AttributeSet attrs)
     {
-        Position createPosition(int offset) throws BadLocationException;
-        int length();
-        UndoableEdit insertString(int where, String str) throws BadLocationException;
-        UndoableEdit remove(int where, int nitems) throws BadLocationException;	
-        String getString(int where, int len) throws BadLocationException;
-        void getChars(int where, int len, Segment txt) throws BadLocationException;
+      attributes = getAttributeContext().addAttributes(attributes, attrs);
     }
-    
-    class DefaultDocumentEvent implements DocumentEvent
+
+    public void removeAttribute(Object name)
     {
-	public int len, off;
-	public Document getDocument() { return AbstractDocument.this; }
-	public int getLength() { return len; }
-	public int getOffset() { return off; }
-	public DocumentEvent.EventType getType()  	              { return null; }
-	public DocumentEvent.ElementChange getChange(Element  elem)  { return null; }
+      attributes = getAttributeContext().removeAttribute(attributes, name);
     }
-    
-    static class ElementEdit
+
+    public void removeAttributes(AttributeSet attrs)
     {
-    }    
-    
-    class LeafElement extends AbstractElement
+      attributes = getAttributeContext().removeAttributes(attributes, attrs);
+    }
+
+    public void removeAttributes(Enumeration names)
+    {
+      attributes = getAttributeContext().removeAttributes(attributes, names);
+    }
+
+    public void setResolveParent(AttributeSet parent)
     {
-	LeafElement(Element e, AttributeSet a, int s, int end)
-	{  super(e, a);	}
+      attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
+    }
+
+
+    // AttributeSet interface support
 
-	public boolean isLeaf() { return true; }
-	public int getEndOffset() {  return 0; }
-	public int getElementCount() { return 0; }
-	public int getElementIndex(int offset) { return 0; }
-	public int getStartOffset() { return 0; }
+    public boolean containsAttribute(Object name, Object value)
+    {
+      return attributes.containsAttribute(name, value);
     }
-  
 
-    Content content;
+    public boolean containsAttributes(AttributeSet attrs)
+    {
+      return attributes.containsAttributes(attrs);
+    }
 
-    AbstractDocument(Content doc)
+    public AttributeSet copyAttributes()
     {
-	content = doc;
+      return attributes.copyAttributes();
     }
-    
-    /********************************************************
-     *
-     *  the meat:
-     *
-     ***********/
-    
 
-    public void addDocumentListener(DocumentListener listener)
+    public Object getAttribute(Object key)
     {
-	doc_list.addElement(listener);
+      return attributes.getAttribute(key);
     }
-  
-    public void addUndoableEditListener(UndoableEditListener listener)
+
+    public int getAttributeCount()
     {
-	undo_list.addElement(listener);
+      return attributes.getAttributeCount();
     }
- 
-    protected  Element createBranchElement(Element parent, AttributeSet a)
-    {	
-	return new BranchElement(parent, a, 0, 0);
+      
+    public Enumeration getAttributeNames()
+    {
+      return attributes.getAttributeNames();
     }
- 
-    protected  Element createLeafElement(Element parent, AttributeSet a, int p0, int p1)
+      
+    public AttributeSet getResolveParent()
     {
-	return new LeafElement(parent, a, p0, p1-p0);
+      return attributes.getResolveParent();
     }
 
-    public Position createPosition(int offs)
+    public boolean isDefined(Object attrName)
     {
-	final int a = offs;
-	return new Position() 
-	    {
-		public int getOffset()
-		{
-		    return a; 
-		}
-	    };
+      return attributes.isDefined(attrName);
     }
-  
-    protected void fireChangedUpdate(DocumentEvent e)
+      
+    public boolean isEqual(AttributeSet attrs) 
     {
+      return attributes.isEqual(attrs);
     }
- 
-    protected  void fireInsertUpdate(DocumentEvent e)
+
+    // Element interface support
+
+    public AttributeSet getAttributes()
     {
+      return attributes;
     }
- 
-    protected  void fireRemoveUpdate(DocumentEvent e)
+
+    public Document getDocument()
     {
+      return AbstractDocument.this;
     }
- 
-    protected  void fireUndoableEditUpdate(UndoableEditEvent e)
+      
+    public Element getElement(int index)
     {
+      return (Element) element_children.get(index);
     }
-    int getAsynchronousLoadPriority()
+      
+    public String getName()
     {
-	return 0;
+      return (String) getAttribute(NameAttribute);
     }
- 
-    protected  AttributeContext getAttributeContext()
+      
+    public Element getParentElement()
     {
-	return null;
+      return element_parent;
     }
+      
+    public abstract int getEndOffset();
+      
+    public abstract int getElementCount();
+      
+    public abstract int getElementIndex(int offset);
+      
+    public abstract int getStartOffset();
+  }
+
+  public class BranchElement extends AbstractElement
+  {
+    private static final long serialVersionUID = -8595176318868717313L;
     
-    Element getBidiRootElement()
+    private Vector children = new Vector();
+
+    public BranchElement(Element parent, AttributeSet attributes)
     {
-	return null;
+      super(parent, attributes);
+    }
+
+    public Enumeration children()
+    {
+      return children.elements();
     }
- 
-    protected Content getContent()
+
+    public boolean getAllowsChildren()
     {
-	return content;
+      return true;
     }
- 
-    protected  Thread getCurrentWriter()
+
+    public Element getElement(int index)
     {
+      if (index < 0 || index >= children.size())
 	return null;
+
+      return (Element) children.get(index);
     }
 
+    public int getElementCount()
+    {
+      return children.size();
+    }
 
-    public Dictionary getDocumentProperties()
+    public int getElementIndex(int offset)
     {
-	return null;
+      if (children.size() == 0)
+	return 0;
+      
+      Element element = positionToElement(offset);
+
+      if (element == null)
+	return 0;
+      
+      return children.indexOf(element);
     }
 
-    public Position getEndPosition()
+    public int getEndOffset()
     {
-	return null;
+      return ((Element) children.lastElement()).getEndOffset();
     }
 
-    public int getLength()
+    public String getName()
     {
-	return content.length();
+      return "AbstractDocument.BranchElement";
     }
-    
-    public EventListener[] getListeners(Class listenerType)
+
+    public int getStartOffset()
     {
-	return null;
+      return ((Element) children.firstElement()).getStartOffset();
     }
-    
-    public Object getProperty(Object key)
+
+    public boolean isLeaf()
     {
-	return null;
+      return false;
     }
 
-    public Element[] getRootElements()
+    public Element positionToElement(int position)
     {
-	return null;
+      // XXX: There is surely a better algorithm
+      // as beginning from first element each time.
+      for (int index = 0; index < children.size(); ++index)
+        {
+	  Element elem = (Element) children.get(index);
+
+	  if ((elem.getStartOffset() <= position)
+	      && (position < elem.getEndOffset()))
+	    return elem;
+        }
+
+      return null;
+    }
+
+    public void replace(int offset, int length, Element[] elems)
+    {
+      for (int index = 0; index < length; ++index)
+	children.removeElementAt(offset);
+
+      for (int index = 0; index < elems.length; ++index)
+	children.add(offset + index, elems[index]);
+    }
+
+    public String toString()
+    {
+      return getName() + ": " + "content";
     }
+  }
+
+  public class DefaultDocumentEvent extends CompoundEdit
+    implements DocumentEvent
+  {
+    private static final long serialVersionUID = -7406103236022413522L;
     
-    public Position getStartPosition()
+    private int offset;
+    private int length;
+    private DocumentEvent.EventType type;
+
+    public DefaultDocumentEvent(int offset, int length,
+				DocumentEvent.EventType type)
     {
-	return null;
+      this.offset = offset;
+      this.length = length;
+      this.type = type;
     }
 
-    public String getText(int offset, int length)
+    public Document getDocument()
     {
-	try {
-	    return content.getString(offset, length);
-	} catch (Exception e) {
-	    System.out.println("Hmmm, fail to getText: " + offset + " -> " + length);
-	    return null;
-	}
+      return AbstractDocument.this;
+    }
+
+    public int getLength()
+    {
+      return length;
     }
-  
-    public void getText(int offset, int length, Segment txt)
+
+    public int getOffset()
     {
-	String a = getText(offset, length);
+      return offset;
+    }
 
-	if (a == null)
-	    {
-		txt.offset = 0;
-		txt.count = 0;
-		txt.array  = new char[0];
-		return;
-	    }
-
-	txt.offset = offset;
-	txt.count  = length;
-
-	char chars[] = new char[ a.length() ];
-	
-	a.getChars(0, a.length(), chars, 0);
-	
-	txt.array  = chars;	
-    }
-  
-    public void insertString(int offs, String str, AttributeSet a)
-    {
-	try {
-	    content.insertString(offs, str);	
-	} catch (Exception e) {
-	    System.err.println("FAILED TO INSERT-STRING: " + e + ", at:"+offs);
-	}
+    public DocumentEvent.EventType getType()
+    {
+      return type;
     }
- 
-    protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
+
+    public DocumentEvent.ElementChange getChange(Element elem)
     {
+      return null;
     }
- 
-    protected  void postRemoveUpdate(DefaultDocumentEvent chng)
+  }
+
+  public static class ElementEdit extends AbstractUndoableEdit
+    implements DocumentEvent.ElementChange
+  {
+    private static final long serialVersionUID = -1216620962142928304L;
+
+    private Element elem;
+    private int index;
+    private Element[] removed;
+    private Element[] added;
+    
+    public ElementEdit(Element elem, int index,
+		       Element[] removed, Element[] added)
     {
+      this.elem = elem;
+      this.index = index;
+      this.removed = removed;
+      this.added = added;
     }
-  
-    public void putProperty(Object key, Object value)
+
+    public Element[] getChildrenAdded()
     {
+      return added;
     }
-  
-    public void readLock()
+    
+    public Element[] getChildrenRemoved()
     {
+      return removed;
     }
-  
-    public void readUnlock()
+
+    public Element getElement()
     {
+      return elem;
     }
-  
-    public void remove(int offs, int len)
+
+    public int getIndex()
     {
+      return index;
     }
-  
-    public void removeDocumentListener(DocumentListener listener)
+  }
+
+  public class LeafElement extends AbstractElement
+  {
+    private static final long serialVersionUID = 5115368706941283802L;
+    private int start;
+    private int end;
+
+    public LeafElement(Element parent, AttributeSet attributes, int start,
+                       int end)
     {
+      super(parent, attributes);
+      this.start = start;
+      this.end = end;
     }
-  
-    public void removeUndoableEditListener(UndoableEditListener listener)
+
+    public Enumeration children()
     {
+      return null;
     }
- 
-    protected void removeUpdate(DefaultDocumentEvent chng)
+
+    public boolean getAllowsChildren()
     {
+      return false;
     }
-  
-    public void render(Runnable r)
+
+    public Element getElement()
     {
+      return null;
     }
-      
-    void setAsynchronousLoadPriority(int p)
+
+    public int getElementCount()
+    {
+      return 0;
+    }
+
+    public int getElementIndex(int offset)
+    {
+      return -1;
+    }
+
+    public int getEndOffset()
+    {
+      return end;
+    }
+
+    public String getName()
     {
+      return "AbstractDocument.LeafElement";
     }
-  
-    void setDocumentProperties(Dictionary x)
+
+    public int getStartOffset()
     {
+      return start;
     }
- 
-    protected  void writeLock()
+
+    public boolean isLeaf()
     {
+      return true;
     }
- 
-    protected  void writeUnlock()
+
+    public String toString()
     {
+      return getName() + ": " + "content";
     }
+  }
 }
Index: javax/swing/text/AttributeSet.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/AttributeSet.java,v
retrieving revision 1.2
diff -u -r1.2 AttributeSet.java
--- javax/swing/text/AttributeSet.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/AttributeSet.java	6 Sep 2004 16:36:09 -0000
@@ -41,13 +41,32 @@
 
 public interface AttributeSet
 { 
-    boolean containsAttribute(Object name, Object value);
-    boolean containsAttributes(AttributeSet attributes);
-    AttributeSet copyAttributes();
-    Object getAttribute(Object key);
-    int getAttributeCount();
-    Enumeration getAttributeNames();
-    AttributeSet getResolveParent();
-    boolean isDefined(Object attrName);
-    boolean isEqual(AttributeSet attr);     
+  static interface CharacterAttribute
+  {
+  }
+
+  static interface ColorAttribute
+  {
+  }
+
+  static interface FontAttribute
+  {
+  }
+
+  static interface ParagraphAttribute
+  {
+  }
+
+  static Object NameAttribute = StyleConstants.NameAttribute;
+  static Object ResolveAttribute = StyleConstants.ResolveAttribute;
+
+  boolean containsAttribute(Object name, Object value);
+  boolean containsAttributes(AttributeSet attributes);
+  AttributeSet copyAttributes();
+  Object getAttribute(Object key);
+  int getAttributeCount();
+  Enumeration getAttributeNames();
+  AttributeSet getResolveParent();
+  boolean isDefined(Object attrName);
+  boolean isEqual(AttributeSet attr);     
 }
Index: javax/swing/text/BadLocationException.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/BadLocationException.java,v
retrieving revision 1.2
diff -u -r1.2 BadLocationException.java
--- javax/swing/text/BadLocationException.java	21 Mar 2003 09:18:31 -0000	1.2
+++ javax/swing/text/BadLocationException.java	6 Sep 2004 16:36:09 -0000
@@ -1,5 +1,5 @@
-/* BadLocationException.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* BadLocationException.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,27 +37,28 @@
 
 package javax.swing.text;
 
-
 public class BadLocationException extends Exception
-{    
-  int offset;
+{
+  private static final long serialVersionUID = -7712259886815656766L;
   
+  int offset;
+
   /**
    * Constructs a <code>BadLocationException</code>
    *
    * @param str A string indicating what was wrong with the arguments
    * @param offset Offset within the document that was requested &gt;= 0
    */
-  public BadLocationException (String str, int offset)
+  public BadLocationException(String str, int offset)
   {
-    super (str);
+    super(str);
     this.offset = offset;
   }
 
   /**
    * Returns the offset into the document that was not legal
    */
-  public int offsetRequested ()
+  public int offsetRequested()
   {
     return offset;
   }
Index: javax/swing/text/CharacterIterator.java
===================================================================
RCS file: javax/swing/text/CharacterIterator.java
diff -N javax/swing/text/CharacterIterator.java
--- javax/swing/text/CharacterIterator.java	9 Aug 2002 04:26:12 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,53 +0,0 @@
-/* CharacterIterator.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package javax.swing.text;
-
-
-public interface CharacterIterator extends Cloneable
-{
-    Object clone();
-    char current();
-    char first();
-    int getBeginIndex();
-    int getEndIndex();
-    int getIndex();
-    char last();
-    char next();
-    char previous();
-    char setIndex(int position);    
-}
Index: javax/swing/text/ComponentView.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/ComponentView.java,v
retrieving revision 1.3
diff -u -r1.3 ComponentView.java
--- javax/swing/text/ComponentView.java	10 Jan 2004 21:07:44 -0000	1.3
+++ javax/swing/text/ComponentView.java	6 Sep 2004 16:36:09 -0000
@@ -79,6 +79,7 @@
     }
 
     public Shape modelToView(int pos, Shape a, Position.Bias b)
+      throws BadLocationException
     {
 	return null;
     }
Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java	10 Jan 2004 21:07:44 -0000	1.3
+++ javax/swing/text/DefaultCaret.java	6 Sep 2004 16:36:10 -0000
@@ -1,4 +1,4 @@
-/* DefaultCaret.java -- 
+/* DefaultCaret.java --
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -41,139 +41,276 @@
 import java.awt.Graphics;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.Shape;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
 import java.util.EventListener;
-import java.util.Vector;
+
+import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.event.EventListenerList;
 
 
-public class DefaultCaret extends Rectangle implements Caret, FocusListener, MouseListener, MouseMotionListener
+public class DefaultCaret extends Rectangle
+  implements Caret, FocusListener, MouseListener, MouseMotionListener
 {
-    Color color = new Color(0,0,0);
-    JTextComponent parent;
+  private static final long serialVersionUID = 228155774675466193L;
+  
+  protected ChangeEvent changeEvent = new ChangeEvent(this);
+  protected EventListenerList listenerList = new EventListenerList();
+  
+  private JTextComponent textComponent;
+  
+  private boolean selectionVisible = true;
+  private int blinkRate = 0;
+  private int dot = 0;
+  private int mark = 0;
+  private Point magicCaretPosition = null;
+  private boolean visible = true;
+  private Object highlightEntry;
+
+  public void mouseDragged(MouseEvent event)
+  {
+  }
+
+  public void mouseMoved(MouseEvent event)
+  {
+  }
+
+  public void mouseClicked(MouseEvent event)
+  {
+  }
+
+  public void mouseEntered(MouseEvent event)
+  {
+  }
+
+  public void mouseExited(MouseEvent event)
+  {
+  }
+
+  public void mousePressed(MouseEvent event)
+  {
+  }
+
+  public void mouseReleased(MouseEvent event)
+  {
+  }
+
+  public void focusGained(FocusEvent event)
+  {
+  }
+
+  public void focusLost(FocusEvent event)
+  {
+  }
+
+  protected void moveCaret(MouseEvent event)
+  {
+  }
+
+  protected void positionCaret(MouseEvent event)
+  {
+  }
+
+  public void deinstall(JTextComponent c)
+  {
+    textComponent.removeFocusListener(this);
+    textComponent.removeMouseListener(this);
+    textComponent.removeMouseMotionListener(this);
+    textComponent = null;
+  }
+
+  public void install(JTextComponent c)
+  {
+    textComponent = c;
+    textComponent.addFocusListener(this);
+    textComponent.addMouseListener(this);
+    textComponent.addMouseMotionListener(this);
+    repaint();
+  }
+
+  public void setMagicCaretPosition(Point p)
+  {
+    magicCaretPosition = p;
+  }
+
+  public Point getMagicCaretPosition()
+  {
+    return magicCaretPosition;
+  }
+
+  public int getMark()
+  {
+    return mark;
+  }
+
+  private void handleHighlight()
+  {
+    Highlighter highlighter = textComponent.getHighlighter();
+    
+    if (highlighter == null)
+      return;
+    
+    int p0 = Math.min(dot, mark);
+    int p1 = Math.max(dot, mark);
+    
+    if (selectionVisible && p0 != p1)
+      {
+	try
+	  {
+	    if (highlightEntry == null)
+	      highlightEntry = highlighter.addHighlight(p0, p1, getSelectionPainter());
+	    else
+	      highlighter.changeHighlight(highlightEntry, p0, p1);
+	  }
+	catch (BadLocationException e)
+	  {
+	    // This should never happen.
+	    throw new InternalError();
+	  }
+      }
+    else
+      {
+	if (highlightEntry != null)
+	  {
+	    highlighter.removeHighlight(highlightEntry);
+	    highlightEntry = null;
+	  }
+      }
+  }
+
+  public void setSelectionVisible(boolean v)
+  {
+    if (selectionVisible == v)
+      return;
+    
+    selectionVisible = v;
+    handleHighlight();
+    repaint();
+  }
+
+  public boolean isSelectionVisible()
+  {
+    return selectionVisible;
+  }
+
+  protected final void repaint()
+  {
+    if (textComponent != null)
+      textComponent.repaint();
+  }
+
+  public void paint(Graphics g)
+  {
+    if (textComponent == null)
+      return;
+
+    int dot = getDot();
+    Rectangle rect = null;
+
+    try
+      {
+	rect = textComponent.modelToView(dot);
+      }
+    catch (BadLocationException e)
+      {
+	// This should never happen as dot should be always valid.
+	return;
+      }
+
+    if (rect == null)
+      return;
+    
+    // First we need to delete the old caret.
+    // FIXME: Implement deleting of old caret.
     
-    public void mouseDragged(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mouseMoved(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mouseClicked(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mouseEntered(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mouseExited(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mousePressed(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void mouseReleased(java.awt.event.MouseEvent  evt)
-    {
-    }
-
-    public void focusGained(java.awt.event.FocusEvent  evt)
-    {
-    }
-
-    public void focusLost(java.awt.event.FocusEvent  evt)
-    {
-    }
-
-    // caret methods:
-
-    public void deinstall(JTextComponent c)
-    {
-	parent.removeFocusListener(this);
-	parent.removeMouseListener(this);
-
-	parent = null;    
-    }
-    public void install(JTextComponent c)
-    {
-	parent.addFocusListener(this);
-	parent.addMouseListener(this);
-	parent = c;
-	repaint();
-    }
-    
-    Point magic = null;
-    public void setMagicCaretPosition(Point p)
-    {	magic = p;    }
-    public Point getMagicCaretPosition()
-    {	return magic;    }
-
-    
-    int mark = 0;
-    public int getMark()
-    {	return mark;    }
-
-    boolean vis_sel = true;
-    public void setSelectionVisible(boolean v)
-    {  vis_sel = v;  repaint();  }
-    public boolean isSelectionVisible()
-    {  return vis_sel;    }
-
-    private void repaint()
-    {	
-	if (parent != null)
-	    {
-		parent.repaint();
-	    }
-    }
-
-    public void paint(Graphics g)
-    {
-	g.setColor(color);
-	g.drawLine(x,y,
-		   x,y+height);
-    }
-
-    
-    Vector changes = new Vector();
-    public void addChangeListener(ChangeListener l)
-    {	changes.addElement(l);    }
-    public void removeChangeListener(ChangeListener l)
-    {   changes.removeElement(l);    }
-
-
-    int blink = 500;
-    public int getBlinkRate()
-    { return blink;    }
-    public void setBlinkRate(int rate)
-    { blink = rate;    }
-
-    int dot = 0;
-    public int getDot()
-    {  return dot;     }
-    public void moveDot(int dot)
-    {   setDot(dot);    }
-    public void setDot(int dot)
-    {
-	this.dot = dot;   
-	repaint();
-    }
-
-    boolean vis = true;
-    public boolean isVisible()
-    {	return vis;    }
-    public void setVisible(boolean v)
-    {
-	vis = v; 
-	repaint();
-    }
+    // Now draw the caret on the new position if visible.
+    if (visible)
+      {
+	g.setColor(textComponent.getCaretColor());
+	g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+      }
+  }
+
+  public EventListener[] getListeners(Class listenerType)
+  {
+    return listenerList.getListeners(listenerType);
+  }
+
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) getListeners(ChangeListener.class);
+  }
+
+  protected void fireStateChanged()
+  {
+    ChangeListener[] listeners = getChangeListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].stateChanged(changeEvent);
+  }
+
+  protected final JTextComponent getComponent()
+  {
+    return textComponent;
+  }
+  
+  public int getBlinkRate()
+  {
+    return blinkRate;
+  }
+
+  public void setBlinkRate(int rate)
+  {
+    blinkRate = rate;
+  }
+
+  public int getDot()
+  {
+    return dot;
+  }
+
+  public void moveDot(int dot)
+  {
+    this.dot = dot;
+    handleHighlight();
+    repaint();
+  }
+
+  public void setDot(int dot)
+  {
+    this.dot = dot;
+    this.mark = dot;
+    handleHighlight();
+    repaint();
+  }
+
+  public boolean isVisible()
+  {
+    return visible;
+  }
+
+  public void setVisible(boolean v)
+  {
+    visible = v;
+    repaint();
+  }
+
+  protected Highlighter.HighlightPainter getSelectionPainter()
+  {
+    return DefaultHighlighter.DefaultPainter;
+  }
 }
Index: javax/swing/text/DefaultEditorKit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/DefaultEditorKit.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultEditorKit.java
--- javax/swing/text/DefaultEditorKit.java	10 Jan 2004 21:07:44 -0000	1.4
+++ javax/swing/text/DefaultEditorKit.java	6 Sep 2004 16:36:10 -0000
@@ -37,15 +37,134 @@
 
 package javax.swing.text;
 
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
 import java.io.InputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 import javax.swing.Action;
 import javax.swing.JEditorPane;
 
+
 public class DefaultEditorKit extends EditorKit
 {
+  public static class BeepAction
+    extends TextAction
+  {
+    public BeepAction()
+    {
+      super(beepAction);
+    }
+
+    public void actionPerformed(ActionEvent event)
+    {
+      Toolkit.getDefaultToolkit().beep();
+    }
+  }
+
+  public static class CopyAction 
+    extends TextAction
+  {
+    public CopyAction()
+    {
+      super(copyAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class CutAction 
+    extends TextAction
+  {
+    public CutAction()
+    {
+      super(cutAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class DefaultKeyTypedAction 
+    extends TextAction
+  {
+    public DefaultKeyTypedAction()
+    {
+      super(defaultKeyTypedAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+      JTextComponent t = getTextComponent(event);
+      if (t != null)
+        {
+          try
+            {
+              t.getDocument().insertString(t.getCaret().getDot(), event.getActionCommand(), null);
+              t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+                                           t.getDocument().getEndPosition().getOffset()));
+              t.repaint();
+            }
+          catch (BadLocationException be)
+            {
+              // FIXME: we're not authorized to throw this.. swallow it?
+            }
+        }
+    }
+  }
+
+  public static class InsertBreakAction 
+    extends TextAction
+  {
+    public InsertBreakAction()
+    {
+      super(insertBreakAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class InsertContentAction 
+    extends TextAction
+  {
+    public InsertContentAction()
+    {
+      super(insertContentAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class InsertTabAction 
+    extends TextAction
+  {
+    public InsertTabAction()
+    {
+      super(insertTabAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class PasteAction 
+    extends TextAction
+  {
+    public PasteAction()
+    {
+      super(pasteAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  private static final long serialVersionUID = 9017245433028523428L;
+  
   public static final String backwardAction = "caret-backward";
   public static final String beepAction = "beep";
   public static final String beginAction = "caret-begin";
@@ -60,7 +179,7 @@
   public static final String downAction = "caret-down";
   public static final String endAction = "caret-end";
   public static final String endLineAction = "caret-end-line";
-  public static final String endOfLineStringProperty = "__EndOfLine__";
+  public static final String EndOfLineStringProperty = "__EndOfLine__";
   public static final String endParagraphAction = "caret-end-paragraph";
   public static final String endWordAction = "caret-end-word";
   public static final String forwardAction = "caret-forward";
@@ -77,16 +196,19 @@
   public static final String selectionBackwardAction = "selection-backward";
   public static final String selectionBeginAction = "selection-begin";
   public static final String selectionBeginLineAction = "selection-begin-line";
-  public static final String selectionBeginParagraphAction = "selection-begin-paragraph";
+  public static final String selectionBeginParagraphAction =
+    "selection-begin-paragraph";
   public static final String selectionBeginWordAction = "selection-begin-word";
   public static final String selectionDownAction = "selection-down";
   public static final String selectionEndAction = "selection-end";
   public static final String selectionEndLineAction = "selection-end-line";
-  public static final String selectionEndParagraphAction = "selection-end-paragraph";
+  public static final String selectionEndParagraphAction =
+    "selection-end-paragraph";
   public static final String selectionEndWordAction = "selection-end-word";
   public static final String selectionForwardAction = "selection-forward";
   public static final String selectionNextWordAction = "selection-next-word";
-  public static final String selectionPreviousWordAction = "selection-previous-word";
+  public static final String selectionPreviousWordAction =
+    "selection-previous-word";
   public static final String selectionUpAction = "selection-up";
   public static final String selectLineAction = "select-line";
   public static final String selectParagraphAction = "select-paragraph";
@@ -94,48 +216,170 @@
   public static final String upAction = "caret-up";
   public static final String writableAction = "set-writable";
 
-    void deinstall(JEditorPane c)
-    {
-	//      Called when the kit is being removed from the JEditorPane. 
-    }
-    void install(JEditorPane c)
-    {
-    }
+  public DefaultEditorKit()
+  {
+  }
 
-    Caret createCaret()
-    {
-	return null;
-    }
-    Document createDefaultDocument()
+  private static Action[] defaultActions = 
+  new Action[] {
+    new BeepAction(),
+    new CopyAction(),
+    new CutAction(),
+    new DefaultKeyTypedAction(),
+    new InsertBreakAction(),
+    new InsertContentAction(),
+    new InsertTabAction(),
+    new PasteAction(),
+    new TextAction(deleteNextCharAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            try
+              {
+                int pos = t.getCaret().getDot();
+                if (pos < t.getDocument().getEndPosition().getOffset())
+                  {
+                    t.getDocument().remove(t.getCaret().getDot(), 1);
+                    t.repaint();
+                  }
+              }
+            catch (BadLocationException e)
+              {
+                // FIXME: we're not authorized to throw this.. swallow it?
+              }
+          }
+      }
+    },
+    new TextAction(deletePrevCharAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            try
+              {
+                int pos = t.getCaret().getDot();
+                if (pos > t.getDocument().getStartPosition().getOffset())
+                  {
+                    t.getDocument().remove(pos - 1, 1);
+                    t.getCaret().setDot(pos - 1);
+                    t.repaint();
+                  }
+              }
+            catch (BadLocationException e)
+              {
+                // FIXME: we're not authorized to throw this.. swallow it?
+              }
+          }
+      }
+    },
+    new TextAction(backwardAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().setDot(Math.max(t.getCaret().getDot() - 1,
+                                         t.getDocument().getStartPosition().getOffset()));
+          }
+      }
+    },
+    new TextAction(forwardAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+                                         t.getDocument().getEndPosition().getOffset()));
+          }
+      }
+    },
+    new TextAction(selectionBackwardAction)
+    {
+      public void actionPerformed(ActionEvent event)
+      {
+	JTextComponent t = getTextComponent(event);
+	if (t != null)
+	  {
+	    t.getCaret().moveDot(Math.max(t.getCaret().getDot() - 1,
+					  t.getDocument().getStartPosition().getOffset()));
+	  }
+      }
+    },
+    new TextAction(selectionForwardAction)
+    {
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().moveDot(Math.min(t.getCaret().getDot() + 1,
+                                          t.getDocument().getEndPosition().getOffset()));
+          }
+      }
+    },
+  };
+
+  /**
+   * Called when the kit is being removed from the JEditorPane.
+   */
+  public void deinstall(JEditorPane c)
     {
-        return new PlainDocument();
     }
 
-    Action[] getActions()
+  public void install(JEditorPane c)
     {
-	return null;
     }
 
-    String getContentType()
+  public Caret createCaret()
+  {
+    return new DefaultCaret();
+  }
+
+  public Document createDefaultDocument()
+  {
+    return new PlainDocument();
+  }
+    
+  public Action[] getActions()
+  {
+    return defaultActions;
+  }
+
+  public String getContentType()
     {
 	return "text/plain";
     }
     
-    ViewFactory getViewFactory()
+  public ViewFactory getViewFactory()
     {
 	return null;
     }
-    void read(InputStream in, Document doc, int pos)
+
+  public void read(InputStream in, Document doc, int pos)
+    throws BadLocationException, IOException
     {
     }
-    void read(Reader in, Document doc, int pos)
+
+  public void read(Reader in, Document doc, int pos)
+    throws BadLocationException, IOException
     {
     }
-    void write(OutputStream out, Document doc, int pos, int len)
+
+  public void write(OutputStream out, Document doc, int pos, int len)
+    throws BadLocationException, IOException
     {
     }
-    void write(Writer out, Document doc, int pos, int len)
+
+  public void write(Writer out, Document doc, int pos, int len)
+    throws BadLocationException, IOException
     {
     }
 }
-
Index: javax/swing/text/DefaultHighlighter.java
===================================================================
RCS file: javax/swing/text/DefaultHighlighter.java
diff -N javax/swing/text/DefaultHighlighter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/DefaultHighlighter.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,250 @@
+/* DefaultHighlighter.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.Vector;
+
+import javax.swing.text.JTextComponent;
+import javax.swing.text.View;
+
+
+public class DefaultHighlighter extends LayeredHighlighter
+{
+  public static class DefaultHighlightPainter
+    extends LayerPainter
+  {
+    private Color color;
+    
+    public DefaultHighlightPainter(Color c)
+    {
+      super();
+      color = c;
+    }
+
+    public Color getColor()
+    {
+      return color;
+    }
+
+    private void paintHighlight(Graphics g, Rectangle rect)
+    {
+      g.fillRect(rect.x, rect.y, rect.width, rect.height);
+    }
+    
+    public void paint(Graphics g, int p0, int p1, Shape bounds,
+		      JTextComponent c)
+    {
+      Rectangle r0 = null;
+      Rectangle r1 = null;
+      Rectangle rect = bounds.getBounds();
+      
+      try
+	{
+	  r0 = c.modelToView(p0);
+	  r1 = c.modelToView(p1);
+	}
+      catch (BadLocationException e)
+        {
+	  // This should never occur.
+          return;
+	}
+
+      if (r0 == null || r1 == null)
+	return;
+
+      if (color == null)
+	g.setColor(c.getSelectionColor());
+      else
+	g.setColor(color);
+
+      // Check if only one line to highlight.
+      if (r0.y == r1.y)
+	{
+	  r0.width = r1.x - r0.x;
+	  paintHighlight(g, r0);
+	  return;
+	}
+
+      // First line, from p0 to end-of-line.
+      r0.width = rect.x + rect.width - r0.x;
+      paintHighlight(g, r0);
+      
+      // FIXME: All the full lines in between, if any (assumes that all lines
+      // have the same height -- not a good assumption with JEditorPane/JTextPane).
+      r0.y += r0.height;
+      r0.x = rect.x;
+
+      while (r0.y < r1.y)
+	{
+	  paintHighlight(g, r0);
+	  r0.y += r0.height;
+	}
+
+      // Last line, from beginnin-of-line to p1.
+      paintHighlight(g, r1);
+    }
+
+    public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
+			    JTextComponent c, View view)
+    {
+      throw new InternalError();
+    }
+  }
+  
+  private class HighlightEntry
+  {
+    int p0;
+    int p1;
+    Highlighter.HighlightPainter painter;
+
+    public HighlightEntry(int p0, int p1, Highlighter.HighlightPainter painter)
+    {
+      this.p0 = p0;
+      this.p1 = p1;
+      this.painter = painter;
+    }
+
+    public int getStartPosition()
+    {
+      return p0;
+    }
+
+    public int getEndPosition()
+    {
+      return p1;
+    }
+
+    public Highlighter.HighlightPainter getPainter()
+    {
+      return painter;
+    }
+  }
+
+  /**
+   * @specnote final as of 1.4
+   */
+  public static final LayeredHighlighter.LayerPainter DefaultPainter =
+    new DefaultHighlightPainter(null);
+  
+  private JTextComponent textComponent;
+  private Vector highlights = new Vector();
+  
+  public DefaultHighlighter()
+  {
+  }
+
+  private void checkPositions(int p0, int p1)
+    throws BadLocationException
+  {
+    if (p0 < 0)
+      throw new BadLocationException("DefaultHighlighter", p0);
+    
+    if (p1 < p0)
+      throw new BadLocationException("DefaultHighlighter", p1);
+  }
+
+  public void install(JTextComponent c)
+  {
+    textComponent = c;
+    removeAllHighlights();
+  }
+
+  public void deinstall(JTextComponent c)
+  {
+    textComponent = null;
+  }
+
+  public Object addHighlight(int p0, int p1, Highlighter.HighlightPainter painter)
+    throws BadLocationException
+  {
+    checkPositions(p0, p1);
+    HighlightEntry entry = new HighlightEntry(p0, p1, painter);
+    highlights.add(entry);
+    return entry;
+  }
+
+  public void removeHighlight(Object tag)
+  {
+    highlights.remove(tag);
+  }
+
+  public void removeAllHighlights()
+  {
+    highlights.clear();
+  }
+
+  public Highlighter.Highlight[] getHighlights()
+  {
+    return null;
+  }
+
+  public void changeHighlight(Object tag, int p0, int p1)
+    throws BadLocationException
+  {
+    checkPositions(p0, p1);
+    HighlightEntry entry = (HighlightEntry) tag;
+    entry.p0 = p0;
+    entry.p1 = p1;
+  }
+
+  public void paintLayeredHighlights(Graphics g, int p0, int p1,
+                                     Shape viewBounds, JTextComponent editor,
+                                     View view)
+  {
+  }
+
+  public void paint(Graphics g)
+  {
+    // Check if there are any highlights.
+    if (highlights.size() == 0)
+      return;
+    
+    Shape bounds = textComponent.getBounds();
+    
+    for (int index = 0; index < highlights.size(); ++index)
+      {
+	HighlightEntry entry = (HighlightEntry) highlights.get(index);
+	entry.painter.paint(g, entry.p0, entry.p1, bounds, textComponent);
+      }
+  }
+}
Index: javax/swing/text/Document.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/Document.java,v
retrieving revision 1.4
diff -u -r1.4 Document.java
--- javax/swing/text/Document.java	10 Jan 2004 21:07:44 -0000	1.4
+++ javax/swing/text/Document.java	6 Sep 2004 16:36:10 -0000
@@ -1,4 +1,4 @@
-/* Document.java -- 
+/* Document.java --
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -40,27 +40,48 @@
 import javax.swing.event.DocumentListener;
 import javax.swing.event.UndoableEditListener;
 
+
 public interface Document
-{ 
+{
   String StreamDescriptionProperty = "stream";
-  
   String TitleProperty = "text";
 
   void addDocumentListener(DocumentListener listener);
+
   void addUndoableEditListener(UndoableEditListener listener);
-  Position createPosition(int offs);
+
+  Position createPosition(int offs)
+    throws BadLocationException;
+
   Element getDefaultRootElement();
+
   Position getEndPosition();
+
   int getLength();
+
   Object getProperty(Object key);
+
   Element[] getRootElements();
+
   Position getStartPosition();
-  String getText(int offset, int length);
-  void getText(int offset, int length, Segment txt);
-  void insertString(int offset, String str, AttributeSet a);
+
+  String getText(int offset, int length)
+    throws BadLocationException;
+
+  void getText(int offset, int length, Segment txt)
+    throws BadLocationException;
+
+  void insertString(int offset, String str, AttributeSet a)
+    throws BadLocationException;
+
   void putProperty(Object key, Object value);
-  void remove(int offs, int len);
+
+  void remove(int offs, int len)
+    throws BadLocationException;
+
   void removeDocumentListener(DocumentListener listener);
+
   void removeUndoableEditListener(UndoableEditListener listener);
+
   void render(Runnable r);
 }
Index: javax/swing/text/EditorKit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/EditorKit.java,v
retrieving revision 1.2
diff -u -r1.2 EditorKit.java
--- javax/swing/text/EditorKit.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/EditorKit.java	6 Sep 2004 16:36:10 -0000
@@ -38,38 +38,58 @@
 package javax.swing.text;
 
 import java.io.InputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Reader;
+import java.io.Serializable;
 import java.io.Writer;
 import javax.swing.Action;
 import javax.swing.JEditorPane;
 
-public abstract class EditorKit implements Cloneable
+
+public abstract class EditorKit
+  implements Cloneable, Serializable
 {
-    EditorKit()
+  private static final long serialVersionUID = -5044124649345887822L;
+  
+  public EditorKit()
     {
     }
 
-    EditorKit(EditorKit kit)
+  public Object clone()
     {
+    try
+      {
+	return super.clone();
     }
-
-    void deinstall(JEditorPane c)
+    catch (CloneNotSupportedException e)
     {
-	//      Called when the kit is being removed from the JEditorPane. 
+	return null;
     }
-    void install(JEditorPane c)
+  }
+
+  /**
+   * Called when the kit is being removed from the JEditorPane.
+   */
+  public void deinstall(JEditorPane c)
     {
     }
 
-    abstract  Caret createCaret();
-    abstract  Document createDefaultDocument();
-    abstract  Action[] getActions();
-    abstract  String getContentType();
-    abstract  ViewFactory getViewFactory();
-    abstract  void read(InputStream in, Document doc, int pos);
-    abstract  void read(Reader in, Document doc, int pos);
-    abstract  void write(OutputStream out, Document doc, int pos, int len);
-    abstract  void write(Writer out, Document doc, int pos, int len);    
+  public void install(JEditorPane c)
+  {
 }
 
+  public abstract Caret createCaret();
+  public abstract Document createDefaultDocument();
+  public abstract Action[] getActions();
+  public abstract String getContentType();
+  public abstract ViewFactory getViewFactory();
+  public abstract void read(InputStream in, Document doc, int pos)
+    throws BadLocationException, IOException;
+  public abstract void read(Reader in, Document doc, int pos)
+    throws BadLocationException, IOException;
+  public abstract void write(OutputStream out, Document doc, int pos, int len)
+    throws BadLocationException, IOException;
+  public abstract void write(Writer out, Document doc, int pos, int len)
+    throws BadLocationException, IOException;
+}
Index: javax/swing/text/FieldView.java
===================================================================
RCS file: javax/swing/text/FieldView.java
diff -N javax/swing/text/FieldView.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/FieldView.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,103 @@
+/* FieldView.java -- 
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text;
+
+import java.awt.Component;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Shape;
+
+
+public class FieldView extends PlainView
+{
+  public FieldView(Element elem)
+  {
+    super(elem);
+  }
+
+  protected FontMetrics getFontMetrics()
+  {
+    Component container = getContainer();
+    return container.getFontMetrics(container.getFont());
+  }
+
+  public float getPreferredSpan(int axis)
+  {
+    if (axis != X_AXIS && axis != Y_AXIS)
+      throw new IllegalArgumentException();
+
+    FontMetrics fm = getFontMetrics();
+
+    if (axis == Y_AXIS)
+      return fm.getHeight();
+
+    String text;
+    Element elem = getElement();
+
+    try
+      {
+	text = elem.getDocument().getText(elem.getStartOffset(),
+					  elem.getEndOffset());
+      }
+    catch (BadLocationException e)
+      {
+	// This should never happen.
+	text = "";
+	System.out.println("Michael: FieldView.getPreferredSpan: Error");
+      }
+    
+    return fm.stringWidth(text);
+  }
+
+  public int getResizeWeight(int axis)
+  {
+    return axis = axis == X_AXIS ? 1 : 0;
+  }
+  
+  public Shape modelToView(int pos, Shape a, Position.Bias bias)
+    throws BadLocationException
+  {
+    return super.modelToView(pos, a, bias);
+  }
+  
+  public void paint(Graphics g, Shape s)
+  {
+    super.paint(g, s);
+  }
+}
Index: javax/swing/text/GapContent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/GapContent.java,v
retrieving revision 1.2
diff -u -r1.2 GapContent.java
--- javax/swing/text/GapContent.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/GapContent.java	6 Sep 2004 16:36:10 -0000
@@ -1,4 +1,4 @@
-/* GapContent.java -- 
+/* GapContent.java --
    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -35,69 +35,75 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-package javax.swing.text; 
+package javax.swing.text;
+
+import java.io.Serializable;
 
 // too lazy to make a real gapcontent.
 // lets just use a stringbuffer instead.
-
 import javax.swing.undo.UndoableEdit;
 
-public class GapContent implements AbstractDocument.Content
+public class GapContent
+  implements AbstractDocument.Content, Serializable
 {
-    StringBuffer buf = new StringBuffer();
-
-    public GapContent()
-    {
-	this(10);
-    }
+  private static final long serialVersionUID = 8374645204155842629L;
     
-    public GapContent(int size)
-    {
-    }
-
-    public Position createPosition(final int offset) throws BadLocationException
-    {
-	return new Position()
-	    {
-		int off = offset;
-		public int getOffset()
-		{
-		    return off;
-		}
-	    };
-    }
-
-    public int length()
-    {
-	return buf.length();
-    }
-
-    public UndoableEdit insertString(int where, String str) throws BadLocationException
-    {
-	buf.insert(where, str);
-	return null;
-    }
-
-    public UndoableEdit remove(int where, int nitems) throws BadLocationException
-    {
-	buf.delete(where, where + nitems);
-	return null;
-    }
-
-    public String getString(int where, int len) throws BadLocationException
-    {
-	return buf.toString();
-    }
-
-    public void getChars(int where, int len, Segment txt) throws BadLocationException
-    {
-	txt.array = new char[len];
-		
-	System.arraycopy(buf.toString().toCharArray(), where, 
-			 txt.array, 0,
-			 len);
-	
-	txt.count  = len;
-	txt.offset = 0;
-    }
+  StringBuffer buf = new StringBuffer();
+
+  public GapContent()
+  {
+    this(10);
+  }
+
+  public GapContent(int size)
+  {
+  }
+
+  public Position createPosition(final int offset) throws BadLocationException
+  {
+    return new Position()
+      {
+	int off = offset;
+
+	public int getOffset()
+	{
+	  return off;
+	}
+      };
+  }
+
+  public int length()
+  {
+    return buf.length();
+  }
+
+  public UndoableEdit insertString(int where, String str)
+    throws BadLocationException
+  {
+    buf.insert(where, str);
+    return null;
+  }
+
+  public UndoableEdit remove(int where, int nitems)
+    throws BadLocationException
+  {
+    buf.delete(where, where + nitems);
+    return null;
+  }
+
+  public String getString(int where, int len) throws BadLocationException
+  {
+    return buf.toString();
+  }
+
+  public void getChars(int where, int len, Segment txt)
+    throws BadLocationException
+  {
+    txt.array = new char[len];
+
+    System.arraycopy(buf.toString().toCharArray(), where, txt.array, 0, len);
+
+    txt.count = len;
+    txt.offset = 0;
+  }
 }
Index: javax/swing/text/Highlighter.java
===================================================================
RCS file: javax/swing/text/Highlighter.java
diff -N javax/swing/text/Highlighter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/Highlighter.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,80 @@
+/* Highlighter.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text;
+
+import java.awt.Graphics;
+import java.awt.Shape;
+
+
+public interface Highlighter
+{
+  public interface Highlight
+  {
+    int getEndOffset();
+
+    int getStartOffset();
+
+    HighlightPainter getPainter();
+  }
+
+  public interface HighlightPainter
+  {
+    public void paint(Graphics g, int p0, int p1, Shape bounds,
+		      JTextComponent c);
+  }
+  
+  void install(JTextComponent c);
+
+  void deinstall(JTextComponent c);
+
+  Object addHighlight(int p0, int p1, HighlightPainter p)
+    throws BadLocationException;
+
+  void removeAllHighlights();
+
+  void removeHighlight(Object tag);
+
+  void changeHighlight(Object tag, int p0, int p1)
+    throws BadLocationException;
+
+  Highlight[] getHighlights();
+
+  void paint(Graphics g);
+}
+
Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/JTextComponent.java,v
retrieving revision 1.3
diff -u -r1.3 JTextComponent.java
--- javax/swing/text/JTextComponent.java	24 Jun 2003 09:51:28 -0000	1.3
+++ javax/swing/text/JTextComponent.java	6 Sep 2004 16:36:10 -0000
@@ -1,5 +1,5 @@
-/* JTextComponent.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* JTextComponent.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,19 +38,30 @@
 package javax.swing.text;
 
 import java.awt.AWTEvent;
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Image;
 import java.awt.Insets;
-import java.awt.Rectangle;
 import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.InputMethodListener;
+import java.awt.event.KeyEvent;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleText;
+import javax.swing.Action;
+import javax.swing.ActionMap;
 import javax.swing.Icon;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
+import javax.swing.JViewport;
 import javax.swing.KeyStroke;
 import javax.swing.Scrollable;
 import javax.swing.UIManager;
@@ -58,454 +69,1268 @@
 import javax.swing.event.CaretListener;
 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;
 
+
 public abstract class JTextComponent extends JComponent
   implements Scrollable, Accessible
 {
-//    public class AccessibleJTextComponent extends AccessibleJComponent
-//      implements AccessibleText, CaretListener, DocumentListener,
-//                 AccessibleAction, AccessibleEditableText
-//    {
-//    } // class AccessibleJTextComponent
-
-	/**
-	 * AccessibleJTextComponent
-	 */
-	public class AccessibleJTextComponent extends AccessibleJComponent
-		implements AccessibleText, CaretListener, DocumentListener {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * caretPos
-		 */
-		int caretPos;
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * Constructor AccessibleJTextComponent
-		 * @param component TODO
-		 */
-		public AccessibleJTextComponent(JTextComponent component) {
-			super(component);
-			// TODO
-		} // AccessibleJTextComponent()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
-
-		/**
-		 * getCaretPosition
-		 * @returns int
-		 */
-		public int getCaretPosition() {
-			return 0; // TODO
-		} // getCaretPosition()
-
-		/**
-		 * getSelectedText
-		 * @returns String
-		 */
-		public String getSelectedText() {
-			return null; // TODO
-		} // getSelectedText()
-
-		/**
-		 * getSelectionStart
-		 * @returns int
-		 */
-		public int getSelectionStart() {
-			return 0; // TODO
-		} // getSelectionStart()
-
-		/**
-		 * getSelectionEnd
-		 * @returns int
-		 */
-		public int getSelectionEnd() {
-			return 0; // TODO
-		} // getSelectionEnd()
-
-		/**
-		 * caretUpdate
-		 * @param value0 TODO
-		 */
-		public void caretUpdate(CaretEvent value0) {
-			// TODO
-		} // caretUpdate()
-
-		/**
-		 * getAccessibleStateSet
-		 * @returns AccessibleStateSet
-		 */
-		public AccessibleStateSet getAccessibleStateSet() {
-			return null; // TODO
-		} // getAccessibleStateSet()
-
-		/**
-		 * getAccessibleRole
-		 * @returns AccessibleRole
-		 */
-		public AccessibleRole getAccessibleRole() {
-			return null; // TODO
-		} // getAccessibleRole()
-
-		/**
-		 * getAccessibleText
-		 * @returns AccessibleText
-		 */
-		public AccessibleText getAccessibleText() {
-			return null; // TODO
-		} // getAccessibleText()
-
-		/**
-		 * insertUpdate
-		 * @param value0 TODO
-		 */
-		public void insertUpdate(DocumentEvent value0) {
-			// TODO
-		} // insertUpdate()
-
-		/**
-		 * removeUpdate
-		 * @param value0 TODO
-		 */
-		public void removeUpdate(DocumentEvent value0) {
-			// TODO
-		} // removeUpdate()
-
-		/**
-		 * changedUpdate
-		 * @param value0 TODO
-		 */
-		public void changedUpdate(DocumentEvent value0) {
-			// TODO
-		} // changedUpdate()
-
-		/**
-		 * getIndexAtPoint
-		 * @param value0 TODO
-		 * @returns int
-		 */
-		public int getIndexAtPoint(Point value0) {
-			return 0; // TODO
-		} // getIndexAtPoint()
-
-		/**
-		 * getRootEditorRect
-		 * @returns Rectangle
-		 */
-		Rectangle getRootEditorRect() {
-			return null; // TODO
-		} // getRootEditorRect()
-
-		/**
-		 * getCharacterBounds
-		 * @param value0 TODO
-		 * @returns Rectangle
-		 */
-		public Rectangle getCharacterBounds(int value0) {
-			return null; // TODO
-		} // getCharacterBounds()
-
-		/**
-		 * getCharCount
-		 * @returns int
-		 */
-		public int getCharCount() {
-			return 0; // TODO
-		} // getCharCount()
-
-		/**
-		 * getCharacterAttribute
-		 * @param value0 TODO
-		 * @returns AttributeSet
-		 */
-		public AttributeSet getCharacterAttribute(int value0) {
-			return null; // TODO
-		} // getCharacterAttribute()
-
-		/**
-		 * getAtIndex
-		 * @param value0 TODO
-		 * @param value1 TODO
-		 * @returns String
-		 */
-		public String getAtIndex(int value0, int value1) {
-			return null; // TODO
-		} // getAtIndex()
-
-		/**
-		 * getAfterIndex
-		 * @param value0 TODO
-		 * @param value1 TODO
-		 * @returns String
-		 */
-		public String getAfterIndex(int value0, int value1) {
-			return null; // TODO
-		} // getAfterIndex()
-
-		/**
-		 * getBeforeIndex
-		 * @param value0 TODO
-		 * @param value1 TODO
-		 * @returns String
-		 */
-		public String getBeforeIndex(int value0, int value1) {
-			return null; // TODO
-		} // getBeforeIndex()
-
+  /**
+   * AccessibleJTextComponent
+   */
+  public class AccessibleJTextComponent extends AccessibleJComponent
+    implements AccessibleText, CaretListener, DocumentListener
+  {
+    private static final long serialVersionUID = 7664188944091413696L;
 
-	} // AccessibleJTextComponent
+    /**
+     * Constructor AccessibleJTextComponent
+     * @param component TODO
+     */
+    public AccessibleJTextComponent()
+    {
+    }
 
+    /**
+     * getCaretPosition
+     * @return int
+     */
+    public int getCaretPosition()
+    {
+      return 0; // TODO
+    }
 
+    /**
+     * getSelectedText
+     * @return String
+     */
+    public String getSelectedText()
+    {
+      return null; // TODO
+    }
 
-  public static class KeyBinding
-  {
-    public KeyStroke key;
-    public String actionName;
-    public KeyBinding(KeyStroke key, String actionName)
+    /**
+     * getSelectionStart
+     * @return int
+     */
+    public int getSelectionStart()
     {
-      this.key = key;
-      this.actionName = actionName;
+      return 0; // TODO
     }
-  } // class KeyBinding
 
-  int icon_gap;
-    Icon icon;
-    int align;
-    Document doc;
+    /**
+     * getSelectionEnd
+     * @return int
+     */
+    public int getSelectionEnd()
+    {
+      return 0; // TODO
+    }
 
-    public JTextComponent()
+    /**
+     * caretUpdate
+     * @param value0 TODO
+     */
+    public void caretUpdate(CaretEvent value0)
     {
-	this("", null, 0);
+      // TODO
     }
 
-    public JTextComponent(Icon image)
+    /**
+     * getAccessibleStateSet
+     * @return AccessibleStateSet
+     */
+    public AccessibleStateSet getAccessibleStateSet()
     {
-	this("", image, 0);
+      return null; // TODO
     }
 
-    public JTextComponent(Icon image, int horizontalAlignment)
+    /**
+     * getAccessibleRole
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
     {
-	this("", image, horizontalAlignment);
+      return null; // TODO
     }
 
-    public JTextComponent(String text)
+    /**
+     * getAccessibleText
+     * @return AccessibleText
+     */
+    public AccessibleText getAccessibleText()
     {
-	this(text, null, 0);
+      return null; // TODO
     }
 
-    public JTextComponent(String text, int horizontalAlignment)
+    /**
+     * insertUpdate
+     * @param value0 TODO
+     */
+    public void insertUpdate(DocumentEvent value0)
     {
-	this(text, null, horizontalAlignment);
+      // TODO
     }
 
-    public JTextComponent(String text, Icon icon, int horizontalAlignment)
+    /**
+     * removeUpdate
+     * @param value0 TODO
+     */
+    public void removeUpdate(DocumentEvent value0)
     {
-	setDocument(new PlainDocument());
+      // TODO
+    }
 
-	// do the work.....
-	setText(text);
-	this.icon  = icon;
-	this.align     = horizontalAlignment;
-	
-        // its an editor, so:
-        enableEvents(AWTEvent.KEY_EVENT_MASK);
-        updateUI();
+    /**
+     * changedUpdate
+     * @param value0 TODO
+     */
+    public void changedUpdate(DocumentEvent value0)
+    {
+      // TODO
     }
 
-    public void setDocument(Document s)
+    /**
+     * getIndexAtPoint
+     * @param value0 TODO
+     * @return int
+     */
+    public int getIndexAtPoint(Point value0)
     {
-	doc = s;
-	revalidate();
-	repaint();
+      return 0; // TODO
     }
 
-    public Document getDocument()
+    /**
+     * getRootEditorRect
+     * @return Rectangle
+     */
+    Rectangle getRootEditorRect()
     {
-	if (doc == null)
-	    System.out.println("doc == null !!!");
-	return doc;
+      return null;
     }
 
-    protected  int checkHorizontalKey(int key, String message)
+    /**
+     * getCharacterBounds
+     * @param value0 TODO
+     * @return Rectangle
+     */
+    public Rectangle getCharacterBounds(int value0)
     {
-	//    Verify that key is a legal value for the horizontalAlignment properties. 
-	return 0;
+      return null; // TODO
     }
-    protected  int checkVerticalKey(int key, String message)
+
+    /**
+     * getCharCount
+     * @return int
+     */
+    public int getCharCount()
     {
-	//      Verify that key is a legal value for the verticalAlignment or verticalTextPosition properties.  
-	return 0;
+      return 0; // TODO
     }
-    public AccessibleContext getAccessibleContext()
+
+    /**
+     * getCharacterAttribute
+     * @param value0 TODO
+     * @return AttributeSet
+     */
+    public AttributeSet getCharacterAttribute(int value0)
     {
-	//          Get the AccessibleContext of this object 
-	return null;
+      return null; // TODO
     }
-    public Icon getDisabledIcon()
+
+    /**
+     * getAtIndex
+     * @param value0 TODO
+     * @param value1 TODO
+     * @return String
+     */
+    public String getAtIndex(int value0, int value1)
     {
-	return null;
+      return null; // TODO
     }
-    public int getDisplayedMnemonic()
+
+    /**
+     * getAfterIndex
+     * @param value0 TODO
+     * @param value1 TODO
+     * @return String
+     */
+    public String getAfterIndex(int value0, int value1)
     {
-	//          Return the keycode that indicates a mnemonic key.   
-	return 0;
+      return null; // TODO
     }
-    public int getHorizontalAlignment()
+
+    /**
+     * getBeforeIndex
+     * @param value0 TODO
+     * @param value1 TODO
+     * @return String
+     */
+    public String getBeforeIndex(int value0, int value1)
     {
-	//          Returns the alignment of the label's contents along the X axis.   
-	return 0;
+      return null; // TODO
     }
-    public int getHorizontalTextPosition()
+  }
+
+  public static class KeyBinding
+  {
+    public KeyStroke key;
+    public String actionName;
+
+    /**
+     * Creates a new <code>KeyBinding</code> instance.
+     *
+     * @param key a <code>KeyStroke</code> value
+     * @param actionName a <code>String</code> value
+     */
+    public KeyBinding(KeyStroke key, String actionName)
     {
-	//          Returns the horizontal position of the label's text, relative to its image.    
-	return 0;
+      this.key = key;
+      this.actionName = actionName;
     }
+  }
 
-    public Icon getIcon()
-    {	return icon;    }
-    public int getIconTextGap()
-    {	return icon_gap;    }
+  /**
+   * According to <a
+   * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
+   * report</a>, a pair of private classes wraps a {@link
+   * javax.swing.text.Keymap} in the new {@link InputMap} / {@link
+   * ActionMap} interfaces, such that old Keymap-using code can make use of
+   * the new framework.</p>
+   *
+   * <p>A little bit of experimentation with these classes reveals the following
+   * structure:
+   *
+   * <ul>
+   *
+   * <li>KeymapWrapper extends {@link InputMap} and holds a reference to
+   * the underlying {@link Keymap}.</li>
+   *
+   * <li>KeymapWrapper maps {@link KeyStroke} objects to {@link Action}
+   * objects, by delegation to the underlying {@link Keymap}.</li>
+   *
+   * <li>KeymapActionMap extends {@link ActionMap} also holds a reference to
+   * the underlying {@link Keymap} but only appears to use it for listing 
+   * its keys. </li>
+   *
+   * <li>KeymapActionMap maps all {@link Action} objects to
+   * <em>themselves</em>, whether they exist in the underlying {@link
+   * Keymap} or not, and passes other objects to the parent {@link
+   * ActionMap} for resolving.
+   *
+   * </ul>
+   */
 
+  private class KeymapWrapper extends InputMap
+  {
+    Keymap map;
 
-    Component getLabelFor()
+    public KeymapWrapper(Keymap k)
     {
-	//          Get the component this is labelling.  
-	return null;
+      map = k;
     }
 
-    public Insets getMargin()
+    public int size()
     {
-        // FIXME: Not implemented.
-        return null;
+      return map.getBoundKeyStrokes().length + super.size();
     }
 
-    public void setText(String text)
+    public Object get(KeyStroke ks)
     {
-	getDocument().remove(0,doc.getLength());
-	getDocument().insertString(0, text, null);
+      Action mapped = null;
+      Keymap m = map;
+      while(mapped == null && m != null)
+        {
+          mapped = m.getAction(ks);
+          if (mapped == null && ks.getKeyEventType() == KeyEvent.KEY_TYPED)
+            mapped = m.getDefaultAction();
+          if (mapped == null)
+            m = m.getResolveParent();
+        }
+
+      if (mapped == null)
+        return super.get(ks);
+      else
+        return mapped;
     }
-  
-    public String getText()
+
+    public KeyStroke[] keys()
     {
-	return getDocument().getText(0, 
-				     getDocument().getLength());
+      KeyStroke[] superKeys = super.keys();
+      KeyStroke[] mapKeys = map.getBoundKeyStrokes(); 
+      KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
     }
 
-    public String getUIClassID()
+    public KeyStroke[] allKeys()
     {
-	//          Returns a string that specifies the name of the l&f class that renders this component.  
-	return "JTextComponent";
+      KeyStroke[] superKeys = super.allKeys();
+      KeyStroke[] mapKeys = map.getBoundKeyStrokes(); 
+      KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
     }
-    public int getVerticalAlignment()
+  }
+
+  private class KeymapActionMap extends ActionMap
+  {
+    Keymap map;
+
+    public KeymapActionMap(Keymap k)
     {
-	//          Returns the alignment of the label's contents along the Y axis. 
-	return 0;
+      map = k;
     }
-    public int getVerticalTextPosition()
+
+    public Action get(Object cmd)
     {
-	//          Returns the vertical position of the label's text, relative to its image. 
-	return 0;
+      if (cmd instanceof Action)
+        return (Action) cmd;
+      else
+        return super.get(cmd);
     }
 
-    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
+    public int size()
     {
-	//          This is overriden to return false if the current Icon's Image is not equal to the passed in Image img. 
-	return (img == icon);
+      return map.getBoundKeyStrokes().length + super.size();
     }
-    protected  String paramString()
+
+    public Object[] keys() 
     {
-	//          Returns a string representation of this JTextComponent.  
-	return "JTextComponent";
+      Object[] superKeys = super.keys();
+      Object[] mapKeys = map.getBoundKeyStrokes(); 
+      Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;      
     }
-    void setDisabledIcon(Icon disabledIcon)
+
+    public Object[] allKeys()
     {
-	//          Set the icon to be displayed if this JTextComponent is "disabled" (JTextComponent.setEnabled(false)).  
+      Object[] superKeys = super.allKeys();
+      Object[] mapKeys = map.getBoundKeyStrokes(); 
+      Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
     }
-    void setDisplayedMnemonic(char aChar)
+
+  }
+
+  static class DefaultKeymap implements Keymap
+  {
+    String name;
+    Keymap parent;
+    Hashtable map;
+    Action defaultAction;
+
+    public DefaultKeymap(String name)
+    {
+      this.name = name;
+      this.map = new Hashtable();
+    }
+
+    public void addActionForKeyStroke(KeyStroke key, Action a)
+    {
+      map.put(key, a);
+    }
+
+    /**
+     * Looks up a KeyStroke either in the current map or the parent Keymap;
+     * does <em>not</em> return the default action if lookup fails.
+     *
+     * @param key The KeyStroke to look up an Action for.
+     *
+     * @return The mapping for <code>key</code>, or <code>null</code>
+     * if no mapping exists in this Keymap or any of its parents.
+     */
+    public Action getAction(KeyStroke key)
+    {
+      if (map.containsKey(key))
+        return (Action) map.get(key);
+      else if (parent != null)
+        return parent.getAction(key);
+      else
+        return null;
+    }
+
+    public Action[] getBoundActions()
     {
-	//          Specifies the displayedMnemonic as a char value.  
+      Action [] ret = new Action[map.size()];
+      Enumeration e = map.elements();
+      int i = 0;
+      while (e.hasMoreElements())
+        {
+          ret[i++] = (Action) e.nextElement();
+        }
+      return ret;
     }
-    void setDisplayedMnemonic(int key)
+
+    public KeyStroke[] getBoundKeyStrokes()
     {
-	//          Specify a keycode that indicates a mnemonic key.  
+      KeyStroke [] ret = new KeyStroke[map.size()];
+      Enumeration e = map.keys();
+      int i = 0;
+      while (e.hasMoreElements())
+        {
+          ret[i++] = (KeyStroke) e.nextElement();
+        }
+      return ret;
     }
-    void setHorizontalAlignment(int alignment)
+
+    public Action getDefaultAction()
     {
-	//          Sets the alignment of the label's contents along the X axis.  
+      return defaultAction;
     }
-    void setHorizontalTextPosition(int textPosition)
+
+    public KeyStroke[] getKeyStrokesForAction(Action a)
     {
-	//          Sets the horizontal position of the label's text, relative to its image.  
+      int i = 0;
+      Enumeration e = map.keys();
+      while (e.hasMoreElements())
+        {
+          if (map.get(e.nextElement()).equals(a))
+            ++i;
+        }
+      KeyStroke [] ret = new KeyStroke[i];
+      i = 0;
+      e = map.keys();
+      while (e.hasMoreElements())
+        {          
+          KeyStroke k = (KeyStroke) e.nextElement();
+          if (map.get(k).equals(a))
+            ret[i++] = k;            
+        }
+      return ret;
     }
-    void setIcon(Icon icon)
+
+    public String getName()
     {
-	//          Defines the icon this component will display.  
+      return name;
     }
-    public void setIconTextGap(int iconTextGap)
+
+    public Keymap getResolveParent()
     {
-	//          If both the icon and text properties are set, this property defines the space between them.  
+      return parent;
     }
-  
-    public void setLabelFor(Component c)
+
+    public boolean isLocallyDefined(KeyStroke key)
     {
-	//          Set the component this is labelling.  
+      return map.containsKey(key);
     }
-    
-    public void setVerticalAlignment(int alignment)
+
+    public void removeBindings()
     {
-	//          Sets the alignment of the label's contents along the Y axis.  
+      map.clear();
     }
-    public void setVerticalTextPosition(int textPosition)
+
+    public void removeKeyStrokeBinding(KeyStroke key)
     {
-	//          Sets the vertical position of the label's text, relative to its image.  
+      map.remove(key);
     }
 
-    public TextUI getUI()
-    {	return (TextUI) ui;
+    public void setDefaultAction(Action a)
+    {
+      defaultAction = a;
     }
 
-    public void updateUI()
+    public void setResolveParent(Keymap p)
     {
-	TextUI b = (TextUI)UIManager.getUI(this);
-	setUI(b);
+      parent = p;
     }
 
+  }
+
+  private static final long serialVersionUID = -8796518220218978795L;
+  
+  public static final String DEFAULT_KEYMAP = "default";
+  public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
+  
+  private static Hashtable keymaps = new Hashtable();
+  private Keymap keymap;
+  
+  /**
+   * Get a Keymap from the global keymap table, by name.
+   *
+   * @param n The name of the Keymap to look up
+   *
+   * @return A Keymap associated with the provided name, or
+   * <code>null</code> if no such Keymap exists
+   *
+   * @see #addKeymap()
+   * @see #removeKeymap()
+   * @see #keymaps
+   */
+  public static Keymap getKeymap(String n)
+  {
+    return (Keymap) keymaps.get(n);
+  }
+
+  /**
+   * Remove a Keymap from the global Keymap table, by name.
+   *
+   * @param n The name of the Keymap to remove
+   *
+   * @return The keymap removed from the global table
+   *
+   * @see #addKeymap()
+   * @see #getKeymap()
+   * @see #keymaps
+   */  
+  public static Keymap removeKeymap(String n)
+  {
+    Keymap km = (Keymap) keymaps.get(n);
+    keymaps.remove(n);
+    return km;
+  }
+
+  /**
+   * Create a new Keymap with a specific name and parent, and add the new
+   * Keymap to the global keymap table. The name may be <code>null</code>,
+   * in which case the new Keymap will <em>not</em> be added to the global
+   * Keymap table. The parent may also be <code>null</code>, which is
+   * harmless.
+   * 
+   * @param n The name of the new Keymap, or <code>null</code>
+   * @param parent The parent of the new Keymap, or <code>null</code>
+   *
+   * @return The newly created Keymap
+   *
+   * @see #removeKeymap()
+   * @see #getKeymap()
+   * @see #keymaps
+   */
+  public static Keymap addKeymap(String n, Keymap parent)
+  {
+    Keymap k = new DefaultKeymap(n);
+    k.setResolveParent(parent);
+    if (n != null)
+      keymaps.put(n, k);
+    return k;
+  }
+
+  /**
+   * Get the current Keymap of this component.
+   *
+   * @return The component's current Keymap
+   *
+   * @see #setKeymap()
+   * @see #keymap
+   */
+  Keymap getKeymap() 
+  {
+    return keymap;
+  }
+
+  /**
+   * Set the current Keymap of this component, installing appropriate
+   * {@link KeymapWrapper} and {@link KeymapActionMap} objects in the
+   * {@link InputMap} and {@link ActionMap} parent chains, respectively,
+   * and fire a property change event with name <code>"keymap"</code>.
+   *
+   * @see #getKeymap()
+   * @see #keymap
+   */
+  public void setKeymap(Keymap k) 
+  {
+
+    // phase 1: replace the KeymapWrapper entry in the InputMap chain.
+    // the goal here is to always maintain the following ordering:
+    //
+    //   [InputMap]? -> [KeymapWrapper]? -> [InputMapUIResource]*
+    // 
+    // that is to say, component-specific InputMaps need to remain children
+    // of Keymaps, and Keymaps need to remain children of UI-installed
+    // InputMaps (and the order of each group needs to be preserved, of
+    // course).
+    
+    KeymapWrapper kw = (k == null ? null : new KeymapWrapper(k));
+    InputMap childInputMap = getInputMap(JComponent.WHEN_FOCUSED);
+    if (childInputMap == null)
+      setInputMap(JComponent.WHEN_FOCUSED, kw);
+    else
+      {
+        while (childInputMap.getParent() != null 
+               && !(childInputMap.getParent() instanceof KeymapWrapper)
+               && !(childInputMap.getParent() instanceof InputMapUIResource))
+          childInputMap = childInputMap.getParent();
+
+        // option 1: there is nobody to replace at the end of the chain
+        if (childInputMap.getParent() == null)
+          childInputMap.setParent(kw);
+        
+        // option 2: there is already a KeymapWrapper in the chain which
+        // needs replacing (possibly with its own parents, possibly without)
+        else if (childInputMap.getParent() instanceof KeymapWrapper)
+          {
+            if (kw == null)
+              childInputMap.setParent(childInputMap.getParent().getParent());
+            else
+              {
+                kw.setParent(childInputMap.getParent().getParent());
+                childInputMap.setParent(kw);
+              }
+          }
+
+        // option 3: there is an InputMapUIResource in the chain, which marks
+        // the place where we need to stop and insert ourselves
+        else if (childInputMap.getParent() instanceof InputMapUIResource)
+          {
+            if (kw != null)
+              {
+                kw.setParent(childInputMap.getParent());
+                childInputMap.setParent(kw);
+              }
+          }
+      }
+
+    // phase 2: replace the KeymapActionMap entry in the ActionMap chain
+
+    KeymapActionMap kam = (k == null ? null : new KeymapActionMap(k));
+    ActionMap childActionMap = getActionMap();
+    if (childActionMap == null)
+      setActionMap(kam);
+    else
+      {
+        while (childActionMap.getParent() != null 
+               && !(childActionMap.getParent() instanceof KeymapActionMap)
+               && !(childActionMap.getParent() instanceof ActionMapUIResource))
+          childActionMap = childActionMap.getParent();
+
+        // option 1: there is nobody to replace at the end of the chain
+        if (childActionMap.getParent() == null)
+          childActionMap.setParent(kam);
+        
+        // option 2: there is already a KeymapActionMap in the chain which
+        // needs replacing (possibly with its own parents, possibly without)
+        else if (childActionMap.getParent() instanceof KeymapActionMap)
+          {
+            if (kam == null)
+              childActionMap.setParent(childActionMap.getParent().getParent());
+            else
+              {
+                kam.setParent(childActionMap.getParent().getParent());
+                childActionMap.setParent(kam);
+              }
+          }
+
+        // option 3: there is an ActionMapUIResource in the chain, which marks
+        // the place where we need to stop and insert ourselves
+        else if (childActionMap.getParent() instanceof ActionMapUIResource)
+          {
+            if (kam != null)
+              {
+                kam.setParent(childActionMap.getParent());
+                childActionMap.setParent(kam);
+              }
+          }
+      }
+
+    // phase 3: update the explicit keymap field
+
+    Keymap old = keymap;
+    keymap = k;
+    firePropertyChange("keymap", old, k);
+  }
+
+  /**
+   * Resolves a set of bindings against a set of actions and inserts the
+   * results into a {@link Keymap}. Specifically, for each provided binding
+   * <code>b</code>, if there exists a provided action <code>a</code> such
+   * that <code>a.getValue(Action.NAME) == b.ActionName</code> then an
+   * entry is added to the Keymap mapping <code>b</code> to
+   * </code>a</code>.
+   *
+   * @param map The Keymap to add new mappings to
+   * @param bindings The set of bindings to add to the Keymap
+   * @param actions The set of actions to resolve binding names against
+   *
+   * @see Action#NAME
+   * @see Action#getValue()
+   * @see KeyBinding#ActionName
+   */
+  public static void loadKeymap(Keymap map, 
+                                JTextComponent.KeyBinding[] bindings, 
+                                Action[] actions)
+  {
+    Hashtable acts = new Hashtable(actions.length);
+    for (int i = 0; i < actions.length; ++i)
+      acts.put(actions[i].getValue(Action.NAME), actions[i]);
+    for (int i = 0; i < bindings.length; ++i)
+      if (acts.containsKey(bindings[i].actionName))
+        map.addActionForKeyStroke(bindings[i].key, (Action) acts.get(bindings[i].actionName));
+  }
+
+  /**
+   * Returns the set of available Actions this component's associated
+   * editor can run.  Equivalent to calling
+   * <code>getUI().getEditorKit().getActions()</code>. This set of Actions
+   * is a reasonable value to provide as a parameter to {@link
+   * #loadKeymap()}, when resolving a set of {@link #KeyBinding} objects
+   * against this component.
+   *
+   * @return The set of available Actions on this component's {@link EditorKit}
+   *
+   * @see TextUI#getEditorKit()
+   * @see EditorKit#getActions()
+   */
+  public Action[] getActions()
+  {
+    return getUI().getEditorKit(this).getActions();
+  }
+    
+  private Document doc;
+  private Caret caret;
+  private Highlighter highlighter;
+  private Color caretColor;
+  private Color disabledTextColor;
+  private Color selectedTextColor;
+  private Color selectionColor;
+  private boolean editable;
+  private Insets margin;
+
+  /**
+   * Creates a new <code>JTextComponent</code> instance.
+   */
+  public JTextComponent()
+  {
+    Keymap defkeymap = getKeymap(DEFAULT_KEYMAP);
+    boolean creatingKeymap = false;
+    if (defkeymap == null)
+      {
+        defkeymap = addKeymap(DEFAULT_KEYMAP, null);
+        defkeymap.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction());
+        creatingKeymap = true;
+      }
+
+    setFocusable(true);
+    enableEvents(AWTEvent.KEY_EVENT_MASK);
+    updateUI();
+    
+    // need to do this after updateUI()
+    if (creatingKeymap)
+      loadKeymap(defkeymap, 
+                 new KeyBinding[] { 
+                   new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
+                                  DefaultEditorKit.backwardAction),
+                   new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
+                                  DefaultEditorKit.forwardAction),
+                   new KeyBinding(KeyStroke.getKeyStroke("typed \b"),
+                                  DefaultEditorKit.deletePrevCharAction),
+                   new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"),
+                                  DefaultEditorKit.deleteNextCharAction)                   
+                 },
+                 getActions());
+  }
+
+  public void setDocument(Document newDoc)
+  {
+    Document oldDoc = doc;
+    doc = newDoc;
+    firePropertyChange("document", oldDoc, newDoc);
+    revalidate();
+    repaint();
+  }
+
+  public Document getDocument()
+  {
+    return doc;
+  }
+
+  /**
+   * Get the <code>AccessibleContext<code> of this object.
+   *
+   * @return an <code>AccessibleContext</code> object
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    return null;
+  }
+
+  public void setMargin(Insets m)
+  {
+    margin = m;
+  }
+
+  public Insets getMargin()
+  {
+    return margin;
+  }
+
+  public void setText(String text)
+  {
+    try
+      {
+	doc.remove(0, doc.getLength());
+	doc.insertString(0, text, null);
+      }
+    catch (BadLocationException e)
+      {
+      }
+  }
+
+  /**
+   * Retrieves the current text in this text document.
+   *
+   * @return the text
+   *
+   * @exception NullPointerException if the underlaying document is null
+   */
+  public String getText()
+  {
+    if (doc == null)
+      return null;
+
+    try
+      {
+	return doc.getText(0, doc.getLength());
+      }
+    catch (BadLocationException e)
+      {
+	// This should never happen.
+	return "";
+      }
+  }
+
+  /**
+   * Retrieves a part of the current text in this document.
+   *
+   * @param offset the postion of the first character
+   * @param length the length of the text to retrieve
+   *
+   * @return the text
+   *
+   * @exception BadLocationException if arguments do not hold pre-conditions
+   */
+  public String getText(int offset, int length)
+    throws BadLocationException
+  {
+    return getDocument().getText(offset, length);
+  }
+
+  /**
+   * Returns a string that specifies the name of the Look and Feel class
+   * that renders this component.
+   *
+   * @return the string "TextComponentUI"
+   */
+  public String getUIClassID()
+  {
+    return "TextComponentUI";
+  }
+
+  /**
+   * Returns a string representation of this JTextComponent.
+   */
+  protected String paramString()
+  {
+    return "JTextComponent";
+  }
+
+  /**
+   * This method returns the label's UI delegate.
+   *
+   * @return The label's UI delegate.
+   */
+  public TextUI getUI()
+  {
+    return (TextUI) ui;
+  }
+
+  /**
+   * This method sets the label's UI delegate.
+   *
+   * @param ui The label's UI delegate.
+   */
+  public void setUI(TextUI newUI)
+  {
+    super.setUI(newUI);
+  }
+
+  /**
+   * This method resets the label's UI delegate to the default UI for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((TextUI) UIManager.getUI(this));
+  }
+
   public Dimension getPreferredScrollableViewportSize()
   {
     return null;
   }
+
   public int getScrollableUnitIncrement(Rectangle visible, int orientation,
                                         int direction)
   {
     return 0;
   }
+
   public int getScrollableBlockIncrement(Rectangle visible, int orientation,
                                          int direction)
   {
     return 0;
   }
-} // class JTextComponent
 
+  /**
+   * Checks whether this text component it editable.
+   *
+   * @return true if editable, false otherwise
+   */
+  public boolean isEditable()
+  {
+    return editable;
+  }
+
+  /**
+   * Enables/disabled this text component's editability.
+   *
+   * @param editable true to make it editable, false otherwise.
+   */
+  public void setEditable(boolean editable)
+  {
+    firePropertyChange("editable", this.editable, editable);
+    this.editable = editable;
+  }
+
+  /**
+   * The <code>Caret</code> object used in this text component.
+   *
+   * @return the caret object
+   */
+  public Caret getCaret()
+  {
+    return caret;
+  }
+
+  /**
+   * Sets a new <code>Caret</code> for this text component.
+   *
+   * @param newCaret the new <code>Caret</code> to set
+   */
+  public void setCaret(Caret newCaret)
+  {
+    if (caret != null)
+      caret.deinstall(this);
+    
+    Caret oldCaret = caret;
+    caret = newCaret;
+
+    if (caret != null)
+      caret.install(this);
+    
+    firePropertyChange("caret", oldCaret, newCaret);
+  }
+
+  public Color getCaretColor()
+  {
+    return caretColor;
+  }
+
+  public void setCaretColor(Color newColor)
+  {
+    Color oldCaretColor = caretColor;
+    caretColor = newColor;
+    firePropertyChange("caretColor", oldCaretColor, newColor);
+  }
+
+  public Color getDisabledTextColor()
+  {
+    return disabledTextColor;
+  }
+
+  public void setDisabledTextColor(Color newColor)
+  {
+    Color oldColor = disabledTextColor;
+    disabledTextColor = newColor;
+    firePropertyChange("disabledTextColor", oldColor, newColor);
+  }
+
+  public Color getSelectedTextColor()
+  {
+    return selectedTextColor;
+  }
+
+  public void setSelectedTextColor(Color newColor)
+  {
+    Color oldColor = selectedTextColor;
+    selectedTextColor = newColor;
+    firePropertyChange("selectedTextColor", oldColor, newColor);
+  }
+
+  public Color getSelectionColor()
+  {
+    return selectionColor;
+  }
+
+  public void setSelectionColor(Color newColor)
+  {
+    Color oldColor = selectionColor;
+    selectionColor = newColor;
+    firePropertyChange("selectionColor", oldColor, newColor);
+  }
+
+  /**
+   * Retrisves the current caret position.
+   *
+   * @return the current position
+   */
+  public int getCaretPosition()
+  {
+    return caret.getDot();
+  }
+
+  /**
+   * Sets the caret to a new position.
+   *
+   * @param position the new position
+   */
+  public void setCaretPosition(int position)
+  {
+    if (doc == null)
+      return;
+
+    if (position < 0 || position > doc.getLength())
+      throw new IllegalArgumentException();
+
+    caret.setDot(position);
+  }
+
+  /**
+   * Moves the caret to a given position. This selects the text between
+   * the old and the new position of the caret.
+   */
+  public void moveCaretPosition(int position)
+  {
+    if (doc == null)
+      return;
+
+    if (position < 0 || position > doc.getLength())
+      throw new IllegalArgumentException();
+
+    caret.moveDot(position);
+  }
+
+  public Highlighter getHighlighter()
+  {
+    return highlighter;
+  }
+
+  public void setHighlighter(Highlighter newHighlighter)
+  {
+    if (highlighter != null)
+      highlighter.deinstall(this);
+    
+    Highlighter oldHighlighter = highlighter;
+    highlighter = newHighlighter;
+
+    if (highlighter != null)
+      highlighter.install(this);
+    
+    firePropertyChange("highlighter", oldHighlighter, newHighlighter);
+  }
 
+  /**
+   * Returns the start postion of the currently selected text.
+   *
+   * @return the start postion
+   */
+  public int getSelectionStart()
+  {
+    return Math.min(caret.getDot(), caret.getMark());
+  }
 
+  /**
+   * Selects the text from the given postion to the selection end position.
+   *
+   * @param end the start positon of the selected text.
+   */
+  public void setSelectionStart(int start)
+  {
+    select(start, getSelectionEnd());
+  }
 
+  /**
+   * Returns the end postion of the currently selected text.
+   *
+   * @return the end postion
+   */
+  public int getSelectionEnd()
+  {
+    return Math.max(caret.getDot(), caret.getMark());
+  }
 
+  /**
+   * Selects the text from the selection start postion to the given position.
+   *
+   * @param end the end positon of the selected text.
+   */
+  public void setSelectionEnd(int end)
+  {
+    select(getSelectionStart(), end);
+  }
 
+  /**
+   * Selects a part of the content of the text component.
+   *
+   * @param start the start position of the selected text
+   * @param ent the end position of the selected text
+   */
+  public void select(int start, int end)
+  {
+    int length = doc.getLength();
+    
+    start = Math.max(start, 0);
+    start = Math.min(start, length);
 
+    end = Math.max(end, 0);
+    end = Math.min(end, length);
 
+    setCaretPosition(start);
+    moveCaretPosition(end);
+  }
 
+  /**
+   * Selects the whole content of the text component.
+   */
+  public void selectAll()
+  {
+    select(0, doc.getLength());
+  }
 
+  public synchronized void replaceSelection(String content)
+  {
+    int dot = caret.getDot();
+    int mark = caret.getMark();
 
+    // If content is empty delete selection.
+    if (content == null)
+      {
+	caret.setDot(dot);
+	return;
+      }
+
+    try
+      {
+	// Remove selected text.
+	if (dot != mark)
+	  doc.remove(Math.min(dot, mark), Math.max(dot, mark));
+
+	// Insert new text.
+	doc.insertString(Math.min(dot, mark), content, null);
+      }
+    catch (BadLocationException e)
+      {
+	// This should never happen.
+	System.out.println("Michael: JTextComponent.replaceSelection: Error");
+      }
+  }
 
+  public boolean getScrollableTracksViewportHeight()
+  {
+    if (getParent() instanceof JViewport)
+      return ((JViewport) getParent()).getHeight() > getPreferredSize().height;
+
+    return false;
+  }
+
+  public boolean getScrollableTracksViewportWidth()
+  {
+    if (getParent() instanceof JViewport)
+      return ((JViewport) getParent()).getWidth() > getPreferredSize().width;
+
+    return false;
+  }
+
+  /**
+   * Adds a <code>CaretListener</code> object to this text component.
+   *
+   * @param listener the listener to add
+   */
+  public void addCaretListener(CaretListener listener)
+  {
+    listenerList.add(CaretListener.class, listener);
+  }
+
+  /**
+   * Removed a <code>CaretListener</code> object from this text component.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeCaretListener(CaretListener listener)
+  {
+    listenerList.remove(CaretListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>CaretListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public CaretListener[] getCaretListeners()
+  {
+    return (CaretListener[]) getListeners(CaretListener.class);
+  }
+
+  /**
+   * Notifies all registered <code>CaretListener</code> objects that the caret
+   * was updated.
+   *
+   * @param event the event to send
+   */
+  protected void fireCaretUpdate(CaretEvent event)
+  {
+    CaretListener[] listeners = getCaretListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].caretUpdate(event);
+  }
+
+  /**
+   * Adds an <code>InputListener</code> object to this text component.
+   *
+   * @param listener the listener to add
+   */
+  public void addInputMethodListener(InputMethodListener listener)
+  {
+    listenerList.add(InputMethodListener.class, listener);
+  }
+
+  /**
+   * Removes an <code>InputListener</code> object from this text component.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeInputMethodListener(InputMethodListener listener)
+  {
+    listenerList.remove(InputMethodListener.class, listener);
+  }
+
+  /**
+   * Returns all added <code>InputMethodListener</code> objects.
+   *
+   * @return an array of listeners
+   */
+  public InputMethodListener[] getInputMethodListeners()
+  {
+    return (InputMethodListener[]) getListeners(InputMethodListener.class);
+  }
+
+  public Rectangle modelToView(int position) throws BadLocationException
+  {
+    return getUI().modelToView(this, position);
+  }
+}
Index: javax/swing/text/LayeredHighlighter.java
===================================================================
RCS file: javax/swing/text/LayeredHighlighter.java
diff -N javax/swing/text/LayeredHighlighter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/LayeredHighlighter.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,61 @@
+/* LayeredHighlighter.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.awt.Graphics;
+import java.awt.Shape;
+
+import javax.swing.text.JTextComponent;
+import javax.swing.text.View;
+
+
+public abstract class LayeredHighlighter
+  implements Highlighter
+{
+  public abstract static class LayerPainter
+    implements Highlighter.HighlightPainter
+  {
+    public abstract Shape paintLayer(Graphics g, int p0, int p1,
+				     Shape viewBounds, JTextComponent editor,
+				     View view);
+  }
+  
+  public abstract void paintLayeredHighlights(Graphics g, int p0, int p1,
+                                              Shape viewBounds,
+                                              JTextComponent editor, View view);
+}
Index: javax/swing/text/MutableAttributeSet.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/MutableAttributeSet.java,v
retrieving revision 1.3
diff -u -r1.3 MutableAttributeSet.java
--- javax/swing/text/MutableAttributeSet.java	10 Jan 2004 21:07:44 -0000	1.3
+++ javax/swing/text/MutableAttributeSet.java	6 Sep 2004 16:36:10 -0000
@@ -44,48 +44,42 @@
  * @author	Andrew Selkirk
  * @version	1.0
  */
-public interface MutableAttributeSet extends AttributeSet {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * addAttribute
-	 * @param name TODO
-	 * @param value TODO
-	 */
-	void addAttribute(Object name, Object value);
-
-	/**
-	 * addAttributes
-	 * @param attributes TODO
-	 */
-	void addAttributes(AttributeSet attributes);
-
-	/**
-	 * removeAttribute
-	 * @param name TODO
-	 */
-	void removeAttribute(Object name);
-
-	/**
-	 * removeAttributes
-	 * @param names TODO
-	 */
-	void removeAttributes(Enumeration names);
-
-	/**
-	 * removeAttributes
-	 * @param attributes TODO
-	 */
-	void removeAttributes(AttributeSet attributes);
-
-	/**
-	 * setResolveParent
-	 * @param parent TODO
-	 */
-	void setResolveParent(AttributeSet parent);
-
-
-} // MutableAttributeSet
+public interface MutableAttributeSet extends AttributeSet
+{
+  /**
+   * addAttribute
+   * @param name TODO
+   * @param value TODO
+   */
+  void addAttribute(Object name, Object value);
+
+  /**
+   * addAttributes
+   * @param attributes TODO
+   */
+  void addAttributes(AttributeSet attributes);
+
+  /**
+   * removeAttribute
+   * @param name TODO
+   */
+  void removeAttribute(Object name);
+
+  /**
+   * removeAttributes
+   * @param names TODO
+   */
+  void removeAttributes(Enumeration names);
+
+  /**
+   * removeAttributes
+   * @param attributes TODO
+   */
+  void removeAttributes(AttributeSet attributes);
+
+  /**
+   * setResolveParent
+   * @param parent TODO
+   */
+  void setResolveParent(AttributeSet parent);
+}
Index: javax/swing/text/PlainDocument.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/PlainDocument.java,v
retrieving revision 1.1
diff -u -r1.1 PlainDocument.java
--- javax/swing/text/PlainDocument.java	9 Aug 2002 04:26:12 -0000	1.1
+++ javax/swing/text/PlainDocument.java	6 Sep 2004 16:36:10 -0000
@@ -1,5 +1,5 @@
-/* PlainDocument.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* PlainDocument.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,22 +37,45 @@
 
 package javax.swing.text;
 
-
 public class PlainDocument extends AbstractDocument
 {
-    PlainDocument()
-    {
-	super(new GapContent());
-    }
-
-    public Element getDefaultRootElement()
-    {
-	return null;
-    }
-
-    public Element getParagraphElement(int  pos)
-    {
-	return null;
-    }
+  private static final long serialVersionUID = 4758290289196893664L;
+    
+  public static final String lineLimitAttribute = "lineLimit";
+  public static final String tabSizeAttribute = "tabSize";
+
+  private Element rootElement;
+  private int tabSize;
+  
+  public PlainDocument()
+  {
+    this(new GapContent());
+  }
+
+  public PlainDocument(AbstractDocument.Content content)
+  {
+    super(content);
+    tabSize = 8;
+    rootElement = createDefaultRoot();
+  }
+
+  protected AbstractDocument.AbstractElement createDefaultRoot()
+  {
+    BranchElement rootElement =
+      (BranchElement) createBranchElement(null, null);
+    Element[] lines = new Element[1];
+    lines[0] = createLeafElement(rootElement, null, 0, 1);
+    rootElement.replace(0, 0, lines);
+    return rootElement;
+  }
+
+  public Element getDefaultRootElement()
+  {
+    return rootElement;
+  }
+
+  public Element getParagraphElement(int pos)
+  {
+    return null;
+  }
 }
-
Index: javax/swing/text/PlainEditorKit.java
===================================================================
RCS file: javax/swing/text/PlainEditorKit.java
diff -N javax/swing/text/PlainEditorKit.java
--- javax/swing/text/PlainEditorKit.java	10 Jan 2004 21:07:44 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,103 +0,0 @@
-/* PlainEditorKit.java -- 
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package javax.swing.text;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import javax.swing.Action;
-import javax.swing.JEditorPane;
-
-public class PlainEditorKit extends EditorKit
-{
-    public PlainEditorKit()
-    {
-    }
-
-    public PlainEditorKit(PlainEditorKit kit)
-    {
-	super(kit);
-    }
-
-    protected Object clone()  
-    {
-	return new PlainEditorKit(this);
-    }
-    void deinstall(JEditorPane c)
-    {
-	//      Called when the kit is being removed from the JEditorPane. 
-    }
-    void install(JEditorPane c)
-    {
-    }
-
-    Caret createCaret()
-    {
-	return null;
-    }
-    Document createDefaultDocument()
-    {
-	return null;
-    }
-    Action[] getActions()
-    {
-	return null;
-    }
-    String getContentType()
-    {
-	return null;
-    }
-    ViewFactory getViewFactory()
-    {
-	return null;
-    }
-    void read(InputStream in, Document doc, int pos)
-    {	
-    }
-    void read(Reader in, Document doc, int pos)
-    {
-    }
-    void write(OutputStream out, Document doc, int pos, int len)
-    {
-    }
-    void write(Writer out, Document doc, int pos, int len)
-    {
-    }
-}
-
Index: javax/swing/text/PlainView.java
===================================================================
RCS file: javax/swing/text/PlainView.java
diff -N javax/swing/text/PlainView.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/PlainView.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,192 @@
+/* PlainView.java -- 
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+
+public class PlainView extends View
+  implements TabExpander
+{
+  private Color selectedColor;
+  private Color unselectedColor;
+  private Font font;
+  
+  protected FontMetrics metrics;
+
+  public PlainView(Element elem)
+  {
+    super(elem);
+  }
+
+  /**
+   * @since 1.4
+   */
+  protected void updateMetrics()
+  {
+    Component component = getContainer();
+    Font font = component.getFont();
+
+    if (this.font != font)
+      {
+	this.font = font;
+	metrics = component.getFontMetrics(font);
+      }
+  }
+  
+  /**
+   * @since 1.4
+   */
+  protected Rectangle lineToRect(Shape a, int line)
+  {
+    // Ensure metrics are up-to-date.
+    updateMetrics();
+    
+    Rectangle rect = a.getBounds();
+    int fontHeight = metrics.getHeight();
+    return new Rectangle(rect.x, rect.y + (line * fontHeight),
+			 rect.width, fontHeight);
+  }
+
+  public Shape modelToView(int position, Shape a, Position.Bias b)
+    throws BadLocationException
+  {
+    Document document = getDocument();
+
+    // Get rectangle of the line containing position.
+    int lineIndex = getElement().getElementIndex(position);
+    Rectangle rect = lineToRect(a, lineIndex);
+
+    // Get the rectangle for position.
+    Element line = getElement().getElement(lineIndex);
+    int lineStart = line.getStartOffset();
+    Segment segment = new Segment();
+    document.getText(lineStart, position - lineStart, segment);
+    int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
+					       this, lineStart);
+
+    // Calc the real rectangle.
+    rect.x += xoffset;
+    rect.width = 1;
+    rect.height = metrics.getHeight();
+
+    return rect;
+  }
+  
+  public void drawLine(int lineIndex, Graphics g, int x, int y)
+  {
+    try
+      {
+	metrics = g.getFontMetrics();
+	// FIXME: Selected text are not drawn yet.
+	drawUnselectedText(g, x, y, 0, getDocument().getLength());
+	//drawSelectedText(g, , , , );
+      }
+    catch (BadLocationException e)
+      {
+	// This should never happen.
+      }
+  }
+
+  public int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+    throws BadLocationException
+  {
+    g.setColor(selectedColor);
+    Segment segment = new Segment();
+    getDocument().getText(p0, p1 - p0, segment);
+    return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+  }
+
+  public int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
+    throws BadLocationException
+  {
+    g.setColor(unselectedColor);
+    Segment segment = new Segment();
+    getDocument().getText(p0, p1 - p0, segment);
+    return Utilities.drawTabbedText(segment, x, y, g, this, 0);
+  }
+
+  public void paint(Graphics g, Shape s)
+  {
+    JTextComponent textComponent = (JTextComponent) getContainer();
+
+    g.setFont(textComponent.getFont());
+    selectedColor = textComponent.getSelectedTextColor();
+    unselectedColor = textComponent.getForeground();
+    
+    Rectangle rect = s.getBounds();
+
+    // FIXME: Text may be scrolled.
+    drawLine(0, g, rect.x, rect.y);
+  }
+
+  public int getTabSize()
+  {
+    return 8;
+  }
+
+  /**
+   * Returns the next tab stop position after a given reference position.
+   *
+   * This implementation ignores the <code>tabStop</code> argument.
+   * 
+   * @param x the current x position in pixels
+   * @param tabStop the position within the text stream that the tab occured at
+   */
+  public float nextTabStop(float x, int tabStop)
+  {
+    float tabSizePixels = getTabSize() + metrics.charWidth('m');
+    return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
+  }
+
+  public float getPreferredSpan(int axis)
+  {
+    if (axis != X_AXIS && axis != Y_AXIS)
+      throw new IllegalArgumentException();
+
+    return 10;
+  }
+}
+
Index: javax/swing/text/Position.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/Position.java,v
retrieving revision 1.1
diff -u -r1.1 Position.java
--- javax/swing/text/Position.java	9 Aug 2002 04:26:12 -0000	1.1
+++ javax/swing/text/Position.java	6 Sep 2004 16:36:10 -0000
@@ -1,5 +1,5 @@
 /* Position.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,6 +42,20 @@
 {
     static class Bias
     {
+    public static final Bias Backward = new Bias("backward");
+    public static final Bias Forward = new Bias("forward");
+
+    private String name;
+    
+    private Bias(String n)
+    {
+      name = n;
+    }
+
+    public String toString()
+    {
+      return name;
+    }
     }
     
     int getOffset();
Index: javax/swing/text/Segment.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/Segment.java,v
retrieving revision 1.2
diff -u -r1.2 Segment.java
--- javax/swing/text/Segment.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/Segment.java	6 Sep 2004 16:36:10 -0000
@@ -37,71 +37,140 @@
 
 package javax.swing.text;
 
-public class Segment implements Cloneable, CharacterIterator
+import java.text.CharacterIterator;
+
+public class Segment
+  implements Cloneable, CharacterIterator
 {
-    char[] array;
-    int count;
-    int offset;
+  private boolean partialReturn;
+  private int current;
+  
+  public char[] array;
+  public int count;
+  public int offset;
+
+  public Segment()
+  {
+  }
+
+  public Segment(char[] array, int offset, int count)
+  {
+    this.array = array;
+    this.offset = offset;
+    this.count = count;
+  }
     
     public Object clone()
     {
-	try {
+    try
+      {
 	    return super.clone();
-	} catch (Exception e) {
-	    System.err.println("Huuuhhh, this class implements cloneable !!!!!!");
-	    System.err.println("I think there is a bug in this JVM somewhere");
 	}
+    catch (CloneNotSupportedException e)
+      {
 	return null;
-    }
+      }
+  }
+
+  public char current()
+  {
+    if (count == 0
+	|| current >= getEndIndex())
+      return DONE;
     
-    public char current()
-    {
-	return array[getIndex()];
-    }
+    return array[current];
+  }
 
-    public char first()
-    {
-	offset = getBeginIndex();
-	return array[offset];
-    }
+  public char first()
+  {
+    if (count == 0)
+      return DONE;
+
+    current = getBeginIndex();
+    return array[current];
+  }
+
+  public int getBeginIndex()
+  {
+    return offset;
+  }
+
+  public int getEndIndex()
+  {
+    return offset + count;
+  }
+
+  public int getIndex()
+  {
+    return current;
+  }
+
+  public char last()
+  {
+    if (count == 0)
+      return DONE;
     
-    public int getBeginIndex()
-    {
-	return offset;
-    }
+    current = getEndIndex() - 1;
+    return array[current];
+  }
+
+  public char next()
+  {
+    if (count == 0)
+      return DONE;
+
+    if ((current + 1) >= getEndIndex())
+      {
+	current = getEndIndex();
+	return DONE;
+      }
     
-    public int getEndIndex()
-    {
-	return offset + count;
-    }
-    public int getIndex()
-    {
-	return offset;
-    }
-    public char last()
-    {
-	offset = getEndIndex() - 1;
-	return array[offset];
-    }
-    public char next()
-    {
-	offset++;
-	return array[offset];
-    }
-    public char previous()
-    {
-	offset--;
-	return array[offset];
-    }
-    public char setIndex(int position)
-    {
-	offset = position;
-	return array[offset];
-    }
+    current++;
+    return array[current];
+  }
 
-    public String toString()
-    {
-	return new String(array, offset, count);
-    }
-}
+  public char previous()
+  {
+    if (count == 0
+	|| current == getBeginIndex())
+      return DONE;
+    
+    current--;
+    return array[current];
+  }
+
+  public char setIndex(int position)
+  {
+    if (position < getBeginIndex()
+	|| position > getEndIndex())
+      throw new IllegalArgumentException();
 
+    current = position;
+
+    if (position == getEndIndex())
+      return DONE;
+    
+    return array[current];
+  }
+
+  public String toString()
+  {
+    return new String(array, offset, count);
+  }
+
+  /**
+   * @since 1.4
+   */
+  public void setPartialReturn(boolean p)
+  {
+    partialReturn = p;
+  }
+  
+  /**
+   * @since 1.4
+   */
+  public boolean isPartialReturn()
+  {
+    return partialReturn;
+  }
+}
Index: javax/swing/text/SimpleAttributeSet.java
===================================================================
RCS file: javax/swing/text/SimpleAttributeSet.java
diff -N javax/swing/text/SimpleAttributeSet.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/SimpleAttributeSet.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,192 @@
+/* SimpleAttributeSet.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.lang.Cloneable;
+
+public class SimpleAttributeSet
+  implements MutableAttributeSet, Serializable, Cloneable
+{
+  Hashtable tab;
+
+  static AttributeSet EMPTY = new SimpleAttributeSet();
+
+  public SimpleAttributeSet()
+  {
+    this(null);
+  }
+  
+  public SimpleAttributeSet(AttributeSet a)
+  {
+    tab = new Hashtable();
+    addAttributes(a);
+  }
+
+  public void addAttribute(Object name, Object value)
+  {
+    tab.put(name, value);
+  }
+
+  public void addAttributes(AttributeSet attributes)
+  {
+    Enumeration e = attributes.getAttributeNames();
+    while (e.hasMoreElements())
+      {
+        Object name = e.nextElement();
+        Object val = attributes.getAttribute(name);
+        tab.put(name, val);
+      }
+  }
+
+  public Object clone()
+  {
+    SimpleAttributeSet s = new SimpleAttributeSet();
+    s.tab = (Hashtable) tab.clone();
+    return s;
+  }
+
+  public boolean containsAttribute(Object name, Object value)
+  {
+    return tab.containsKey(name) 
+      && tab.get(name).equals(value);
+  }
+    
+  public boolean containsAttributes(AttributeSet attributes)
+  {
+    Enumeration e = attributes.getAttributeNames();
+    while (e.hasMoreElements())
+      {
+        Object name = e.nextElement();
+        Object val = attributes.getAttribute(name);
+        if (! containsAttribute(name, val))
+          return false;		
+      }
+    return true;
+  }
+
+  public AttributeSet copyAttributes()
+  {
+    return (AttributeSet) clone();
+  }
+
+  public boolean equals(Object obj)
+  {
+    return (obj != null) 
+      && (obj instanceof SimpleAttributeSet)
+      && ((SimpleAttributeSet)obj).tab.equals(this.tab);
+  }
+
+  public Object getAttribute(Object name)
+  {
+    Object val = tab.get(name);
+    if (val != null) 
+      return val;
+
+    Object p = getResolveParent();
+    if (p != null && p instanceof AttributeSet)
+      return (((AttributeSet)p).getAttribute(name));
+
+    return null;
+  }
+
+  public int getAttributeCount()
+  {
+    return tab.size();
+  }
+
+  public Enumeration getAttributeNames()
+  {
+    return tab.keys();
+  }
+
+  public AttributeSet getResolveParent()
+  {
+    return (AttributeSet) tab.get(ResolveAttribute);
+  }
+
+  public int hashCode()
+  {
+    return tab.hashCode();
+  }
+
+  public boolean isDefined(Object attrName)
+  {
+    return tab.containsKey(attrName);
+  }
+
+  public boolean isEmpty()
+  {
+    return tab.isEmpty();	
+  }
+        
+  public boolean isEqual(AttributeSet attr)
+  {
+    return this.equals(attr);
+  }
+    
+  public void removeAttribute(Object name)
+  {
+    tab.remove(name);
+  }
+
+  public void removeAttributes(AttributeSet attributes)
+  {
+    removeAttributes(attributes.getAttributeNames());
+  }
+
+  public void removeAttributes(Enumeration names)
+  {
+    while (names.hasMoreElements())
+      {
+        removeAttribute(names.nextElement());
+      }	
+  }
+
+  public void setResolveParent(AttributeSet parent)
+  {
+    addAttribute(ResolveAttribute, parent);
+  }
+    
+  public String toString()
+  {
+    return tab.toString();
+  }    
+}
Index: javax/swing/text/Style.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/Style.java,v
retrieving revision 1.2
diff -u -r1.2 Style.java
--- javax/swing/text/Style.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/Style.java	6 Sep 2004 16:36:10 -0000
@@ -39,9 +39,26 @@
 
 import javax.swing.event.ChangeListener;
 
-public interface Style
+public interface Style extends MutableAttributeSet
 {
-    void addChangeListener(ChangeListener l);
-    String getName();
-    void removeChangeListener(ChangeListener l);
+  /**
+   * Returns the name of the style.
+   *
+   * @return the name
+   */
+  String getName();
+
+  /**
+   * Adds a <code>ChangeListener</code> object to the style.
+   *
+   * @param listener the listener object to add
+   */
+  void addChangeListener(ChangeListener listener);
+
+  /**
+   * Removes a <code>ChangeListener</code> from to the style.
+   *
+   * @param listener the listener object to remove,
+   */
+  void removeChangeListener(ChangeListener listener);
 }
Index: javax/swing/text/StyleConstants.java
===================================================================
RCS file: javax/swing/text/StyleConstants.java
diff -N javax/swing/text/StyleConstants.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/StyleConstants.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,439 @@
+/* StyleConstants.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Component;
+import javax.swing.Icon;
+
+public class StyleConstants
+{
+
+  String keyname;
+  private StyleConstants(String k) 
+  {
+    keyname = k;
+  }
+
+  public String toString()
+  {
+    return keyname;
+  }
+
+  public static int ALIGN_CENTER;
+  public static int ALIGN_JUSTIFIED;
+  public static int ALIGN_LEFT;
+  public static int ALIGN_RIGHT;
+
+  public static Object Background = CharacterConstants.Background;
+  public static Object BidiLevel = CharacterConstants.BidiLevel;
+  public static Object Bold = CharacterConstants.Bold;
+  public static Object ComponentAttribute = CharacterConstants.ComponentAttribute;
+  public static Object FontFamily = CharacterConstants.Family;
+  public static Object FontSize = CharacterConstants.Size;
+  public static Object Foreground = CharacterConstants.Foreground;
+  public static Object IconAttribute = CharacterConstants.IconAttribute;
+  public static Object Italic = CharacterConstants.Italic;
+  public static Object StrikeThrough = CharacterConstants.StrikeThrough;
+  public static Object Subscript = CharacterConstants.Subscript;
+  public static Object Superscript = CharacterConstants.Superscript;
+  public static Object Underline = CharacterConstants.Underline;
+
+  public static Object Alignment = ParagraphConstants.Alignment;
+  public static Object FirstLineIndent = ParagraphConstants.FirstLineIndent;
+  public static Object LeftIndent = ParagraphConstants.LeftIndent;
+  public static Object LineSpacing = ParagraphConstants.LineSpacing;
+  public static Object Orientation = ParagraphConstants.Orientation;
+  public static Object RightIndent = ParagraphConstants.RightIndent;
+  public static Object SpaceAbove = ParagraphConstants.SpaceAbove;
+  public static Object SpaceBelow = ParagraphConstants.SpaceBelow;
+  public static Object TabSet = ParagraphConstants.TabSet;
+
+  public static String ComponentElementName = new String("component");
+  public static String IconElementName = new String("icon");
+
+  public static Object ComposedTextAttribute = new StyleConstants("composed text");
+  public static Object ModelAttribute = new StyleConstants("model");
+  public static Object NameAttribute = new StyleConstants("name");
+  public static Object ResolveAttribute = new StyleConstants("resolver");
+
+  public static int getAlignment(AttributeSet a)
+  {
+    if (a.isDefined(Alignment))
+      return ((Integer)a.getAttribute(Alignment)).intValue();
+    else
+      return ALIGN_LEFT;      
+  } 
+
+  public static Color getBackground(AttributeSet a)
+  {
+    if (a.isDefined(Background))
+      return (Color) a.getAttribute(Background);
+    else
+      return Color.BLACK;
+  } 
+  
+  public static int getBidiLevel(AttributeSet a)
+  {
+    if (a.isDefined(BidiLevel))
+      return ((Integer)a.getAttribute(BidiLevel)).intValue();
+    else
+      return 0;
+  } 
+
+  public static Component getComponent(AttributeSet a)
+  {
+    if (a.isDefined(ComponentAttribute))
+      return (Component) a.getAttribute(ComponentAttribute);
+    else
+      return (Component) null;
+  } 
+
+  public static float getFirstLineIndent(AttributeSet a)
+  {
+    if (a.isDefined(FirstLineIndent))
+      return ((Float)a.getAttribute(FirstLineIndent)).floatValue();
+    else
+      return 0.f;
+  } 
+
+  public static String getFontFamily(AttributeSet a)
+  {
+    if (a.isDefined(FontFamily))
+      return (String) a.getAttribute(FontFamily);
+    else
+      return "Monospaced";
+  } 
+
+  public static int getFontSize(AttributeSet a)
+  {
+    if (a.isDefined(FontSize))
+      return ((Integer)a.getAttribute(FontSize)).intValue();
+    else
+      return 12;
+  } 
+
+  public static Color getForeground(AttributeSet a)
+  {
+    if (a.isDefined(Foreground))
+      return (Color) a.getAttribute(Foreground);
+    else
+      return Color.BLACK;
+  } 
+
+  public static Icon getIcon(AttributeSet a)
+  {
+    if (a.isDefined(IconAttribute))
+      return (Icon) a.getAttribute(IconAttribute);
+    else
+      return (Icon) null;
+  } 
+
+  public static float getLeftIndent(AttributeSet a)
+  {
+    if (a.isDefined(LeftIndent))
+      return ((Float)a.getAttribute(LeftIndent)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getLineSpacing(AttributeSet a)
+  {
+    if (a.isDefined(LineSpacing))
+      return ((Float)a.getAttribute(LineSpacing)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getRightIndent(AttributeSet a)
+  {
+    if (a.isDefined(RightIndent))
+      return ((Float)a.getAttribute(RightIndent)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getSpaceAbove(AttributeSet a)
+  {
+    if (a.isDefined(SpaceAbove))
+      return ((Float)a.getAttribute(SpaceAbove)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getSpaceBelow(AttributeSet a)
+  {
+    if (a.isDefined(SpaceBelow))
+      return ((Float)a.getAttribute(SpaceBelow)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static javax.swing.text.TabSet getTabSet(AttributeSet a)
+  {
+    if (a.isDefined(StyleConstants.TabSet))
+      return (javax.swing.text.TabSet) a.getAttribute(StyleConstants.TabSet);
+    else
+      return (javax.swing.text.TabSet) null;
+  } 
+
+  public static boolean isBold(AttributeSet a)
+  {
+    if (a.isDefined(Bold))
+      return ((Boolean) a.getAttribute(Bold)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isItalic(AttributeSet a)
+  {
+    if (a.isDefined(Italic))
+      return ((Boolean) a.getAttribute(Italic)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isStrikeThrough(AttributeSet a)
+  {
+    if (a.isDefined(StrikeThrough))
+      return ((Boolean) a.getAttribute(StrikeThrough)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isSubscript(AttributeSet a)
+  {
+    if (a.isDefined(Subscript))
+      return ((Boolean) a.getAttribute(Subscript)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isSuperscript(AttributeSet a)
+  {
+    if (a.isDefined(Superscript))
+      return ((Boolean) a.getAttribute(Superscript)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isUnderline(AttributeSet a)
+  {
+    if (a.isDefined(Underline))
+      return ((Boolean) a.getAttribute(Underline)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static void setAlignment(MutableAttributeSet a, int align)
+  {
+    a.addAttribute(Alignment, new Integer(align));
+  } 
+
+  public static void setBackground(MutableAttributeSet a, Color fg)
+  {
+    a.addAttribute(Background, fg);
+  } 
+
+  public static void setBidiLevel(MutableAttributeSet a, int lev)
+  {
+    a.addAttribute(BidiLevel, new Integer(lev));
+  } 
+
+  public static void setBold(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Bold, new Boolean(b));
+  } 
+  
+  public static void setComponent(MutableAttributeSet a, Component c)
+  {
+    a.addAttribute(ComponentAttribute, c);
+  } 
+
+  public static void setFirstLineIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(FirstLineIndent, new Float(i));
+  } 
+
+  public static void setFontFamily(MutableAttributeSet a, String fam)
+  {
+    a.addAttribute(FontFamily, fam);
+  } 
+
+  public static void setFontSize(MutableAttributeSet a, int s)
+  {
+    a.addAttribute(FontSize, new Integer(s));
+  } 
+
+  public static void setForeground(MutableAttributeSet a, Color fg)
+  {
+    a.addAttribute(Foreground, fg);
+  }
+
+  public static void setIcon(MutableAttributeSet a, Icon c)
+  {
+    a.addAttribute(IconAttribute, c);
+  }
+ 
+  public static void setItalic(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Italic, new Boolean(b));
+  }
+ 
+  public static void setLeftIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(LeftIndent, new Float(i));
+  } 
+
+  public static void setLineSpacing(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(LineSpacing, new Float(i));
+  } 
+
+  public static void setRightIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(RightIndent, new Float(i));
+  } 
+
+  public static void setSpaceAbove(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(SpaceAbove, new Float(i));
+  } 
+
+  public static void setSpaceBelow(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(SpaceBelow, new Float(i));
+  } 
+
+  public static void setStrikeThrough(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(StrikeThrough, new Boolean(b));
+  } 
+
+  public static void setSubscript(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Subscript, new Boolean(b));
+  } 
+
+  public static void setSuperscript(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Superscript, new Boolean(b));
+  } 
+
+  public static void setTabSet(MutableAttributeSet a, javax.swing.text.TabSet tabs)
+  {
+    a.addAttribute(StyleConstants.TabSet, tabs);
+  } 
+
+  public static void setUnderline(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Underline, new Boolean(b));
+  } 
+
+  // The remainder are so-called "typesafe enumerations" which 
+  // alias subsets of the above constants.
+  public static class CharacterConstants
+    extends StyleConstants
+    implements AttributeSet.CharacterAttribute
+  {
+    private CharacterConstants(String k) 
+    {
+      super(k);
+    }
+    
+    public static Object Background = ColorConstants.Background;
+    public static Object BidiLevel = new CharacterConstants("bidiLevel");
+    public static Object Bold = FontConstants.Bold;
+    public static Object ComponentAttribute = new CharacterConstants("component");
+    public static Object Family = FontConstants.Family;
+    public static Object Size = FontConstants.Size;
+    public static Object Foreground = ColorConstants.Foreground;
+    public static Object IconAttribute = new CharacterConstants("icon");
+    public static Object Italic = FontConstants.Italic;
+    public static Object StrikeThrough = new CharacterConstants("strikethrough");
+    public static Object Subscript = new CharacterConstants("subscript");
+    public static Object Superscript = new CharacterConstants("superscript");
+    public static Object Underline = new CharacterConstants("underline");
+  }
+
+  public static class ColorConstants
+    extends StyleConstants
+    implements AttributeSet.ColorAttribute, AttributeSet.CharacterAttribute
+  {
+    private ColorConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Foreground = new ColorConstants("foreground");
+    public static Object Background = new ColorConstants("background");
+  }
+
+  public static class FontConstants
+    extends StyleConstants
+    implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute
+  {
+    private FontConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Bold = new FontConstants("bold");
+    public static Object Family = new FontConstants("family");
+    public static Object Italic = new FontConstants("italic");
+    public static Object Size = new FontConstants("size");
+  }
+
+  public static class ParagraphConstants
+    extends StyleConstants
+    implements AttributeSet.ParagraphAttribute
+  {
+    private ParagraphConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Alignment = new ParagraphConstants("Alignment");
+    public static Object FirstLineIndent = new ParagraphConstants("FirstLineIndent");
+    public static Object LeftIndent = new ParagraphConstants("LeftIndent");
+    public static Object LineSpacing = new ParagraphConstants("LineSpacing");
+    public static Object Orientation = new ParagraphConstants("Orientation");
+    public static Object RightIndent = new ParagraphConstants("RightIndent");
+    public static Object SpaceAbove = new ParagraphConstants("SpaceAbove");
+    public static Object SpaceBelow = new ParagraphConstants("SpaceBelow");
+    public static Object TabSet = new ParagraphConstants("TabSet");
+  }
+
+}
Index: javax/swing/text/StyleContext.java
===================================================================
RCS file: javax/swing/text/StyleContext.java
diff -N javax/swing/text/StyleContext.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/StyleContext.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,697 @@
+/* StyleContext.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Toolkit;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Hashtable;
+
+public class StyleContext 
+    implements Serializable, AbstractDocument.AttributeContext
+{
+  public class NamedStyle
+    implements Serializable, Style
+  {
+    protected ChangeEvent changeEvent;
+    protected EventListenerList listenerList;
+      
+    AttributeSet attributes;
+    String name;
+
+    public NamedStyle()
+    {
+      this(null, null);
+    }
+
+    public NamedStyle(Style parent)
+    {
+      this(null, parent);
+    }
+
+    public NamedStyle(String name, Style parent)
+    {
+      this.name = name;
+      this.attributes = getEmptySet();
+      this.changeEvent = new ChangeEvent(this);
+      this.listenerList = new EventListenerList();
+      setResolveParent(parent);
+    }
+
+    public String getName()
+    {
+      return name;
+    }
+
+    public void setName(String n)
+    {
+      name = n;
+      fireStateChanged();
+    }
+
+    public void addChangeListener(ChangeListener l)
+    {
+      listenerList.add(ChangeListener.class, l);
+    }
+      
+    public void removeChangeListener(ChangeListener l)
+    {
+      listenerList.remove(ChangeListener.class, l);
+    }
+      
+    public EventListener[] getListeners(Class listenerType)
+    {
+      return listenerList.getListeners(listenerType);
+    }
+
+    public ChangeListener[] getChangeListeners()
+    {
+      return (ChangeListener[]) getListeners(ChangeListener.class);
+    }
+
+    protected  void fireStateChanged()
+    {
+      ChangeListener[] listeners = getChangeListeners();
+      for (int i = 0; i < listeners.length; ++i)
+        {
+          listeners[i].stateChanged(changeEvent);
+        }
+    }
+
+    public void addAttribute(Object name, Object value)
+    {
+      attributes = StyleContext.this.addAttribute(attributes, name, value);
+      fireStateChanged();
+    }
+
+    public void addAttributes(AttributeSet attr)
+    {
+      attributes = StyleContext.this.addAttributes(attributes, attr);
+      fireStateChanged();
+    }
+
+    public boolean containsAttribute(Object name, Object value)
+    {
+      return attributes.containsAttribute(name, value);
+    }
+      
+    public boolean containsAttributes(AttributeSet attrs)
+    {
+      return attributes.containsAttributes(attrs);
+    }
+
+    public AttributeSet copyAttributes()
+    {
+      return attributes.copyAttributes();
+    }
+            
+    public Object getAttribute(Object attrName)
+    {
+      return attributes.getAttribute(attrName);
+    }
+
+    public int getAttributeCount()
+    {
+      return attributes.getAttributeCount();
+    }
+
+    public Enumeration getAttributeNames()
+    {
+      return attributes.getAttributeNames();
+    }
+      
+    public boolean isDefined(Object attrName)
+    {
+      return attributes.isDefined(attrName);        
+    }
+
+    public boolean isEqual(AttributeSet attr)
+    {
+      return attributes.isEqual(attr);
+    }
+
+    public void removeAttribute(Object name)
+    {
+      attributes = StyleContext.this.removeAttribute(attributes, name);
+      fireStateChanged();
+    }
+
+    public void removeAttributes(AttributeSet attrs)
+    {
+      attributes = StyleContext.this.removeAttributes(attributes, attrs);
+      fireStateChanged();
+    }
+
+    public void removeAttributes(Enumeration names)
+    {
+      attributes = StyleContext.this.removeAttributes(attributes, names);
+      fireStateChanged();
+    }
+
+
+    public AttributeSet getResolveParent()
+    {
+      return attributes.getResolveParent();        
+    }
+
+    public void setResolveParent(AttributeSet parent)
+    {
+      attributes = StyleContext.this.addAttribute(attributes, ResolveAttribute, parent);
+      fireStateChanged();
+    }
+      
+    public String toString()
+    {
+      return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
+    }      
+  }
+  
+  public class SmallAttributeSet
+    implements AttributeSet
+  {
+    final Object [] attrs;
+    public SmallAttributeSet(AttributeSet a)
+    {
+      if (a == null)
+        attrs = new Object[0];
+      else
+        {
+          int n = a.getAttributeCount();
+          int i = 0;
+          attrs = new Object[n * 2];
+          Enumeration e = a.getAttributeNames();
+          while (e.hasMoreElements())
+            {
+              Object name = e.nextElement();
+              attrs[i++] = name;
+              attrs[i++] = a.getAttribute(name);
+            }
+        }
+    }
+
+    public SmallAttributeSet(Object [] a)
+    {
+      if (a == null)
+        attrs = new Object[0];
+      else
+        {
+          attrs = new Object[a.length];
+          System.arraycopy(a, 0, attrs, 0, a.length);
+        }
+    }
+
+    public Object clone()
+    {
+      return new SmallAttributeSet(this.attrs);
+    }
+
+    public boolean containsAttribute(Object name, Object value)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(name) &&
+              attrs[i+1].equals(value))
+            return true;
+        }
+      return false;
+    }
+
+    public boolean containsAttributes(AttributeSet a)
+    {
+      Enumeration e = a.getAttributeNames();
+      while (e.hasMoreElements())
+        {
+          Object name = e.nextElement();
+          Object val = a.getAttribute(name);
+          if (!containsAttribute(name, val))
+            return false;
+        }
+      return true;			
+    }
+
+    public AttributeSet copyAttributes()
+    {
+      return (AttributeSet) clone();
+    }
+
+    public boolean equals(Object obj)
+    {
+      return 
+        (obj instanceof SmallAttributeSet)
+        && this.isEqual((AttributeSet)obj);
+    }
+ 
+    public Object getAttribute(Object key)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(key))
+            return attrs[i+1];
+        }
+            
+      Object p = getResolveParent();
+      if (p != null && p instanceof AttributeSet)
+        return (((AttributeSet)p).getAttribute(key));
+      
+      return null;
+    }
+
+    public int getAttributeCount()
+    {
+      return attrs.length / 2;
+    }
+
+    public Enumeration getAttributeNames()
+    {      
+      return new Enumeration() 
+        {
+          int i = 0;
+          public boolean hasMoreElements() 
+          { 
+            return i < attrs.length; 
+          }
+          public Object nextElement() 
+          { 
+            i += 2; 
+            return attrs[i-2]; 
+          }
+        };
+    }
+
+    public AttributeSet getResolveParent()
+    {
+      return (AttributeSet) getAttribute(ResolveAttribute);
+    }
+
+    public int hashCode()
+    {
+      return java.util.Arrays.asList(attrs).hashCode();
+    }
+
+    public boolean isDefined(Object key)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(key))
+            return true;
+        }
+      return false;
+    }
+	
+    public boolean isEqual(AttributeSet attr)
+    {
+      return attr != null 
+        && attr.containsAttributes(this)
+        && this.containsAttributes(attr);
+    }
+	
+    public String toString()
+    {
+      StringBuffer sb = new StringBuffer();
+      sb.append("[StyleContext.SmallattributeSet:");
+      for (int i = 0; i < attrs.length; ++i)
+        {
+          sb.append(" (");
+          sb.append(attrs[i].toString());
+          sb.append("=");
+          sb.append(attrs[i+1].toString());
+          sb.append(")");
+        }
+      sb.append("]");
+      return sb.toString();
+    }
+  }
+
+  // FIXME: official javadocs suggest that these might be more usefully
+  // implemented using a WeakHashMap, but not sure if that works most
+  // places or whether it really matters anyways.
+  //
+  // FIXME: also not sure if these tables ought to be static (singletons),
+  // shared across all StyleContexts. I think so, but it's not clear in
+  // docs. revert to non-shared if you think it matters.
+
+  public static final String DEFAULT_STYLE = "default";
+  
+  static Hashtable sharedAttributeSets = new Hashtable();
+  static Hashtable sharedFonts = new Hashtable();
+
+  static StyleContext defaultStyleContext = new StyleContext();
+  static final int compressionThreshold = 9;
+  
+  EventListenerList listenerList;
+  Hashtable styleTable;
+  
+  public StyleContext()
+  {
+    listenerList = new EventListenerList();
+    styleTable = new Hashtable();
+  }
+
+  protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
+  {
+    return new SmallAttributeSet(a);
+  }
+  
+  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
+  {
+    return new SimpleAttributeSet(a);
+  }
+
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+    
+  public Style addStyle(String name, Style parent)
+  {
+    Style newStyle = new NamedStyle(name, parent);
+    if (name != null)
+      styleTable.put(name, newStyle);
+    return newStyle;
+  }
+
+  public void removeStyle(String name)
+  {
+    styleTable.remove(name);
+  }
+
+  public Style getStyle(String name)
+  {
+    return (Style) styleTable.get(name);
+  }
+
+  public Enumeration getStyleNames()
+  {
+    return styleTable.keys();
+  }
+
+  //
+  // StyleContexts only understand the "simple" model of fonts present in
+  // pre-java2d systems: fonts are a family name, a size (integral number
+  // of points), and a mask of style parameters (plain, bold, italic, or
+  // bold|italic). We have an inner class here called SimpleFontSpec which
+  // holds such triples.
+  //
+  // A SimpleFontSpec can be built for *any* AttributeSet because the size,
+  // family, and style keys in an AttributeSet have default values (defined
+  // over in StyleConstants).
+  //
+  // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
+  // that we reuse Fonts between styles and style contexts.
+  // 
+
+  private static class SimpleFontSpec
+  {
+    String family;
+    int style;
+    int size;
+    public SimpleFontSpec(String family,
+                          int style,
+                          int size)
+    {
+      this.family = family;
+      this.style = style;
+      this.size = size;
+    }
+    public boolean equals(Object obj)
+    {
+      return (obj != null)
+        && (obj instanceof SimpleFontSpec)
+        && (((SimpleFontSpec)obj).family.equals(this.family))
+        && (((SimpleFontSpec)obj).style == this.style)
+        && (((SimpleFontSpec)obj).size == this.size);
+    }
+    public int hashCode()
+    {
+      return family.hashCode() + style + size;
+    }
+  }
+  
+  public Font getFont(AttributeSet attr)
+  {
+    String family = StyleConstants.getFontFamily(attr);
+    int style = Font.PLAIN;
+    if (StyleConstants.isBold(attr))
+      style += Font.BOLD;
+    if (StyleConstants.isItalic(attr))
+      style += Font.ITALIC;      
+    int size = StyleConstants.getFontSize(attr);
+    return getFont(family, style, size);
+  }
+
+  public Font getFont(String family, int style, int size)
+  {
+    SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
+    if (sharedFonts.containsKey(spec))
+      return (Font) sharedFonts.get(spec);
+    else
+      {
+        Font tmp = new Font(family, style, size);
+        sharedFonts.put(spec, tmp);
+        return tmp;
+      }
+  }
+  
+  public FontMetrics getFontMetrics(Font f)
+  {
+    return Toolkit.getDefaultToolkit().getFontMetrics(f);
+  }
+
+  public Color getForeground(AttributeSet a)
+  {
+    return StyleConstants.getForeground(a);
+  }
+
+  public Color getBackground(AttributeSet a)
+  {
+    return StyleConstants.getBackground(a);
+  }
+
+  protected int getCompressionThreshold() 
+  {
+    return compressionThreshold;
+  }
+
+  public static StyleContext getDefaultStyleContext()
+  {
+    return defaultStyleContext;
+  }
+
+  public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).addAttribute(name, value);
+        return old;
+      }
+    else 
+      {
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.addAttribute(name, value);
+        if (mutable.getAttributeCount() >= getCompressionThreshold())
+          return mutable;
+        else
+          {
+            SmallAttributeSet small = createSmallAttributeSet(mutable);
+            if (sharedAttributeSets.containsKey(small))
+              small = (SmallAttributeSet) sharedAttributeSets.get(small);
+            else
+              sharedAttributeSets.put(small,small);
+            return small;
+          }
+      }
+  }
+
+  public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).addAttributes(attributes);
+        return old;
+      }
+    else 
+      {
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.addAttributes(attributes);
+        if (mutable.getAttributeCount() >= getCompressionThreshold())
+          return mutable;
+        else
+          {
+            SmallAttributeSet small = createSmallAttributeSet(mutable);
+            if (sharedAttributeSets.containsKey(small))
+              small = (SmallAttributeSet) sharedAttributeSets.get(small);
+            else
+              sharedAttributeSets.put(small,small);
+            return small;
+          }
+      }
+  }
+
+  public AttributeSet getEmptySet()
+  {
+    AttributeSet e = createSmallAttributeSet(null);
+    if (sharedAttributeSets.containsKey(e))
+      e = (AttributeSet) sharedAttributeSets.get(e);
+    else
+      sharedAttributeSets.put(e, e);
+    return e;
+  }
+
+  public void reclaim(AttributeSet attributes)
+  {
+    if (sharedAttributeSets.containsKey(attributes))
+      sharedAttributeSets.remove(attributes);
+  }
+
+  public AttributeSet removeAttribute(AttributeSet old, Object name)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).removeAttribute(name);
+        if (old.getAttributeCount() < getCompressionThreshold())
+          {
+            SmallAttributeSet small = createSmallAttributeSet(old);
+            if (!sharedAttributeSets.containsKey(small))
+              sharedAttributeSets.put(small,small);
+            old = (AttributeSet) sharedAttributeSets.get(small);
+          }
+        return old;
+      }
+    else 
+      {          
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.removeAttribute(name);
+        SmallAttributeSet small = createSmallAttributeSet(mutable);
+        if (sharedAttributeSets.containsKey(small))
+          small = (SmallAttributeSet) sharedAttributeSets.get(small);
+        else
+          sharedAttributeSets.put(small,small);
+        return small;
+      }
+  }
+
+  public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
+  {
+    return removeAttributes(old, attributes.getAttributeNames());
+  }
+
+  public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).removeAttributes(names);
+        if (old.getAttributeCount() < getCompressionThreshold())
+          {
+            SmallAttributeSet small = createSmallAttributeSet(old);
+            if (!sharedAttributeSets.containsKey(small))
+              sharedAttributeSets.put(small,small);
+            old = (AttributeSet) sharedAttributeSets.get(small);
+          }
+        return old;
+      }
+    else 
+      {          
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.removeAttributes(names);
+        SmallAttributeSet small = createSmallAttributeSet(mutable);
+        if (sharedAttributeSets.containsKey(small))
+          small = (SmallAttributeSet) sharedAttributeSets.get(small);
+        else
+          sharedAttributeSets.put(small,small);
+        return small;
+      }	
+  }
+
+
+  // FIXME: there's some sort of quasi-serialization stuff in here which I
+  // have left incomplete; I'm not sure I understand the intent properly.
+
+  public static Object getStaticAttribute(Object key)
+  {
+    throw new InternalError("not implemented");
+  }
+  
+  public static Object getStaticAttributeKey(Object key)
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
+    throws ClassNotFoundException, IOException
+  {
+    throw new InternalError("not implemented");
+  }
+  
+  public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
+    throws IOException
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
+    throws ClassNotFoundException, IOException 
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public void writeAttributes(ObjectOutputStream out, AttributeSet a)
+    throws IOException
+  {
+    throw new InternalError("not implemented");
+  }
+}
Index: javax/swing/text/StyledEditorKit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/StyledEditorKit.java,v
retrieving revision 1.3
diff -u -r1.3 StyledEditorKit.java
--- javax/swing/text/StyledEditorKit.java	10 Jan 2004 21:07:44 -0000	1.3
+++ javax/swing/text/StyledEditorKit.java	6 Sep 2004 16:36:10 -0000
@@ -41,339 +41,242 @@
 import java.awt.event.ActionEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
 import java.io.Serializable;
-import java.io.Writer;
 import javax.swing.Action;
 import javax.swing.JEditorPane;
 import javax.swing.event.CaretEvent;
 import javax.swing.event.CaretListener;
 
+
 /**
  * StyledEditorKit
+ *
  * @author	Andrew Selkirk
- * @version	1.0
  */
 public class StyledEditorKit extends DefaultEditorKit
 {
-  static final long serialVersionUID = 7002391892985555948L;
-
-	//-------------------------------------------------------------
-	// Classes ----------------------------------------------------
-	//-------------------------------------------------------------
+  private static final long serialVersionUID = 7002391892985555948L;
 
 	/**
 	 * UnderlineAction
 	 */
-	public static class UnderlineAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class UnderlineAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * Constructor UnderlineAction
 		 */
-		public UnderlineAction() {
+    public UnderlineAction()
+    {
 			super("TODO");
 			// TODO
-		} // UnderlineAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // UnderlineAction
+    }
+  }
 
 	/**
 	 * ItalicAction
 	 */
-	public static class ItalicAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class ItalicAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * Constructor ItalicAction
 		 */
-		public ItalicAction() {
+    public ItalicAction()
+    {
 			super("TODO");
 			// TODO
-		} // ItalicAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // ItalicAction
+    }
+  }
 
 	/**
 	 * BoldAction
 	 */
-	public static class BoldAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class BoldAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * Constructor BoldAction
 		 */
-		public BoldAction() {
+    public BoldAction()
+    {
 			super("TODO");
 			// TODO
-		} // BoldAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // BoldAction
+    }
+  }
 
 	/**
 	 * AlignmentAction
 	 */
-	public static class AlignmentAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class AlignmentAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * a
 		 */
 		private int a;
 
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
 		/**
 		 * Constructor AlignmentAction
 		 * @param nm TODO
 		 * @param a TODO
 		 */
-		public AlignmentAction(String nm, int a) {
+    public AlignmentAction(String nm, int a)
+    {
 			super("TODO");
 			// TODO
-		} // AlignmentAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // AlignmentAction
+    }
+  }
 
 	/**
 	 * ForegroundAction
 	 */
-	public static class ForegroundAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class ForegroundAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * fg
 		 */
 		private Color fg;
 
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
 		/**
 		 * Constructor ForegroundAction
 		 * @param nm TODO
 		 * @param fg TODO
 		 */
-		public ForegroundAction(String nm, Color fg) {
+    public ForegroundAction(String nm, Color fg)
+    {
 			super("TODO");
 			// TODO
-		} // ForegroundAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // ForegroundAction
+    }
+  }
 
 	/**
 	 * FontSizeAction
 	 */
-	public static class FontSizeAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class FontSizeAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * size
 		 */
 		private int size;
 
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
 		/**
 		 * Constructor FontSizeAction
 		 * @param nm TODO
 		 * @param size TODO
 		 */
-		public FontSizeAction(String nm, int size) {
+    public FontSizeAction(String nm, int size)
+    {
 			super("TODO");
 			// TODO
-		} // FontSizeAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // FontSizeAction
+    }
+  }
 
 	/**
 	 * FontFamilyAction
 	 */
-	public static class FontFamilyAction extends StyledEditorKit.StyledTextAction {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
+  public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
+  {
 		/**
 		 * family
 		 */
 		private String family;
 
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
 		/**
 		 * Constructor FontFamilyAction
 		 * @param nm TODO
 		 * @param family TODO
 		 */
-		public FontFamilyAction(String nm, String family) {
+    public FontFamilyAction(String nm, String family)
+    {
 			super("TODO");
 			// TODO
-		} // FontFamilyAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * actionPerformed
 		 * @param event TODO
 		 */
-		public void actionPerformed(ActionEvent event) {
+    public void actionPerformed(ActionEvent event)
+    {
 			// TODO
-		} // actionPerformed()
-
-
-	} // FontFamilyAction
+    }
+  }
 
 	/**
 	 * StyledTextAction
 	 */
-	public abstract static class StyledTextAction extends TextAction {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  public abstract static class StyledTextAction extends TextAction
+  {
 		/**
 		 * Constructor StyledTextAction
 		 * @param nm TODO
 		 */
-		public StyledTextAction(String nm) {
+    public StyledTextAction(String nm)
+    {
 			super(nm);
 			// TODO
-		} // StyledTextAction()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * getEditor
 		 * @param event TODO
 		 * @returns JEditorPane
 		 */
-		protected final JEditorPane getEditor(ActionEvent event) {
+    protected final JEditorPane getEditor(ActionEvent event)
+    {
 			return null; // TODO
-		} // getEditor()
+    }
 
 		/**
 		 * setCharacterAttributes
@@ -381,27 +284,32 @@
 		 * @param value1 TODO
 		 * @param value2 TODO
 		 */
-		protected final void setCharacterAttributes(JEditorPane value0, AttributeSet value1, boolean value2) {
+    protected final void setCharacterAttributes(JEditorPane value0,
+                                                AttributeSet value1,
+                                                boolean value2)
+    {
 			// TODO
-		} // setCharacterAttributes()
+    }
 
 		/**
 		 * getStyledDocument
 		 * @param value0 TODO
 		 * @returns StyledDocument
 		 */
-		protected final StyledDocument getStyledDocument(JEditorPane value0) {
+    protected final StyledDocument getStyledDocument(JEditorPane value0)
+    {
 			return null; // TODO
-		} // getStyledDocument()
+    }
 
 		/**
 		 * getStyledEditorKit
 		 * @param value0 TODO
 		 * @returns StyledEditorKit
 		 */
-		protected final StyledEditorKit getStyledEditorKit(JEditorPane value0) {
+    protected final StyledEditorKit getStyledEditorKit(JEditorPane value0)
+    {
 			return null; // TODO
-		} // getStyledEditorKit()
+    }
 
 		/**
 		 * setParagraphAttributes
@@ -409,72 +317,53 @@
 		 * @param value1 TODO
 		 * @param value2 TODO
 		 */
-		protected final void setParagraphAttributes(JEditorPane value0, AttributeSet value1, boolean value2) {
+    protected final void setParagraphAttributes(JEditorPane value0,
+                                                AttributeSet value1,
+                                                boolean value2)
+    {
 			// TODO
-		} // setParagraphAttributes()
-
-
-	} // StyledTextAction
+    }
+  }
 
 	/**
 	 * StyledViewFactory
 	 */
-	static class StyledViewFactory implements ViewFactory {
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  static class StyledViewFactory
+    implements ViewFactory
+  {
 		/**
 		 * Constructor StyledViewFactory
 		 */
-		StyledViewFactory() {
+    StyledViewFactory()
+    {
 			// TODO
-		} // StyledViewFactory()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * create
 		 * @param value0 TODO
 		 * @returns View
 		 */
-		public View create(Element value0) {
+    public View create(Element value0)
+    {
 			return null; // TODO
-		} // create()
-
-
-	} // StyledViewFactory
+    }
+  }
 
 	/**
 	 * AttributeTracker
 	 */
-	 class AttributeTracker implements CaretListener, PropertyChangeListener, Serializable {
-
-		//-------------------------------------------------------------
-		// Variables --------------------------------------------------
-		//-------------------------------------------------------------
-
-
-		//-------------------------------------------------------------
-		// Initialization ---------------------------------------------
-		//-------------------------------------------------------------
-
+  class AttributeTracker
+    implements CaretListener, PropertyChangeListener, Serializable
+  {
 		/**
 		 * Constructor AttributeTracker
 		 * @param value0 TODO
 		 */
-		AttributeTracker(StyledEditorKit value0) {
+    AttributeTracker(StyledEditorKit value0)
+    {
 			// TODO
-		} // AttributeTracker()
-
-
-		//-------------------------------------------------------------
-		// Methods ----------------------------------------------------
-		//-------------------------------------------------------------
+    }
 
 		/**
 		 * updateInputAttributes
@@ -482,33 +371,29 @@
 		 * @param value1 TODO
 		 * @param value2 TODO
 		 */
-		void updateInputAttributes(int value0, int value1, JTextComponent value2) {
+    void updateInputAttributes(int value0, int value1, JTextComponent value2)
+    {
 			// TODO
-		} // updateInputAttributes()
+    }
 
 		/**
 		 * propertyChange
 		 * @param value0 TODO
 		 */
-		public void propertyChange(PropertyChangeEvent value0) {
+    public void propertyChange(PropertyChangeEvent value0)
+    {
 			// TODO
-		} // propertyChange()
+    }
 
 		/**
 		 * caretUpdate
 		 * @param value0 TODO
 		 */
-		public void caretUpdate(CaretEvent value0) {
+    public void caretUpdate(CaretEvent value0)
+    {
 			// TODO
-		} // caretUpdate()
-
-
-	} // AttributeTracker
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
+    }
+  }
 
 	/**
 	 * currentRun
@@ -525,96 +410,93 @@
 	 */
 	MutableAttributeSet inputAttributes;
 
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
 	/**
 	 * Constructor StyledEditorKit
 	 */
-	public StyledEditorKit() {
+  public StyledEditorKit()
+  {
 		// TODO
-	} // StyledEditorKit()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  }
 
 	/**
 	 * clone
 	 * @returns Object
 	 */
-	public Object clone() {
+  public Object clone()
+  {
 		return null; // TODO
-	} // clone()
+  }
 
 	/**
 	 * getActions
 	 * @returns Action[]
 	 */
-	public Action[] getActions() {
+  public Action[] getActions()
+  {
 		return null; // TODO
-	} // getActions()
+  }
 
 	/**
 	 * getInputAttributes
 	 * @returns MutableAttributeSet
 	 */
-	public MutableAttributeSet getInputAttributes() {
+  public MutableAttributeSet getInputAttributes()
+  {
 		return null; // TODO
-	} // getInputAttributes()
+  }
 
 	/**
 	 * getCharacterAttributeRun
 	 * @returns Element
 	 */
-	public Element getCharacterAttributeRun() {
+  public Element getCharacterAttributeRun()
+  {
 		return null; // TODO
-	} // getCharacterAttributeRun()
+  }
 
 	/**
 	 * createDefaultDocument
 	 * @returns Document
 	 */
-	public Document createDefaultDocument() {
+  public Document createDefaultDocument()
+  {
 		return null; // TODO
-	} // createDefaultDocument()
+  }
 
 	/**
 	 * install
 	 * @param component TODO
 	 */
-	public void install(JEditorPane component) {
+  public void install(JEditorPane component)
+  {
 		// TODO
-	} // install()
+  }
 
 	/**
 	 * deinstall
 	 * @param component TODO
 	 */
-	public void deinstall(JEditorPane component) {
+  public void deinstall(JEditorPane component)
+  {
 		// TODO
-	} // deinstall()
+  }
 
 	/**
 	 * getViewFactory
 	 * @returns ViewFactory
 	 */
-	public ViewFactory getViewFactory() {
+  public ViewFactory getViewFactory()
+  {
 		return null; // TODO
-	} // getViewFactory()
+  }
 
 	/**
 	 * createInputAttributes
 	 * @param element TODO
 	 * @param set TODO
 	 */
-	protected void createInputAttributes(Element element,
-			MutableAttributeSet set) {
+  protected void createInputAttributes(Element element, MutableAttributeSet set)
+  {
 		// TODO
-	} // createInputAttributes()
-
-
-} // StyledEditorKit
+  }
+}
Index: javax/swing/text/TabExpander.java
===================================================================
RCS file: javax/swing/text/TabExpander.java
diff -N javax/swing/text/TabExpander.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabExpander.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,43 @@
+/* TabExpander.java --
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+public interface TabExpander
+{
+  float nextTabStop(float x, int tabOffset);
+}
\ No newline at end of file
Index: javax/swing/text/TabSet.java
===================================================================
RCS file: javax/swing/text/TabSet.java
diff -N javax/swing/text/TabSet.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabSet.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,102 @@
+/* TabSet.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.io.Serializable;
+
+public class TabSet implements Serializable
+{
+  TabStop[] tabs;
+
+  public TabSet(TabStop[] t) 
+  {
+    tabs = t;
+  }
+ 
+  public TabStop getTab(int i) 
+  {
+    return tabs[i];
+  }
+
+  public TabStop getTabAfter(float location) 
+  {
+    int idx = getTabIndexAfter(location);
+    if (idx == -1)
+      return null;
+    else
+      return tabs[idx];        
+  }
+
+  public int getTabCount() 
+  {
+    return tabs.length;
+  }
+
+  public int getTabIndex(TabStop tab) 
+  {
+    for (int i = 0; i < tabs.length; ++i)
+      if (tabs[i] == tab)
+        return i;
+    return -1;
+  }
+
+  public int getTabIndexAfter(float location) 
+  {
+    int idx = -1;
+    for (int i = 0; i < tabs.length; ++i)
+      {
+        if (location < tabs[i].getPosition())
+          idx = i;
+      }
+    return idx;
+  }
+
+  public String toString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append("[");
+    for (int i = 0; i < tabs.length; ++i)
+      {
+        if (i != 0)
+          sb.append(" - ");
+        sb.append(tabs[i].toString());
+      }
+    sb.append("]");
+    return sb.toString();
+  }
+}
Index: javax/swing/text/TabStop.java
===================================================================
RCS file: javax/swing/text/TabStop.java
diff -N javax/swing/text/TabStop.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabStop.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,133 @@
+/* TabSet.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+import java.io.Serializable;
+
+public class TabStop implements Serializable
+{
+  public static final int ALIGN_LEFT = 0;
+  public static final int ALIGN_RIGHT = 1;
+  public static final int ALIGN_CENTER = 2;
+  public static final int ALIGN_DECIMAL = 4;
+  public static final int ALIGN_BAR = 5;
+
+  public static final int LEAD_NONE = 0;
+  public static final int LEAD_DOTS = 1;
+  public static final int LEAD_HYPHENS = 2;
+  public static final int LEAD_UNDERLINE = 3;
+  public static final int LEAD_THICKLINE = 4;
+  public static final int LEAD_EQUALS = 5;
+
+  float pos;
+  int align;
+  int leader;
+
+  public TabStop(float pos) 
+  {
+    this(pos, ALIGN_LEFT, LEAD_NONE);
+  }
+  
+  public TabStop(float pos, int align, int leader)
+  {
+    this.pos = pos;
+    this.align = align;
+    this.leader = leader;
+  }
+    
+  public boolean equals(Object other) 
+  {
+    return (other != null)
+      && (other instanceof TabStop)
+      && (((TabStop)other).getPosition() == this.getPosition())
+      && (((TabStop)other).getLeader() == this.getLeader())
+      && (((TabStop)other).getAlignment() == this.getAlignment());
+  }
+
+  public int getAlignment() 
+  {
+    return align;
+  }
+
+  public int getLeader() 
+  {
+    return leader;
+  }
+
+  public float getPosition() 
+  {
+    return pos;
+  }
+
+  public int hashCode() 
+  {
+    return (int) pos + (int) leader + (int) align;
+  }
+
+  public String toString() 
+  {
+    String prefix = "";
+    switch (align)
+      {
+      case ALIGN_LEFT:
+        prefix = "left ";
+        break;
+      case ALIGN_RIGHT:
+        prefix = "right ";
+        break;
+
+      case ALIGN_CENTER:
+        prefix = "center ";
+        break;
+
+      case ALIGN_DECIMAL:
+        prefix = "decimal ";
+        break;
+        
+      case ALIGN_BAR:
+        prefix = "bar ";
+        break;
+
+      default:
+        break;
+      }
+    
+    return (prefix + "tab @" + pos + ((leader == LEAD_NONE) ? "" : "(w/leaders)"));
+  }
+
+}
Index: javax/swing/text/TabableView.java
===================================================================
RCS file: javax/swing/text/TabableView.java
diff -N javax/swing/text/TabableView.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabableView.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,44 @@
+/* TabableView.java -- 
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.text;
+
+public interface TabableView
+{
+  float getPartialSpan(int p0, int p1);
+  float getTabbedSpan(float x, TabExpander expander);
+}
Index: javax/swing/text/TextAction.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/TextAction.java,v
retrieving revision 1.2
diff -u -r1.2 TextAction.java
--- javax/swing/text/TextAction.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/TextAction.java	6 Sep 2004 16:36:10 -0000
@@ -41,56 +41,53 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 
+
 /**
  * TextAction
  * @author	Andrew Selkirk
- * @version	1.0
  */
-public abstract class TextAction extends AbstractAction {
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
+public abstract class TextAction extends AbstractAction
+{
 	/**
 	 * Constructor TextAction
 	 * @param name TODO
 	 */
-	public TextAction(String name) {
-		// TODO
-	} // TextAction()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
+  public TextAction(String name)
+  {
+    super(name);
+  }
 
 	/**
 	 * getTextComponent
 	 * @param event TODO
-	 * @returns JTextComponent
+   * @return JTextComponent
 	 */
-	protected final JTextComponent getTextComponent(ActionEvent event) {
-		return null; // TODO
-	} // getTextComponent()
+  protected final JTextComponent getTextComponent(ActionEvent event)
+  {
+    if (event.getSource() != null &&
+        event.getSource() instanceof JTextComponent)
+      return (JTextComponent) event.getSource();
+    else
+      return getFocusedComponent();
+  }
 
 	/**
 	 * augmentList
 	 * @param list1 TODO
 	 * @param list2 TODO
-	 * @returns Action[]
+   * @return Action[]
 	 */
-	public static final Action[] augmentList(Action[] list1, Action[] list2) {
+  public static final Action[] augmentList(Action[] list1, Action[] list2)
+  {
 		return null; // TODO
-	} // augmentList()
+  }
 
 	/**
 	 * getFocusedComponent
-	 * @returns JTextComponent
+   * @return JTextComponent
 	 */
-	protected final JTextComponent getFocusedComponent() {
+  protected final JTextComponent getFocusedComponent()
+  {
 		return null; // TODO
-	} // getFocusedComponent()
-
-
-} // TextAction
+  }
+}
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: javax/swing/text/Utilities.java
diff -N javax/swing/text/Utilities.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/Utilities.java	6 Sep 2004 16:36:10 -0000
@@ -0,0 +1,182 @@
+/* Utilities.java --
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text;
+
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+
+/**
+ * A set of utilities to deal with text. This is used by several other classes
+ * inside this package.
+ *
+ * @author Roman Kennke <roman@ontographics.com>
+ */
+public class Utilities
+{
+  /**
+   * The length of the char buffer that holds the characters to be drawn.
+   */
+  private static final int BUF_LENGTH = 64;
+
+  /**
+   * Creates a new <code>Utilities</code> object.
+   */
+  public Utilities()
+  {
+    // Nothing to be done here.
+  }
+
+  /**
+   * Draws the given text segment. Contained tabs and newline characters
+   * are taken into account. Tabs are expanded using the
+   * specified {@link TabExpander}.
+   *
+   * @param s the text fragment to be drawn.
+   * @param x the x position for drawing.
+   * @param y the y position for drawing.
+   * @param g the {@link Graphics} context for drawing.
+   * @param e the {@link TabExpander} which specifies the Tab-expanding
+   *     technique.
+   * @param startOffset starting offset in the text.
+   * @return the x coordinate at the end of the drawn text.
+   */
+  public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
+                                         TabExpander e, int startOffset)
+  {
+    // This buffers the chars to be drawn.
+    char[] buffer = s.array;
+
+
+    // The current x and y pixel coordinates.
+    int pixelX = x;
+    int pixelY = y;
+
+    // The font metrics of the current selected font.
+    FontMetrics metrics = g.getFontMetrics();
+    int ascent = metrics.getAscent();
+
+    for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+      {
+	switch (buffer[offset])
+	  {
+	  case '\t':
+	    // In case we have a tab, we just 'jump' over the tab.
+	    // When we have no tab expander we just use the width of 'm'.
+	    if (e != null)
+	      pixelX = (int) e.nextTabStop((float) pixelX,
+					   startOffset + offset - s.offset);
+	    else
+	      pixelX += metrics.charWidth(' ');
+	    break;
+	  case '\n':
+	    // In case we have a newline, we must draw
+	    // the buffer and jump on the next line.
+	    g.drawChars(buffer, offset, 1, pixelX, y);
+	    pixelY += metrics.getHeight();
+	    pixelX = x;
+	    break;
+	  default:
+	    // Here we draw the char.
+	    g.drawChars(buffer, offset, 1, pixelX, pixelY + ascent);
+	    pixelX += metrics.charWidth(buffer[offset]);
+	    break;
+	  }
+      }
+
+    return pixelX;
+  }
+
+  /**
+   * Determines the width, that the given text <code>s</code> would take
+   * if it was printed with the given {@link java.awt.FontMetrics} on the
+   * specified screen position.
+   * @param s the text fragment
+   * @param metrics the font metrics of the font to be used
+   * @param x the x coordinate of the point at which drawing should be done
+   * @param e the {@link TabExpander} to be used
+   * @param startOffset the index in <code>s</code> where to start
+   * @returns the width of the given text s. This takes tabs and newlines
+   * into account.
+   */
+  public static final int getTabbedTextWidth(Segment s, FontMetrics metrics,
+                                             int x, TabExpander e,
+                                             int startOffset)
+  {
+    // This buffers the chars to be drawn.
+    char[] buffer = s.array;
+
+    // The current x coordinate.
+    int pixelX = x;
+
+    // The current maximum width.
+    int maxWidth = 0;
+
+    for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+      {
+	switch (buffer[offset])
+	  {
+	  case '\t':
+	    // In case we have a tab, we just 'jump' over the tab.
+	    // When we have no tab expander we just use the width of 'm'.
+	    if (e != null)
+	      pixelX = (int) e.nextTabStop((float) pixelX,
+					   startOffset + offset - s.offset);
+	    else
+	      pixelX += metrics.charWidth(' ');
+	    break;
+	  case '\n':
+	    // In case we have a newline, we must 'draw'
+	    // the buffer and jump on the next line.
+	    pixelX += metrics.charWidth(buffer[offset]);
+	    maxWidth = Math.max(maxWidth, pixelX - x);
+	    pixelX = x;
+	    break;
+	  default:
+	    // Here we draw the char.
+	    pixelX += metrics.charWidth(buffer[offset]);
+	    break;
+	  }
+      }
+
+    // Take the last line into account.
+    maxWidth = Math.max(maxWidth, pixelX - x);
+
+    return maxWidth;
+  }
+}
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/View.java,v
retrieving revision 1.2
diff -u -r1.2 View.java
--- javax/swing/text/View.java	10 Jan 2004 21:07:44 -0000	1.2
+++ javax/swing/text/View.java	6 Sep 2004 16:36:10 -0000
@@ -37,6 +37,7 @@
 
 package javax.swing.text;
 
+import java.awt.Container;
 import java.awt.Graphics;
 import java.awt.Shape;
 import java.util.Vector;
@@ -44,97 +45,165 @@
 
 public abstract class View implements SwingConstants
 {
-    static int BadBreakWeight;    
-    static int ExcellentBreakWeight;
-    static int ForcedBreakWeight;
-    static int GoodBreakWeight;
-
-    public final static int X_AXIS = 0;
-    public final static int Y_AXIS = 1;
-    
-    float width, height;
-    Element elt;
-    View parent;
+  public static final int BadBreakWeight = 0;
+  public static final int ExcellentBreakWeight = 2000;
+  public static final int ForcedBreakWeight = 3000;
+  public static final int GoodBreakWeight = 1000;
+
+  public static final int X_AXIS = 0;
+  public static final int Y_AXIS = 1;
+    
+  private float width, height;
+  private Element elt;
+  private View parent;
 
     /** 
-     * this vector contains the views ordered at offsets...
+   * Creates a new <code>View</code> instance.
+   *
+   * @param elem an <code>Element</code> value
      */
-    Vector v = new Vector();
-
-
     public View(Element elem)
     {
 	elt = elem;
     }
 
-    public int getViewCount() 
+  public abstract void paint(Graphics g, Shape s);
+
+  public void setParent(View a)
     {
-	return v.size();
+    parent = a;
     }
 
-    public View getView(int a)
+  public View getParent()
     {
-	return (View) v.get(a);
+    return parent;
     }
     
-    public void remove(int i)
+  public void setSize(int w, int h)
     {
-	v.removeElementAt(i);
+    width = w;
+    height = h;
     }
     
-    public void insert(int off, View view)
+  public Container getContainer()
     {
-	v.insertElementAt(view, off);	
+    return parent != null ? parent.getContainer() : null;
     }	   
     
-    public void append(View view)
+  public Document getDocument()
     {
-	v.addElement(view);
+    return getElement().getDocument();
     }
 	
-    public void paint(Graphics g, Shape allocation)
+  public Element getElement()
     {
-	System.out.println("view.paint() !!!!");
+    return elt;
     }
 
-    public void setParent(View a)
+  public abstract float getPreferredSpan(int axis);
+  
+  public float getAlignment(int axis)
     {
-	parent = a;
+    return 0.5f;
     }
     
-    public View getParent()
+  public AttributeSet getAttributes()
     {
-	return parent;
+    return elt.getAttributes();
     }
     
-    public void setSize(int w, int h)
+  public boolean isVisible()
     {
-	width  = w;
-	height = h;
+    return true;
     }
 
-    public Document getDocument()
+  public int getViewCount()
     {
-	return getElement().getDocument();
+    return 0;
     }
     
-    public Element getElement()
+  public View getView(int index)
     {
-        return elt;
+    return null;
     }
 
-    public float getPreferredSpan(int a)
+  public ViewFactory getViewFactory()
     {
-	switch (a)
+    return parent != null ? parent.getViewFactory() : null;
+  }
+
+  public void replace(int offset, int length, View[] views)
 	    {
-	    case X_AXIS:  return width;
-	    case Y_AXIS:  return height;
-	    default:
+    // Default implementation does nothing.
+  }
+
+  public void insert(int offset, View view)
 		{
-		    System.err.println("I sure wish Java had enums !!! ");
-		    return 0;
+    View[] array = { view };
+    replace(offset, 1, array);
 		}
+
+  public void append(View view)
+  {
+    View[] array = { view };
+    replace(getViewCount(), 1, array);
+  }
+
+  public void removeAll()
+  {
+    replace(0, getViewCount(), null); 
 	    }
-    }
+
+  public void remove(int index)
+  {
+    replace(index, 1, null); 
+  }
+
+  public View createFragment(int p0, int p1)
+  {
+    // The default implementation doesn't support fragmentation.
+    return this;
+  }
+
+  public int getStartOffset()
+  {
+    return elt.getStartOffset();
+  }
+
+  public int getEndOffset()
+  {
+    return elt.getEndOffset();
+  }
+
+  public Shape getChildAllocation(int index, Shape a)
+  {
+    return null;
+  }
+  
+  /**
+   * @since 1.4
+   */
+  public int getViewIndex(float x, float y, Shape allocation)
+  {
+    return -1;
+  }
+  
+  /**
+   * @since 1.4
+   */
+  public String getToolTipText(float x, float y, Shape allocation)
+  {
+    int index = getViewIndex(x, y, allocation);
+
+    if (index < -1)
+      return null;
+
+    Shape childAllocation = getChildAllocation(index, allocation);
+
+    if (childAllocation.getBounds().contains(x, y))
+      return getView(index).getToolTipText(x, y, childAllocation);
+
+    return null;
+  }
 }
 
Index: javax/swing/text/ViewFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/ViewFactory.java,v
retrieving revision 1.2
diff -u -r1.2 ViewFactory.java
--- javax/swing/text/ViewFactory.java	12 Oct 2003 13:33:32 -0000	1.2
+++ javax/swing/text/ViewFactory.java	6 Sep 2004 16:36:10 -0000
@@ -1,5 +1,5 @@
 /* ViewFactory.java -- 
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,5 +39,12 @@
 
 public interface ViewFactory
 {
+  /**
+   * Creates a view for a given element.
+   *
+   * @param elem them element to create view for
+   *
+   * @return a new created view
+   */
     View create (Element elem);
 }
Index: javax/swing/tree/DefaultMutableTreeNode.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/tree/DefaultMutableTreeNode.java,v
retrieving revision 1.4
diff -u -r1.4 DefaultMutableTreeNode.java
--- javax/swing/tree/DefaultMutableTreeNode.java	12 Oct 2003 13:33:32 -0000	1.4
+++ javax/swing/tree/DefaultMutableTreeNode.java	6 Sep 2004 16:36:10 -0000
@@ -997,17 +997,17 @@
 	public int getLeafCount() {
 
 		// Variables
-		Enumeration	enum;
+		Enumeration	e;
 		int			count;
 		TreeNode	current;
 
 		// Get Enumeration of all descendants
-		enum = depthFirstEnumeration();
+		e = depthFirstEnumeration();
 
 		// Process Nodes
 		count = 0;
-		while (enum.hasMoreElements() == true) {
-			current = (TreeNode) enum.nextElement();
+		while (e.hasMoreElements() == true) {
+			current = (TreeNode) e.nextElement();
 			if (current.isLeaf() == true) {
 				count++;
 			} // if
Index: javax/swing/tree/DefaultTreeCellEditor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/tree/DefaultTreeCellEditor.java,v
retrieving revision 1.2
diff -u -r1.2 DefaultTreeCellEditor.java
--- javax/swing/tree/DefaultTreeCellEditor.java	11 Jun 2003 13:20:41 -0000	1.2
+++ javax/swing/tree/DefaultTreeCellEditor.java	6 Sep 2004 16:36:11 -0000
@@ -1,5 +1,5 @@
 /* DefaultTreeCellEditor.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -50,12 +50,12 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.EventObject;
+
 import javax.swing.Icon;
 import javax.swing.JTextField;
 import javax.swing.JTree;
 import javax.swing.border.Border;
 import javax.swing.event.CellEditorListener;
-import javax.swing.event.EventListenerList;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
 
Index: javax/swing/undo/CompoundEdit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/undo/CompoundEdit.java,v
retrieving revision 1.4
diff -u -r1.4 CompoundEdit.java
--- javax/swing/undo/CompoundEdit.java	11 Jan 2004 12:40:49 -0000	1.4
+++ javax/swing/undo/CompoundEdit.java	6 Sep 2004 16:36:11 -0000
@@ -45,17 +45,18 @@
  * <code>UndoableEdits</code>.
  *
  * <p>The use of a <code>CompoundEdit</code> is divided in two separate
- * phases.
- *
- * <ol><li>In the first phase, the <code>CompoundEdit</code> is
- * initialized.  After a new instance of <code>CompoundEdit</code> has
- * been created, {@link #addEdit(UndoableEdit)} is called for each
- * element of the compound.  To terminate the initialization phase,
- * call {@link #end()}.</li>
+ * phases.</p>
  *
+ * <ol>
+ * <li>In the first phase, the <code>CompoundEdit</code> is
+ *     initialized.  After a new instance of <code>CompoundEdit</code> has
+ *     been created, {@link #addEdit(UndoableEdit)} is called for each
+ *     element of the compound.  To terminate the initialization phase,
+ *     call {@link #end()}.</li>
  * <li>In the second phase, the the <code>CompoundEdit</code> can be
- * used, typically by invoking {@link #undo()} and {@link
- * #redo()}.</li></ol>
+ *     used, typically by invoking {@link #undo()} and
+ *     {@link #redo()}.</li>
+ * </ol>
  *
  * @author Andrew Selkirk (aselkirk@sympatico.ca)
  * @author Sascha Brawer (brawer@dandelis.ch)
Index: javax/swing/undo/StateEdit.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/undo/StateEdit.java,v
retrieving revision 1.4
diff -u -r1.4 StateEdit.java
--- javax/swing/undo/StateEdit.java	26 Nov 2003 22:23:40 -0000	1.4
+++ javax/swing/undo/StateEdit.java	6 Sep 2004 16:36:11 -0000
@@ -44,52 +44,54 @@
 /**
  * A helper class, making it easy to support undo and redo.
  *
- * <p>The following example shows how to use this class.
+ * <p>The following example shows how to use this class.</p>
  *
- * <pre>  Foo foo; // class Foo implements {@link StateEditable}
- *  StateEdit edit;
- *
- *  edit = new StateEdit(foo, "Name Change");
- *  foo.setName("Jane Doe");
- *  edit.end();
- *  undoManager.addEdit(edit);</pre>
+ * <pre>
+ * Foo foo; // class Foo implements {@link StateEditable}
+ * StateEdit edit;
+ *
+ * edit = new StateEdit(foo, "Name Change");
+ * foo.setName("Jane Doe");
+ * edit.end();
+ * undoManager.addEdit(edit);
+ * </pre>
  *
  * <p>If <code>Foo</code>&#x2019;s implementation of {@link
  * StateEditable} considers the name as part of the editable state,
  * the user can now choose &#x201c;Undo Name Change&#x201d; or
  * &#x201c;Redo Name Change&#x201d; from the respective menu. No
- * further undo support is needed from the application.
- *
- * <p>The following explains what happens in the example.
+ * further undo support is needed from the application.</p>
  *
- * <p><ol><li>When a <code>StateEdit</code> is created, the associated
- * {@link StateEditable} gets asked to store its state into a hash
- * table, {@link #preState}.</li>
+ * <p>The following explains what happens in the example.</p>
  *
+ * <ol>
+ * <li>When a <code>StateEdit</code> is created, the associated
+ *     {@link StateEditable} gets asked to store its state into a hash
+ *     table, {@link #preState}.</li>
  * <li>The application will now perform some changes to the edited
- * object.  This typically happens by invoking methods on the edited
- * object.</li>
- *
+ *     object. This typically happens by invoking methods on the edited
+ *     object.</li>
  * <li>The editing phase is terminated by invoking the {@link #end()}
- * method of the <code>StateEdit</code>. The <code>end()</code> method
- * does two things.
- *
- *   <ul><li>The edited object receives a second request for storing
- *   its state.  This time, it will use a different hash table, {@link
- *   #postState}.</li>
- *
- *   <li>To increase efficiency, the <code>StateEdit</code> now removes
- *   any entries from {@link #preState} and {@link #postState} that have
- *   the same key, and whose values are equal. Equality is determined
- *   by invoking the <code>equals</code> method inherited from
- *   {@link java.lang.Object}.</li></ul></li>
+ *     method of the <code>StateEdit</code>. The <code>end()</code> method
+ *     does two things.
  *
+ *     <ul>
+ *     <li>The edited object receives a second request for storing
+ *         its state.  This time, it will use a different hash table, {@link
+ *         #postState}.</li>
+ *     <li>To increase efficiency, the <code>StateEdit</code> now removes
+ *         any entries from {@link #preState} and {@link #postState} that have
+ *         the same key, and whose values are equal. Equality is determined
+ *         by invoking the <code>equals</code> method inherited from
+ *         {@link java.lang.Object}.</li>
+ *     </ul></li>
  * <li>When the user later chooses to undo the <code>StateEdit</code>,
  * the edited object is asked to {@linkplain StateEditable#restoreState
  * restore its state} from the {@link #preState} table.  Similarly,
  * when the user chooses to <i>redo</i> the <code>StateEdit</code>,
  * the edited object gets asked to restore its state from the {@link
- * #postState}.</li></ol>
+ * #postState}.</li>
+ * </ol>
  *
  * @author Andrew Selkirk (aselkirk@sympatico.ca)
  * @author Sascha Brawer (brawer@dandelis.ch)
Index: javax/swing/undo/UndoManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/undo/UndoManager.java,v
retrieving revision 1.2
diff -u -r1.2 UndoManager.java
--- javax/swing/undo/UndoManager.java	11 Jun 2003 13:20:41 -0000	1.2
+++ javax/swing/undo/UndoManager.java	6 Sep 2004 16:36:11 -0000
@@ -1,5 +1,5 @@
 /* AbstractTableModel.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,223 +38,588 @@
 
 package javax.swing.undo;
 
+import javax.swing.UIManager;
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.event.UndoableEditListener;
 
+
 /**
- * UndoManager
- * @author	Andrew Selkirk
+ * A manager for providing an application&#x2019;s undo/redo
+ * functionality.
+ *
+ * <p>Tyipcally, an application will create only one single instance
+ * of UndoManager. When the user performs an undoable action, for
+ * instance changing the color of an object from green to blue, the
+ * application registers an {@link UndoableEdit} object with the
+ * <code>UndoManager</code>. To implement the &#x201c;undo&#x201d; and
+ * &#x201c;redo&#x201d; menu commands, the application invokes the
+ * UndoManager&#x2019;s {@link #undo} and {@link #redo} methods.  The
+ * human-readable text of these menu commands is provided by {@link
+ * #getUndoPresentationName} and {@link #getRedoPresentationName},
+ * respectively. To determine whether the menu item should be
+ * selectable or greyed out, use {@link #canUndo} and {@link
+ * #canRedo}.
+ *
+ * <p>The UndoManager will only keep a specified number of editing
+ * actions, the <em>limit</em>. The value of this parameter can be
+ * retrieved by calling {@link #getLimit} and set with {@link
+ * #setLimit}.  If more UndoableEdits are added to the UndoManager,
+ * the oldest actions will be discarded.
+ *
+ * <p>Some applications do not provide separate menu commands for
+ * &#x201c;undo&#x201d; and &#x201c;redo.&#x201d; Instead, they
+ * have just a single command whose text switches between the two.
+ * Such applications would use an UndoManager with a <code>limit</code>
+ * of 1. The text of this combined menu item is available via
+ * {@link #getUndoOrRedoPresentationName}, and it is implemented
+ * by calling {@link #undoOrRedo}.
+ *
+ * <p><b>Thread Safety:</b> In constrast to the other classes of the
+ * <code>javax.swing.undo</code> package, the public methods of an
+ * <code>UndoManager</code> are safe to call from concurrent threads.
+ * The caller does not need to perform external synchronization, and
+ * {@link javax.swing.event.UndoableEvent} sources do not need to
+ * broadcast their events from inside the Swing worker thread.
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
  */
-public class UndoManager extends CompoundEdit implements UndoableEditListener {
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * indexOfNextAdd
-	 */
-	int indexOfNextAdd;
-
-	/**
-	 * limit
-	 */
-	int limit;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor UndoManager
-	 */
-	public UndoManager() {
-		// TODO
-	} // UndoManager()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * toString
-	 * @returns String
-	 */
-	public String toString() {
-		return null; // TODO
-	} // toString()
-
-	/**
-	 * end
-	 */
-	public synchronized void end() {
-		// TODO
-	} // end()
-
-	/**
-	 * getLimit
-	 * @returns int
-	 */
-	public synchronized int getLimit() {
-		return 0; // TODO
-	} // getLimit()
-
-	/**
-	 * discardAllEdits
-	 */
-	public synchronized void discardAllEdits() {
-		// TODO
-	} // discardAllEdits()
-
-	/**
-	 * trimForLimit
-	 */
-	protected void trimForLimit() {
-		// TODO
-	} // trimForLimit()
-
-	/**
-	 * trimEdits
-	 * @param value0 TODO
-	 * @param value1 TODO
-	 */
-	protected void trimEdits(int value0, int value1) {
-		// TODO
-	} // trimEdits()
-
-	/**
-	 * setLimit
-	 * @param value0 TODO
-	 */
-	public synchronized void setLimit(int value0) {
-		// TODO
-	} // setLimit()
-
-	/**
-	 * editToBeUndone
-	 * @returns UndoableEdit
-	 */
-	protected UndoableEdit editToBeUndone() {
-		return null; // TODO
-	} // editToBeUndone()
-
-	/**
-	 * editToBeRedone
-	 * @returns UndoableEdit
-	 */
-	protected UndoableEdit editToBeRedone() {
-		return null; // TODO
-	} // editToBeRedone()
-
-	/**
-	 * undoTo
-	 * @param value0 TODO
-	 * @exception CannotUndoException TODO
-	 */
-	protected void undoTo(UndoableEdit value0) throws CannotUndoException {
-		// TODO
-	} // undoTo()
-
-	/**
-	 * redoTo
-	 * @param value0 TODO
-	 * @exception CannotRedoException TODO
-	 */
-	protected void redoTo(UndoableEdit value0) throws CannotRedoException {
-		// TODO
-	} // redoTo()
-
-	/**
-	 * undoOrRedo
-	 * @exception CannotRedoException TODO
-	 * @exception CannotUndoException TODO
-	 */
-	public synchronized void undoOrRedo() throws CannotRedoException, CannotUndoException {
-		// TODO
-	} // undoOrRedo()
-
-	/**
-	 * canUndoOrRedo
-	 * @returns boolean
-	 */
-	public synchronized boolean canUndoOrRedo() {
-		return false; // TODO
-	} // canUndoOrRedo()
-
-	/**
-	 * undo
-	 * @exception CannotUndoException TODO
-	 */
-	public synchronized void undo() throws CannotUndoException {
-		// TODO
-	} // undo()
-
-	/**
-	 * canUndo
-	 * @returns boolean
-	 */
-	public synchronized boolean canUndo() {
-		return false; // TODO
-	} // canUndo()
-
-	/**
-	 * redo
-	 * @exception CannotRedoException TODO
-	 */
-	public synchronized void redo() throws CannotRedoException {
-		// TODO
-	} // redo()
-
-	/**
-	 * canRedo
-	 * @returns boolean
-	 */
-	public synchronized boolean canRedo() {
-		return false; // TODO
-	} // canRedo()
-
-	/**
-	 * addEdit
-	 * @param value0 TODO
-	 * @returns boolean
-	 */
-	public synchronized boolean addEdit(UndoableEdit value0) {
-		return false; // TODO
-	} // addEdit()
-
-	/**
-	 * getUndoOrRedoPresentationName
-	 * @returns String
-	 */
-	public synchronized String getUndoOrRedoPresentationName() {
-		return null; // TODO
-	} // getUndoOrRedoPresentationName()
-
-	/**
-	 * getUndoPresentationName
-	 * @returns String
-	 */
-	public synchronized String getUndoPresentationName() {
-		return null; // TODO
-	} // getUndoPresentationName()
-
-	/**
-	 * getRedoPresentationName
-	 * @returns String
-	 */
-	public synchronized String getRedoPresentationName() {
-		return null; // TODO
-	} // getRedoPresentationName()
-
-	/**
-	 * undoableEditHappened
-	 * @param value0 TODO
-	 */
-	public void undoableEditHappened(UndoableEditEvent value0) {
-		// TODO
-	} // undoableEditHappened()
-
-
-} // UndoManager
+public class UndoManager
+  extends CompoundEdit
+  implements UndoableEditListener
+{
+  /**
+   * The unique ID for serializing instances of this class. Determined
+   * using the <code>serialver</code> tool of Sun JDK 1.4.1_01 on
+   * GNU/Linux.
+   */
+  static final long serialVersionUID = -2077529998244066750L;
+
+
+  /**
+   * An index into the inherited {@link #edits} Vector that indicates
+   * at which position newly added editing actions would get inserted.
+   *
+   * <p>Normally, the value of <code>indexOfNextAdd</code> equals
+   * the number of UndoableEdits stored by this UndoManager, i.e.
+   * <code>edits.size()</code>. For each call to {@link #undo},
+   * <code>indexOfNextAdd</code> is decremented by one. For each
+   * call to {@link #redo}, it is incremented again.
+   */
+  int indexOfNextAdd;
+
+
+  /**
+   * The maximum number of UndoableEdits stored by this UndoManager.
+   */
+  int limit;
+
+
+  /**
+   * Constructs an UndoManager.
+   *
+   * <p>The <code>limit</code> of the freshly constructed UndoManager
+   * is 100.
+   */
+  public UndoManager()
+  {
+    limit = 100;
+  }
+
+
+  /**
+   * Returns a string representation for this UndoManager. This may be
+   * useful for debugging purposes. For the text of menu items, please
+   * refer to {@link #getUndoPresentationName}, {@link
+   * #getRedoPresentationName}, and {@link
+   * #getUndoOrRedoPresentationName}.
+   */
+  public String toString()
+  {
+    return super.toString()
+      + " limit: " + limit
+      + " indexOfNextAdd: " + indexOfNextAdd;
+  }
+
+
+  /**
+   * Puts this UndoManager into a state where it acts as a normal
+   * {@link CompoundEdit}. It is unlikely that an application would
+   * want to do this.
+   */
+  public synchronized void end()
+  {
+    super.end();
+    trimEdits(indexOfNextAdd, edits.size() - 1);
+  }
+
+
+  /**
+   * Returns how many edits this UndoManager can maximally hold.
+   *
+   * @see #setLimit
+   */
+  public synchronized int getLimit()
+  {
+    return limit;
+  }
+
+
+  /**
+   * Changes the maximal number of edits that this UndoManager can
+   * process. If there are currently more edits than the new limit
+   * allows, they will receive a {@link UndoableEdit#die() die}
+   * message in reverse order of addition.
+   *
+   * @param limit the new limit.
+   *
+   * @throws IllegalStateException if {@link #end()} has already been
+   * called on this UndoManager.
+   */
+  public synchronized void setLimit(int limit)
+  {
+    if (!isInProgress())
+      throw new IllegalStateException();
+
+    this.limit = limit;
+    trimForLimit();
+  }
+
+
+  /**
+   * Discards all editing actions that are currently registered with
+   * this UndoManager. Each {@link UndoableEdit} will receive a {@link
+   * UndoableEdit#die() die message}.
+   */
+  public synchronized void discardAllEdits()
+  {
+    int size;
+
+    size = edits.size();
+    for (int i = size - 1; i >= 0; i--)
+      ((UndoableEdit) edits.get(i)).die();
+    indexOfNextAdd = 0;
+    edits.clear();
+  }
+
+
+  /**
+   * Called by various internal methods in order to enforce
+   * the <code>limit</code> value.
+   */
+  protected void trimForLimit()
+  {
+    int high, s;
+
+    s = edits.size();
+
+    /* The Sun J2SE1.4.1_01 implementation can be observed to do
+     * nothing (instead of throwing an exception) with a negative or
+     * zero limit. It may be debatable whether this is the best
+     * behavior, but we replicate it for sake of compatibility.
+     */
+    if (limit <= 0 || s <= limit)
+      return;
+
+    high = Math.min(indexOfNextAdd + limit/2 - 1, s - 1);
+    trimEdits(high + 1, s - 1);
+    trimEdits(0, high - limit);
+  }
+
+
+  /**
+   * Discards a range of edits. All edits in the range <code>[from
+   * .. to]</code> will receive a {@linkplain UndoableEdit#die() die
+   * message} before being removed from the edits array.  If
+   * <code>from</code> is greater than <code>to</code>, nothing
+   * happens.
+   *
+   * @param from the lower bound of the range of edits to be
+   * discarded.
+   *
+   * @param to the upper bound of the range of edits to be discarded.
+   */
+  protected void trimEdits(int from, int to)
+  {
+    if (from > to)
+      return;
+
+    for (int i = to; i >= from; i--)
+        ((UndoableEdit) edits.get(i)).die();
+
+    // Remove the range [from .. to] from edits. If from == to, which
+    // is likely to be a very common case, we can do better than
+    // creating a sub-list and clearing it.
+    if (to == from)
+      edits.remove(from);
+    else
+      edits.subList(from, to + 1).clear();
+
+    if (indexOfNextAdd > to)
+      indexOfNextAdd = indexOfNextAdd - to + from - 1;
+    else if (indexOfNextAdd >= from)
+      indexOfNextAdd = from;
+  }
+
+
+  /**
+   * Determines which significant edit would be undone if {@link
+   * #undo()} was called.
+   *
+   * @returns the significant edit that would be undone, or
+   * <code>null</code> if no significant edit would be affected by
+   * calling {@link #undo()}.
+   */
+  protected UndoableEdit editToBeUndone()
+  {
+    UndoableEdit result;
+
+    for (int i = indexOfNextAdd - 1; i >= 0; i--)
+      {
+        result = (UndoableEdit) edits.get(i);
+        if (result.isSignificant())
+          return result;
+      }
+
+    return null;
+  }
+
+
+  /**
+   * Determines which significant edit would be redone if {@link
+   * #redo()} was called.
+   *
+   * @returns the significant edit that would be redone, or
+   * <code>null</code> if no significant edit would be affected by
+   * calling {@link #redo()}.
+   */
+  protected UndoableEdit editToBeRedone()
+  {
+    UndoableEdit result;
+
+    for (int i = indexOfNextAdd; i < edits.size(); i++)
+      {
+        result = (UndoableEdit) edits.get(i);
+        if (result.isSignificant())
+          return result;
+      }
+
+    return null;
+  }
+
+
+  /**
+   * Undoes all editing actions in reverse order of addition,
+   * up to the specified action,
+   *
+   * @param edit the last editing action to be undone.
+   */
+  protected void undoTo(UndoableEdit edit)
+    throws CannotUndoException
+  {
+    UndoableEdit cur;
+
+    if (!edits.contains(edit))
+      throw new CannotUndoException();
+
+    while (true)
+      {
+        indexOfNextAdd -= 1;
+        cur = (UndoableEdit) edits.get(indexOfNextAdd);
+        cur.undo();
+        if (cur == edit)
+          return;
+      }
+  }
+
+
+  /**
+   * Redoes all editing actions in the same order as they were
+   * added to this UndoManager, up to the specified action.
+   *
+   * @param edit the last editing action to be redone.
+   */
+  protected void redoTo(UndoableEdit edit)
+    throws CannotRedoException
+  {
+    UndoableEdit cur;
+
+    if (!edits.contains(edit))
+      throw new CannotRedoException();
+
+    while (true)
+      {
+        cur = (UndoableEdit) edits.get(indexOfNextAdd);
+        indexOfNextAdd += 1;
+        cur.redo();
+        if (cur == edit)
+          return;
+      }
+  }
+
+  
+  /**
+   * Undoes or redoes the last action. If the last action has already
+   * been undone, it will be re-done, and vice versa.
+   *
+   * <p>This is useful for applications that do not present a separate
+   * undo and redo facility, but just have a single menu item for
+   * undoing and redoing the very last action. Such applications will
+   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
+   */
+  public synchronized void undoOrRedo()
+    throws CannotRedoException, CannotUndoException
+  {
+    if (indexOfNextAdd == edits.size())
+      undo();
+    else
+      redo();
+  }
+
+
+  /**
+   * Determines whether it would be possible to either undo or redo
+   * this editing action.
+   *
+   * <p>This is useful for applications that do not present a separate
+   * undo and redo facility, but just have a single menu item for
+   * undoing and redoing the very last action. Such applications will
+   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
+   *
+   * @return <code>true</code> to indicate that this action can be
+   * undone or redone; <code>false</code> if neither is possible at
+   * the current time.
+   */
+  public synchronized boolean canUndoOrRedo()
+  {
+    return indexOfNextAdd == edits.size() ? canUndo() : canRedo();
+  }
+
+
+  /**
+   * Undoes one significant edit action. If insignificant actions have
+   * been posted after the last signficant action, the insignificant
+   * ones will be undone first.
+   *
+   * <p>However, if {@link #end()} has been called on this
+   * UndoManager, it will behave like a normal {@link
+   * CompoundEdit}. In this case, all actions will be undone in
+   * reverse order of addition. Typical applications will never call
+   * {@link #end()} on their <code>UndoManager</code>.
+   *
+   * @throws CannotUndoException if no action can be undone.
+   *
+   * @see #canUndo()
+   * @see #redo()
+   * @see #undoOrRedo()
+   */
+  public synchronized void undo()
+    throws CannotUndoException
+  {
+    if (!isInProgress())
+      {
+        super.undo();
+        return;
+      }
+
+    UndoableEdit edit = editToBeUndone();
+    if (edit == null)
+      throw new CannotUndoException();
+
+    undoTo(edit);
+  }
+
+
+  /**
+   * Determines whether it would be possible to undo this editing
+   * action.
+   *
+   * @return <code>true</code> to indicate that this action can be
+   * undone; <code>false</code> otherwise.
+   *
+   * @see #undo()
+   * @see #canRedo()
+   * @see #canUndoOrRedo()
+   */
+  public synchronized boolean canUndo()
+  {
+    UndoableEdit edit;
+
+    if (!isInProgress())
+      return super.canUndo();
+
+    edit = editToBeUndone();
+    return edit != null && edit.canUndo();
+  }
+
+
+
+  /**
+   * Redoes one significant edit action. If insignificant actions have
+   * been posted in between, the insignificant ones will be redone
+   * first.
+   *
+   * <p>However, if {@link #end()} has been called on this
+   * UndoManager, it will behave like a normal {@link
+   * CompoundEdit}. In this case, <em>all</em> actions will be redone
+   * in order of addition. Typical applications will never call {@link
+   * #end()} on their <code>UndoManager</code>.
+   *
+   * @throws CannotRedoException if no action can be redone.
+   *
+   * @see #canRedo()
+   * @see #redo()
+   * @see #undoOrRedo()
+   */
+  public synchronized void redo()
+    throws CannotRedoException
+  {
+    if (!isInProgress())
+      {
+        super.redo();
+        return;
+      }
+
+    UndoableEdit edit = editToBeRedone();
+    if (edit == null)
+      throw new CannotRedoException();
+
+    redoTo(edit);
+  }
+
+
+  /**
+   * Determines whether it would be possible to redo this editing
+   * action.
+   *
+   * @return <code>true</code> to indicate that this action can be
+   * redone; <code>false</code> otherwise.
+   *
+   * @see #redo()
+   * @see #canUndo()
+   * @see #canUndoOrRedo()
+   */
+  public synchronized boolean canRedo()
+  {
+    UndoableEdit edit;
+
+    if (!isInProgress())
+      return super.canRedo();
+
+    edit = editToBeRedone();
+    return edit != null && edit.canRedo();
+  }
+
+
+  /**
+   * Registers an undoable editing action with this UndoManager.  If
+   * the capacity <code>limit</code> is reached, the oldest action
+   * will be discarded (and receives a {@linkplain UndoableEdit#die()
+   * die message}. Equally, any actions that were undone (but not re-done)
+   * will be discarded, too.
+   *
+   * @param edit the editing action that is added to this UndoManager.
+   *
+   * @return <code>true</code> if <code>edit</code> could be
+   * incorporated; <code>false</code> if <code>edit</code> has not
+   * been incorporated because {@link #end()} has already been called
+   * on this <code>UndoManager</code>.
+   */
+  public synchronized boolean addEdit(UndoableEdit edit)
+  {
+    boolean result;
+
+    // Discard any edits starting at indexOfNextAdd.
+    trimEdits(indexOfNextAdd, edits.size() - 1);
+
+    result = super.addEdit(edit);
+    indexOfNextAdd = edits.size();
+    trimForLimit();
+    return result;
+  }
+
+
+  /**
+   * Calculates a localized text for presenting the undo or redo
+   * action to the user, for example in the form of a menu command.
+   *
+   * <p>This is useful for applications that do not present a separate
+   * undo and redo facility, but just have a single menu item for
+   * undoing and redoing the very last action. Such applications will
+   * use an <code>UndoManager</code> whose <code>limit</code> is 1.
+   *
+   * @return the redo presentation name if the last action has already
+   * been undone, or the undo presentation name otherwise.
+   *
+   * @see #getUndoPresentationName()
+   * @see #getRedoPresentationName()
+   */
+  public synchronized String getUndoOrRedoPresentationName()
+  {
+    if (indexOfNextAdd == edits.size())
+      return getUndoPresentationName();
+    else
+      return getRedoPresentationName();
+  }
+
+
+  /**
+   * Calculates a localized text for presenting the undo action
+   * to the user, for example in the form of a menu command.
+   */
+  public synchronized String getUndoPresentationName()
+  {
+    UndoableEdit edit;
+
+    if (!isInProgress())
+      return super.getUndoPresentationName();
+
+    edit = editToBeUndone();
+    if (edit == null)
+      return UIManager.getString("AbstractUndoableEdit.undoText");
+    else
+      return edit.getUndoPresentationName();
+  }
+
+
+  /**
+   * Calculates a localized text for presenting the redo action
+   * to the user, for example in the form of a menu command.
+   */
+  public synchronized String getRedoPresentationName()
+  {
+    UndoableEdit edit;
+
+    if (!isInProgress())
+      return super.getRedoPresentationName();
+
+    edit = editToBeRedone();
+    if (edit == null)
+      return UIManager.getString("AbstractUndoableEdit.redoText");
+    else
+      return edit.getRedoPresentationName();
+  }
+  
+  
+  /**
+   * Registers the edit action of an {@link UndoableEditEvent}
+   * with this UndoManager.
+   *
+   * <p><b>Thread Safety:</b> This method may safely be invoked from
+   * concurrent threads.  The caller does not need to perform external
+   * synchronization. This means that {@link
+   * javax.swing.event.UndoableEvent} sources do not need to broadcast
+   * their events from inside the Swing worker thread.
+   *
+   * @param event the event whose <code>edit</code> will be
+   * passed to {@link #addEdit}.
+   *
+   * @see UndoableEditEvent#getEdit()
+   * @see #addEdit
+   */
+  public void undoableEditHappened(UndoableEditEvent event)
+  {
+    // Note that this method does not need to be synchronized,
+    // because addEdit will obtain and release the mutex.
+    addEdit(event.getEdit());
+  }
+}
Index: jni/classpath/jcl.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/classpath/jcl.c,v
retrieving revision 1.2
diff -u -r1.2 jcl.c
--- jni/classpath/jcl.c	8 Oct 2003 15:49:32 -0000	1.2
+++ jni/classpath/jcl.c	6 Sep 2004 16:36:11 -0000
@@ -1,5 +1,5 @@
 /* jcl.c
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -37,13 +37,17 @@
 
 #include <stdio.h>
 #include <jcl.h>
-#include <malloc.h>
+#include <stdlib.h>
 
 #ifndef __GNUC__
 #define __attribute__(x) /* nothing */
 #endif
 
-static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory.
+/*
+ * This way the memory is pre-allocated, so that we do not have to worry
+ * if we are out of memory.
+ */
+static char errstr[4098];
 
 JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg) {
 	jclass excClass;
Index: jni/classpath/jnilink.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/classpath/jnilink.c,v
retrieving revision 1.1
diff -u -r1.1 jnilink.c
--- jni/classpath/jnilink.c	31 Jan 2003 17:54:14 -0000	1.1
+++ jni/classpath/jnilink.c	6 Sep 2004 16:36:11 -0000
@@ -1,5 +1,5 @@
 /* JNILINK 1.1: JNI version.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,7 +40,7 @@
 #include <string.h>
 #include <jcl.h>
 
-#include <malloc.h>
+#include <stdlib.h>
 
 #define GETCLASS(c) *(jclass*)(c)
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c
===================================================================
RCS file: jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c
diff -N jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c	6 Sep 2004 16:36:11 -0000
@@ -0,0 +1,68 @@
+/* Native implementation of functions in GThreadNativeMethodRunner
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h"
+#include "gthread-jni.h"
+
+/*
+ * Class:     GThreadNativeMethodRunner
+ * Method:    nativeRun
+ * Signature: (J)V
+ *
+ * Purpose: Run the C function whose function pointer is
+ * 
+ */
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun(JNIEnv *gdk_env, jobject lcl_obj, 
+					 jlong funcAddr, jlong funcArg)
+{
+  /* Convert the function's address back into a pointer to a C function. */
+  void *(*funcPtr)(void *) = (void *(*)(void *)) funcAddr;
+  
+  /* We do not need to worry about the return value from funcPtr(); it's
+     just thrown away.  That is part of the g_threads spec, so no reason
+     to worry about returning it.  */
+  (void) funcPtr((void *) funcArg);
+  /* Fall off the end and terminate the thread of control. */
+}
+
+/* Local Variables: */
+/* c-file-style: "gnu" */
+/* End: */
+
+
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c	20 Nov 2003 22:44:01 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c	6 Sep 2004 16:36:11 -0000
@@ -112,9 +112,10 @@
   struct peerfont *pfont = NULL;
   PangoFontMap *map = NULL; 
   char const *family_name = NULL;
+  enum java_awt_font_style style;
 
   gdk_threads_enter ();
-  enum java_awt_font_style style = (enum java_awt_font_style) style_int;
+  style = (enum java_awt_font_style) style_int;
 
   g_assert (self != NULL);
   pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
@@ -135,7 +136,7 @@
   pango_font_description_set_family (pfont->desc, family_name);
   (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
 
-  pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);  
+  pango_font_description_set_size (pfont->desc, size * dpi_conversion_factor);
 
   if (style & java_awt_font_BOLD)
     pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c	31 Dec 2003 08:58:31 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c	6 Sep 2004 16:36:11 -0000
@@ -53,6 +53,9 @@
   jintArray array;
   jint *metrics;
   struct peerfont *pf = NULL;
+  FT_Matrix mat;
+  double pointsize;
+  FT_Face face;
 
   pf = NSA_GET_FONT_PTR(env, font);
   g_assert (pf != NULL);
@@ -62,14 +65,21 @@
 
   gdk_threads_enter ();
 
-#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 63.0))
-#define DOUBLE_FROM_26_6(t) (((double)((t) >> 6)) \
-			     + ((double)((t) & 0x3F) / 63.0))
+#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
+#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
+#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
+#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
 
-  double pointsize = pango_font_description_get_size (pf->desc);
+  pointsize = pango_font_description_get_size (pf->desc);
   pointsize /= (double) PANGO_SCALE;
 
-  FT_Face face = pango_ft2_font_get_face (pf->font);  
+  mat.xx = DOUBLE_TO_16_16(1);
+  mat.xy = DOUBLE_TO_16_16(0);
+  mat.yx = DOUBLE_TO_16_16(0);
+  mat.yy = DOUBLE_TO_16_16(1);  
+  
+  face = pango_ft2_font_get_face (pf->font);  
+  FT_Set_Transform(face, &mat, NULL);
   FT_Set_Char_Size( face, 
 		    DOUBLE_TO_26_6 (pointsize),
 		    DOUBLE_TO_26_6 (pointsize),
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c,v
retrieving revision 1.3
diff -u -r1.3 gnu_java_awt_peer_gtk_GdkFontMetrics.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c	2 Dec 2003 21:00:05 -0000	1.3
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c	6 Sep 2004 16:36:11 -0000
@@ -47,7 +47,8 @@
 #define NUM_METRICS 5
 
 JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_initState
-  (JNIEnv *env, jobject obj __attribute__((unused)), jstring fname, jint size)
+  (JNIEnv *env, jobject obj __attribute__((unused)),
+   jstring fname, jint style, jint size)
 {
   jintArray array;
   jint *metrics;
@@ -64,21 +65,28 @@
   gdk_threads_enter ();
 
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
 
   context = gdk_pango_context_get();
   pango_context_set_font_description (context, font_desc);
 
-  pango_metrics = pango_context_get_metrics (context, font_desc, NULL);
+  pango_metrics = pango_context_get_metrics (context, font_desc,
+                                             gtk_get_default_language ());
 
   metrics[ASCENT] =
-    pango_font_metrics_get_ascent (pango_metrics) / PANGO_SCALE;
+    PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
   metrics[MAX_ASCENT]  = metrics[ASCENT];
   metrics[DESCENT] =
-    pango_font_metrics_get_descent (pango_metrics) / PANGO_SCALE;
+    PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
   metrics[MAX_DESCENT] = metrics[DESCENT];
   metrics[MAX_ADVANCE] =
-    pango_font_metrics_get_approximate_char_width (pango_metrics) / PANGO_SCALE;
+    PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (pango_metrics));
 
   pango_font_metrics_unref (pango_metrics);
 
@@ -94,7 +102,7 @@
 
 JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_stringWidth
   (JNIEnv *env, jobject obj __attribute__((unused)),
-   jstring fname, jint size, jstring str)
+   jstring fname, jint style, jint size, jstring str)
 {
   PangoFontDescription *font_desc;
   PangoContext *context;
@@ -109,7 +117,13 @@
   gdk_threads_enter ();
 
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
 
   context = gdk_pango_context_get();
   pango_context_set_font_description (context, font_desc);
@@ -117,6 +131,7 @@
   layout = pango_layout_new (context);
 
   pango_layout_set_text (layout, cstr, -1);
+
   pango_layout_get_pixel_size (layout, &width, NULL);
 
   pango_font_description_free (font_desc);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GdkGlyphVector.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c	20 Nov 2003 22:44:01 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c	6 Sep 2004 16:36:11 -0000
@@ -47,10 +47,11 @@
   double height;
 } rect_t;
 
-#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 63.0))
-#define DOUBLE_FROM_26_6(t) (((double)((t) >> 6)) \
-			     + ((double)((t) & 0x3F) / 63.0))
-
+#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
+#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
+#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
+#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
+ 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initStaticState 
   (JNIEnv *env, jclass clazz)
 {
@@ -401,6 +402,21 @@
   return idx;
 }
 
+static void 
+assume_pointsize_and_identity_transform(double pointsize,
+					FT_Face face)
+{
+  FT_Matrix mat;
+  mat.xx = DOUBLE_TO_16_16(1);
+  mat.xy = DOUBLE_TO_16_16(0);
+  mat.yx = DOUBLE_TO_16_16(0);
+  mat.yy = DOUBLE_TO_16_16(1);    
+  FT_Set_Transform(face, &mat, NULL);
+  FT_Set_Char_Size( face, 
+		    DOUBLE_TO_26_6 (pointsize),
+		    DOUBLE_TO_26_6 (pointsize),
+		    0, 0);  
+}				    
 
 JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkExtents 
   (JNIEnv *env, jobject self)
@@ -432,10 +448,7 @@
       g_assert (gi->glyphs != NULL);
 
       face = pango_ft2_font_get_face (gi->item->analysis.font);
-      FT_Set_Char_Size( face, 
-			DOUBLE_TO_26_6 (pointsize),
-			DOUBLE_TO_26_6 (pointsize),
-			0, 0);
+      assume_pointsize_and_identity_transform (pointsize, face);
       
       for (j = 0; j < gi->glyphs->num_glyphs; ++j)
 	{
@@ -487,10 +500,7 @@
       g_assert (gi->glyphs != NULL);
 
       face = pango_ft2_font_get_face (gi->item->analysis.font);
-      FT_Set_Char_Size( face, 
-			DOUBLE_TO_26_6 (pointsize),
-			DOUBLE_TO_26_6 (pointsize),
-			0, 0);
+      assume_pointsize_and_identity_transform (pointsize, face);
       
       for (j = 0; j < gi->glyphs->num_glyphs; ++j)
 	{
@@ -541,11 +551,9 @@
   pointsize = pango_font_description_get_size (vec->desc);
   pointsize /= (double) PANGO_SCALE;
   face = pango_ft2_font_get_face (font);
-  FT_Set_Char_Size( face, 
-		    DOUBLE_TO_26_6 (pointsize),
-		    DOUBLE_TO_26_6 (pointsize),
-		    0, 0);
-  
+
+  assume_pointsize_and_identity_transform (pointsize, face);  
+
   FT_Load_Glyph (face, gi->glyph, FT_LOAD_DEFAULT);
 
   /* FIXME: this is probably not the correct set of metrics;
@@ -588,10 +596,8 @@
   pointsize = pango_font_description_get_size (vec->desc);
   pointsize /= (double) PANGO_SCALE;
   face = pango_ft2_font_get_face (font);
-  FT_Set_Char_Size( face, 
-		    DOUBLE_TO_26_6 (pointsize),
-		    DOUBLE_TO_26_6 (pointsize),
-		    0, 0);
+
+  assume_pointsize_and_identity_transform (pointsize, face);  
   
   FT_Load_Glyph (face, gi->glyph, FT_LOAD_DEFAULT);
   /* FIXME: this needs to change for vertical layouts */
@@ -630,9 +636,12 @@
 
   gdk_threads_leave ();
 
-  return 
+  return 1;
+  /* FIXME: Pango doesn't seem to have decided how it will deal
+     with vertical text. for the time being we inherit this limitation.
     ((dir == PANGO_DIRECTION_LTR) ||
      (dir == PANGO_DIRECTION_RTL));    
+  */
 }
 
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GdkGraphics.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c	8 Oct 2003 23:38:45 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c	6 Sep 2004 16:36:12 -0000
@@ -94,15 +94,13 @@
 
 /* copy the native state of the peer (GtkWidget *) to the native state
    of the graphics object */
-JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
   (JNIEnv *env, jobject obj, jobject peer)
 {
   struct graphics *g = (struct graphics *) malloc (sizeof (struct graphics));
   void *ptr;
   GtkWidget *widget;
   GdkColor color;
-  jintArray array;
-  jint *rgb;
 
   ptr = NSA_GET_PTR (env, peer);
   g->x_offset = g->y_offset = 0;
@@ -133,16 +131,7 @@
 
   gdk_threads_leave ();
 
-  array = (*env)->NewIntArray (env, 3);
-  rgb = (*env)->GetIntArrayElements (env, array, NULL);
-  rgb[0] = color.red >> 8;
-  rgb[1] = color.green >> 8;
-  rgb[2] = color.blue >> 8;
-  (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
-
   NSA_SET_PTR (env, obj, g);
-
-  return array;
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose
@@ -188,7 +177,7 @@
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
   (JNIEnv *env, jobject obj, jstring str, jint x, jint y, 
-   jstring fname, jint size)
+   jstring fname, jint style, jint size)
 {
   struct graphics *g;
   const char *cstr;
@@ -207,7 +196,14 @@
   gdk_threads_enter ();
 
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
 
   context = gdk_pango_context_get();
   pango_context_set_font_description (context, font_desc);
@@ -219,12 +215,15 @@
 
   baseline_y = pango_layout_iter_get_baseline (iter);
 
-  gdk_draw_layout (g->drawable, g->gc, 
-  		   x + g->x_offset, y + g->y_offset - (baseline_y / PANGO_SCALE), layout);
+  gdk_draw_layout (g->drawable, g->gc,
+                   x + g->x_offset,
+                   y + g->y_offset - PANGO_PIXELS (baseline_y),
+                   layout);
 
   pango_font_description_free (font_desc);
   pango_layout_iter_free (iter);
 
+  gdk_flush ();
   gdk_threads_leave ();
 
   (*env)->ReleaseStringUTFChars (env, fname, font_name);
@@ -242,6 +241,7 @@
   gdk_draw_line (g->drawable, g->gc, 
 		 x + g->x_offset, y + g->y_offset, 
 		 x2 + g->x_offset, y2 + g->y_offset);
+  gdk_flush ();
   gdk_threads_leave ();
 }
 
@@ -253,8 +253,10 @@
   g = (struct graphics *) NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
+
   gdk_draw_rectangle (g->drawable, g->gc, TRUE, 
 		      x + g->x_offset, y + g->y_offset, width, height);
+  gdk_flush ();
   gdk_threads_leave ();
 }
 
@@ -268,6 +270,7 @@
   gdk_threads_enter ();
   gdk_draw_rectangle (g->drawable, g->gc, FALSE, 
 		      x + g->x_offset, y + g->y_offset, width, height);
+  gdk_flush ();
   gdk_threads_leave ();
 }
 
@@ -286,6 +289,7 @@
 			(GdkWindow *)g->drawable,
 			x + g->x_offset, y + g->y_offset,
 			width, height);
+  gdk_flush ();
   gdk_threads_leave ();
 }
 
@@ -305,9 +309,114 @@
 			(GdkWindow *)g2->drawable,
 			0 + g2->x_offset, 0 + g2->y_offset, 
 			width, height);
+  gdk_flush ();
   gdk_threads_leave ();
 }
+
+static void flip_pixbuf (GdkPixbuf *pixbuf,
+                         jboolean flip_x,
+                         jboolean flip_y,
+                         jint width,
+                         jint height)
+{
+  gint src_rs;
+  guchar *src_pix;
+
+  src_rs = gdk_pixbuf_get_rowstride (pixbuf);
+  src_pix = gdk_pixbuf_get_pixels (pixbuf);
+
+  if (flip_x) 
+    {
+      gint i, channels;
+      guchar buf[4];
+
+      channels = gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3;
+
+      for (i = 0; i < height; i++) 
+        {
+          guchar *left = src_pix + i * src_rs;
+          guchar *right = left + channels * (width - 1);
+          while (left < right)
+            { 
+              g_memmove (buf, left, channels);
+              g_memmove (left, right, channels);
+              g_memmove (right, buf, channels);
+              left += channels;
+              right -= channels;
+            }
+        }
+    }
+
+  if (flip_y) 
+    {
+      guchar *top = src_pix;
+      guchar *bottom = top + (height - 1) * src_rs;
+      gpointer buf = g_malloc (src_rs);
+      
+      while (top < bottom)
+        {
+          g_memmove (buf, top, src_rs);
+          g_memmove (top, bottom, src_rs);
+          g_memmove (bottom, buf, src_rs); 
+          top += src_rs;
+          bottom -= src_rs;
+        }
+
+      g_free (buf);
+    }
+}
   
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyAndScalePixmap
+  (JNIEnv *env, jobject obj, jobject offscreen, jboolean flip_x, jboolean flip_y,
+   jint src_x, jint src_y, jint src_width, jint src_height,
+   jint dest_x, jint dest_y, jint dest_width, jint dest_height)
+{
+  struct graphics *g1, *g2;
+  GdkPixbuf *buf_src, *buf_dest;
+
+  g1 = (struct graphics *) NSA_GET_PTR (env, obj);
+  g2 = (struct graphics *) NSA_GET_PTR (env, offscreen);
+
+  gdk_threads_enter ();
+
+  buf_src = gdk_pixbuf_get_from_drawable (NULL,
+                                          g2->drawable,
+                                          g2->cm,
+                                          src_x,
+                                          src_y,
+                                          0,
+                                          0,
+                                          src_width,
+                                          src_height);
+
+  buf_dest = gdk_pixbuf_scale_simple (buf_src, 
+                                      dest_width, 
+                                      dest_height, 
+                                      GDK_INTERP_BILINEAR);
+
+  if (flip_x || flip_y)
+    {
+      flip_pixbuf (buf_dest, flip_x, flip_y, dest_width, dest_height);
+    }
+
+  gdk_pixbuf_render_to_drawable (buf_dest,
+                                 g1->drawable,
+                                 g1->gc,
+                                 0,
+                                 0,
+                                 dest_x,
+                                 dest_y,
+                                 dest_width,
+                                 dest_height,
+                                 GDK_RGB_DITHER_NORMAL,
+                                 0,
+                                 0);
+
+  g_object_unref (G_OBJECT (buf_src));
+  g_object_unref (G_OBJECT (buf_dest));
+
+  gdk_threads_leave ();
+}
 
 
 
@@ -316,12 +425,25 @@
   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
 {
   struct graphics *g;
+  GdkGCValues saved;
 
   g = (struct graphics *) NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gdk_window_clear_area ((GdkWindow *)g->drawable, 
-			 x + g->x_offset, y + g->y_offset, width, height);
+  if (GDK_IS_WINDOW (g->drawable))
+    {
+      gdk_window_clear_area ((GdkWindow *)g->drawable, 
+			     x + g->x_offset, y + g->y_offset, width, height);
+    }
+  else
+    {
+      gdk_gc_get_values (g->gc, &saved);
+      gdk_gc_set_foreground (g->gc, &(saved.background));
+      gdk_draw_rectangle (g->drawable, g->gc, TRUE, 
+			  x + g->x_offset, y + g->y_offset, width, height);
+      gdk_gc_set_foreground (g->gc, &(saved.foreground));
+    }
+  gdk_flush ();
   gdk_threads_leave ();
 }
 
@@ -352,6 +474,7 @@
   gdk_threads_enter ();
   gdk_color_alloc (g->cm, &color);
   gdk_gc_set_foreground (g->gc, &color);
+
   gdk_threads_leave ();
 }
 
@@ -367,6 +490,7 @@
   gdk_draw_arc (g->drawable, g->gc, FALSE, 
 		x + g->x_offset, y + g->y_offset, 
 		width, height, angle1 << 6, angle2 << 6);
+  gdk_flush ();
   gdk_threads_leave ();
 }  
 
@@ -410,6 +534,7 @@
 
   gdk_threads_enter ();
   gdk_draw_lines (g->drawable, g->gc, points, npoints);
+  gdk_flush ();
   gdk_threads_leave ();
 
   g_free (points);
@@ -433,6 +558,7 @@
 
   gdk_threads_enter ();
   gdk_draw_lines (g->drawable, g->gc, points, npoints);
+  gdk_flush ();
   gdk_threads_leave ();
 
   g_free (points);
@@ -450,6 +576,7 @@
 			     g->x_offset, g->y_offset);
   gdk_threads_enter ();
   gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints);
+  gdk_flush ();
   gdk_threads_leave ();
 
   g_free (points);
@@ -467,6 +594,7 @@
   gdk_draw_arc (g->drawable, g->gc, TRUE, 
 		x + g->x_offset, y + g->y_offset, 
 		width, height, angle1 << 6, angle2 << 6);
+  gdk_flush ();
   gdk_threads_leave ();
 }  
 
@@ -481,6 +609,7 @@
   gdk_draw_arc (g->drawable, g->gc, FALSE, 
 		x + g->x_offset, y + g->y_offset, 
 		width, height, 0, 23040);
+  gdk_flush ();
   gdk_threads_leave ();
 }  
 
@@ -495,8 +624,9 @@
   gdk_draw_arc (g->drawable, g->gc, TRUE, 
 		x + g->x_offset, y + g->y_offset, 
 		width, height, 0, 23040);
+  gdk_flush ();
   gdk_threads_leave ();
-}  
+}
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c,v
retrieving revision 1.5
diff -u -r1.5 gnu_java_awt_peer_gtk_GdkGraphics2D.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c	31 Dec 2003 08:58:31 -0000	1.5
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c	6 Sep 2004 16:36:12 -0000
@@ -67,7 +67,9 @@
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState 
   (JNIEnv *env, jclass clazz)
 {
-    NSA_G2D_INIT (env, clazz);
+   gdk_threads_enter();
+   NSA_G2D_INIT (env, clazz);
+   gdk_threads_leave();
 }
 
 /* these public final constants are part of the java2d public API, so we
@@ -114,6 +116,41 @@
     java_awt_geom_path_iterator_WIND_NON_ZERO = 1
   };
 
+enum java_awt_rendering_hints_filter
+  {
+    java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,    
+    java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
+    java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
+    java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
+    java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
+ 
+  };
+
+static int
+peer_is_disposed(JNIEnv *env, jobject obj)
+{
+  static jfieldID fid = NULL;
+  jclass cls;
+  jobject peer;
+
+  return 0;
+
+  if (fid == NULL)
+    {
+      cls = (*env)->GetObjectClass(env, obj);
+      fid = (*env)->GetFieldID(env, cls, "component",
+			       "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
+    }
+  g_assert(fid != NULL);
+  peer = (*env)->GetObjectField(env, obj, fid);
+  if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
+    return 0;
+  else
+    {
+      return 1;
+    }
+}
+
 
 static void 
 grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
@@ -136,7 +173,7 @@
     }
 
   *draw = *win;
-  gdk_window_get_internal_paint_info (*win, draw, 0, 0);
+  gdk_window_get_internal_paint_info (*win, draw, 0, 0); 
   g_object_ref (*draw);
 }
 
@@ -211,7 +248,7 @@
 static void
 begin_drawing_operation (struct graphics2d * gr)
 {  
-  gdk_threads_enter ();
+  g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
   if (gr->drawbuf)
     {
 
@@ -239,6 +276,7 @@
 static void
 end_drawing_operation (struct graphics2d * gr)
 {
+  g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
   if (gr->drawbuf)
     { 
       gint drawable_width, drawable_height;
@@ -259,7 +297,6 @@
       if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
 			     width, height);
     }
-  gdk_threads_leave ();
 }
 
 
@@ -279,7 +316,7 @@
   mat = cairo_matrix_create ();
   g_assert (mat != NULL);
   cairo_matrix_set_affine (mat, a, b, c, d, tx, ty);
-  cairo_surface_set_matrix (gr->pattern, mat);
+  cairo_pattern_set_matrix (gr->pattern, mat);
   cairo_matrix_destroy (mat);
 }
 
@@ -294,6 +331,7 @@
 {
   struct graphics2d *g = NULL, *g_old = NULL;
 
+  gdk_threads_enter();
   g = (struct graphics2d *) malloc (sizeof (struct graphics2d));
   g_assert (g != NULL);
   memset (g, 0, sizeof(struct graphics2d));
@@ -306,7 +344,6 @@
   g->drawable = g_old->drawable;
   g->debug = g_old->debug; 
 
-  gdk_threads_enter ();
   g_object_ref (g->drawable);
   
   g->cr = cairo_create();
@@ -319,9 +356,8 @@
 
   cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
 
-  gdk_threads_leave ();
-
   NSA_SET_G2D_PTR (env, obj, g);
+  gdk_threads_leave();
 }
 
 
@@ -329,9 +365,8 @@
   (JNIEnv *env, jobject obj, jint width, jint height)
 {
   struct graphics2d *gr;
-
-  gdk_threads_enter ();
   
+  gdk_threads_enter();
   gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
   g_assert (gr != NULL);
   memset (gr, 0, sizeof(struct graphics2d));
@@ -340,7 +375,7 @@
 
   if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
 			 width, height);
-  
+
   gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height, 
 						 gdk_rgb_get_visual ()->depth);
   g_assert (gr->drawable != NULL);
@@ -353,10 +388,10 @@
   else
     init_graphics2d_as_pixbuf (gr);
 
-  gdk_threads_leave ();
   if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
 			 width, height);
   NSA_SET_G2D_PTR (env, obj, gr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
@@ -364,8 +399,11 @@
 {
   struct graphics2d *src = NULL, *dst = NULL;
   gint s_height, s_width, d_height, d_width, height, width;
-  GdkGC *gc;
+  cairo_matrix_t *matrix;
+  cairo_operator_t tmp_op;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
   src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
   dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
   g_assert (src != NULL);
@@ -373,64 +411,48 @@
 
   if (src->debug) printf ("copying from offscreen drawable\n");
 
-  gdk_threads_enter ();
+  begin_drawing_operation(dst); 
+
+  gdk_flush();
+
   gdk_drawable_get_size (src->drawable, &s_width, &s_height);
   gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
   width = min (s_width, d_width);
-  height = min (s_width, d_height);
-
-  gc = gdk_gc_new (dst->drawable);
-  g_assert (gc != NULL);
-
-  gdk_draw_drawable(dst->drawable, gc, src->drawable, 
- 		    0, 0, x, y, width, height); 
-  gdk_flush ();
-
-  g_object_unref (gc);
+  height = min (s_height, d_height);
 
-  if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
-  gdk_threads_leave ();  
-}
+  matrix = cairo_matrix_create ();
+  cairo_surface_get_matrix (src->surface, matrix);
+  cairo_matrix_translate (matrix, (double)-x, (double)-y);
+  cairo_surface_set_matrix (src->surface, matrix);
 
-static jintArray
-current_colors_of_widget (GtkWidget *widget, JNIEnv *env)
-{
-  GdkColor color;
-  jintArray array;
-  jint *rgb;
-
-  g_assert (widget != NULL);
-  g_assert (env != NULL);
+  tmp_op = cairo_current_operator (dst->cr); 
+  cairo_set_operator(dst->cr, CAIRO_OPERATOR_SRC); 
+  cairo_show_surface (dst->cr, src->surface, width, height);
+  cairo_set_operator(dst->cr, tmp_op);
 
-  color = widget->style->fg[GTK_STATE_NORMAL];
-  array = (*env)->NewIntArray (env, 6);
+  cairo_matrix_translate (matrix, (double)x, (double)y);
+  cairo_surface_set_matrix (src->surface, matrix);
+  cairo_matrix_destroy (matrix);
 
-  rgb = (*env)->GetIntArrayElements (env, array, NULL);
-  rgb[0] = color.red >> 8;
-  rgb[1] = color.green >> 8;
-  rgb[2] = color.blue >> 8;
+  gdk_flush();
 
-  color = widget->style->bg[GTK_STATE_NORMAL];
-  rgb[3] = color.red >> 8;
-  rgb[4] = color.green >> 8;
-  rgb[5] = color.blue >> 8;
+  end_drawing_operation(dst);
 
-  (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
-  
-  return array;
+  if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
+  gdk_threads_leave();
 }
 
-JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
   (JNIEnv *env, jobject obj, jobject peer)
 {
   struct graphics2d *gr = NULL;
   GtkWidget *widget = NULL;
   void *ptr = NULL;
-  jintArray color;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
   ptr = NSA_GET_PTR (env, peer);
   g_assert (ptr != NULL);
-  gdk_threads_enter ();
 
   gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
   g_assert (gr != NULL);
@@ -452,11 +474,8 @@
   else
     init_graphics2d_as_pixbuf (gr);
 
-  color = current_colors_of_widget (widget, env);
-
-  gdk_threads_leave ();
   NSA_SET_G2D_PTR (env, obj, gr);
-  return color;
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
@@ -464,11 +483,13 @@
 {
   struct graphics2d *gr = NULL;
 
+  gdk_threads_enter();
   gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
   if (gr == NULL) 
-    return; /* dispose has been called more than once */
-  
-  gdk_threads_enter ();
+    {
+      gdk_threads_leave();
+      return; /* dispose has been called more than once */
+    }
 
   if (gr->surface)
     cairo_surface_destroy (gr->surface);
@@ -481,15 +502,18 @@
   g_object_unref (gr->drawable);
 
   if (gr->pattern)
-    cairo_surface_destroy (gr->pattern);
+    cairo_pattern_destroy (gr->pattern);
+
+  if (gr->pattern_surface)
+    cairo_surface_destroy (gr->pattern_surface);
 
   if (gr->pattern_pixels)
     free (gr->pattern_pixels);
 
   if (gr->debug) printf ("disposed of graphics2d\n");
-  free (gr);
 
-  gdk_threads_leave ();
+  free (gr);
+  gdk_threads_leave();
 }
 
 
@@ -507,6 +531,8 @@
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
   if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
 			 x1, y1, 
 			 x2, y2, 
@@ -578,38 +604,41 @@
      negate offsets. oh well.
      
    */
-
-  double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
-  double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
-  double dx = (x1 == 0.) ? 0. : 1. / x1;
-  double dy = (y1 == 0.) ? 0. : 1. / y1;
-
-  cairo_matrix_set_affine (mat,
-			   a, 0.,
-			   c, 0.,
-			   dx, dy);
-
-  cairo_surface_set_matrix (surf, mat);
-  cairo_matrix_destroy (mat);
-  cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
+  {
+    double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
+    double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
+    double dx = (x1 == 0.) ? 0. : 1. / x1;
+    double dy = (y1 == 0.) ? 0. : 1. / y1;
+    
+    cairo_matrix_set_affine (mat,
+			     a, 0.,
+			     c, 0.,
+			     dx, dy);
+    
+    cairo_surface_set_matrix (surf, mat);
+    cairo_matrix_destroy (mat);
+    cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
+  }
 
   /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
   /*   cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
 
   if (gr->pattern)
-    cairo_surface_destroy (gr->pattern);
+    cairo_pattern_destroy (gr->pattern);
+  
+  if (gr->pattern_surface)
+    cairo_surface_destroy (gr->pattern_surface);
 
   if (gr->pattern_pixels)
-    {
-      free (gr->pattern_pixels);
-      gr->pattern_pixels = NULL;
-    }
-
-  gr->pattern = surf;  
+    free (gr->pattern_pixels);
+  
+  gr->pattern_pixels = NULL;  
+  gr->pattern_surface = surf;  
+  gr->pattern = cairo_pattern_create_for_surface(surf);
 
   cairo_restore (gr->cr);    
   cairo_set_pattern (gr->cr, gr->pattern);
-
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels 
@@ -618,6 +647,8 @@
   struct graphics2d *gr = NULL;
   jint *jpixels = NULL;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
@@ -625,12 +656,16 @@
 			 (*env)->GetArrayLength (env, jarr), w, h, stride);
 
   if (gr->pattern)
-    cairo_surface_destroy (gr->pattern);
+    cairo_pattern_destroy (gr->pattern);
+
+  if (gr->pattern_surface)
+    cairo_surface_destroy (gr->pattern_surface);
 
   if (gr->pattern_pixels)
     free (gr->pattern_pixels);
 
   gr->pattern = NULL;
+  gr->pattern_surface = NULL;
   gr->pattern_pixels = NULL;
 
   gr->pattern_pixels = (char *) malloc (h * stride * 4);
@@ -641,13 +676,15 @@
   memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
   (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
 
-  gr->pattern = cairo_surface_create_for_image (gr->pattern_pixels, 
-						CAIRO_FORMAT_ARGB32, 
-						w, h, stride * 4);
+  gr->pattern_surface = cairo_surface_create_for_image (gr->pattern_pixels, 
+							CAIRO_FORMAT_ARGB32, 
+							w, h, stride * 4);
+  g_assert (gr->pattern_surface != NULL);
+  cairo_surface_set_repeat (gr->pattern_surface, 1);
+  gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
   g_assert (gr->pattern != NULL);
-  cairo_surface_set_repeat (gr->pattern, 1);
   cairo_set_pattern (gr->cr, gr->pattern);
-
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels 
@@ -658,6 +695,9 @@
   jint *native_pixels = NULL;
   jdouble *native_matrix = NULL;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
@@ -683,30 +723,86 @@
 			    native_matrix[2], native_matrix[3],
 			    native_matrix[4], native_matrix[5]);
    cairo_surface_set_matrix (surf, mat);
-   if (native_matrix[0] != 1.
-       || native_matrix[1] != 0.
-       || native_matrix[2] != 0.
-       || native_matrix[3] != 1.)
-     {
-       cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
-       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
-     }
-   else
-     {
-       cairo_surface_set_filter (surf, CAIRO_FILTER_FAST);
-       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
-     }
+   cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface));
    cairo_show_surface (gr->cr, surf, w, h);
-   cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
    cairo_matrix_destroy (mat);
    cairo_surface_destroy (surf);
  }
   
  end_drawing_operation (gr);
+ 
+ (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+ 
+  gdk_threads_leave();
+}
 
-  (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
-  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getImagePixels 
+   (JNIEnv *env, jobject obj)
+{
+  struct graphics2d *gr = NULL;
+  jintArray java_pixels;
+  jint* native_pixels;
+  GdkPixbuf *buf = NULL;
+  gint width, height;
+  gint bits_per_sample = 8;
+  gboolean has_alpha = TRUE;
+  gint total_channels = 4;
+  jint i, px;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return NULL; }
+
+  gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+  g_assert (gr != NULL);
+  
+  if (gr->debug) printf ("getImagePixels\n");
+  
+  gdk_drawable_get_size (gr->drawable, &width, &height);
+    
+  buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 
+                        bits_per_sample,
+                        width, height);
+  g_assert (buf != NULL);
+  g_assert (gdk_pixbuf_get_bits_per_sample (buf) == bits_per_sample);
+  g_assert (gdk_pixbuf_get_n_channels (buf) == total_channels);
+  
+      
+  /* copy pixels from drawable to pixbuf */
+  
+  gdk_pixbuf_get_from_drawable (buf, gr->drawable,
+                                NULL, 
+                                0, 0, 0, 0,
+                                width, height);
+ 								      				      
+  native_pixels= gdk_pixbuf_get_pixels (buf);
+  
+     
+  /* NOTE: The pixels we got in the pixbuf are stored 
+     in reversed order. i.e 0xBBGGRRAA. 
+     We need to convert them to  0xAARRGGBB. */
+   
+  for (i=0; i<width * height; i++) 
+    {	     
+  	      
+        /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
+        
+        px = native_pixels[i];
+        px = ((px >> 24) & 0xff) | ((px << 8) & 0xffffff00); 
+        px = ((px >>  8) & 0x00ff00ff) | ((px <<  8) & 0xff00ff00); 
+        px = ((px >> 16) & 0x0000ffff) | ((px << 16) & 0xffff0000); 
+        native_pixels[i] = px;
+      
+    }
+
+   java_pixels = (*env) -> NewIntArray (env, width * height);   
+   
+   (*env)->SetIntArrayRegion(env, java_pixels, 
+                            (jsize)0, (jsize) width*height, 
+                            (jint*) native_pixels);
+   
+   gdk_threads_leave();
+   return java_pixels;
 }
 
 /* passthrough methods to cairo */
@@ -715,21 +811,31 @@
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_save\n");
   cairo_save (gr->cr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore 
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_restore\n");
   cairo_restore (gr->cr);
   update_pattern_transform (gr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix 
@@ -738,6 +844,9 @@
   struct graphics2d *gr = NULL;
   jdouble *native_matrix = NULL;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
@@ -762,6 +871,7 @@
 
   (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
   update_pattern_transform (gr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont 
@@ -772,14 +882,15 @@
   cairo_font_t *ft = NULL;
   FT_Face face = NULL;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
   pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
   g_assert (pfont != NULL);
 
-  gdk_threads_enter ();
-
   face = pango_ft2_font_get_face (pfont->font);
   g_assert (face != NULL);
 
@@ -795,8 +906,7 @@
 		    (double)PANGO_SCALE);
 
   cairo_font_destroy (ft);
-
-  gdk_threads_leave ();
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs
@@ -809,6 +919,9 @@
   jint i;
   jint ncodes, nposns;
 
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
@@ -843,12 +956,17 @@
   end_drawing_operation (gr);
 
   free(glyphs);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator 
    (JNIEnv *env, jobject obj, jint op)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_operator %d\n", op);
@@ -902,12 +1020,17 @@
       cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
       break;
     }
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBColor 
    (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
@@ -922,22 +1045,33 @@
     cairo_set_rgb_color (gr->cr, b, g, r);
   else
     cairo_set_rgb_color (gr->cr, r, g, b);
+
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetAlpha 
    (JNIEnv *env, jobject obj, jdouble a)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_alpha %f\n", a);
   cairo_set_alpha (gr->cr, a);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule 
    (JNIEnv *env, jobject obj, jint rule)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
   g_assert (gr != NULL);
@@ -950,22 +1084,32 @@
       cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
       break;
     }  
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth 
    (JNIEnv *env, jobject obj, jdouble width)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_line_width %f\n", width);
   cairo_set_line_width (gr->cr, width);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap 
    (JNIEnv *env, jobject obj, jint cap)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
@@ -983,12 +1127,17 @@
       cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
       break;
     }
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin 
    (JNIEnv *env, jobject obj, jint join)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_line_join %d\n", join);
@@ -1006,6 +1155,7 @@
       cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
       break;
     }
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash 
@@ -1013,6 +1163,10 @@
 {
   struct graphics2d *gr = NULL;
   jdouble *dasharr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_dash\n");
@@ -1020,16 +1174,22 @@
   g_assert (dasharr != NULL);
   cairo_set_dash (gr->cr, dasharr, ndash, offset);
   (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit 
    (JNIEnv *env, jobject obj, jdouble miter)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
   cairo_set_miter_limit (gr->cr, miter);
+  gdk_threads_leave();
 }
 
 
@@ -1037,123 +1197,217 @@
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_new_path\n");
   cairo_new_path (gr->cr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo 
    (JNIEnv *env, jobject obj, jdouble x, jdouble y)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
   cairo_move_to (gr->cr, x, y);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo 
    (JNIEnv *env, jobject obj, jdouble x, jdouble y)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
   cairo_line_to (gr->cr, x, y);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo 
    (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", x1, y1, x2, y2, x3, y3);
   cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo 
    (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
   cairo_rel_move_to (gr->cr, dx, dy);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo 
    (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
   cairo_rel_line_to (gr->cr, dx, dy);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo 
    (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", dx1, dy1, dx2, dy2, dx3, dy3);
   cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle 
    (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
   cairo_rectangle (gr->cr, x, y, width, height);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath 
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_close_path\n");
   cairo_close_path (gr->cr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke 
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_stroke\n");
   begin_drawing_operation (gr);
   cairo_stroke (gr->cr);
   end_drawing_operation (gr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill 
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_fill\n");
   begin_drawing_operation (gr);
   cairo_fill (gr->cr);
   end_drawing_operation (gr);
+  gdk_threads_leave();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip 
    (JNIEnv *env, jobject obj)
 {
   struct graphics2d *gr = NULL;
+
+  gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_clip\n");
+  begin_drawing_operation (gr);
+  cairo_init_clip (gr->cr);
   cairo_clip (gr->cr);
+  end_drawing_operation (gr);
+  gdk_threads_leave();
 }
 
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
+   (JNIEnv *env, jobject obj, jint filter)
+{
+   struct graphics2d *gr = NULL;   
+
+   gdk_threads_enter();
+  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
+
+   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+   g_assert (gr != NULL);
+   if (gr->debug) printf ("cairo_surface_set_filter %d\n", filter);   
+   switch ((enum java_awt_rendering_hints_filter) filter)
+     {
+     case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
+       break;
+     case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
+       break; 
+     case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
+       break;
+     case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
+       break;
+     case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BEST);
+       break;
+     }
+   gdk_threads_leave();
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c	1 Dec 2003 18:05:32 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c	6 Sep 2004 16:36:12 -0000
@@ -1,5 +1,5 @@
 /* gdkpixbufdecoder.c
-   Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GNU Classpath.
    
@@ -35,36 +35,38 @@
    obligated to do so.  If you do not wish to do so, delete this
    exception statement from your version. */
 
-
-#include <gtk/gtk.h>
+#include <gtkpeer.h>
+#include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 
-#include "gtkpeer.h"
+#include <jni.h>
+#include "native_state.h"
 #include "gnu_java_awt_peer_gtk_GdkPixbufDecoder.h"
 
-struct state_table *native_pixbufdecoder_state_table;
-
-#define NSA_PB_INIT(env, clazz) \
-  native_pixbufdecoder_state_table = init_state_table (env, clazz)
+#include <string.h>
+#include <stdlib.h>
 
-#define NSA_GET_PB_PTR(env, obj) \
-  get_state (env, obj, native_pixbufdecoder_state_table)
-
-#define NSA_SET_PB_PTR(env, obj, ptr) \
-  set_state (env, obj, native_pixbufdecoder_state_table, (void *)ptr)
+struct state_table *native_pixbufdecoder_state_table;
 
-#define NSA_DEL_PB_PTR(env, obj) \
-  remove_state_slot (env, obj, native_pixbufdecoder_state_table)
+/* Union used for type punning. */
+union env_union
+{
+  void **void_env;
+  JNIEnv **jni_env;
+};
 
+static JavaVM *vm;
 
-jmethodID areaPreparedID;
-jmethodID areaUpdatedID;
+static jmethodID areaPreparedID;
+static jmethodID areaUpdatedID;
 
 static void
 area_prepared (GdkPixbufLoader *loader, 
 	       jobject *decoder)
 {
+  JNIEnv *env;
+  union env_union e;
   jint width, height;
 
   GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
@@ -72,17 +74,19 @@
     return;
 
   width = gdk_pixbuf_get_width (pixbuf); 
-  height = gdk_pixbuf_get_height (pixbuf), 
+  height = gdk_pixbuf_get_height (pixbuf);
 
   gdk_threads_leave ();
 
   g_assert (decoder != NULL);
 
-  (*gdk_env)->CallVoidMethod (gdk_env,
-			      *decoder,
-			      areaPreparedID,
-			      width, height);
-
+  e.jni_env = &env;
+  (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+  (*env)->CallVoidMethod (env,
+			  *decoder,
+			  areaPreparedID,
+			  width, height);
+  
   gdk_threads_enter ();
 }
 
@@ -92,6 +96,8 @@
 	      gint width, gint height,
 	      jobject *decoder)
 {
+  JNIEnv *env;
+  union env_union e;
   jint stride_bytes, stride_pixels, n_channels, n_pixels;
   int i, px;
   jintArray jpixels;  
@@ -114,8 +120,10 @@
   n_pixels = height * stride_pixels;
   gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
 
-  jpixels = (*gdk_env)->NewIntArray (gdk_env, n_pixels);
-  java_pixels = (*gdk_env)->GetIntArrayElements (gdk_env, jpixels, NULL);
+  e.jni_env = &env;
+  (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+  jpixels = (*env)->NewIntArray (env, n_pixels);
+  java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
 
   memcpy (java_pixels, 
 	  gdk_pixels + (y * stride_bytes), 
@@ -141,22 +149,27 @@
 
   gdk_threads_leave ();
 
-  (*gdk_env)->ReleaseIntArrayElements (gdk_env, jpixels, java_pixels, 0);
-  (*gdk_env)->CallVoidMethod (gdk_env, 
-			      *decoder, 
-			      areaUpdatedID,
-			      (jint) x, (jint) y,
-			      (jint) width, (jint) height,
-			      jpixels,
-			      stride_pixels);
+  (*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
+  (*env)->CallVoidMethod (env, 
+			  *decoder, 
+			  areaUpdatedID,
+			  (jint) x, (jint) y,
+			  (jint) width, (jint) height,
+			  jpixels,
+			  stride_pixels);
   gdk_threads_enter ();
 }
 
 static void
 closed (GdkPixbufLoader *loader __attribute__((unused)), jobject *decoder)
 {
+  JNIEnv *env;
+  union env_union e;
+  e.jni_env = &env;
+  (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+
   gdk_threads_leave ();
-  (*gdk_env)->DeleteGlobalRef (gdk_env, *decoder); 
+  (*env)->DeleteGlobalRef (env, *decoder); 
   free (decoder);
   gdk_threads_enter ();
 }
@@ -187,6 +200,8 @@
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initStaticState 
   (JNIEnv *env, jclass clazz)
 {
+  (*env)->GetJavaVM(env, &vm);
+
   areaPreparedID = (*env)->GetMethodID (env, clazz, 
 				        "areaPrepared", 
 					"(II)V");
@@ -223,14 +238,14 @@
   if (len < 1)
     return;
 
-  bytes = (*gdk_env)->GetByteArrayElements (gdk_env, jarr, NULL);
+  bytes = (*env)->GetByteArrayElements (env, jarr, NULL);
   g_assert (bytes != NULL);
   loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
   g_assert (loader != NULL);
 
   gdk_threads_enter ();
-  gdk_pixbuf_loader_write (loader, bytes, len, NULL);
+  gdk_pixbuf_loader_write (loader, (const guchar *) bytes, len, NULL);
   gdk_threads_leave ();
 
-  (*gdk_env)->ReleaseByteArrayElements (gdk_env, jarr, bytes, 0);
+  (*env)->ReleaseByteArrayElements (env, jarr, bytes, 0);
 }
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c,v
retrieving revision 1.7
diff -u -r1.7 gnu_java_awt_peer_gtk_GtkButtonPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c	13 Dec 2003 01:15:47 -0000	1.7
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c	6 Sep 2004 16:36:12 -0000
@@ -42,20 +42,23 @@
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkButtonPeer_create
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jobject obj, jstring label)
 {
+  const char *c_label;
   GtkWidget *button;
 
-  /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
+  c_label = (*env)->GetStringUTFChars (env, label, NULL);
+
   gdk_threads_enter ();
-  
-  button = gtk_button_new();
+
+  button = gtk_button_new_with_label (c_label);
   gtk_widget_show (button);
 
   gdk_threads_leave ();
 
+  (*env)->ReleaseStringUTFChars (env, label, c_label);
   NSA_SET_PTR (env, obj, button);
 }
 
@@ -88,29 +91,46 @@
 }
 
 JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkSetLabel
+  (JNIEnv *env, jobject obj, jstring jtext)
+{
+  const char *text;
+  GtkWidget *label;
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  text = (*env)->GetStringUTFChars (env, jtext, NULL);
+
+  gdk_threads_enter ();
+
+  label = gtk_bin_get_child (GTK_BIN (ptr));
+  gtk_label_set_text (GTK_LABEL (label), text);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseStringUTFChars (env, jtext, text);
+}
+
+JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkSetFont
   (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
 {
   const char *font_name;
   void *ptr;
-  GtkWidget *button;
   GtkWidget *label;
   PangoFontDescription *font_desc;
 
   ptr = NSA_GET_PTR (env, obj);
 
-  button = GTK_WIDGET (ptr);
-  label = gtk_bin_get_child (GTK_BIN(button));
-  
-  if (!label)
-      return;
-
   font_name = (*env)->GetStringUTFChars (env, name, NULL);
 
   gdk_threads_enter();
 
+  label = gtk_bin_get_child (GTK_BIN (ptr));
+
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
 
   if (style & AWT_STYLE_BOLD)
     pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
@@ -145,12 +165,24 @@
 
   label = gtk_bin_get_child (GTK_BIN(ptr));
 
-  if (!label)
-      return;
-
   gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &color);
   gtk_widget_modify_fg (label, GTK_STATE_ACTIVE, &color);
   gtk_widget_modify_fg (label, GTK_STATE_PRELIGHT, &color);
 
   gdk_threads_leave ();
 }
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkActivate
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  gtk_widget_activate (GTK_WIDGET (ptr));
+
+  gdk_threads_leave ();
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
===================================================================
RCS file: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
diff -N jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c	6 Sep 2004 16:36:12 -0000
@@ -0,0 +1,75 @@
+/* gtkcheckboxgrouppeer.c -- Native implementation of GtkCheckboxGroupPeer
+   Copyright (C) 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
+  (JNIEnv *env, jobject obj)
+{
+  /* The actual underlying widget is owned by a different class.  So
+     we just clean up the hash table here.  */
+  NSA_DEL_PTR (env, obj);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
+  (JNIEnv *env, jobject obj, jobject checkbox)
+{
+  GtkRadioButton *button;
+  void *ptr;
+  GSList *list;
+
+  ptr = NSA_GET_PTR (env, checkbox);
+  gdk_threads_enter ();
+  button = GTK_RADIO_BUTTON (ptr);
+
+  /* Update the group to point to some other widget in the group.  We
+     have to do this because Gtk doesn't have a separate object to
+     represent a radio button's group.  */
+  for (list = gtk_radio_button_group (button); list != NULL;
+       list = list->next)
+    {
+      if (list->data != button)
+       break;
+    }
+
+  gdk_threads_leave ();
+
+  NSA_SET_PTR (env, obj, list ? list->data : NULL);
+}
+
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c	13 Dec 2003 01:15:47 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c	6 Sep 2004 16:36:12 -0000
@@ -37,7 +37,7 @@
 
 
 #include "gtkpeer.h"
-#include "gnu_java_awt_peer_gtk_GtkMenuItemPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h"
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_create
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c	6 Sep 2004 16:36:12 -0000
@@ -1,5 +1,5 @@
 /* gtkcheckboxpeer.c -- Native implementation of GtkCheckboxPeer
-   Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,47 +42,12 @@
 
 static void item_toggled (GtkToggleButton *item, jobject peer);
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
-  (JNIEnv *env, jobject obj)
-{
-  /* The actual underlying widget is owned by a different class.  So
-     we just clean up the hash table here.  */
-  NSA_DEL_PTR (env, obj);
-}
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
-  (JNIEnv *env, jobject obj, jobject checkbox)
-{
-  GtkRadioButton *button;
-  void *ptr;
-  GSList *list;
-
-  ptr = NSA_GET_PTR (env, checkbox);
-  gdk_threads_enter ();
-  button = GTK_RADIO_BUTTON (ptr);
-
-  /* Update the group to point to some other widget in the group.  We
-     have to do this because Gtk doesn't have a separate object to
-     represent a radio button's group.  */
-  for (list = gtk_radio_button_group (button); list != NULL;
-       list = list->next)
-    {
-      if (list->data != button)
-	break;
-    }
-
-  gdk_threads_leave ();
-
-  NSA_SET_PTR (env, obj, list ? list->data : NULL);
-}
-
 JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_nativeCreate
-  (JNIEnv *env, jobject obj, jobject group, jboolean state)
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_create
+  (JNIEnv *env, jobject obj, jobject group)
 {
   GtkWidget *button;
 
-  /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
@@ -100,7 +65,6 @@
 	  NSA_SET_PTR (env, group, button);
 	}
     }
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), state);
 
   gdk_threads_leave ();
 
@@ -164,10 +128,86 @@
     NSA_SET_PTR (env, group, native_group);
 }
 
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkToggleButtonSetActive
+  (JNIEnv *env, jobject obj, jboolean is_active)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptr), is_active);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+  const char *font_name;
+  void *ptr;
+  GtkWidget *button;
+  GtkWidget *label;
+  PangoFontDescription *font_desc;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  button = GTK_WIDGET (ptr);
+  label = gtk_bin_get_child (GTK_BIN(button));
+
+  if (!label)
+      return;
+
+  font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+  gdk_threads_enter();
+
+  font_desc = pango_font_description_from_string (font_name);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+  
+  gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
+  
+  pango_font_description_free (font_desc);
+  
+  gdk_threads_leave();
+  
+  (*env)->ReleaseStringUTFChars (env, name, font_name);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkButtonSetLabel
+  (JNIEnv *env, jobject obj, jstring label)
+{
+  const char *c_label;
+  GtkWidget *label_widget;
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  c_label = (*env)->GetStringUTFChars (env, label, NULL);
+
+  gdk_threads_enter ();
+
+  label_widget = gtk_bin_get_child (GTK_BIN (ptr));
+  gtk_label_set_text (GTK_LABEL (label_widget), c_label);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseStringUTFChars (env, label, c_label);
+}
+
 static void
 item_toggled (GtkToggleButton *item, jobject peer)
 {
-  //g_print ("toggled\n");
   (*gdk_env)->CallVoidMethod (gdk_env, peer,
 			      postItemEventID,
 			      peer,
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c,v
retrieving revision 1.6
diff -u -r1.6 gnu_java_awt_peer_gtk_GtkChoicePeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c	5 Jan 2004 21:18:06 -0000	1.6
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c	6 Sep 2004 16:36:12 -0000
@@ -39,38 +39,27 @@
 #include "gtkpeer.h"
 #include "gnu_java_awt_peer_gtk_GtkChoicePeer.h"
 
-static void connect_choice_item_selectable_hook (JNIEnv *env, 
-						 jobject peer_obj, 
-						 GtkItem *menuitem, 
-						 const char *label);
+static void selection_changed (GtkComboBox *combobox, gpointer data);
 
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkChoicePeer_create 
   (JNIEnv *env, jobject obj)
 {
   GtkWidget *menu;
-  GtkOptionMenu *option_menu;
-  GtkRequisition child_requisition;
+  GtkComboBox *combobox;
 
-  /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
   
-  option_menu = GTK_OPTION_MENU (gtk_option_menu_new ());
-  menu = gtk_menu_new ();
-  gtk_widget_show (menu);
+  combobox = gtk_combo_box_new_text ();
 
-  gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
-
-  gtk_widget_size_request (gtk_menu_item_new_with_label (""), 
-			   &child_requisition);
-  option_menu->width = child_requisition.width;
-  option_menu->height = child_requisition.height;
+  g_signal_connect (combobox, "changed",
+                    G_CALLBACK (selection_changed), obj);
 
   gdk_threads_leave ();
 
-  NSA_SET_PTR (env, obj, option_menu);
+  NSA_SET_PTR (env, obj, combobox);
 }
 
 JNIEXPORT void JNICALL 
@@ -78,45 +67,27 @@
   (JNIEnv *env, jobject obj, jobjectArray items)
 {
   gpointer ptr;
-  GtkMenu *menu;
   jsize count, i;
-  int need_set_history = 0;
 
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
 
-  menu = GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr)));
-
-  /* Are we adding the first element? */
-  if (gtk_option_menu_get_history (GTK_OPTION_MENU (ptr)) < 0)
-      need_set_history = 1;
-
   count = (*env)->GetArrayLength (env, items);
 
   for (i = 0; i < count; i++) 
     {
       jobject item;
       const char *label;
-      GtkWidget *menuitem;
 
       item = (*env)->GetObjectArrayElement (env, items, i);
       label = (*env)->GetStringUTFChars (env, item, NULL);
 
-      menuitem = gtk_menu_item_new_with_label (label);
-      gtk_menu_append (menu, menuitem);
-      gtk_widget_show (menuitem);
-
-      connect_choice_item_selectable_hook (env, obj, 
-					   GTK_ITEM (menuitem), label);
+      gtk_combo_box_append_text (GTK_COMBO_BOX (ptr), label);
 
       (*env)->ReleaseStringUTFChars (env, item, label);
     }
 
-  /* If we just added the first element select it. */  
-  if (need_set_history)
-    gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
-
   gdk_threads_leave ();
 }
 
@@ -126,36 +97,13 @@
 {
   void *ptr;
   const char *label;
-  GtkWidget *menu, *menuitem;
-  int current;
-  int need_set_history = 0;
 
   ptr = NSA_GET_PTR (env, obj);
   
   label = (*env)->GetStringUTFChars (env, item, 0);      
 
   gdk_threads_enter ();
-  
-  current = gtk_option_menu_get_history (GTK_OPTION_MENU (ptr));
-
-  /* Are we adding the first element or below or at the currently
-     selected one? */
-  if ((current < 0) || (current >= index))
-      need_set_history = 1;
-
-  menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr));
-  menuitem = gtk_menu_item_new_with_label (label);
-  gtk_menu_insert (GTK_MENU (menu), menuitem, index);
-  gtk_widget_show (menuitem);
-
-  connect_choice_item_selectable_hook (env, obj, GTK_ITEM (menuitem), label);
-
-  /* If we just added the first element select it.
-     If we added at of below the currently selected position make
-     the first item the selected one. */  
-  if (need_set_history)
-    gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
-
+  gtk_combo_box_insert_text (GTK_COMBO_BOX (ptr), index, label);
   gdk_threads_leave ();
 
   (*env)->ReleaseStringUTFChars (env, item, label);
@@ -166,50 +114,35 @@
   (JNIEnv *env, jobject obj, jint index)
 {
   void *ptr;
-  GtkContainer *menu;
-  GtkWidget *menuitem;
-  GList *children;
-  int need_set_history = 0;
-  int i, from, to;
 
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
+  gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), index);
+  gdk_threads_leave ();
+}
 
-  menu = GTK_CONTAINER (gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr)));
-  children = gtk_container_children (menu);
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemoveAll 
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+  GtkTreeModel *model;
+  gint count, i;
 
-  if (index == -1)
-    {
-      /* Remove all elements (removeAll) */
-      from = g_list_length (children) - 1;
-      to = 0;
+  ptr = NSA_GET_PTR (env, obj);
 
-      /* Select the first item to prevent spurious activate signals */
-      gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
-    }
-  else
-    {
-      /* Remove the specific index element */
-      from = index;
-      to = index;
-
-      /* Are we removing the currently selected element? */
-      if (gtk_option_menu_get_history (GTK_OPTION_MENU (ptr)) == index)
-        need_set_history = 1;
-    }
+  gdk_threads_enter ();
 
-  for (i = from; i >= to; i--)
-    {
-      menuitem = GTK_WIDGET (g_list_nth (children, i)->data);
-      gtk_container_remove (menu, menuitem);
-      gtk_widget_destroy (menuitem);
-    }
+  model = gtk_combo_box_get_model (GTK_COMBO_BOX (ptr));
+  count = gtk_tree_model_iter_n_children (model, NULL);
+
+  /* First, unselect everything, to avoid problems when removing items. */
+  gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), -1);
 
-  /* If we just removed the currently selected element and there are
-     still elements left in the list, make the first item the selected one. */  
-  if (need_set_history && gtk_container_children (menu))
-    gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
+  for (i = count - 1; i >= 0; i--) {
+    gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), i);
+  }
 
   gdk_threads_leave ();
 }
@@ -223,12 +156,12 @@
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), index);
+  gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), index);
   gdk_threads_leave ();
 }
 
 JNIEXPORT jint JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkChoicePeer_getHistory 
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeGetSelected 
   (JNIEnv *env, jobject obj)
 {
   void *ptr;
@@ -237,57 +170,38 @@
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-
-  index = gtk_option_menu_get_history (GTK_OPTION_MENU (ptr));
-
+  index = gtk_combo_box_get_active (GTK_COMBO_BOX (ptr));
   gdk_threads_leave ();
 
   return index;
 }
 
-static void
-item_activate (GtkItem *item __attribute__((unused)),
-	       struct item_event_hook_info *ie)
+void selection_changed (GtkComboBox *combobox, jobject peer)
 {
-  gdk_threads_leave ();
+  jstring label;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GValue value;
+  gchar *selected;
+  gint index;
 
-  jstring label = (*gdk_env)->NewStringUTF (gdk_env, ie->label);
-  (*gdk_env)->CallVoidMethod (gdk_env, ie->peer_obj,
-			      choicePostItemEventID,
-			      label,
-			      (jint) AWT_ITEM_SELECTED);
-  gdk_threads_enter ();
-}
-
-static void
-item_removed (gpointer data, 
-	      GClosure gc __attribute__((unused)))
-{
-  struct item_event_hook_info *ie = data;
-
-  free ((void *) ie->label);
-  free (ie);
-}
+  index = gtk_combo_box_get_active(combobox);
 
-static void
-connect_choice_item_selectable_hook (JNIEnv *env, 
-				     jobject peer_obj, 
-				     GtkItem *menuitem, 
-				     const char *label)
-{
-  struct item_event_hook_info *ie;
-  jobject *peer_objGlobPtr;
+  if (index >= 0)
+    {
+      model = gtk_combo_box_get_model (combobox);
 
-  ie = (struct item_event_hook_info *) 
-    malloc (sizeof (struct item_event_hook_info));
+      gtk_combo_box_get_active_iter (combobox, &iter);
 
-  peer_objGlobPtr = NSA_GET_GLOBAL_REF (env, peer_obj);
-  g_assert (peer_objGlobPtr);
+      gtk_tree_model_get (model, &iter, 0, &selected, -1);
 
-  ie->peer_obj = *peer_objGlobPtr;
-  ie->label = strdup (label);
+      gdk_threads_leave ();
 
-  g_signal_connect_data (G_OBJECT (menuitem), "activate", 
-		      GTK_SIGNAL_FUNC (item_activate), ie,
-		      (GClosureNotify) item_removed, 0);
+      label = (*gdk_env)->NewStringUTF (gdk_env, selected);
+      (*gdk_env)->CallVoidMethod (gdk_env, peer,
+			          choicePostItemEventID,
+			          label,
+			          (jint) AWT_ITEM_SELECTED);
+      gdk_threads_enter ();
+    }
 }
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c,v
retrieving revision 1.12
diff -u -r1.12 gnu_java_awt_peer_gtk_GtkComponentPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c	5 Jan 2004 21:13:46 -0000	1.12
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c	6 Sep 2004 16:36:12 -0000
@@ -1,5 +1,5 @@
 /* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,28 +39,372 @@
 #include "gtkpeer.h"
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 #include <gtk/gtkprivate.h>
+#include <gdk/gdkkeysyms.h>
 
 static GtkWidget *find_fg_color_widget (GtkWidget *widget);
 static GtkWidget *find_bg_color_widget (GtkWidget *widget);
+static gboolean focus_in_cb (GtkWidget *widget,
+                             GdkEventFocus *event,
+                             jobject peer);
+static gboolean focus_out_cb (GtkWidget *widget,
+                              GdkEventFocus *event,
+                              jobject peer);
+/*
+ * This method returns a GDK keyval that corresponds to one of the
+ * keysyms in the X keymap table.  The return value is only used to
+ * determine the keyval's corresponding hardware keycode, and doesn't
+ * reflect an accurate translation of a Java virtual key value to a
+ * GDK keyval.
+ */
+#ifdef __GNUC__
+__inline
+#endif
+static guint
+awt_keycode_to_keysym (jint keyCode, jint keyLocation)
+{
+  /* GDK_A through GDK_Z */
+  if (keyCode >= VK_A && keyCode <= VK_Z)
+    return gdk_keyval_to_lower (keyCode);
+
+  /* GDK_0 through GDK_9 */
+  if (keyCode >= VK_0 && keyCode <= VK_9)
+    return keyCode;
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
-  (JNIEnv *env, jobject obj)
-{
-  void *ptr;
-
-  /* Remove entries from state tables */
-  NSA_DEL_GLOBAL_REF (env, obj);
-  ptr = NSA_DEL_PTR (env, obj);
-
-  gdk_threads_enter ();
-  
-  /* For now the native state for any object must be a widget.
-     However, a subclass could override dispose() if required.  */
-  gtk_widget_destroy (GTK_WIDGET (ptr));
-
-  gdk_threads_leave ();
+  switch (keyCode)
+    {
+    case VK_ENTER:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Enter : GDK_Return;
+    case VK_BACK_SPACE:
+      return GDK_BackSpace;
+    case VK_TAB:
+      return GDK_Tab;
+    case VK_CANCEL:
+      return GDK_Cancel;
+    case VK_CLEAR:
+      return GDK_Clear;
+    case VK_SHIFT:
+      return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Shift_L : GDK_Shift_R;
+    case VK_CONTROL:
+      return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Control_L : GDK_Control_R;
+    case VK_ALT:
+      return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Alt_L : GDK_Alt_R;
+    case VK_PAUSE:
+      return GDK_Pause;
+    case VK_CAPS_LOCK:
+      return GDK_Caps_Lock;
+    case VK_ESCAPE:
+      return GDK_Escape;
+    case VK_SPACE:
+      return GDK_space;
+    case VK_PAGE_UP:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Up : GDK_Page_Up;
+    case VK_PAGE_DOWN:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Down : GDK_Page_Down;
+    case VK_END:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_End : GDK_End;
+    case VK_HOME:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Home : GDK_Home;
+    case VK_LEFT:
+      return GDK_Left;
+    case VK_UP:
+      return GDK_Up;
+    case VK_RIGHT:
+      return GDK_Right;
+    case VK_DOWN:
+      return GDK_Down;
+    case VK_COMMA:
+      return GDK_comma;
+    case VK_MINUS:
+      return GDK_minus;
+    case VK_PERIOD:
+      return GDK_period;
+    case VK_SLASH:
+      return GDK_slash;
+      /*
+    case VK_0:
+    case VK_1:
+    case VK_2:
+    case VK_3:
+    case VK_4:
+    case VK_5:
+    case VK_6:
+    case VK_7:
+    case VK_8:
+    case VK_9:
+      */
+    case VK_SEMICOLON:
+      return GDK_semicolon;
+    case VK_EQUALS:
+      return GDK_equal;
+      /*
+    case VK_A:
+    case VK_B:
+    case VK_C:
+    case VK_D:
+    case VK_E:
+    case VK_F:
+    case VK_G:
+    case VK_H:
+    case VK_I:
+    case VK_J:
+    case VK_K:
+    case VK_L:
+    case VK_M:
+    case VK_N:
+    case VK_O:
+    case VK_P:
+    case VK_Q:
+    case VK_R:
+    case VK_S:
+    case VK_T:
+    case VK_U:
+    case VK_V:
+    case VK_W:
+    case VK_X:
+    case VK_Y:
+    case VK_Z:
+      */
+    case VK_OPEN_BRACKET:
+      return GDK_bracketleft;
+    case VK_BACK_SLASH:
+      return GDK_backslash;
+    case VK_CLOSE_BRACKET:
+      return GDK_bracketright;
+    case VK_NUMPAD0:
+      return GDK_KP_0;
+    case VK_NUMPAD1:
+      return GDK_KP_1;
+    case VK_NUMPAD2:
+      return GDK_KP_2;
+    case VK_NUMPAD3:
+      return GDK_KP_3;
+    case VK_NUMPAD4:
+      return GDK_KP_4;
+    case VK_NUMPAD5:
+      return GDK_KP_5;
+    case VK_NUMPAD6:
+      return GDK_KP_6;
+    case VK_NUMPAD7:
+      return GDK_KP_7;
+    case VK_NUMPAD8:
+      return GDK_KP_8;
+    case VK_NUMPAD9:
+      return GDK_KP_9;
+    case VK_MULTIPLY:
+      return GDK_KP_Multiply;
+    case VK_ADD:
+      return GDK_KP_Add;
+      /*
+    case VK_SEPARATER:
+      */
+    case VK_SEPARATOR:
+      return GDK_KP_Separator;
+    case VK_SUBTRACT:
+      return GDK_KP_Subtract;
+    case VK_DECIMAL:
+      return GDK_KP_Decimal;
+    case VK_DIVIDE:
+      return GDK_KP_Divide;
+    case VK_DELETE:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Delete : GDK_Delete;
+    case VK_NUM_LOCK:
+      return GDK_Num_Lock;
+    case VK_SCROLL_LOCK:
+      return GDK_Scroll_Lock;
+    case VK_F1:
+      return GDK_F1;
+    case VK_F2:
+      return GDK_F2;
+    case VK_F3:
+      return GDK_F3;
+    case VK_F4:
+      return GDK_F4;
+    case VK_F5:
+      return GDK_F5;
+    case VK_F6:
+      return GDK_F6;
+    case VK_F7:
+      return GDK_F7;
+    case VK_F8:
+      return GDK_F8;
+    case VK_F9:
+      return GDK_F9;
+    case VK_F10:
+      return GDK_F10;
+    case VK_F11:
+      return GDK_F11;
+    case VK_F12:
+      return GDK_F12;
+    case VK_F13:
+      return GDK_F13;
+    case VK_F14:
+      return GDK_F14;
+    case VK_F15:
+      return GDK_F15;
+    case VK_F16:
+      return GDK_F16;
+    case VK_F17:
+      return GDK_F17;
+    case VK_F18:
+      return GDK_F18;
+    case VK_F19:
+      return GDK_F19;
+    case VK_F20:
+      return GDK_F20;
+    case VK_F21:
+      return GDK_F21;
+    case VK_F22:
+      return GDK_F22;
+    case VK_F23:
+      return GDK_F23;
+    case VK_F24:
+      return GDK_F24;
+    case VK_PRINTSCREEN:
+      return GDK_Print;
+    case VK_INSERT:
+      return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Insert : GDK_Insert;
+    case VK_HELP:
+      return GDK_Help;
+    case VK_META:
+      return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Meta_L : GDK_Meta_R;
+    case VK_BACK_QUOTE:
+      return GDK_grave;
+    case VK_QUOTE:
+      return GDK_apostrophe;
+    case VK_KP_UP:
+      return GDK_KP_Up;
+    case VK_KP_DOWN:
+      return GDK_KP_Down;
+    case VK_KP_LEFT:
+      return GDK_KP_Left;
+    case VK_KP_RIGHT:
+      return GDK_KP_Right;
+    case VK_DEAD_GRAVE:
+      return GDK_dead_grave;
+    case VK_DEAD_ACUTE:
+      return GDK_dead_acute;
+    case VK_DEAD_CIRCUMFLEX:
+      return GDK_dead_circumflex;
+    case VK_DEAD_TILDE:
+      return GDK_dead_tilde;
+    case VK_DEAD_MACRON:
+      return GDK_dead_macron;
+    case VK_DEAD_BREVE:
+      return GDK_dead_breve;
+    case VK_DEAD_ABOVEDOT:
+      return GDK_dead_abovedot;
+    case VK_DEAD_DIAERESIS:
+      return GDK_dead_diaeresis;
+    case VK_DEAD_ABOVERING:
+      return GDK_dead_abovering;
+    case VK_DEAD_DOUBLEACUTE:
+      return GDK_dead_doubleacute;
+    case VK_DEAD_CARON:
+      return GDK_dead_caron;
+    case VK_DEAD_CEDILLA:
+      return GDK_dead_cedilla;
+    case VK_DEAD_OGONEK:
+      return GDK_dead_ogonek;
+    case VK_DEAD_IOTA:
+      return GDK_dead_iota;
+    case VK_DEAD_VOICED_SOUND:
+      return GDK_dead_voiced_sound;
+    case VK_DEAD_SEMIVOICED_SOUND:
+      return GDK_dead_semivoiced_sound;
+    case VK_AMPERSAND:
+      return GDK_ampersand;
+    case VK_ASTERISK:
+      return GDK_asterisk;
+    case VK_QUOTEDBL:
+      return GDK_quotedbl;
+    case VK_LESS:
+      return GDK_less;
+    case VK_GREATER:
+      return GDK_greater;
+    case VK_BRACELEFT:
+      return GDK_braceleft;
+    case VK_BRACERIGHT:
+      return GDK_braceright;
+    case VK_AT:
+      return GDK_at;
+    case VK_COLON:
+      return GDK_colon;
+    case VK_CIRCUMFLEX:
+      return GDK_asciicircum;
+    case VK_DOLLAR:
+      return GDK_dollar;
+    case VK_EURO_SIGN:
+      return GDK_EuroSign;
+    case VK_EXCLAMATION_MARK:
+      return GDK_exclam;
+    case VK_INVERTED_EXCLAMATION_MARK:
+      return GDK_exclamdown;
+    case VK_LEFT_PARENTHESIS:
+      return GDK_parenleft;
+    case VK_NUMBER_SIGN:
+      return GDK_numbersign;
+    case VK_PLUS:
+      return GDK_plus;
+    case VK_RIGHT_PARENTHESIS:
+      return GDK_parenright;
+    case VK_UNDERSCORE:
+      return GDK_underscore;
+      /*
+    case VK_FINAL:
+    case VK_CONVERT:
+    case VK_NONCONVERT:
+    case VK_ACCEPT:
+      */
+    case VK_MODECHANGE:
+      return GDK_Mode_switch;
+      /*
+    case VK_KANA:
+      */
+    case VK_KANJI:
+      return GDK_Kanji;
+      /*
+    case VK_ALPHANUMERIC:
+      */
+    case VK_KATAKANA:
+      return GDK_Katakana;
+    case VK_HIRAGANA:
+      return GDK_Hiragana;
+      /*
+    case VK_FULL_WIDTH:
+    case VK_HALF_WIDTH:
+    case VK_ROMAN_CHARACTERS:
+    case VK_ALL_CANDIDATES:
+      */
+    case VK_PREVIOUS_CANDIDATE:
+      return GDK_PreviousCandidate;
+    case VK_CODE_INPUT:
+      return GDK_Codeinput;
+      /*
+    case VK_JAPANESE_KATAKANA:
+    case VK_JAPANESE_HIRAGANA:
+    case VK_JAPANESE_ROMAN:
+      */
+    case VK_KANA_LOCK:
+      return GDK_Kana_Lock;
+      /*
+    case VK_INPUT_METHOD_ON_OFF:
+    case VK_CUT:
+    case VK_COPY:
+    case VK_PASTE:
+    case VK_UNDO:
+    case VK_AGAIN:
+    case VK_FIND:
+    case VK_PROPS:
+    case VK_STOP:
+    case VK_COMPOSE:
+    case VK_ALT_GRAPH:
+      */
+    default:
+      return GDK_VoidSymbol;
+    }
 }
 
+
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor 
   (JNIEnv *env, jobject obj, jint type) 
@@ -128,7 +472,65 @@
   gdk_threads_leave ();
 }
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_requestFocus
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetParent
+  (JNIEnv *env, jobject obj, jobject parent)
+{
+  void *ptr;
+  void *parent_ptr;
+  GtkWidget *widget;
+  GtkWidget *parent_widget;
+
+  ptr = NSA_GET_PTR (env, obj);
+  parent_ptr = NSA_GET_PTR (env, parent);
+
+  gdk_threads_enter ();
+
+  widget = GTK_WIDGET (ptr);
+  parent_widget = GTK_WIDGET (parent_ptr);
+
+  if (GTK_IS_WINDOW (parent_widget))
+    {
+      GList *children = gtk_container_children 
+        (GTK_CONTAINER (GTK_BIN (parent_widget)->child));
+
+      if (GTK_IS_MENU_BAR (children->data))
+	gtk_layout_put (GTK_LAYOUT (children->next->data), widget, 0, 0);
+      else
+	gtk_layout_put (GTK_LAYOUT (children->data), widget, 0, 0);
+    }
+  else
+    if (GTK_IS_SCROLLED_WINDOW (parent_widget))
+      {
+        gtk_scrolled_window_add_with_viewport 
+          (GTK_SCROLLED_WINDOW (parent_widget), widget);
+        gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent), 
+                                      GTK_SHADOW_NONE);
+
+      }
+    else
+      gtk_layout_put (GTK_LAYOUT (parent_widget), widget, 0, 0);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetSensitive
+  (JNIEnv *env, jobject obj, jboolean sensitive)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  gtk_widget_set_sensitive (GTK_WIDGET (ptr), sensitive);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetRequestFocus
   (JNIEnv *env, jobject obj)
 {
   void *ptr;
@@ -141,6 +543,126 @@
 }
 
 /*
+ * Translate a Java KeyEvent object into a GdkEventKey event, then
+ * pass it to the GTK main loop for processing.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent
+  (JNIEnv *env, jobject obj, jint id, jlong when, jint mods,
+   jint keyCode, jint keyLocation)
+{
+  void *ptr;
+  GdkEvent *event = NULL;
+  GdkKeymapKey *keymap_keys = NULL;
+  gint n_keys = 0;
+  guint lookup_keyval = 0;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  if (id == AWT_KEY_PRESSED)
+    event = gdk_event_new (GDK_KEY_PRESS);
+  else if (id == AWT_KEY_RELEASED)
+    event = gdk_event_new (GDK_KEY_RELEASE);
+  else
+    {
+      gdk_threads_leave ();
+      /* Don't send AWT KEY_TYPED events to GTK. */
+      return;
+    }
+
+  if (GTK_IS_BUTTON (ptr))
+    event->key.window = GTK_BUTTON (ptr)->event_window;
+  else if (GTK_IS_SCROLLED_WINDOW (ptr))
+    event->key.window = GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child)->window;
+  else
+    event->key.window = GTK_WIDGET (ptr)->window;
+
+  event->key.send_event = 0;
+  event->key.time = (guint32) when;
+
+  if (mods & AWT_SHIFT_DOWN_MASK)
+    event->key.state |= GDK_SHIFT_MASK;
+  if (mods & AWT_CTRL_DOWN_MASK)
+    event->key.state |= GDK_CONTROL_MASK;
+  if (mods & AWT_ALT_DOWN_MASK)
+    event->key.state |= GDK_MOD1_MASK;
+
+  /* This hack is needed because the AWT has no notion of num lock.
+     It infers numlock state from the only Java virtual keys that are
+     affected by it. */
+  if (keyCode == VK_NUMPAD9
+      || keyCode == VK_NUMPAD8
+      || keyCode == VK_NUMPAD7
+      || keyCode == VK_NUMPAD6
+      || keyCode == VK_NUMPAD5
+      || keyCode == VK_NUMPAD4
+      || keyCode == VK_NUMPAD3
+      || keyCode == VK_NUMPAD2
+      || keyCode == VK_NUMPAD1
+      || keyCode == VK_NUMPAD0
+      || keyCode == VK_DECIMAL)
+    event->key.state |= GDK_MOD2_MASK;
+
+  /* These values don't need to be filled in since GTK doesn't use
+     them. */
+  event->key.length = 0;
+  event->key.string = NULL;
+
+  lookup_keyval = awt_keycode_to_keysym (keyCode, keyLocation);
+
+  if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
+                                          lookup_keyval,
+                                          &keymap_keys,
+                                          &n_keys))
+    {
+      /* No matching keymap entry was found. */
+      g_printerr ("No matching keymap entries were found\n");
+      gdk_threads_leave ();
+      return;
+    }
+
+  /* Note: if n_keys > 1 then there are multiple hardware keycodes
+     that translate to lookup_keyval.  We arbitrarily choose the first
+     hardware keycode from the list returned by
+     gdk_keymap_get_entries_for_keyval. */
+
+  event->key.hardware_keycode = keymap_keys[0].keycode;
+  event->key.group =  keymap_keys[0].group;
+
+  g_free (keymap_keys);
+
+  if (!gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
+                                            event->key.hardware_keycode,
+                                            event->key.state,
+                                            event->key.group,
+                                            &event->key.keyval,
+                                            NULL, NULL, NULL))
+    {
+      /* No matching keyval was found. */
+      g_printerr ("No matching keyval was found\n");
+      gdk_threads_leave ();
+      return;
+    }
+
+  /*  keyevent = (GdkEventKey *) event; */
+  /*  g_printerr ("generated event: sent: %d  time: %d  state: %d  keyval: %d  length: %d  string: %s  hardware_keycode: %d  group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */
+
+  /* We already received the original key event on the window itself,
+     so we don't want to resend it. */
+  if (!GTK_IS_WINDOW (ptr))
+    {
+      if (GTK_IS_SCROLLED_WINDOW (ptr))
+        gtk_widget_event (GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child), event);
+      else
+        gtk_widget_event (GTK_WIDGET (ptr), event);
+    }
+
+  gdk_threads_leave ();
+}
+
+/*
  * Find the origin of a widget's window.
  */
 JNIEXPORT void JNICALL 
@@ -215,38 +737,39 @@
 
   gdk_threads_enter ();
 
-  /* Save the widget's current size request. */
-  gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
+  /* Widgets that extend GtkWindow such as GtkFileChooserDialog may have
+     a default size.  These values seem more useful then the natural
+     requisition values, particularly for GtkFileChooserDialog. */
+  if (GTK_IS_WINDOW (ptr))
+    {
+      gint width, height;
+      gtk_window_get_default_size (GTK_WINDOW (ptr), &width, &height);
 
-  /* Get the widget's "natural" size request. */
-  gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
-  gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
-
-  /* Reset the widget's size request. */
-  gtk_widget_set_size_request (GTK_WIDGET (ptr),
-			       current_req.width, current_req.height);
+      dims[0] = width;
+      dims[1] = height;
+    }
+  else
+    {
+      /* Save the widget's current size request. */
+      gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
 
-  dims[0] = natural_req.width;
-  dims[1] = natural_req.height;
+      /* Get the widget's "natural" size request. */
+      gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
+      gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
+
+      /* Reset the widget's size request. */
+      gtk_widget_set_size_request (GTK_WIDGET (ptr),
+			           current_req.width, current_req.height);
+
+      dims[0] = natural_req.width;
+      dims[1] = natural_req.height;
+    }
 
   gdk_threads_leave ();
 
   (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
 }
 
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetUsize (JNIEnv *env, 
-    jobject obj, jint w, jint h)
-{
-  void *ptr;
-
-  ptr = NSA_GET_PTR (env, obj);
-  
-  gdk_threads_enter ();
-  gtk_widget_set_usize (GTK_WIDGET (ptr), w, h);
-  gdk_threads_leave ();
-}
-
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
   (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
 {
@@ -258,13 +781,17 @@
   gdk_threads_enter ();
 
   widget = GTK_WIDGET (ptr);
+
+  /* We assume that -1 is a width or height and not a request for the
+     widget's natural size. */
+  width = width < 0 ? 0 : width;
+  height = height < 0 ? 0 : height;
+
   if (GTK_IS_VIEWPORT (widget->parent))
-    {
-      gtk_widget_set_usize (widget, width, height);
-    }
+    gtk_widget_set_size_request (widget, width, height);
   else
     {
-      gtk_widget_set_usize (widget, width, height);
+      gtk_widget_set_size_request (widget, width, height);
       gtk_layout_move (GTK_LAYOUT (widget->parent), widget, x, y);
     }
 
@@ -380,36 +907,66 @@
   gdk_threads_leave ();
 }
 
-void
-set_visible (GtkWidget *widget, jboolean visible)
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
 {
-  if (visible)
-    gtk_widget_show (widget);
-  else
-    gtk_widget_hide (widget);
+  const char *font_name;
+  void *ptr;
+  PangoFontDescription *font_desc;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+  gdk_threads_enter();
+
+  font_desc = pango_font_description_from_string (font_name);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+  gtk_widget_modify_font (GTK_WIDGET(ptr), font_desc);
+
+  pango_font_description_free (font_desc);
+
+  gdk_threads_leave();
+
+  (*env)->ReleaseStringUTFChars (env, name, font_name);
 }
 
-GtkLayout *
-find_gtk_layout (GtkWidget *parent)
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_show
+  (JNIEnv *env, jobject obj)
 {
-  if (GTK_IS_WINDOW (parent))
-    {
-      GList *children = gtk_container_children 
-	                  (GTK_CONTAINER (GTK_BIN (parent)->child));
+  void *ptr;
 
-      if (GTK_IS_MENU_BAR (children->data))
-	return GTK_LAYOUT (children->next->data);
-      else /* GTK_IS_LAYOUT (children->data) */
-	return GTK_LAYOUT (children->data);
-    }
+  ptr = NSA_GET_PTR (env, obj);
 
-  return NULL;
+  gdk_threads_enter();
+  gtk_widget_show (GTK_WIDGET (ptr));
+  gdk_threads_leave();
 }
 
-#define WIDGET_CLASS(w)  GTK_WIDGET_CLASS (GTK_OBJECT (w)->klass)
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_hide
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter();
+  gtk_widget_hide (GTK_WIDGET (ptr));
+  gdk_threads_leave();
+}
 
-void
-set_parent (GtkWidget *widget, GtkContainer *parent)
+GtkLayout *
+find_gtk_layout (GtkWidget *parent)
 {
   if (GTK_IS_WINDOW (parent))
     {
@@ -417,32 +974,12 @@
 	                  (GTK_CONTAINER (GTK_BIN (parent)->child));
 
       if (GTK_IS_MENU_BAR (children->data))
-	gtk_layout_put (GTK_LAYOUT (children->next->data), widget, 0, 0);
+	return GTK_LAYOUT (children->next->data);
       else /* GTK_IS_LAYOUT (children->data) */
-	gtk_layout_put (GTK_LAYOUT (children->data), widget, 0, 0);
+	return GTK_LAYOUT (children->data);
     }
-  else
-    if (GTK_IS_SCROLLED_WINDOW (parent))
-      {
-/*  	if (WIDGET_CLASS (widget)->set_scroll_adjustments_signal) */
-/*  	  gtk_container_add (GTK_CONTAINER (parent), widget); */
-/*  	else */
-/*  	  { */
-	    gtk_scrolled_window_add_with_viewport 
-	      (GTK_SCROLLED_WINDOW (parent), widget);
-	    gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent), 
-					  GTK_SHADOW_NONE);
-/*  	  } */
 
-      }
-/*        gtk_layout_put  */
-/*  	(GTK_LAYOUT (GTK_BIN (parent)->child), widget, 0, 0); */
-
-/*      if (GTK_IS_SCROLLED_WINDOW (parent)) */
-/*        gtk_layout_put  */
-/*  	(GTK_LAYOUT (GTK_BIN (GTK_BIN (parent)->child)->child), widget, 0, 0); */
-    else
-      gtk_layout_put (GTK_LAYOUT (parent), widget, 0, 0);
+  return NULL;
 }
 
 JNIEXPORT jboolean JNICALL 
@@ -476,103 +1013,159 @@
   return retval;
 }
 
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_String_2
-  (JNIEnv *env, jobject obj, jstring jname, jstring jvalue)
+static gboolean
+filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
 {
-  const char *name;
-  const char *value;
-  void *ptr;
-
-  ptr = NSA_GET_PTR (env, obj);
-  name = (*env)->GetStringUTFChars (env, jname, NULL);
-  value = (*env)->GetStringUTFChars (env, jvalue, NULL);
-
-  gdk_threads_enter();
-  g_object_set(ptr, name, value, NULL);
-  gdk_threads_leave();
-
-  (*env)->ReleaseStringUTFChars (env, jname, name);
-  (*env)->ReleaseStringUTFChars (env, jvalue, value);
+  /*
+   * Prevent the default event handler from getting this signal if applicable
+   * FIXME: I came up with these filters by looking for patterns in the unwanted
+   *        expose events that are fed back to us from gtk/X. Perhaps there is
+   *        a way to prevent them from occuring in the first place.
+   */
+  if (event->type == GDK_EXPOSE && (!GTK_IS_LAYOUT(widget)
+                                    || event->any.window != widget->window))
+    {
+      g_signal_stop_emission_by_name(GTK_OBJECT(widget), "event");
+      return FALSE;
+    }
+  else
+    {
+      /* There may be non-expose events that are triggered while we're
+        painting a heavyweight peer. */
+      return pre_event_handler(widget, event, peer);
+    }
 }
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Z
-  (JNIEnv *env, jobject obj, jstring jname, jboolean value)
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter
+  (JNIEnv *env, jobject obj)
 {
-  const char *name;
-  void *ptr;
+  GtkObject *filterobj;
+  GtkWidget *vbox, *layout;
+  GList *children;
+  void *ptr = NSA_GET_PTR (env, obj);
+  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+  gulong hid;
 
-  ptr = NSA_GET_PTR (env, obj);
+  g_assert (gref);
 
-  name = (*env)->GetStringUTFChars (env, jname, NULL);
+  gdk_threads_enter ();
 
-  gdk_threads_enter();
-  g_object_set(ptr, name, value, NULL);
-  gdk_threads_leave();
+  /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
+     Events go to the GtkLayout layer, so we filter them there. */
+  if (GTK_IS_WINDOW(ptr))
+    {
+      children = gtk_container_get_children(GTK_CONTAINER(ptr));
+      vbox = children->data;
+      g_assert (GTK_IS_VBOX(vbox));
+
+      children = gtk_container_get_children(GTK_CONTAINER(vbox));
+      do
+      {
+        layout = children->data;
+        children = children->next;
+      }
+      while (!GTK_IS_LAYOUT (layout) && children != NULL);
+      g_assert (GTK_IS_LAYOUT(layout));
+
+      filterobj = GTK_OBJECT(layout);
+    }
+  else if (GTK_IS_SCROLLED_WINDOW(ptr))
+    {
+      /* The event will go to the parent GtkLayout. */
+      filterobj = GTK_OBJECT(GTK_WIDGET(ptr)->parent);
+    }
+  else
+    {
+      filterobj = GTK_OBJECT(ptr);
+    }
+  hid = g_signal_handler_find(filterobj,
+                              G_SIGNAL_MATCH_FUNC,
+                              0, 0, NULL, *pre_event_handler, NULL);
+  if (hid > 0)
+  {
+    g_signal_handler_block(filterobj, hid);
+  }
+  g_signal_connect( filterobj, "event",
+                    G_CALLBACK(filter_expose_event_handler), *gref);
 
-  (*env)->ReleaseStringUTFChars (env, jname, name);
+  gdk_threads_leave ();
 }
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2I
-  (JNIEnv *env, jobject obj, jstring jname, jint value)
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter
+  (JNIEnv *env, jobject obj)
 {
-  const char *name;
-  void *ptr;
+  GtkObject *filterobj;
+  GtkWidget *vbox, *layout;
+  GList *children;
+  void *ptr = NSA_GET_PTR (env, obj);
+  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+  gulong hid;
 
-  ptr = NSA_GET_PTR (env, obj);
-  name = (*env)->GetStringUTFChars (env, jname, NULL);
+  g_assert (gref);
 
-  gdk_threads_enter();                          
-  g_object_set(ptr, name, value, NULL);
-  gdk_threads_leave();
+  gdk_threads_enter ();
 
-  (*env)->ReleaseStringUTFChars (env, jname, name);
-}
+  /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
+     Events go to the GtkLayout layer, so we filter them there. */
+  if (GTK_IS_WINDOW(ptr))
+    {
+      children = gtk_container_get_children(GTK_CONTAINER(ptr));
+      vbox = children->data;
+      g_assert (GTK_IS_VBOX(vbox));
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2F
-  (JNIEnv *env, jobject obj, jstring jname, jfloat value)
-{
-  const char *name;
-  void *ptr;
+      children = gtk_container_get_children(GTK_CONTAINER(vbox));
+      do
+      {
+        layout = children->data;
+        children = children->next;
+      }
+      while (!GTK_IS_LAYOUT (layout) && children != NULL);
+      g_assert (GTK_IS_LAYOUT(layout));
 
-  ptr = NSA_GET_PTR (env, obj);
-  name = (*env)->GetStringUTFChars (env, jname, NULL);
+      filterobj = GTK_OBJECT(layout);
+    }
+  else if (GTK_IS_SCROLLED_WINDOW(ptr))
+    {
+      /* The event will go to the parent GtkLayout. */
+      filterobj = GTK_OBJECT(GTK_WIDGET(ptr)->parent);
+    }
+  else
+    {
+      filterobj = GTK_OBJECT(ptr);
+    }
 
-  gdk_threads_enter();                          
-  g_object_set(ptr, name, value, NULL);
-  gdk_threads_leave();
+  g_signal_handlers_disconnect_by_func (filterobj,
+                                        *filter_expose_event_handler, *gref);
+  hid = g_signal_handler_find(filterobj,
+                              G_SIGNAL_MATCH_FUNC,
+                              0, 0, NULL, *pre_event_handler, NULL);
+  if (hid > 0)
+  {
+    g_signal_handler_unblock(filterobj, hid);
+  }
 
-  (*env)->ReleaseStringUTFChars (env, jname, name);
+  gdk_threads_leave ();
 }
 
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_Object_2
-  (JNIEnv *env, jobject obj1, jstring jname, jobject obj2)
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetQueueDrawArea
+  (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
 {
-  const char *name;
-  void *ptr1, *ptr2;
+  GdkRectangle rect;
+  void *ptr;
 
-  ptr1 = NSA_GET_PTR (env, obj1);
-  ptr2 = NSA_GET_PTR (env, obj2);
-  
-  name = (*env)->GetStringUTFChars (env, jname, NULL);
+  ptr = NSA_GET_PTR (env, obj);
 
-  /* special case to catch where we need to set the parent */
-  if (!strcmp (name, "parent"))
-    {
-      gdk_threads_enter ();
-      set_parent (GTK_WIDGET (ptr1), GTK_CONTAINER (ptr2));
-      gdk_threads_leave ();
+  rect.x = x + GTK_WIDGET(ptr)->allocation.x;
+  rect.y = y + GTK_WIDGET(ptr)->allocation.y;
+  rect.width = width;
+  rect.height = height;
 
-      (*env)->ReleaseStringUTFChars (env, jname, name);
-      return;
-    }
+  gdk_threads_enter ();
 
-  gdk_threads_enter();                          
-  g_object_set(ptr1, name, ptr2, NULL);
-  gdk_threads_leave();
+  gdk_window_invalidate_rect (GTK_WIDGET (ptr)->window, &rect, 0);
+  gdk_window_process_all_updates();
 
-  (*env)->ReleaseStringUTFChars (env, jname, name);
+  gdk_threads_leave ();
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectJObject
@@ -613,6 +1206,12 @@
   g_signal_connect (GTK_OBJECT (ptr), "event", 
                     G_CALLBACK (pre_event_handler), *gref);
 
+  g_signal_connect (G_OBJECT (ptr), "focus-in-event",
+                    G_CALLBACK (focus_in_cb), *gref);
+
+  g_signal_connect (G_OBJECT (ptr), "focus-out-event",
+                    G_CALLBACK (focus_out_cb), *gref);
+
   gdk_threads_leave ();
 }
 
@@ -621,7 +1220,9 @@
 {
   GtkWidget *fg_color_widget;
 
-  if (GTK_IS_EVENT_BOX (widget))
+  if (GTK_IS_EVENT_BOX (widget)
+      || (GTK_IS_BUTTON (widget)
+          && !GTK_IS_OPTION_MENU (widget)))
     fg_color_widget = gtk_bin_get_child (GTK_BIN(widget));
   else
     fg_color_widget = widget;
@@ -651,3 +1252,26 @@
   return bg_color_widget;
 }
 
+static gboolean
+focus_in_cb (GtkWidget *widget __attribute((unused)),
+             GdkEventFocus *event __attribute((unused)),
+             jobject peer)
+{
+  (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                              postFocusEventID,
+                              AWT_FOCUS_GAINED,
+                              JNI_FALSE);
+  return FALSE;
+}
+
+static gboolean
+focus_out_cb (GtkWidget *widget __attribute((unused)),
+              GdkEventFocus *event __attribute((unused)),
+              jobject peer)
+{
+  (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                              postFocusEventID,
+                              AWT_FOCUS_LOST,
+                              JNI_FALSE);
+  return FALSE;
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c,v
retrieving revision 1.17
diff -u -r1.17 gnu_java_awt_peer_gtk_GtkEvents.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c	13 Jan 2004 20:54:46 -0000	1.17
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c	6 Sep 2004 16:36:13 -0000
@@ -1,5 +1,5 @@
 /* gtkevents.c -- GDK/GTK event handlers
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -58,11 +58,11 @@
   switch (button)
     {
     case 1:
-      return AWT_BUTTON1_MASK;
+      return AWT_BUTTON1_DOWN_MASK;
     case 2:
-      return AWT_BUTTON2_MASK;
+      return AWT_BUTTON2_DOWN_MASK;
     case 3:
-      return AWT_BUTTON3_MASK;
+      return AWT_BUTTON3_DOWN_MASK;
     }
 
   return 0;
@@ -74,11 +74,32 @@
   jint result = 0;
 
   if (state & GDK_SHIFT_MASK)
-    result |= AWT_SHIFT_MASK;
+    result |= AWT_SHIFT_DOWN_MASK;
   if (state & GDK_CONTROL_MASK)
-    result |= AWT_CTRL_MASK;
+    result |= AWT_CTRL_DOWN_MASK;
   if (state & GDK_MOD1_MASK)
-    result |= AWT_ALT_MASK;
+    result |= AWT_ALT_DOWN_MASK;
+
+  return result;
+}
+
+static jint
+state_to_awt_mods_with_button_states (guint state)
+{
+  jint result = 0;
+
+  if (state & GDK_SHIFT_MASK)
+    result |= AWT_SHIFT_DOWN_MASK;
+  if (state & GDK_CONTROL_MASK)
+    result |= AWT_CTRL_DOWN_MASK;
+  if (state & GDK_MOD1_MASK)
+    result |= AWT_ALT_DOWN_MASK;
+  if (state & GDK_BUTTON1_MASK)
+    result |= AWT_BUTTON1_DOWN_MASK;
+  if (state & GDK_BUTTON2_MASK)
+    result |= AWT_BUTTON2_DOWN_MASK;
+  if (state & GDK_BUTTON3_MASK)
+    result |= AWT_BUTTON3_DOWN_MASK;
 
   return result;
 }
@@ -103,29 +124,29 @@
 
       if (event->key.keyval == GDK_Shift_L
           || event->key.keyval == GDK_Shift_R)
-        result |= AWT_SHIFT_MASK;
+        result |= AWT_SHIFT_DOWN_MASK;
       else
         {
           if (state & GDK_SHIFT_MASK)
-            result |= AWT_SHIFT_MASK;
+            result |= AWT_SHIFT_DOWN_MASK;
         }
 
       if (event->key.keyval == GDK_Control_L
           || event->key.keyval == GDK_Control_R)
-        result |= AWT_CTRL_MASK;
+        result |= AWT_CTRL_DOWN_MASK;
       else
         {
           if (state & GDK_CONTROL_MASK)
-            result |= AWT_CTRL_MASK;
+            result |= AWT_CTRL_DOWN_MASK;
         }
 
       if (event->key.keyval == GDK_Alt_L
           || event->key.keyval == GDK_Alt_R)
-        result |= AWT_ALT_MASK;
+        result |= AWT_ALT_DOWN_MASK;
       else
         {
           if (state & GDK_MOD1_MASK)
-            result |= AWT_ALT_MASK;
+            result |= AWT_ALT_DOWN_MASK;
         }
     }
   else if (event->type == GDK_KEY_RELEASE)
@@ -136,20 +157,20 @@
           && event->key.keyval != GDK_Shift_R)
         {
           if (state & GDK_SHIFT_MASK)
-            result |= AWT_SHIFT_MASK;
+            result |= AWT_SHIFT_DOWN_MASK;
         }
       if (event->key.keyval != GDK_Control_L
           && event->key.keyval != GDK_Control_R)
         {
           if (state & GDK_CONTROL_MASK)
-            result |= AWT_CTRL_MASK;
+            result |= AWT_CTRL_DOWN_MASK;
         }
 
       if (event->key.keyval != GDK_Alt_L
           && event->key.keyval != GDK_Alt_R)
         {
           if (state & GDK_MOD1_MASK)
-            result |= AWT_ALT_MASK;
+            result |= AWT_ALT_DOWN_MASK;
         }
     }
 
@@ -785,31 +806,6 @@
     }
 }
 
-/* Checks if keyval triggers a KEY_TYPED event on the source widget.
-   This function identifies special keyvals that don't trigger
-   GtkIMContext "commit" signals, but that do trigger Java KEY_TYPED
-   events. */
-static int
-generates_key_typed_event (GdkEvent *event, GtkWidget *source)
-{
-  guint keyval;
-
-  if (!GTK_IS_ENTRY (source)
-      && !GTK_IS_TEXT_VIEW (source))
-    return event->key.length ? 1 : 0;
-
-  keyval = event->key.keyval;
-
-  return (keyval == GDK_Escape
-          || keyval == GDK_BackSpace
-          || keyval == GDK_Delete
-          || keyval == GDK_KP_Delete
-          || keyval == GDK_Return
-          || keyval == GDK_KP_Enter
-          || (keyval == GDK_Tab
-              && GTK_IS_TEXT_VIEW(source))) ? 1 : 0;
-}
-
 void
 awt_event_handler (GdkEvent *event)
 {
@@ -830,6 +826,7 @@
   static GdkWindow *button_window = NULL;
   static guint button_number = -1;
   static jint click_count = 1;
+  static int hasBeenDragged;
 
   /* If it is not a focus change event, the widget must be realized already.
      If not, ignore the event (Gtk+ will do the same). */
@@ -888,13 +885,14 @@
                                   postMouseEventID,
 				  AWT_MOUSE_PRESSED, 
 				  (jlong)event->button.time,
-				  state_to_awt_mods (event->button.state) |
-				  button_to_awt_mods (event->button.button), 
+                                  state_to_awt_mods (event->button.state)
+                                  | button_to_awt_mods (event->button.button),
 				  (jint)event->button.x,
 				  (jint)event->button.y, 
 				  click_count, 
 				  (event->button.button == 3) ? JNI_TRUE :
 				                                JNI_FALSE);
+      hasBeenDragged = FALSE;
       break;
     case GDK_BUTTON_RELEASE:
       {
@@ -904,17 +902,19 @@
 				    postMouseEventID,
 				    AWT_MOUSE_RELEASED, 
 				    (jlong)event->button.time,
-				    state_to_awt_mods (event->button.state) |
-				    button_to_awt_mods (event->button.button), 
+                                    state_to_awt_mods (event->button.state)
+                                    | button_to_awt_mods (event->button.button),
 				    (jint)event->button.x,
 				    (jint)event->button.y, 
 				    click_count,
 				    JNI_FALSE);
 
-	/* check to see if the release occured in the window it was pressed
-	   in, and if so, generate an AWT click event */
+	/* Generate an AWT click event only if the release occured in the
+	   window it was pressed in, and the mouse has not been dragged since
+	   the last time it was pressed. */
 	gdk_window_get_size (event->any.window, &width, &height);
-	if (event->button.x >= 0
+	if (! hasBeenDragged
+	    && event->button.x >= 0
             && event->button.y >= 0
 	    && event->button.x <= width 
 	    && event->button.y <= height)
@@ -923,8 +923,8 @@
 				        postMouseEventID,
 				        AWT_MOUSE_CLICKED, 
 				        (jlong)event->button.time,
-				        state_to_awt_mods (event->button.state) |
-				        button_to_awt_mods (event->button.button), 
+				        state_to_awt_mods (event->button.state)
+                                        | button_to_awt_mods (event->button.button),
 				        (jint)event->button.x,
 				        (jint)event->button.y, 
 				        click_count,
@@ -933,15 +933,6 @@
       }
       break;
     case GDK_MOTION_NOTIFY:
-      (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
-				  AWT_MOUSE_MOVED,
-				  (jlong)event->motion.time,
-				  state_to_awt_mods (event->motion.state),
-				  (jint)event->motion.x,
-				  (jint)event->motion.y,
-				  0,
-				  JNI_FALSE);
-
       if (event->motion.state & (GDK_BUTTON1_MASK
 				 | GDK_BUTTON2_MASK
 				 | GDK_BUTTON3_MASK
@@ -952,30 +943,45 @@
 			              postMouseEventID,
 				      AWT_MOUSE_DRAGGED,
 				      (jlong)event->motion.time,
-				      state_to_awt_mods (event->motion.state),
+				      state_to_awt_mods_with_button_states (event->motion.state),
 				      (jint)event->motion.x,
 				      (jint)event->motion.y,
 				      0,
 				      JNI_FALSE);
+	  hasBeenDragged = TRUE;
 	}
+      else
+        (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
+				    AWT_MOUSE_MOVED,
+				    (jlong)event->motion.time,
+				    state_to_awt_mods (event->motion.state),
+				    (jint)event->motion.x,
+				    (jint)event->motion.y,
+				    0,
+				    JNI_FALSE);
       break;
     case GDK_ENTER_NOTIFY:
-      (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
-				  AWT_MOUSE_ENTERED, 
-				  (jlong)event->crossing.time,
-				  state_to_awt_mods (event->crossing.state), 
-				  (jint)event->crossing.x,
-				  (jint)event->crossing.y, 
-				  0,
-				  JNI_FALSE);
+      /* We are not interested in enter events that are due to
+         grab/ungrab and not to actually crossing boundaries */
+      if (event->crossing.mode == GDK_CROSSING_NORMAL)
+        (*gdk_env)->CallVoidMethod (gdk_env, peer, postMouseEventID,
+				    AWT_MOUSE_ENTERED, 
+				    (jlong)event->crossing.time,
+				    state_to_awt_mods_with_button_states (event->crossing.state), 
+				    (jint)event->crossing.x,
+				    (jint)event->crossing.y, 
+				    0,
+				    JNI_FALSE);
       break;
     case GDK_LEAVE_NOTIFY:
+      /* We are not interested in leave events that are due to
+         grab/ungrab and not to actually crossing boundaries */
       if (event->crossing.mode == GDK_CROSSING_NORMAL)
 	(*gdk_env)->CallVoidMethod (gdk_env, peer,
 				    postMouseEventID,
 				    AWT_MOUSE_EXITED, 
 				    (jlong)event->crossing.time,
-				    state_to_awt_mods (event->crossing.state),
+				    state_to_awt_mods_with_button_states (event->crossing.state),
 				    (jint)event->crossing.x,
 				    (jint)event->crossing.y, 
 				    0,
@@ -983,11 +989,9 @@
       break;
     case GDK_CONFIGURE:
       {
-	/* GtkWidget *widget;
-
-	gdk_window_get_user_data (event->any.window, (void **) &widget); */
-	    
-	if (widget && GTK_WIDGET_TOPLEVEL (widget))
+        /* Only send configure events to visible top-level windows. */
+	if (widget && GTK_WIDGET_TOPLEVEL (widget)
+            && GTK_WIDGET_VISIBLE (widget))
 	  {
 	    /* Configure events are not posted to the AWT event
 	       queue, and as such, the gdk/gtk peer functions will
@@ -1007,112 +1011,70 @@
       break;
     case GDK_EXPOSE:
       {
-	(*gdk_env)->CallVoidMethod (gdk_env, peer,
-				    postExposeEventID,
-				    (jint)event->expose.area.x,
-				    (jint)event->expose.area.y,
-				    (jint)event->expose.area.width,
-				    (jint)event->expose.area.height);
+        /* This filters out unwanted feedback expose events from gtk/X
+           when we explictly invalidate and update heavyweight components,
+           thus avoiding an infinite loop.
+           FIXME: I'm not quite sure why we're getting these expose events. 
+                  Maybe there is a way to avoid them? */
+        if((event->any.window == widget->window && event->any.send_event)
+           || GTK_IS_LAYOUT(widget))
+          {
+	    (*gdk_env)->CallVoidMethod (gdk_env, peer,
+				        postExposeEventID,
+				        (jint)event->expose.area.x,
+				        (jint)event->expose.area.y,
+				        (jint)event->expose.area.width,
+				        (jint)event->expose.area.height);
+          }
       }
       break;
+
     case GDK_FOCUS_CHANGE:
       (*gdk_env)->CallVoidMethod (gdk_env, peer,
 				  postFocusEventID,
-				  (jint) (event->focus_change.in) ? 
+				  (jint) (event->focus_change.in) ?
 				  AWT_FOCUS_GAINED : AWT_FOCUS_LOST,
 				  JNI_FALSE);
       break;
     case GDK_KEY_PRESS:
-    case GDK_KEY_RELEASE:
-      {
-        GdkWindow *obj_window;
-        jobject *focus_obj_ptr = NULL;
-	int generates_key_typed = 0;
-
-        /* A widget with a grab will get key events */
-	if (!GTK_IS_WINDOW (widget))
-	  focus_obj_ptr = &peer;
-	else
-	  {
-            GtkWindow *window;
-
-            /* Check if we have an enabled focused widget in this window.
-	       If not don't handle the event. */
-	    window = GTK_WINDOW (widget);
-	    if (!window->focus_widget
-	        || !GTK_WIDGET_IS_SENSITIVE (window->focus_widget)
-	        || !window->focus_widget->window)
-	      return FALSE;
-	
-            /* TextArea peers are attached to the scrolled window
-               that contains the GtkTextView, not to the text view
-               itself.  Same for List. */
-            if (GTK_IS_TEXT_VIEW (window->focus_widget)
-                || GTK_IS_CLIST (window->focus_widget))
-              {
-                obj_window = gtk_widget_get_parent (window->focus_widget)->window;
-              }
-            else if (GTK_IS_BUTTON (window->focus_widget))
-	      /* GtkButton events go to the "event_window" and this is what
-	         we registered when the button was created. */
-              obj_window = GTK_BUTTON (window->focus_widget)->event_window;
-            else
-              obj_window = window->focus_widget->window;
-
-            gdk_property_get (obj_window,
-                              gdk_atom_intern ("_GNU_GTKAWT_ADDR", FALSE),
-                              gdk_atom_intern ("CARDINAL", FALSE),
-                              0,
-                              sizeof (jobject),
-                              FALSE,
-                              NULL,
-                              NULL,
-                              NULL,
-                              (guchar **)&focus_obj_ptr);
-
-            /* If the window has no jobject attached we can't send anything */
-	    if (!focus_obj_ptr)
-	      return FALSE;
-	      
-	    /* Should we generate an AWT_KEY_TYPED event? */
-	    generates_key_typed = generates_key_typed_event (event, window->focus_widget);
-	  }	
+        if (GTK_IS_WINDOW (widget))
+          {
+            /*            GdkEventKey *keyevent = (GdkEventKey *) event; */
+            /*            g_printerr ("key press event: sent: %d  time: %d  state: %d  keyval: %d  length: %d  string: %s  hardware_keycode: %d  group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */
 
-	if (event->type == GDK_KEY_PRESS)	
-	  {
-            (*gdk_env)->CallVoidMethod (gdk_env, *focus_obj_ptr,
-				        postKeyEventID,
-				        (jint) AWT_KEY_PRESSED,
-				        (jlong) event->key.time,
+            (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                        postKeyEventID,
+                                        (jint) AWT_KEY_PRESSED,
+                                        (jlong) event->key.time,
                                         keyevent_state_to_awt_mods (event),
                                         keysym_to_awt_keycode (event),
                                         keyevent_to_awt_keychar (event),
                                         keysym_to_awt_keylocation (event));
-
-            if (generates_key_typed)
-              {
-                (*gdk_env)->CallVoidMethod (gdk_env, *focus_obj_ptr,
-                                            postKeyEventID,
-                                            (jint) AWT_KEY_TYPED,
-                                            (jlong) event->key.time,
-                                            state_to_awt_mods (event->key.state),
-                                            VK_UNDEFINED,
-                                            keyevent_to_awt_keychar (event),
-                                            AWT_KEY_LOCATION_UNKNOWN);
-              }
+            /* FIXME: generation of key typed events needs to be moved
+               to GtkComponentPeer.postKeyEvent.  If the key in a key
+               press event is not an "action" key
+               (KeyEvent.isActionKey) and is not a modifier key, then
+               it should generate a key typed event. */
+            return TRUE;
           }
-	else /* GDK_KEY_RELEASE */
-          {
-	    (*gdk_env)->CallVoidMethod (gdk_env, *focus_obj_ptr,
-				        postKeyEventID,
-				        (jint) AWT_KEY_RELEASED,
-				        (jlong) event->key.time,
-			                keyevent_state_to_awt_mods (event),
-			                keysym_to_awt_keycode (event),
+        else
+          return FALSE;
+        break;
+    case GDK_KEY_RELEASE:
+      if (GTK_IS_WINDOW (widget))
+        {
+            (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                        postKeyEventID,
+                                        (jint) AWT_KEY_RELEASED,
+                                        (jlong) event->key.time,
+                                        keyevent_state_to_awt_mods (event),
+                                        keysym_to_awt_keycode (event),
                                         keyevent_to_awt_keychar (event),
                                         keysym_to_awt_keylocation (event));
-	  }
-      }
+            return TRUE;
+        }
+      else
+        return FALSE;
       break;
     default:
       break;
@@ -1141,7 +1103,6 @@
 			 | GDK_KEY_PRESS_MASK
 			 | GDK_FOCUS_CHANGE_MASK);
 
-  //  g_print("storing obj %p property on window %p\n", obj, window);
   gdk_property_change (window,
 		       addr_atom,
 		       type_atom,
@@ -1156,10 +1117,8 @@
 {
   va_list ap;
   jobject *obj;
-  //void *ptr = NSA_GET_PTR (env, peer_obj);
 
   obj = NSA_GET_GLOBAL_REF (env, peer_obj);
-  //g_print("Connection obj %s\n", gtk_widget_get_name (GTK_WIDGET (ptr)));
   g_assert (obj);
 
   va_start (ap, nwindows);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c	8 Jan 2004 21:12:25 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c	6 Sep 2004 16:36:13 -0000
@@ -1,5 +1,5 @@
 /* gtkfiledialogpeer.c -- Native implementation of GtkFileDialogPeer
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,13 +40,9 @@
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 #include "gnu_java_awt_peer_gtk_GtkFileDialogPeer.h"
 
-static void window_closed (GtkDialog *dialog,
+static void handle_response (GtkDialog *dialog,
                            gint responseId,
                            jobject peer_obj);
-static void ok_clicked (GtkButton *button,
-	                jobject peer_obj);
-static void cancel_clicked (GtkButton *button,
-	                    jobject peer_obj);
 
 /*
  * Make a new file selection dialog
@@ -54,16 +50,28 @@
 
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_create 
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jobject obj, jobject parent)
 {
+  void *parentp;
   gpointer widget;
 
   /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
+  parentp = NSA_GET_PTR(env, parent);
+
   gdk_threads_enter ();
   
-  widget = gtk_file_selection_new ("");
+  widget = gtk_file_chooser_dialog_new("",
+                                       GTK_WINDOW(parentp),
+                                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                       NULL);
+
+  /* GtkFileChooser doesn't show hidden files by default. */
+  g_object_set(GTK_FILE_CHOOSER(widget), "show_hidden", TRUE);
+
   /* GtkFileSelect is not modal by default */
   gtk_window_set_modal (GTK_WINDOW (widget), TRUE);
 
@@ -103,19 +111,9 @@
 
   gtk_widget_realize (GTK_WIDGET (ptr));
 
-  /* connect buttons to handlers */
-
   g_signal_connect (G_OBJECT (GTK_DIALOG (ptr)),
                     "response", 
-		    GTK_SIGNAL_FUNC (window_closed), *gref);
-
-  g_signal_connect (G_OBJECT (GTK_FILE_SELECTION (ptr)->ok_button),
-                    "clicked", 
-		    GTK_SIGNAL_FUNC (ok_clicked), *gref);
-
-  g_signal_connect (G_OBJECT (GTK_FILE_SELECTION (ptr)->cancel_button),
-                    "clicked", 
-		    GTK_SIGNAL_FUNC (cancel_clicked), *gref);
+		    GTK_SIGNAL_FUNC (handle_response), *gref);
 		    
   gdk_threads_leave ();
 
@@ -123,120 +121,171 @@
   Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, obj);
 }
 
-/*
- * Set the filename in the file selection dialog.
- */
-
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFile 
-    (JNIEnv *env, jobject obj, jstring filename)
+JNIEXPORT jstring JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeGetDirectory
+    (JNIEnv *env, jobject obj)
 {
   void *ptr;
   const char *str;
 
   ptr = NSA_GET_PTR (env, obj);
     
-  str = (*env)->GetStringUTFChars (env, filename, 0);
-     
   gdk_threads_enter ();
 
-  gtk_file_selection_set_filename (GTK_FILE_SELECTION (ptr), str);
+  str = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(ptr));
 
   gdk_threads_leave ();
 
-  (*env)->ReleaseStringUTFChars (env, filename, str);
+  return (*env)->NewStringUTF(env, str);
 }
 
-static void
-window_closed (GtkDialog *dialog __attribute__((unused)),
-               gint responseId,
-               jobject peer_obj)
-{
-  static int isIDSet = 0;
-  static jmethodID disposeID;
-  void *ptr;
 
-  // We only need this for the case when the user closed the window
-  if (responseId != GTK_RESPONSE_DELETE_EVENT)
-    return;
+/* This function interfaces with the Java callback method of the same name.
+   This function extracts the filename from the GtkFileFilterInfo object,
+   and passes it to the Java method.  The Java method will call the filter's
+   accept() method and will give back the return value. */
+gboolean filenameFilterCallback (const GtkFileFilterInfo *filter_info,
+                                 gpointer obj)
+{
+  gchar* dirname;
+  jclass cx;
+  jmethodID id;
+  jstring *filename;
+  gboolean accepted;
+
+  cx = (*gdk_env)->GetObjectClass (gdk_env, (jobject) obj);
+  id = (*gdk_env)->GetMethodID (gdk_env, cx, "filenameFilterCallback",
+                                             "(Ljava/lang/String;)Z");
 
-  ptr = NSA_GET_PTR (gdk_env, peer_obj);
+  filename = (*gdk_env)->NewStringUTF(gdk_env, filter_info->filename);
   
-  if (!isIDSet)
+  gdk_threads_leave();
+  accepted = (*gdk_env)->CallBooleanMethod(gdk_env, obj, id, filename);
+  gdk_threads_enter();
+
+  return accepted;
+}
+
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFilenameFilter
+    (JNIEnv *env, jobject obj, jobject filter_obj)
     {
-      jclass cx = (*gdk_env)->GetObjectClass (gdk_env, peer_obj);
-      disposeID = (*gdk_env)->GetMethodID (gdk_env, cx, "gtkDisposeFileDialog", "()V");
-      isIDSet = 1;
+  void *ptr;
+  GtkFileFilter *filter;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  filter = gtk_file_filter_new();
+  gtk_file_filter_add_custom(filter,
+                             GTK_FILE_FILTER_FILENAME,
+                             G_CALLBACK(filenameFilterCallback),
+                             obj,
+                             NULL);
+
+  gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(ptr), filter);
+
+  gdk_threads_leave ();
     }
     
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetDirectory
+    (JNIEnv *env, jobject obj, jstring directory)
+{
+  void *ptr;
+  const char *str;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  str = (*env)->GetStringUTFChars (env, directory, 0);
+
+  gdk_threads_enter ();
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(ptr), str);
   gdk_threads_leave ();
 
-  /* We can dispose of the dialog now (and unblock show) */
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, disposeID);
+  (*env)->ReleaseStringUTFChars (env, directory, str);
+}
+
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFile 
+    (JNIEnv *env, jobject obj, jstring filename)
+{
+  void *ptr;
+  const char *str;
+
+  ptr = NSA_GET_PTR (env, obj);
+    
+  str = (*env)->GetStringUTFChars (env, filename, 0);
 
   gdk_threads_enter ();
+  gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (ptr), str);
+  gdk_threads_leave ();
+
+  (*env)->ReleaseStringUTFChars (env, filename, str);
 }
 
 static void
-ok_clicked (GtkButton *button __attribute__((unused)),
+handle_response (GtkDialog *dialog __attribute__((unused)),
+                 gint responseId,
 	                jobject peer_obj)
 {
+  static int isDisposeIDSet = 0;
   static int isIDSet = 0;
   static jmethodID gtkSetFilenameID;
   static jmethodID hideID;
+  static jmethodID disposeID;
   void *ptr;
   G_CONST_RETURN gchar *fileName;
+  jstring str_fileName;
 
-  ptr = NSA_GET_PTR (gdk_env, peer_obj);
+  /* We only need this for the case when the user closed the window,
+     or clicked ok or cancel. */
+  if (responseId != GTK_RESPONSE_DELETE_EVENT
+      && responseId != GTK_RESPONSE_OK
+      && responseId != GTK_RESPONSE_CANCEL)
+    return;
   
-  fileName = gtk_file_selection_get_filename (
-               GTK_FILE_SELECTION (GTK_WIDGET (ptr)));
+  ptr = NSA_GET_PTR (gdk_env, peer_obj);
   
-  if (!isIDSet)
+  if (responseId == GTK_RESPONSE_DELETE_EVENT)
+  {
+    if (!isDisposeIDSet)
     {
       jclass cx = (*gdk_env)->GetObjectClass (gdk_env, peer_obj);
-      hideID = (*gdk_env)->GetMethodID (gdk_env, cx, "gtkHideFileDialog", "()V");
-      gtkSetFilenameID = (*gdk_env)->GetMethodID (gdk_env, cx,
-                                   "gtkSetFilename", "(Ljava.lang.String;)V");
-      isIDSet = 1;
+        disposeID = (*gdk_env)->GetMethodID (gdk_env, cx, "gtkDisposeFileDialog", "()V");
+        isDisposeIDSet = 1;
     }
     
   gdk_threads_leave ();
   
-  /* Set the Java object field 'file' with this value. */
-  jstring str_fileName = (*gdk_env)->NewStringUTF (gdk_env, fileName);
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, gtkSetFilenameID, str_fileName);
-
-  /* We can hide the dialog now (and unblock show) */
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, hideID);
+    /* We can dispose of the dialog now (and unblock show) */
+    (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, disposeID);
 
   gdk_threads_enter ();
+    return;
 }
 
-static void
-cancel_clicked (GtkButton *button __attribute__((unused)),
-	                    jobject peer_obj)
-{
-  static int isIDSet = 0;
-  static jmethodID gtkSetFilenameID;
-  static jmethodID hideID;
-  void *ptr;
-
-  ptr = NSA_GET_PTR (gdk_env, peer_obj);
+  if (responseId == GTK_RESPONSE_OK) {
+    fileName = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (GTK_WIDGET (ptr)));
+    str_fileName = (*gdk_env)->NewStringUTF (gdk_env, fileName);
+  } else if (responseId == GTK_RESPONSE_CANCEL) {
+    str_fileName = NULL;
+  }
   
   if (!isIDSet)
     {
       jclass cx = (*gdk_env)->GetObjectClass (gdk_env, peer_obj);
       hideID = (*gdk_env)->GetMethodID (gdk_env, cx, "gtkHideFileDialog", "()V");
       gtkSetFilenameID = (*gdk_env)->GetMethodID (gdk_env, cx,
-                                   "gtkSetFilename", "(Ljava.lang.String;)V");
+                                   "gtkSetFilename", "(Ljava/lang/String;)V");
       isIDSet = 1;
     }
     
   gdk_threads_leave ();
 
-  /* Set the Java object field 'file' with the null value. */
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, gtkSetFilenameID, NULL);
+  /* Set the Java object field 'file' with this value. */
+  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, gtkSetFilenameID, str_fileName);
 
   /* We can hide the dialog now (and unblock show) */
   (*gdk_env)->CallVoidMethod (gdk_env, peer_obj, hideID);
@@ -244,4 +293,3 @@
   gdk_threads_enter ();
 }
 
-
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
===================================================================
RCS file: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
diff -N jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c	6 Sep 2004 16:36:13 -0000
@@ -0,0 +1,59 @@
+/* gtkgenericpeer.c -- Native implementation of GtkGenericPeer
+   Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkGenericPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+
+  /* Remove entries from state tables */
+  NSA_DEL_GLOBAL_REF (env, obj);
+  ptr = NSA_DEL_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  /* For now the native state for any object must be a widget.
+     However, a subclass could override dispose() if required.  */
+  gtk_widget_destroy (GTK_WIDGET (ptr));
+
+  gdk_threads_leave ();
+}
+
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkImagePainter.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c	8 Oct 2003 15:49:33 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c	6 Sep 2004 16:36:13 -0000
@@ -58,6 +58,9 @@
 
   g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
 
+  if (!jpixels)
+    return;
+
   elems = (*env)->GetIntArrayElements (env, jpixels, NULL);
   num_pixels = (*env)->GetArrayLength (env, jpixels);
  
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c,v
retrieving revision 1.6
diff -u -r1.6 gnu_java_awt_peer_gtk_GtkLabelPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c	13 Dec 2003 01:15:47 -0000	1.6
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c	6 Sep 2004 16:36:13 -0000
@@ -54,7 +54,7 @@
   str = (*env)->GetStringUTFChars (env, text, 0);
 
   gdk_threads_enter ();
-  
+
   ebox = gtk_event_box_new ();
   ebox_container = GTK_CONTAINER (ebox);
   label = gtk_label_new (str);
@@ -70,6 +70,44 @@
 }
 
 JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+  const char *font_name;
+  void *ptr;
+  GtkWidget *label;
+  PangoFontDescription *font_desc;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+  gdk_threads_enter ();
+
+  label = gtk_bin_get_child (GTK_BIN (ptr));
+
+  if (!label)
+    return;
+
+  font_desc = pango_font_description_from_string (font_name);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+  gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
+
+  pango_font_description_free (font_desc);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseStringUTFChars (env, name, font_name);
+}
+
+JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkLabelPeer_setText
   (JNIEnv *env, jobject obj, jstring text)
 {
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c,v
retrieving revision 1.7
diff -u -r1.7 gnu_java_awt_peer_gtk_GtkListPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c	13 Dec 2003 01:15:47 -0000	1.7
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c	6 Sep 2004 16:36:13 -0000
@@ -1,76 +1,116 @@
 /* gtklistpeer.c -- Native implementation of GtkListPeer
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
 
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
+   This file is part of GNU Classpath.
 
+   GNU Classpath is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GNU Classpath is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Classpath; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   Linking this library statically or dynamically with other modules is
+   making a combined work based on this library.  Thus, the terms and
+   conditions of the GNU General Public License cover the whole
+   combination.
+
+   As a special exception, the copyright holders of this library give you
+   permission to link this library with independent modules to produce an
+   executable, regardless of the license terms of these independent
+   modules, and to copy and distribute the resulting executable under
+   terms of your choice, provided that you also meet, for each linked
+   independent module, the terms and conditions of the license of that
+   module.  An independent module is a module which is not derived from
+   or based on this library.  If you modify this library, you may extend
+   this exception to your version of the library, but you are not
+   obligated to do so.  If you do not wish to do so, delete this
+   exception statement from your version. */
 
 #include "gtkpeer.h"
-#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 #include "gnu_java_awt_peer_gtk_GtkListPeer.h"
 
-static void item_select (GtkCList *list __attribute__((unused)),
-	                 int row, int col __attribute__((unused)),
-	                 GdkEventButton *event __attribute__((unused)), 
-	                 jobject peer_obj);
-static void item_unselect (GtkCList *list __attribute__((unused)),
-	                   int row,
-	                   int col __attribute__((unused)),
-	                   GdkEventButton *event __attribute__((unused)),
-	                   jobject peer_obj);
+enum
+  {
+    COLUMN_STRING,
+    N_COLUMNS
+  };
+
+gboolean item_highlighted (GtkTreeSelection *selection,
+                           GtkTreeModel *model,
+                           GtkTreePath *path,
+                           gboolean path_currently_selected,
+                           jobject peer);
 
-#define CLIST_FROM_SW(obj) (GTK_CLIST(GTK_SCROLLED_WINDOW (obj)->container.child))
 
-JNIEXPORT void JNICALL 
+#define TREE_VIEW_FROM_SW(obj) \
+           (GTK_TREE_VIEW (GTK_SCROLLED_WINDOW (obj)->container.child))
+
+JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkListPeer_create
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jobject obj, jint rows)
 {
-  GtkWidget *list, *sw;
+  GtkWidget *sw;
+  GtkWidget *list;
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+  GtkListStore *list_store;
+  GtkTreeIter iter;
+  GtkRequisition req;
+  gint i;
 
   /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
-  
-  list = gtk_clist_new (1);
-  gtk_widget_show (list);
+
+  list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
+  /* Add the number of rows so that we can calculate the tree view's
+     size request. */
+  for (i = 0; i < rows; i++)
+    {
+      gtk_list_store_append (list_store, &iter);
+      gtk_list_store_set (list_store, &iter,
+                          COLUMN_STRING, "",
+                          -1);
+    }
+  list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes (NULL,
+				     renderer,
+				     "text",
+				     COLUMN_STRING,
+				     NULL);
+
   sw = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), 
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
 				  GTK_POLICY_AUTOMATIC,
 				  GTK_POLICY_AUTOMATIC);
+
+  gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
+
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
+
+  gtk_widget_size_request (GTK_WIDGET (list), &req);
+
+  gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
+
   gtk_container_add (GTK_CONTAINER (sw), list);
 
+  /* Remove the blank rows. */
+  gtk_list_store_clear (list_store);
+
+  gtk_widget_show (list);
+  gtk_widget_show (sw);
+
   gdk_threads_leave ();
 
   NSA_SET_PTR (env, obj, sw);
@@ -87,7 +127,6 @@
   gdk_threads_enter ();
 
   gtk_widget_realize (GTK_WIDGET (ptr));
-
   connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window);
 
   gdk_threads_leave ();
@@ -97,50 +136,105 @@
 Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
   (JNIEnv *env, jobject obj)
 {
-  GtkCList *list;
-  void *ptr = NSA_GET_PTR (env, obj);
-  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
-  g_assert (gref);
+  void *ptr;
+  jobject *gref;
+  GtkTreeView *list;
+  GtkTreeSelection *selection;
+
+  ptr = NSA_GET_PTR (env, obj);
+  gref = NSA_GET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
 
+  g_assert (gref);
+
   gtk_widget_realize (GTK_WIDGET (ptr));
 
-  /* connect selectable hook */
-  
-  list = CLIST_FROM_SW (ptr);
+  list = TREE_VIEW_FROM_SW (ptr);
 
-  g_signal_connect (G_OBJECT (list), "select_row", 
-		      GTK_SIGNAL_FUNC (item_select), *gref);
+  g_signal_connect (G_OBJECT (list), "event",
+                    G_CALLBACK (pre_event_handler), *gref);
 
-  g_signal_connect (G_OBJECT (list), "unselect_row", 
-		      GTK_SIGNAL_FUNC (item_unselect), *gref);
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+  gtk_tree_selection_set_select_function (selection, item_highlighted,
+                                          *gref, NULL);
 
-  /* Connect the superclass signals.  */
-  /* FIXME: Cannot do that here or it will get the sw and not the list.
-     We must a generic way of doing this. */
-  /* Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, peer_obj); */
-  g_signal_connect (GTK_OBJECT (list), "event", 
-                    G_CALLBACK (pre_event_handler), *gref);
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+  const char *font_name;
+  void *ptr;
+  GtkWidget *list;
+  PangoFontDescription *font_desc;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter();
+
+  list = GTK_WIDGET (TREE_VIEW_FROM_SW (ptr));
+
+  font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+  font_desc = pango_font_description_from_string (font_name);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
+
+  if (style & AWT_STYLE_BOLD)
+    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+  if (style & AWT_STYLE_ITALIC)
+    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+  gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
+
+  pango_font_description_free (font_desc);
+
+  (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+  gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+  GtkWidget *list;
+
+  ptr = NSA_GET_PTR (env, obj);
+  
+  gdk_threads_enter ();
+
+  list = GTK_WIDGET (TREE_VIEW_FROM_SW (ptr));
+  gtk_widget_grab_focus (list);
 
   gdk_threads_leave ();
 }
 
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkListPeer_append 
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_append
   (JNIEnv *env, jobject obj, jobjectArray items)
 {
   void *ptr;
-  GtkCList *list;
-  jint count, i;
+  GtkTreeView *list;
+  GtkTreeIter iter;
+  GtkTreeModel *list_store;
+  jint count;
+  jint i;
 
   ptr = NSA_GET_PTR (env, obj);
 
   count = (*env)->GetArrayLength (env, items);
 
   gdk_threads_enter ();
-  list = CLIST_FROM_SW (ptr);
-  for (i = 0; i < count; i++) 
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  list_store = gtk_tree_view_get_model (list);
+
+  for (i = 0; i < count; i++)
     {
       const char *text;
       jobject item;
@@ -148,11 +242,13 @@
       item = (*env)->GetObjectArrayElement (env, items, i);
 
       text = (*env)->GetStringUTFChars (env, item, NULL);
-      gtk_clist_append (list, (char **)&text);
+      gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
+      gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
+                          COLUMN_STRING, text,
+                          -1);
       (*env)->ReleaseStringUTFChars (env, item, text);
     }
 
-  gtk_clist_columns_autosize (list);
   gdk_threads_leave ();
 }
 
@@ -162,12 +258,26 @@
 {
   void *ptr;
   const char *str;
-    
+  GtkTreeView *list;
+  GtkTreeIter iter;
+  GtkTreeModel *list_store;
+
   ptr = NSA_GET_PTR (env, obj);
   str = (*env)->GetStringUTFChars (env, text, NULL);
 
   gdk_threads_enter ();
-  gtk_clist_insert (CLIST_FROM_SW (ptr), index, (char **)&str);
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  list_store = gtk_tree_view_get_model (list);
+
+  if (index == -1)
+    gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
+  else
+    gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
+
+  gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
+                      COLUMN_STRING, str, -1);
+
   gdk_threads_leave ();
 
   (*env)->ReleaseStringUTFChars (env, text, str);
@@ -179,22 +289,32 @@
   (JNIEnv *env, jobject obj, jint start, jint end)
 {
   void *ptr;
-  GtkCList *list;
+  GtkTreeView *list;
+  GtkTreeIter iter;
+  GtkTreeModel *list_store;
   jint i;
+  jint num_items;
     
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  list = CLIST_FROM_SW (ptr);
 
-  if (end == -1)		/* special case for removing all rows */
-    gtk_clist_clear (list);
+  list = TREE_VIEW_FROM_SW (ptr);
+  list_store = gtk_tree_view_get_model (list);
+
+  /* Special case: remove all rows. */
+  if (end == -1)
+    gtk_list_store_clear (GTK_LIST_STORE (list_store));
   else
     {
-      gtk_clist_freeze (list);
-      for (i = end; i >= start; i--)
-        gtk_clist_remove (list, i);
-      gtk_clist_thaw (list);
+      i = 0;
+      num_items = end - start + 1;
+      gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
+      while (i < num_items)
+	{
+	  gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
+	  i++;
+	}
     }
 
   gdk_threads_leave ();
@@ -205,11 +325,17 @@
   (JNIEnv *env, jobject obj, jint index)
 {
   void *ptr;
+  GtkTreeView *list;
+  GtkTreePath *path;
     
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gtk_clist_select_row (CLIST_FROM_SW (ptr), index, 0);
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  path = gtk_tree_path_new_from_indices (index, -1);
+  gtk_tree_view_set_cursor (list, path, NULL, FALSE);
+
   gdk_threads_leave ();
 }
 
@@ -218,40 +344,61 @@
   (JNIEnv *env, jobject obj, jint index)
 {
   void *ptr;
+  GtkTreeView *list;
+  GtkTreeSelection *selection;
+  GtkTreePath *path;
 
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gtk_clist_unselect_row (CLIST_FROM_SW (ptr), index, 0);
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  selection = gtk_tree_view_get_selection (list);
+  path = gtk_tree_path_new_from_indices (index, -1);
+  gtk_tree_selection_unselect_path (selection, path);
+
   gdk_threads_leave ();
 }
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
-  (JNIEnv *env, jobject obj, jint rows, jintArray jdims)
+  (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
 {
   void *ptr;
   jint *dims;
-  GtkWidget *list;
-  GtkScrolledWindow *sw;
-  GtkRequisition myreq;
+  GtkRequisition current_req;
+  GtkRequisition natural_req;
 
   dims = (*env)->GetIntArrayElements (env, jdims, NULL);
   dims[0] = dims[1] = 0;
 
-  if (rows < 3)
-    rows = 3;
-
   ptr = NSA_GET_PTR (env, obj);
+
   gdk_threads_enter ();
 
-  list = GTK_WIDGET (CLIST_FROM_SW (ptr));
-  sw = GTK_SCROLLED_WINDOW (ptr);
+  /* Save the widget's current size request. */
+  gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
+      
+  /* Get the widget's "natural" size request. */
+  gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
+  gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
+
+  /* Reset the widget's size request. */
+  gtk_widget_set_size_request (GTK_WIDGET (ptr),
+                               current_req.width, current_req.height);
+
+  dims[0] = natural_req.width;
+
+  /* Calculate the final height, by comparing the number of rows
+     in the list to the number of rows requested by the caller.
+     FIXME: Is there a GTK method that counts the number of rows
+     in the list? If so, we don't need to bring visible_rows from
+     the Java peer. */
+  if (rows == visible_rows)
+    dims[1] = natural_req.height;
+  else
+    dims[1] = natural_req.height / visible_rows * rows;
 
-  gtk_widget_size_request(GTK_WIDGET(sw), &myreq);
-  dims[1]=myreq.height;
-  dims[0]=myreq.width;
-  
   gdk_threads_leave ();
 
   (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
@@ -263,31 +410,53 @@
   (JNIEnv *env, jobject obj)
 {
   void *ptr;
-  GtkCList *list;
-  jintArray selection;
-  jint *sel;
-  GList *child;
-  jint count, i;
+  GtkTreeView *list;
+  GtkTreeSelection *selection;
+  jintArray result_array;
+  jint *result_array_iter;
+  GList *current_row;
+  GList *rows;
+  gint *indices;
+  jint count;
+  jint i;
 
   ptr = NSA_GET_PTR (env, obj);
+
   gdk_threads_enter ();
 
-  list = CLIST_FROM_SW (ptr);
-  count = g_list_length (list->selection);
+  list = TREE_VIEW_FROM_SW (ptr);
+  selection = gtk_tree_view_get_selection (list);
+  count = gtk_tree_selection_count_selected_rows (selection);
+  if (count > 0)
+    {
+      current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
 
-  selection = (*env)->NewIntArray (env, count);
-  sel = (*env)->GetIntArrayElements (env, selection, NULL);  
+      result_array = (*env)->NewIntArray (env, count);
+      result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
 
-  for (i = 0, child = list->selection; i < count; i++)
-    {
-      sel[i] = GPOINTER_TO_INT (child->data);
-      child = g_list_next (child);
-    }
-  gdk_threads_leave ();
+      for (i = 0; i < count; i++)
+        {
+          indices = gtk_tree_path_get_indices (current_row->data);
+          result_array_iter[i] = indices ? indices[0] : -1;
+          current_row = g_list_next (current_row);
+        }
+
+      if (rows)
+        {
+          g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
+          g_list_free (rows);
+        }
+
+      gdk_threads_leave ();
 
-  (*env)->ReleaseIntArrayElements (env, selection, sel, 0);
+      (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
+
+      return result_array;
+    }
+  else
+    gdk_threads_leave ();
 
-  return selection;
+  return (jintArray) NULL;
 }
 
 JNIEXPORT void JNICALL
@@ -295,11 +464,17 @@
   (JNIEnv *env, jobject obj, jint index)
 {
   void *ptr;
+  GtkTreeView *list;
+  GtkTreePath *path;
 
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gtk_clist_moveto (CLIST_FROM_SW (ptr), index, 0, 0.5, 0.5);
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  path = gtk_tree_path_new_from_indices (index, -1);
+  gtk_tree_view_scroll_to_cell (list, path, NULL, FALSE, 0.0, 0.0);
+
   gdk_threads_leave ();
 }
 
@@ -308,40 +483,49 @@
   (JNIEnv *env, jobject obj, jboolean mode)
 {
   void *ptr;
-    
+  GtkTreeView *list;
+  GtkTreeSelection *selection;
+
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
-  gtk_clist_set_selection_mode (CLIST_FROM_SW (ptr),
-				mode ? GTK_SELECTION_MULTIPLE : 
-				       GTK_SELECTION_SINGLE);
+
+  list = TREE_VIEW_FROM_SW (ptr);
+  selection = gtk_tree_view_get_selection (list);
+  gtk_tree_selection_set_mode (selection,
+                               mode ? GTK_SELECTION_MULTIPLE
+                               : GTK_SELECTION_SINGLE);
+
   gdk_threads_leave ();
 }
 
-static void
-item_select (GtkCList *list __attribute__((unused)),
-	     int row, int col __attribute__((unused)),
-	     GdkEventButton *event __attribute__((unused)), 
-	     jobject peer_obj)
-{
-  //g_print ("select_row\n");
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
-			      postListItemEventID,
-			      row,
-			      (jint) AWT_ITEM_SELECTED);
-}
-
-static void
-item_unselect (GtkCList *list __attribute__((unused)),
-	       int row,
-	       int col __attribute__((unused)),
-	       GdkEventButton *event __attribute__((unused)),
-	       jobject peer_obj)
-{
-  //g_print ("unselect_row\n");
-  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
-			      postListItemEventID,
-			      row,
-	   		      (jint) AWT_ITEM_DESELECTED);
-}
+gboolean
+item_highlighted (GtkTreeSelection *selection __attribute__((unused)),
+                  GtkTreeModel *model,
+                  GtkTreePath *path,
+                  gboolean path_currently_selected,
+                  jobject peer)
+{
+  GtkTreeIter iter;
+  jint row;
+  gint *indices;
+
+  if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+      indices = gtk_tree_path_get_indices (path);
+      row = indices ? indices[0] : -1;
 
+      if (!path_currently_selected)
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postListItemEventID,
+                                    row,
+                                    (jint) AWT_ITEM_SELECTED);
+      else
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postListItemEventID,
+                                    row,
+                                    (jint) AWT_ITEM_DESELECTED);
+    }
+
+  return TRUE;
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c,v
retrieving revision 1.12
diff -u -r1.12 gnu_java_awt_peer_gtk_GtkMainThread.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c	13 Jan 2004 20:54:46 -0000	1.12
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c	6 Sep 2004 16:36:13 -0000
@@ -63,19 +63,30 @@
 
 JNIEnv *gdk_env;
 
-#ifdef PORTABLE_NATIVE_SYNC
-JavaVM *gdk_vm;
-#endif
-
 GtkWindowGroup *global_gtk_window_group;
 
+static void init_glib_threads(JNIEnv *, jint);
+
+double dpi_conversion_factor;
+
+static void init_dpi_conversion_factor ();
+static void dpi_changed_cb (GtkSettings  *settings,
+                            GParamSpec   *pspec);
+
 /*
  * Call gtk_init.  It is very important that this happen before any other
  * gtk calls.
+ *
+ * The portableNativeSync argument may have the values:
+ *   1 if the Java property gnu.classpath.awt.gtk.portable.native.sync
+ *     is set to "true".  
+ *   0 if it is set to "false"
+ *  -1 if unset.
  */
 
 JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz)
+Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz,
+                                                  jint portableNativeSync)
 {
   int argc = 1;
   char **argv;
@@ -85,23 +96,22 @@
     gtkmenuitempeer, gtktextcomponentpeer, window;
 
   NSA_INIT (env, clazz);
+  gdk_env = env;
 
   /* GTK requires a program's argc and argv variables, and requires that they
-     be valid.  */
-
-  argv = (char **) malloc (sizeof (char *) * 2);
-  argv[0] = "";
+     be valid.   Set it up. */
+  argv = (char **) g_malloc (sizeof (char *) * 2);
+  argv[0] = (char *) g_malloc(1);
+#if 1
+  strcpy(argv[0], "");
+#else  /* The following is a more efficient alternative, but less intuitively
+	* expresses what we are trying to do.   This code is only run once, so
+	* I'm going for intuitive. */
+  argv[0][0] = '\0';
+#endif
   argv[1] = NULL;
 
-  /* until we have JDK 1.2 JNI, assume we have a VM with threads that 
-     match what GLIB was compiled for */
-#ifdef PORTABLE_NATIVE_SYNC
-  (*env)->GetJavaVM( env, &gdk_vm );
-  g_thread_init ( &g_thread_jni_functions );
-  printf("called gthread init\n");
-#else
-  g_thread_init ( NULL );
-#endif
+  init_glib_threads(env, portableNativeSync);
 
   /* From GDK 2.0 onwards we have to explicitly call gdk_threads_init */
   gdk_threads_init();
@@ -116,21 +126,19 @@
      we're shutting down. */
   atexit (gdk_threads_enter);
 
-  gdk_env = env;
   gdk_event_handler_set ((GdkEventFunc)awt_event_handler, NULL, NULL);
 
   if ((homedir = getenv ("HOME")))
     {
-      rcpath = (char *) malloc (strlen (homedir) + strlen (RC_FILE) + 2);
+      rcpath = (char *) g_malloc (strlen (homedir) + strlen (RC_FILE) + 2);
       sprintf (rcpath, "%s/%s", homedir, RC_FILE);
     }
   
   gtk_rc_parse ((rcpath) ? rcpath : RC_FILE);
 
-  if (rcpath)
-    free (rcpath);
-
-  free (argv);
+  g_free (rcpath);
+  g_free (argv[0]);
+  g_free (argv);
 
   /* setup cached IDs for posting GTK events to Java */
 /*    gtkgenericpeer = (*env)->FindClass (env,  */
@@ -166,7 +174,7 @@
 					       "postMenuActionEvent",
 					       "()V");
   postMouseEventID = (*env)->GetMethodID (env, gtkcomponentpeer, 
-					  "postMouseEvent", "(IJIIIIZ)V");
+                                          "postMouseEvent", "(IJIIIIZ)V");
   postConfigureEventID = (*env)->GetMethodID (env, gtkwindowpeer, 
 					      "postConfigureEvent", "(IIII)V");
   postWindowEventID = (*env)->GetMethodID (env, gtkwindowpeer,
@@ -194,8 +202,41 @@
 					     "postTextEvent",
 					     "()V");
   global_gtk_window_group = gtk_window_group_new ();
+
+  init_dpi_conversion_factor ();
 }
 
+
+/** Initialize GLIB's threads properly, based on the value of the
+    gnu.classpath.awt.gtk.portable.native.sync Java system property.  If
+    that's unset, use the PORTABLE_NATIVE_SYNC config.h macro.  (TODO: 
+    In some release following 0.10, that config.h macro will go away.)
+    */ 
+static void 
+init_glib_threads(JNIEnv *env, jint portableNativeSync)
+{
+  if (portableNativeSync < 0)
+    {
+#ifdef PORTABLE_NATIVE_SYNC /* Default value, if not set by the Java system
+                               property */ 
+      portableNativeSync = 1;
+#else
+      portableNativeSync = 0;
+#endif
+    }
+  
+  (*env)->GetJavaVM( env, &the_vm );
+  if (portableNativeSync)
+    g_thread_init ( &portable_native_sync_jni_functions );
+  else
+    g_thread_init ( NULL );
+
+  /* Debugging progress message; uncomment if needed: */
+  /*   printf("called gthread init\n"); */
+}
+
+
+
 /*
  * Run gtk_main and block.
  */ 
@@ -207,3 +248,45 @@
   gtk_main ();
   gdk_threads_leave ();
 }
+
+/* This is a big hack, needed until this pango bug is resolved:
+   http://bugzilla.gnome.org/show_bug.cgi?id=119081.
+   See: http://mail.gnome.org/archives/gtk-i18n-list/2003-August/msg00001.html
+   for details. */
+static void
+init_dpi_conversion_factor ()
+{
+  GtkSettings *settings = gtk_settings_get_default ();
+  GObjectClass *klass;
+
+  klass = G_OBJECT_CLASS (GTK_SETTINGS_GET_CLASS (settings));
+  if (g_object_class_find_property (klass, "gtk-xft-dpi"))
+    {
+      int int_dpi;
+      g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
+      /* If int_dpi == -1 gtk-xft-dpi returns the default value. So we
+	 have to do approximate calculation here.  */
+      if (int_dpi < 0)
+	dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+      else
+	dpi_conversion_factor = PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
+
+      g_signal_connect (settings, "notify::gtk-xft-dpi",
+			G_CALLBACK (dpi_changed_cb), NULL);
+    }
+  else
+    /* Approximate. */
+    dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+}
+
+static void
+dpi_changed_cb (GtkSettings  *settings,
+		GParamSpec *pspec __attribute__((unused)))
+{
+  int int_dpi;
+  g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
+  if (int_dpi < 0)
+    dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+  else
+    dpi_conversion_factor = PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c	13 Dec 2003 01:15:47 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c	6 Sep 2004 16:36:13 -0000
@@ -66,7 +66,30 @@
   menu = NSA_GET_PTR (env, menupeer);
 
   gdk_threads_enter ();
-  gtk_menu_bar_append (GTK_MENU_BAR (mbar), GTK_WIDGET (menu));
+  gtk_menu_shell_append (GTK_MENU_SHELL (mbar), GTK_WIDGET (menu));
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_nativeSetHelpMenu
+  (JNIEnv *env, jobject obj, jobject menupeer)
+{
+  static void *helpmenu;
+  void *mbar, *menu;
+  GList *list;
+
+  mbar = NSA_GET_PTR (env, obj);
+  menu = NSA_GET_PTR (env, menupeer);
+
+  gdk_threads_enter ();
+  if (helpmenu != NULL)
+    {
+      list = gtk_container_children (GTK_CONTAINER (mbar));
+      while (list != NULL && list->data != helpmenu)
+        list = list->next;
+      if (list != NULL && list->data == helpmenu)
+        gtk_container_remove (GTK_CONTAINER (mbar), GTK_WIDGET (list->data));
+    }
+  helpmenu = menu;
   gdk_threads_leave ();
 }
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c
===================================================================
RCS file: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c
diff -N jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c	6 Sep 2004 16:36:13 -0000
@@ -0,0 +1,56 @@
+/* gtkmenucomponentpeer.c -- Native implementation of GtkMenuComponentPeer
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkMenuComponentPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuComponentPeer_dispose
+  (JNIEnv *env, jobject obj)
+{
+  /* For MenuComponents and its subclasses, the widgets are
+     automatically destroyed by Gtk when the parent MenuBar
+     is removed from the Frame. So we avoid the widget
+     destruction in GtkGenericPeer dispose() by overriding
+     it here. */
+     
+  /* However, references to the Java objects still exist in the
+     state tables, so we still have to remove those. */
+     
+  NSA_DEL_GLOBAL_REF (env, obj);
+  NSA_DEL_PTR (env, obj);  
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c	6 Sep 2004 16:36:13 -0000
@@ -41,18 +41,16 @@
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 
 static void item_activate (GtkMenuItem *item __attribute__((unused)),
-                           jobject *peer_obj);
+                           jobject peer_obj);
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
   (JNIEnv *env, jobject obj, jstring label)
 {
   GtkWidget *widget;
   const char *str;
-  jobject *gref;
 
   /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
-  gref = NSA_GET_GLOBAL_REF (env, obj);
 
   str = (*env)->GetStringUTFChars (env, label, NULL);
 
@@ -63,10 +61,6 @@
   else
     widget = gtk_menu_item_new_with_label (str);
 
-  /* Connect activate hook */
-  g_signal_connect (G_OBJECT (widget), "activate", 
-		      GTK_SIGNAL_FUNC (item_activate), *gref);
-
   gtk_widget_show (widget);
 
   gdk_threads_leave ();
@@ -76,6 +70,34 @@
   NSA_SET_PTR (env, obj, widget);
 }
 
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr = NSA_GET_PTR (env, obj);
+  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+  g_assert (gref);
+  
+  gdk_threads_enter ();
+  
+  g_signal_connect (G_OBJECT (ptr), "activate",
+                    G_CALLBACK (item_activate), *gref);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setEnabled
+  (JNIEnv *env, jobject obj, jboolean enabled)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+  gtk_widget_set_sensitive (GTK_WIDGET (ptr), enabled);
+  gdk_threads_leave ();
+}
+
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
   (JNIEnv *env, jobject obj, jstring label)
 {
@@ -104,9 +126,9 @@
 }
 
 static void
-item_activate (GtkMenuItem *item __attribute__((unused)), jobject *peer_obj)
+item_activate (GtkMenuItem *item __attribute__((unused)), jobject peer_obj)
 {
-  (*gdk_env)->CallVoidMethod (gdk_env, *peer_obj,
+  (*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
 			      postMenuActionEventID);
 }
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkMenuPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c	6 Sep 2004 16:36:13 -0000
@@ -1,5 +1,5 @@
 /* gtkmenupeer.c -- Native implementation of GtkMenuPeer
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,17 +39,6 @@
 #include "gtkpeer.h"
 #include "gnu_java_awt_peer_gtk_GtkMenuPeer.h"
 
-static void
-accel_attach (GtkMenuItem *menu_item,
-	      gpointer *user_data __attribute__((unused)))
-{
-  GtkAccelGroup *accel;
-
-  accel = gtk_menu_get_accel_group (GTK_MENU (menu_item->submenu));
-  _gtk_accel_group_attach (accel, 
-    G_OBJECT (gtk_widget_get_toplevel (GTK_WIDGET(menu_item))));
-}
-
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_setupAccelGroup
   (JNIEnv *env, jobject obj, jobject parent)
 {
@@ -62,14 +51,6 @@
     {
       gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu), 
 				gtk_accel_group_new ());
-
-      if (GTK_WIDGET_REALIZED (GTK_WIDGET (ptr1)))
-	accel_attach (GTK_MENU_ITEM (ptr1), NULL);
-      else
-	g_signal_connect (G_OBJECT (ptr1),
-			    "realize",
-			    GTK_SIGNAL_FUNC (accel_attach), 
-			    NULL);
     }
   else
     {
@@ -89,7 +70,7 @@
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create
   (JNIEnv *env, jobject obj, jstring label)
 {
-  GtkWidget *menu_title, *menu;
+  GtkWidget *menu_title, *menu, *toplevel;
   const char *str;
 
   /* Create global reference and save it for future use */
@@ -101,10 +82,21 @@
   
   menu = gtk_menu_new ();
   
-  menu_title = gtk_menu_item_new_with_label (str);
+  if (str != NULL)
+    menu_title = gtk_menu_item_new_with_label (str);
+  else
+    menu_title = gtk_menu_item_new();
+
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_title), menu);
 
-  gtk_widget_show (menu);
+  /* Allow this menu to grab the pointer. */
+  toplevel = gtk_widget_get_toplevel (menu);
+  if (GTK_IS_WINDOW (toplevel))
+    {
+      gtk_window_group_add_window (global_gtk_window_group,
+                                   GTK_WINDOW(toplevel));
+    }
+
   gtk_widget_show (menu_title);
 
   NSA_SET_PTR (env, obj, menu_title);
@@ -114,24 +106,42 @@
   (*env)->ReleaseStringUTFChars (env, label, str);
 }
 
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addTearOff
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr1;
+  GtkWidget *menu, *item;
+
+  ptr1 = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (ptr1));
+  item = gtk_tearoff_menu_item_new ();
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+  gtk_widget_show (item);
+
+  gdk_threads_leave ();
+}
+
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem
   (JNIEnv *env, jobject obj, jobject menuitempeer, jint key, jboolean shift)
 {
   void *ptr1, *ptr2;
-  GtkMenu *menu;
+  GtkWidget *menu;
 
   ptr1 = NSA_GET_PTR (env, obj);
   ptr2 = NSA_GET_PTR (env, menuitempeer);
 
   gdk_threads_enter ();
 
-  menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
-  gtk_menu_append (menu, GTK_WIDGET (ptr2));
+  menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
+  gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));
 
   if (key)
     {
       gtk_widget_add_accelerator (GTK_WIDGET (ptr2), "activate",
-				  gtk_menu_get_accel_group (menu), key, 
+				  gtk_menu_get_accel_group (GTK_MENU (menu)), key, 
 				  (GDK_CONTROL_MASK
 				   | ((shift) ? GDK_SHIFT_MASK : 0)), 
 				  GTK_ACCEL_VISIBLE);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c,v
retrieving revision 1.4
diff -u -r1.4 gnu_java_awt_peer_gtk_GtkPanelPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c	13 Dec 2003 01:15:47 -0000	1.4
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c	6 Sep 2004 16:36:13 -0000
@@ -53,19 +53,13 @@
   
   widget = gtk_layout_new (NULL, NULL);
 
+  GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+
   gdk_threads_leave ();
 
   NSA_SET_PTR (env, obj, widget);
 }
 
-typedef struct _GtkLayoutChild   GtkLayoutChild;
-
-struct _GtkLayoutChild {
-  GtkWidget *widget;
-  gint x;
-  gint y;
-};
-
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectJObject
   (JNIEnv *env, jobject obj)
@@ -80,59 +74,3 @@
 
   gdk_threads_leave ();
 }
-
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectSignals
-  (JNIEnv *env, jobject obj)
-{
-  void *ptr = NSA_GET_PTR (env, obj);
-  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
-  g_assert (gref);
-
-  gdk_threads_enter ();
-  gtk_widget_realize (GTK_WIDGET (ptr));
-
-  /* FIXME: If we don't need this then remove this method. */
-/*    g_signal_connect (G_OBJECT (ptr), "size_request", GTK_SIGNAL_FUNC (sr), */
-/*  		      NULL); */
-  gdk_threads_leave ();
-
-  /* Connect the superclass signals.  */
-  Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, obj);
-}
-
-/* FIXME: The following doesn't seem to be used.
-   Is not declared as a native function in GtkPanelPeer.java */
-/*
- * Make a new panel.
- */
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkPanelPeer_gtkPanelNew
-    (JNIEnv *env, jobject obj, jobject parent_obj)
-{
-  GtkWidget *layout;
-  void *parent;
-
-  /* Create global reference and save it for future use */
-  NSA_SET_GLOBAL_REF (env, obj);
-
-  parent = NSA_GET_PTR (env, parent_obj);
-
-  gdk_threads_enter ();
-
-  layout = gtk_layout_new (NULL, NULL);
-  
-  set_parent (layout, GTK_CONTAINER (parent));
-
-  gtk_widget_realize (layout);
-
-  connect_awt_hook (env, obj, 1, GTK_LAYOUT (layout)->bin_window);
-
-  set_visible (layout, 1);
-
-  gdk_threads_leave ();
-
-  NSA_SET_PTR (env, obj, layout);
-}
-
-
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c	8 Oct 2003 15:49:33 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c	6 Sep 2004 16:36:13 -0000
@@ -1,5 +1,5 @@
 /* gtkpopupmenupeer.c -- Native implementation of GtkPopupMenuPeer
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -45,7 +45,7 @@
   gint y;
 };
 
-void 
+static void 
 menu_pos (GtkMenu *menu __attribute__((unused)),
 	  gint *x, gint *y,
 	  gboolean *push_in,
@@ -72,7 +72,7 @@
   
   gdk_threads_enter ();
   gtk_menu_popup (GTK_MENU (GTK_MENU_ITEM (ptr)->submenu), 
-		  NULL, NULL, menu_pos, p, 3, time);
+		  NULL, NULL, menu_pos, p, 0, time);
   gdk_threads_leave ();
 
   g_free (p);
@@ -91,7 +91,10 @@
   gdk_threads_enter ();
   menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
   gtk_menu_set_accel_group (menu, gtk_accel_group_new ());
+  /* FIXME: update this to use GTK-2.4 GtkActions. */
+#if 0
   _gtk_accel_group_attach (gtk_menu_get_accel_group (menu),
 			   G_OBJECT (gtk_widget_get_toplevel (ptr2)));
+#endif
   gdk_threads_leave ();
 }
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c,v
retrieving revision 1.6
diff -u -r1.6 gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c	13 Dec 2003 01:15:47 -0000	1.6
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c	6 Sep 2004 16:36:13 -0000
@@ -40,72 +40,14 @@
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 #include "gnu_java_awt_peer_gtk_GtkScrollbarPeer.h"
 
-struct range_scrollbar
-{
-  GtkRange *range;
-  jobject *scrollbar;
-};
-
-static void 
-post_change_event (GtkRange *range,
-		   struct range_scrollbar *rs)
-{
-  GtkAdjustment *adj;
-  adj = gtk_range_get_adjustment (range);
-  (*gdk_env)->CallVoidMethod (gdk_env, *(rs->scrollbar), postAdjustmentEventID,
-			      AWT_ADJUSTMENT_TRACK, (jint) adj->value);
-  
-}
-
-static void 
-post_adjustment_event (GtkRange *range, GtkScrollType scroll, 
-		       struct range_scrollbar *rs)
-{
-  jint type;
-  GtkAdjustment *adj;
-
-  adj = gtk_range_get_adjustment (range);
-
-  switch (scroll)
-    {
-    case GTK_SCROLL_STEP_UP:
-    case GTK_SCROLL_STEP_RIGHT:
-    case GTK_SCROLL_STEP_FORWARD:
-      type = AWT_ADJUSTMENT_UNIT_INCREMENT;
-      break;
-    case GTK_SCROLL_STEP_DOWN:
-    case GTK_SCROLL_STEP_LEFT:
-    case GTK_SCROLL_STEP_BACKWARD:
-      type = AWT_ADJUSTMENT_UNIT_DECREMENT;
-      break;
-    case GTK_SCROLL_PAGE_UP:
-    case GTK_SCROLL_PAGE_RIGHT:
-    case GTK_SCROLL_PAGE_FORWARD:
-      type = AWT_ADJUSTMENT_BLOCK_INCREMENT;
-      break;
-    case GTK_SCROLL_PAGE_DOWN:
-    case GTK_SCROLL_PAGE_LEFT:
-    case GTK_SCROLL_PAGE_BACKWARD:
-      type = AWT_ADJUSTMENT_BLOCK_DECREMENT;
-      break;
-    case GTK_SCROLL_JUMP:
-    case GTK_SCROLL_NONE:  /* Apparently generated when slider is dragged. */
-      type = AWT_ADJUSTMENT_TRACK;
-      break;
-    default: /* Can this happen?  If so, is this right? */
-      return;
-    }
-  
-  (*gdk_env)->CallVoidMethod (gdk_env, *(rs->scrollbar), postAdjustmentEventID,
-			      type, (jint) adj->value);
-}
+static void post_change_event (GtkRange *range, jobject peer);
 
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create
 (JNIEnv *env, jobject obj, jint orientation, jint value, 
  jint min, jint max, jint step_incr, jint page_incr, jint visible_amount)
 {
-  GtkWidget *sb;
+  GtkWidget *scrollbar;
   GtkObject *adj;
 
   /* Create global reference and save it for future use */
@@ -113,16 +55,26 @@
 
   gdk_threads_enter ();
   
-  adj = gtk_adjustment_new (value, min, max, 
-			    step_incr, page_incr, 
-			    visible_amount);
+  adj = gtk_adjustment_new ((gdouble) value,
+                            (gdouble) min,
+                            (gdouble) max,
+			    (gdouble) step_incr,
+                            (gdouble) page_incr,
+			    (gdouble) visible_amount);
 
-  sb = (orientation) ? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj)) :
+  scrollbar = (orientation) ? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj)) :
                        gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
 
+  GTK_RANGE (scrollbar)->round_digits = 0;
+  /* These calls seem redundant but they are not.  They clamp values
+     so that the slider's entirety is always between the two
+     steppers. */
+  gtk_range_set_range (GTK_RANGE (scrollbar), (gdouble) min, (gdouble) max);
+  gtk_range_set_value (GTK_RANGE (scrollbar), (gdouble) value);
+
   gdk_threads_leave ();
 
-  NSA_SET_PTR (env, obj, sb);
+  NSA_SET_PTR (env, obj, scrollbar);
 }
 
 JNIEXPORT void JNICALL
@@ -137,7 +89,7 @@
 
   gtk_widget_realize (GTK_WIDGET (ptr));
 
-  connect_awt_hook (env, obj, 1, GTK_SCROLLBAR (ptr)->range);
+  connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window);
 
   gdk_threads_leave ();
 }
@@ -146,27 +98,14 @@
 Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals
   (JNIEnv *env, jobject obj)
 {
-  struct range_scrollbar *rs;
   void *ptr = NSA_GET_PTR (env, obj);
   jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
   g_assert (gref);
 
-  rs = (struct range_scrollbar *) malloc (sizeof (struct range_scrollbar));
-
   gdk_threads_enter ();
 
-  gtk_widget_realize (GTK_WIDGET (ptr));
-
-  rs->range = GTK_RANGE (ptr);
-  rs->scrollbar = gref;
-
-  g_signal_connect (G_OBJECT (GTK_RANGE (ptr)), 
-		      "move-slider", 
-		      GTK_SIGNAL_FUNC (post_adjustment_event), rs);
-
-  g_signal_connect (G_OBJECT (GTK_RANGE (ptr)), 
-		      "value-changed", 
-		      GTK_SIGNAL_FUNC (post_change_event), rs);
+  g_signal_connect (G_OBJECT (ptr), "value-changed",
+                    G_CALLBACK (post_change_event), *gref);
 
   gdk_threads_leave ();
 
@@ -186,8 +125,8 @@
 
   gdk_threads_enter ();
 
-  adj = GTK_RANGE (ptr)->adjustment;
-  adj->step_increment = amount;
+  adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+  adj->step_increment = (gdouble) amount;
   gtk_adjustment_changed (adj);
 
   gdk_threads_leave ();
@@ -204,8 +143,8 @@
 
   gdk_threads_enter ();
 
-  adj = GTK_RANGE (ptr)->adjustment;
-  adj->page_increment = amount;
+  adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+  adj->page_increment = (gdouble) amount;
   gtk_adjustment_changed (adj);
 
   gdk_threads_leave ();
@@ -222,12 +161,22 @@
 
   gdk_threads_enter ();
 
-  adj = GTK_RANGE (ptr)->adjustment;
-  adj->value = value;
-  adj->page_size = visible;
-  adj->lower = min;
-  adj->upper = max;
+  adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+  adj->page_size = (gdouble) visible;
+
+  gtk_range_set_range (GTK_RANGE (ptr), (gdouble) min, (gdouble) max);
+  gtk_range_set_value (GTK_RANGE (ptr), (gdouble) value);
+
   gtk_adjustment_changed (adj);
 
   gdk_threads_leave ();
 }
+
+static void
+post_change_event (GtkRange *range, jobject peer)
+{
+  GtkAdjustment *adj;
+  adj = gtk_range_get_adjustment (range);
+  (*gdk_env)->CallVoidMethod (gdk_env, peer, postAdjustmentEventID,
+                              AWT_ADJUSTMENT_TRACK, (jint) adj->value);
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c,v
retrieving revision 1.11
diff -u -r1.11 gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c	13 Jan 2004 20:58:33 -0000	1.11
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c	6 Sep 2004 16:36:13 -0000
@@ -54,6 +54,8 @@
 
   text = gtk_text_view_new ();
   gtk_widget_set_size_request (text, textview_width, textview_height);
+  gtk_text_view_set_cursor_visible(text, TRUE);
+
   gtk_widget_show (text);
 
   sw = gtk_scrolled_window_new (NULL, NULL);
@@ -156,7 +158,7 @@
   gdk_threads_enter();
 
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
 
   if (style & AWT_STYLE_BOLD)
     pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
@@ -164,7 +166,7 @@
   if (style & AWT_STYLE_ITALIC)
     pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
 
-  gtk_widget_modify_font (GTK_WIDGET(text), font_desc);
+  gtk_widget_modify_font (GTK_WIDGET (text), font_desc);
 
   pango_font_description_free (font_desc);
 
@@ -173,6 +175,24 @@
   (*env)->ReleaseStringUTFChars (env, name, font_name);
 }
 
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+  GtkWidget *text;
+
+  ptr = NSA_GET_PTR (env, obj);
+  
+  gdk_threads_enter ();
+
+  text = GTK_WIDGET (TEXT_FROM_SW (ptr));
+
+  gtk_widget_grab_focus (text);
+
+  gdk_threads_leave ();
+}
+
 JNIEXPORT jint JNICALL
 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight
   (JNIEnv *env, jobject obj)
@@ -188,9 +208,12 @@
   gdk_threads_enter ();
   sw = GTK_SCROLLED_WINDOW (ptr);
 
-  gtk_widget_size_request (sw->hscrollbar, &requisition);
-  gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
-  height = requisition.height + spacing;
+  if (sw)
+    {
+      gtk_widget_size_request (sw->hscrollbar, &requisition);
+      gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+      height = requisition.height + spacing;
+    }
 
   gdk_threads_leave ();
 
@@ -212,9 +235,12 @@
   gdk_threads_enter ();
   sw = GTK_SCROLLED_WINDOW (ptr);
 
-  gtk_widget_size_request (sw->vscrollbar, &requisition);
-  gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
-  width = requisition.width + spacing;
+  if (sw)
+    {
+      gtk_widget_size_request (sw->vscrollbar, &requisition);
+      gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+      width = requisition.width + spacing;
+    }
 
   gdk_threads_leave ();
 
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c,v
retrieving revision 1.11
diff -u -r1.11 gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c	13 Dec 2003 01:15:47 -0000	1.11
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c	6 Sep 2004 16:36:13 -0000
@@ -1,5 +1,5 @@
 /* gtktextcomponentpeer.c -- Native implementation of GtkTextComponentPeer
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,10 +40,6 @@
 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
 #include "gnu_java_awt_peer_gtk_GtkTextComponentPeer.h"
 
-static void textcomponent_commit_cb (GtkIMContext *context,
-                                 const gchar  *str,
-                                 jobject peer);
-
 static void textcomponent_changed_cb (GtkEditable *editable,
                                   jobject peer);
 
@@ -61,9 +57,6 @@
 
   if (GTK_IS_ENTRY(ptr))
     {
-      g_signal_connect (GTK_ENTRY (ptr)->im_context, "commit",
-                        G_CALLBACK (textcomponent_commit_cb), *gref);
-
       g_signal_connect (GTK_EDITABLE (ptr), "changed",
                         G_CALLBACK (textcomponent_changed_cb), *gref);
 
@@ -85,9 +78,6 @@
 
       if (text)
 	{
-          g_signal_connect (text->im_context, "commit",
-                            G_CALLBACK (textcomponent_commit_cb), *gref);
-
           buf = gtk_text_view_get_buffer (text);
           if (buf)
             g_signal_connect (buf, "changed",
@@ -112,8 +102,8 @@
 {
   void *ptr;
   int pos = 0;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextMark *mark;
   GtkTextIter iter;
@@ -157,10 +147,13 @@
   (JNIEnv *env, jobject obj, jint pos)
 {
   void *ptr;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextIter iter;
+  GtkTextMark *oldmark;
+  GtkTextIter olditer;
+  int oldpos;
 
   ptr = NSA_GET_PTR (env, obj);
 
@@ -184,8 +177,24 @@
       if (text)
 	{
 	  buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+	  /* Save old position. */
+	  oldmark = gtk_text_buffer_get_insert (buf);
+	  gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
+	  oldpos = gtk_text_iter_get_offset (&olditer);
+
+	  /* Move to new position. */
 	  gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
 	  gtk_text_buffer_place_cursor (buf, &iter);
+
+	  /* Scroll to new position. Alignment is determined
+	     comparing the new position to the old position. */
+	  if (oldpos > pos)
+	    gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
+	                                  &iter, 0, TRUE, 0, 0);
+	  else if (oldpos < pos)
+	    gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
+	                                  &iter, 0, TRUE, 1, 1);
 	}
     }
 
@@ -198,8 +207,8 @@
 {
   void *ptr;
   int pos = 0;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextIter start;
   GtkTextIter end;
@@ -255,8 +264,8 @@
 {
   void *ptr;
   int pos = 0;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextIter start;
   GtkTextIter end;
@@ -311,8 +320,8 @@
   (JNIEnv *env, jobject obj, jint start, jint end)
 {
   void *ptr;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextIter iter;
 
@@ -357,8 +366,8 @@
   (JNIEnv *env, jobject obj, jboolean state)
 {
   void *ptr;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
 
   ptr = NSA_GET_PTR (env, obj);
 
@@ -396,8 +405,8 @@
   void *ptr;
   char *contents = NULL;
   jstring jcontents;
-  GtkEditable *editable;    // type of GtkEntry    (TextField)
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkEditable *editable;
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
   GtkTextIter start, end;
 
@@ -444,7 +453,7 @@
 {
   void *ptr;
   const char *str;
-  GtkWidget *text = NULL;   // type of GtkTextView (TextArea)
+  GtkWidget *text = NULL;
   GtkTextBuffer *buf;
 
   ptr = NSA_GET_PTR (env, obj);
@@ -480,28 +489,6 @@
 }
 
 static void
-textcomponent_commit_cb (GtkIMContext *context __attribute__((unused)),
-                         const gchar  *str,
-                         jobject peer)
-{
-  /* str is a \0-terminated UTF-8 encoded character. */
-  gunichar2 *jc = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
-  GdkEvent *event = gtk_get_current_event ();
-
-  if (jc)
-    (*gdk_env)->CallVoidMethod (gdk_env, peer,
-                                postKeyEventID,
-                                (jint) AWT_KEY_TYPED,
-                                (jlong) event->key.time,
-                                keyevent_state_to_awt_mods (event),
-                                VK_UNDEFINED,
-                                (jchar) jc[0],
-                                AWT_KEY_LOCATION_UNKNOWN);
-  g_free (jc);
-  gdk_event_free (event);
-}
-
-static void
 textcomponent_changed_cb (GtkEditable *editable __attribute__((unused)),
 			  jobject peer)
 {
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c,v
retrieving revision 1.9
diff -u -r1.9 gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c	13 Dec 2003 01:15:47 -0000	1.9
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c	6 Sep 2004 16:36:13 -0000
@@ -39,48 +39,115 @@
 #include "gtkpeer.h"
 #include "gnu_java_awt_peer_gtk_GtkTextFieldPeer.h"
 
+static jint
+get_border_width (GtkWidget *entry);
+
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_create
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jobject obj, jint text_width)
 {
-  GtkWidget *widget;
+  GtkWidget *entry;
 
   /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
-  
-  widget = gtk_entry_new ();
+
+  entry = gtk_entry_new ();
+  gtk_widget_set_size_request (entry,
+			       text_width + 2 * get_border_width (entry), -1);
 
   gdk_threads_leave ();
 
-  NSA_SET_PTR (env, obj, widget);
+  NSA_SET_PTR (env, obj, entry);
 }
 
 JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetSize
-  (JNIEnv *env, jobject obj, jintArray jdims)
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetBackground
+  (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
 {
+  GdkColor color;
   void *ptr;
-  jint *dims;
-  GtkRequisition myreq;
-  GtkWidget *entry;
-  
+
   ptr = NSA_GET_PTR (env, obj);
-  dims = (*env)->GetIntArrayElements (env, jdims, 0);  
-  
+
+  color.red = (red / 255.0) * 65535;
+  color.green = (green / 255.0) * 65535;
+  color.blue = (blue / 255.0) * 65535;
+
   gdk_threads_enter ();
-  
-  entry = GTK_WIDGET (ptr);
-  gtk_widget_size_request(entry, &myreq);
-  dims[0]=myreq.width;
-  dims[1]=myreq.height;
-  
+
+  gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetForeground
+  (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+  GdkColor color;
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  color.red = (red / 255.0) * 65535;
+  color.green = (green / 255.0) * 65535;
+  color.blue = (blue / 255.0) * 65535;
+
+  gdk_threads_enter ();
+
+  gtk_widget_modify_text (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
+  gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_SELECTED, &color);
+
   gdk_threads_leave ();
-  
-  (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
 }
 
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetBorderWidth
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+  int border_width = 0;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  border_width = get_border_width (GTK_WIDGET (ptr));
+
+  gdk_threads_leave ();
+
+  return border_width;
+}
+
+/* GTK hard-codes this value.  It is the space between a GtkEntry's
+   frame and its text. */
+#define INNER_BORDER 2
+
+static jint
+get_border_width (GtkWidget *entry)
+{
+  gint focus_width;
+  gboolean interior_focus;
+  int x_border_width = INNER_BORDER;
+
+  gtk_widget_style_get (entry,
+			"interior-focus", &interior_focus,
+			"focus-line-width", &focus_width,
+			NULL);
+
+  if (GTK_ENTRY (entry)->has_frame)
+    x_border_width += entry->style->xthickness;
+
+  if (!interior_focus)
+    x_border_width += focus_width;
+
+  return x_border_width;
+}
+
+#undef INNER_BORDER
+
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
   (JNIEnv *env, jobject obj, jchar c)
@@ -93,10 +160,12 @@
   gdk_threads_enter ();
 
   entry = GTK_ENTRY (ptr);
-    
-  if (c!=0)
+
+  if (c != 0)
     {
-/*        gtk_entry_set_echo_char (entry, c); */
+      /* FIXME: use gtk_entry_set_invisible_char (GtkEntry *entry,
+	 gunichar ch) here.  That means we must convert from jchar
+	 (utf16) to gunichar (ucs4). */
       gtk_entry_set_visibility (entry, FALSE);
     }
   else
@@ -122,7 +191,7 @@
   gdk_threads_enter();
 
   font_desc = pango_font_description_from_string (font_name);
-  pango_font_description_set_size (font_desc, size * PANGO_SCALE);
+  pango_font_description_set_size (font_desc, size * dpi_conversion_factor);
 
   if (style & AWT_STYLE_BOLD)
     pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_awt_peer_gtk_GtkToolkit.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c	8 Oct 2003 15:49:33 -0000	1.2
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c	6 Sep 2004 16:36:13 -0000
@@ -39,6 +39,8 @@
 #include "gtkpeer.h"
 #include "gnu_java_awt_peer_gtk_GtkToolkit.h"
 
+static jint gdk_color_to_java_color (GdkColor color);
+
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkToolkit_beep
   (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
@@ -88,3 +90,70 @@
   return res;
 }
 
+#define CONVERT(type, state) \
+  gdk_color_to_java_color (style->type[GTK_STATE_ ## state])
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_loadSystemColors
+  (JNIEnv *env, jobject obj __attribute__((unused)),
+   jintArray jcolors)
+{
+  jint *colors;
+  GtkStyle *style;
+
+  colors = (*env)->GetIntArrayElements (env, jcolors, 0);
+
+  gdk_threads_enter ();
+
+  style = gtk_widget_get_default_style ();
+
+  colors[AWT_DESKTOP]                 = CONVERT (bg, SELECTED);
+  colors[AWT_ACTIVE_CAPTION]          = CONVERT (bg, SELECTED);
+  colors[AWT_ACTIVE_CAPTION_TEXT]     = CONVERT (text, SELECTED);
+  colors[AWT_ACTIVE_CAPTION_BORDER]   = CONVERT (fg, NORMAL);
+  colors[AWT_INACTIVE_CAPTION]        = CONVERT (base, INSENSITIVE);
+  colors[AWT_INACTIVE_CAPTION_TEXT]   = CONVERT (fg, INSENSITIVE);
+  colors[AWT_INACTIVE_CAPTION_BORDER] = CONVERT (fg, INSENSITIVE);
+  colors[AWT_WINDOW]                  = CONVERT (bg, NORMAL);
+  colors[AWT_WINDOW_BORDER]           = CONVERT (fg, NORMAL);
+  colors[AWT_WINDOW_TEXT]             = CONVERT (fg, NORMAL);
+  colors[AWT_MENU]                    = CONVERT (bg, NORMAL);
+  colors[AWT_MENU_TEXT]               = CONVERT (fg, NORMAL);
+  colors[AWT_TEXT]                    = CONVERT (bg, NORMAL);
+  colors[AWT_TEXT_TEXT]               = CONVERT (fg, NORMAL);
+  colors[AWT_TEXT_HIGHLIGHT]          = CONVERT (bg, SELECTED);
+  colors[AWT_TEXT_HIGHLIGHT_TEXT]     = CONVERT (fg, SELECTED);
+  colors[AWT_TEXT_INACTIVE_TEXT]      = CONVERT (bg, INSENSITIVE);
+  colors[AWT_CONTROL]                 = CONVERT (bg, NORMAL);
+  colors[AWT_CONTROL_TEXT]            = CONVERT (fg, NORMAL);
+  colors[AWT_CONTROL_HIGHLIGHT]       = CONVERT (base, ACTIVE);
+  colors[AWT_CONTROL_LT_HIGHLIGHT]    = CONVERT (bg, PRELIGHT);
+  colors[AWT_CONTROL_SHADOW]          = CONVERT (bg, ACTIVE);
+  colors[AWT_CONTROL_DK_SHADOW]       = CONVERT (fg, INSENSITIVE);
+  colors[AWT_SCROLLBAR]               = CONVERT (base, INSENSITIVE);
+  colors[AWT_INFO]                    = CONVERT (bg, NORMAL);
+  colors[AWT_INFO_TEXT]               = CONVERT (fg, NORMAL);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseIntArrayElements(env, jcolors, colors, 0);
+}
+
+#undef CONVERT
+
+static jint
+gdk_color_to_java_color (GdkColor gdk_color)
+{
+  guchar red;
+  guchar green;
+  guchar blue;
+  float factor;
+
+  factor = 255.0 / 65535.0;
+
+  red   = (float) gdk_color.red   * factor;
+  green = (float) gdk_color.green * factor;
+  blue  = (float) gdk_color.blue  * factor;
+
+  return (jint) (0xff000000 | (red << 16) | (green << 8) | blue);
+}
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c,v
retrieving revision 1.12
diff -u -r1.12 gnu_java_awt_peer_gtk_GtkWindowPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c	13 Jan 2004 20:54:46 -0000	1.12
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c	6 Sep 2004 16:36:14 -0000
@@ -44,27 +44,39 @@
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
 
+/* FIXME: we're currently seeing the double-activation that occurs
+   with metacity and GTK.  See
+   http://bugzilla.gnome.org/show_bug.cgi?id=140977 for details. */
+
 static void window_get_frame_extents (GtkWidget *window,
                                       int *top, int *left,
                                       int *bottom, int *right);
 
 static void request_frame_extents (GtkWidget *window);
 
-static int property_notify_predicate (Display *xdisplay,
-                                      XEvent  *event,
-                                      XPointer window_id);
+static Bool property_notify_predicate (Display *display,
+                                       XEvent  *xevent,
+                                       XPointer arg);
+
+static GtkLayout *find_layout (GtkWindow *window);
 
 static void window_delete_cb (GtkWidget *widget, GdkEvent *event,
 			      jobject peer);
 static void window_destroy_cb (GtkWidget *widget, GdkEvent *event,
 			       jobject peer);
 static void window_show_cb (GtkWidget *widget, jobject peer);
+static void window_active_state_change_cb (GtkWidget *widget,
+                                           GParamSpec *pspec,
+                                           jobject peer);
+static void window_focus_state_change_cb (GtkWidget *widget,
+                                                    GParamSpec *pspec,
+                                                    jobject peer);
 static gboolean window_focus_in_cb (GtkWidget * widget,
-				    GdkEventFocus *event,
-				    jobject peer);
+                                    GdkEventFocus *event,
+                                    jobject peer);
 static gboolean window_focus_out_cb (GtkWidget * widget,
-				     GdkEventFocus *event,
-				     jobject peer);
+                                     GdkEventFocus *event,
+                                     jobject peer);
 static gboolean window_window_state_cb (GtkWidget *widget,
 					GdkEvent *event,
 					jobject peer);
@@ -73,10 +85,6 @@
 					    GdkEventProperty *event,
 					    jobject peer);
 
-/*
- * Make a new window.
- */
-
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create 
   (JNIEnv *env, jobject obj, jint type, jboolean decorated,
@@ -96,7 +104,6 @@
   insets = (*env)->GetIntArrayElements (env, jinsets, 0);
   insets[0] = insets[1] = insets[2] = insets[3] = 0;
 
-  /* Create global reference and save it for future use */
   NSA_SET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
@@ -155,6 +162,56 @@
 }
 
 JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetTitle
+  (JNIEnv *env, jobject obj, jstring title)
+{
+  const char *c_title;
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  c_title = (*env)->GetStringUTFChars (env, title, NULL);
+
+  gdk_threads_enter ();
+
+  gtk_window_set_title (GTK_WINDOW (ptr), c_title);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseStringUTFChars (env, title, c_title);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetResizable
+  (JNIEnv *env, jobject obj, jboolean resizable)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  gtk_window_set_policy (GTK_WINDOW (ptr), resizable, resizable, FALSE);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetModal
+  (JNIEnv *env, jobject obj, jboolean modal)
+{
+  void *ptr;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  gtk_window_set_modal (GTK_WINDOW (ptr), modal);
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible
   (JNIEnv *env, jobject obj, jboolean visible)
 {
@@ -179,39 +236,22 @@
   (JNIEnv *env, jobject obj)
 {
   void *ptr;
-  GtkWidget* vbox, *layout;
-  GList* children;
+  GtkLayout *layout;
 
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
 
-  children = gtk_container_get_children(GTK_CONTAINER(ptr));
-  vbox = children->data;
-
-  if(!GTK_IS_VBOX(vbox))
-    {
-      printf("*** this is not a vbox\n");
-    }
-  children = gtk_container_get_children(GTK_CONTAINER(vbox));
-  layout = children->data;
+  layout = find_layout (GTK_WINDOW (ptr));
 
-  if(!GTK_IS_LAYOUT(layout))
-    {
-      printf("*** widget is not a layout ***");
-    }
+  gtk_widget_realize (GTK_WIDGET (layout));
 
-  gtk_widget_realize (layout);
-
-  connect_awt_hook (env, obj, 1, GTK_LAYOUT (layout)->bin_window);
+  connect_awt_hook (env, obj, 1, layout->bin_window);
 
   gtk_widget_realize (ptr);
 
   connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window);
 
-  g_signal_connect (G_OBJECT (ptr), "property-notify-event",
-		    G_CALLBACK (window_property_changed_cb), obj);
-
   gdk_threads_leave ();
 }
 
@@ -219,14 +259,24 @@
 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
   (JNIEnv *env, jobject obj)
 {
-  void *ptr = NSA_GET_PTR (env, obj);
-  jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
-  g_assert (gref);
+  void *ptr;
+  jobject *gref;
+  GtkLayout *layout;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gref = NSA_GET_GLOBAL_REF (env, obj);
 
   gdk_threads_enter ();
 
   gtk_widget_realize (ptr);
 
+  /* Receive events from the GtkLayout too */
+  layout = find_layout (GTK_WINDOW (ptr));
+
+  g_signal_connect (G_OBJECT (layout), "event",
+		    G_CALLBACK (pre_event_handler), *gref);
+
   /* Connect signals for window event support. */
   g_signal_connect (G_OBJECT (ptr), "delete-event",
 		    G_CALLBACK (window_delete_cb), *gref);
@@ -237,15 +287,24 @@
   g_signal_connect (G_OBJECT (ptr), "show",
 		    G_CALLBACK (window_show_cb), *gref);
 
+  g_signal_connect (G_OBJECT (ptr), "notify::is-active",
+  		    G_CALLBACK (window_active_state_change_cb), *gref);
+
+  g_signal_connect (G_OBJECT (ptr), "notify::has-toplevel-focus",
+  		    G_CALLBACK (window_focus_state_change_cb), *gref);
+
   g_signal_connect (G_OBJECT (ptr), "focus-in-event",
-		    G_CALLBACK (window_focus_in_cb), *gref);
+                    G_CALLBACK (window_focus_in_cb), *gref);
 
   g_signal_connect (G_OBJECT (ptr), "focus-out-event",
-		    G_CALLBACK (window_focus_out_cb), *gref);
+                    G_CALLBACK (window_focus_out_cb), *gref);
 
   g_signal_connect (G_OBJECT (ptr), "window-state-event",
 		    G_CALLBACK (window_window_state_cb), *gref);
 
+  g_signal_connect (G_OBJECT (ptr), "property-notify-event",
+		    G_CALLBACK (window_property_changed_cb), *gref);
+
   gdk_threads_leave ();
 
   /* Connect the superclass signals.  */
@@ -253,28 +312,6 @@
 }
 
 /*
- * Set a frame's title
- */
-
-JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setTitle
-  (JNIEnv *env, jobject obj, jstring title)
-{
-  void *ptr;
-  const char *str;
-
-  ptr = NSA_GET_PTR (env, obj);
-  
-  str = (*env)->GetStringUTFChars (env, title, NULL);
-  
-  gdk_threads_enter ();
-  gtk_window_set_title (GTK_WINDOW (ptr), str);
-  gdk_threads_leave ();
-  
-  (*env)->ReleaseStringUTFChars (env, title, str);
-}
-
-/*
  * Lower the z-level of a window. 
  */
 
@@ -348,6 +385,20 @@
 
   gdk_threads_enter ();
   gtk_window_move (GTK_WINDOW(ptr), x, y);
+  /* The call to gdk_window_move is needed in addition to the call to
+     gtk_window_move.  If gdk_window_move isn't called, then the
+     following set of operations doesn't give the expected results:
+
+     1. show a window
+     2. manually move it to another position on the screen
+     3. hide the window
+     4. reposition the window with Component.setLocation
+     5. show the window
+
+     Instead of being at the position set by setLocation, the window
+     is reshown at the position to which it was moved manually. */
+  gdk_window_move (GTK_WIDGET (ptr)->window, x, y);
+
   /* Need to change the widget's request size. */
   gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
   /* Also need to call gtk_window_resize.  If the resize is requested
@@ -358,46 +409,196 @@
 }
 
 JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer
+  (JNIEnv *env, jobject obj)
+{
+  void *wptr;
+  GtkWidget *box;
+  GtkWidget *mptr;
+  GList* children;
+
+  wptr = NSA_GET_PTR (env, obj);
+  
+  gdk_threads_enter ();
+
+  box = GTK_BIN (wptr)->child;
+  
+  children = gtk_container_get_children (GTK_CONTAINER (box));
+  
+  while (children != NULL && !GTK_IS_MENU_SHELL (children->data)) 
+  {
+    children = children->next;
+  }
+  
+  /* If there isn't a MenuBar in this Frame's list of children
+     then we can just return. */
+  if (!GTK_IS_MENU_SHELL (children->data))
+    return;
+  else
+    mptr = children->data;
+    
+  /* This will actually destroy the MenuBar. By removing it from
+     its parent, the reference count for the MenuBar widget will
+     decrement to 0. The widget will be automatically destroyed 
+     by Gtk. */
+  gtk_container_remove (GTK_CONTAINER (box), GTK_WIDGET (mptr));  
+  
+  gdk_threads_leave();
+}  
+  
+JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer
   (JNIEnv *env, jobject obj, jobject menubar)
 {
-  void *wptr, *mptr;
-  GtkBox *box;
-
-  if (!menubar) return;
+  void *wptr;
+  GtkWidget *mptr;
+  GtkWidget *box;
 
   wptr = NSA_GET_PTR (env, obj);
   mptr = NSA_GET_PTR (env, menubar);
+  
+  gdk_threads_enter ();
 
-  if (!mptr) return; /* this case should remove a menu */
+  box = GTK_BIN (wptr)->child;		    
+  gtk_box_pack_start (GTK_BOX (box), mptr, 0, 0, 0);
+ 
+  gtk_widget_show (mptr);
 
-  gdk_threads_enter ();
-  box = GTK_BOX (GTK_BIN (wptr)->child);
-  gtk_box_pack_start (box, GTK_WIDGET (mptr), 0, 0, 0);
+ 
   gdk_threads_leave ();
 }
 
 JNIEXPORT jint JNICALL
 Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
-  (JNIEnv *env, jobject obj)
+  (JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar)
+{
+  GtkWidget *ptr;
+  jint height;
+  GtkRequisition gtkreq;
+  
+  ptr = NSA_GET_PTR (env, menubar);
+
+  gdk_threads_enter ();
+  gtk_widget_size_request (ptr, &gtkreq);
+
+  height = gtkreq.height;
+  gdk_threads_leave ();
+  return height;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_moveLayout
+  (JNIEnv *env, jobject obj, jint offset)
+{
+  void* ptr;
+  GList* children;
+  GtkLayout* layout;
+  GtkWidget* widget;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  layout = find_layout (GTK_WINDOW (ptr));
+
+  children = gtk_container_get_children (GTK_CONTAINER (layout));
+  
+  while (children != NULL)
+  {
+    widget = children->data;
+    gtk_layout_move (layout, widget, widget->allocation.x,
+                     widget->allocation.y+offset);
+    children = children->next;
+  }
+  
+  gdk_threads_leave ();
+}
+  
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_gtkLayoutSetVisible
+  (JNIEnv *env, jobject obj, jboolean visible)
+{
+  void* ptr;
+  GtkLayout* layout;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  layout = find_layout (GTK_WINDOW (ptr));
+  
+  if (visible)
+    gtk_widget_show (GTK_WIDGET (layout));
+  else
+    gtk_widget_hide (GTK_WIDGET (layout));
+
+  gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImageFromDecoder
+  (JNIEnv *env, jobject obj, jobject decoder)
 {
   void *ptr;
-  GList *children;
-  jint height = 0;
+  GdkPixbufLoader *loader = NULL;
+  GdkPixbuf *pixbuf = NULL;
 
   ptr = NSA_GET_PTR (env, obj);
 
+  loader = NSA_GET_PB_PTR (env, decoder);
+  g_assert (loader != NULL);
+
   gdk_threads_enter ();
-  children = gtk_container_children (GTK_CONTAINER (GTK_BIN (ptr)->child));
-  if (g_list_length (children) == 2)
-    {
-      GtkWidget *menubar = GTK_WIDGET (children->data);
-      height = menubar->allocation.height;
 
-    }
+  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+  g_assert (pixbuf != NULL);
+
+  gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
+
   gdk_threads_leave ();
+}
 
-  return height;
+void free_pixbuf_data (guchar *pixels, gpointer data __attribute__((unused)))
+{
+  free(pixels);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImageFromData
+  (JNIEnv *env, jobject obj, jintArray pixelArray, jint width, jint height)
+{
+  void *ptr;
+  GdkPixbuf *pixbuf;
+  jint *pixels;
+  int pixels_length, i;
+  guchar *data;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  pixels = (*env)->GetIntArrayElements (env, pixelArray, 0);
+  pixels_length = (*env)->GetArrayLength (env, pixelArray);
+
+  data = malloc (sizeof (guchar) * pixels_length);
+  for (i = 0; i < pixels_length; i++)
+    data[i] = (guchar) pixels[i];
+
+  gdk_threads_enter ();
+
+  pixbuf = gdk_pixbuf_new_from_data (data,
+                                     GDK_COLORSPACE_RGB,
+                                     TRUE,
+                                     8,
+                                     width,
+                                     height,
+                                     width*4,
+                                     free_pixbuf_data,
+                                     NULL);
+
+  gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseIntArrayElements(env, pixelArray, pixels, 0);
 }
 
 static void
@@ -491,7 +692,7 @@
     }
 }
 
-static int
+static Bool
 property_notify_predicate (Display *xdisplay __attribute__((unused)),
                            XEvent  *event,
                            XPointer window_id)
@@ -502,7 +703,7 @@
       && event->xany.window == *window
       && event->xproperty.atom == extents_atom)
         return True;
-
+  else
   return False;
 }
 
@@ -538,40 +739,65 @@
 			      (jobject) NULL, (jint) 0);
 }
 
+static void
+window_active_state_change_cb (GtkWidget *widget,
+                                        GParamSpec *pspec,
+                                        jobject peer)
+{
+  /* FIXME: not sure if this is needed or not. */
+#if 0
+      if (GTK_WINDOW (widget)->is_active)
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postWindowEventID,
+                                    (jint) AWT_WINDOW_GAINED_FOCUS,
+                                    (jobject) NULL, (jint) 0);
+      else
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postWindowEventID,
+                                    (jint) AWT_WINDOW_DEACTIVATED,
+                                    (jobject) NULL, (jint) 0);
+#endif
+    }
+
+static void
+window_focus_state_change_cb (GtkWidget *widget,
+                              GParamSpec *pspec,
+                              jobject peer)
+    {
+      if (GTK_WINDOW (widget)->has_toplevel_focus)
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postWindowEventID,
+                                    (jint) AWT_WINDOW_ACTIVATED,
+                                    (jobject) NULL, (jint) 0);
+      else
+        (*gdk_env)->CallVoidMethod (gdk_env, peer,
+                                    postWindowEventID,
+                                (jint) AWT_WINDOW_DEACTIVATED,
+                                    (jobject) NULL, (jint) 0);
+    }
+
 static gboolean
-window_focus_in_cb (GtkWidget * widget __attribute__((unused)),
-		    GdkEventFocus *event __attribute__((unused)),
-		    jobject peer)
+window_focus_in_cb (GtkWidget * widget,
+                   GdkEventFocus *event,
+                   jobject peer)
 {
-  /* FIXME: when hiding then showing, we get two sets of
-     (LOST_FOCUS/DEACTIVATED, ACTIVATED/GAINED_FOCUS) events. */
   (*gdk_env)->CallVoidMethod (gdk_env, peer,
-			      postWindowEventID,
-			      (jint) AWT_WINDOW_ACTIVATED,
-			      (jobject) NULL, (jint) 0);
-
-  (*gdk_env)->CallVoidMethod (gdk_env, peer,
-			      postWindowEventID,
-			      (jint) AWT_WINDOW_GAINED_FOCUS,
-			      (jobject) NULL, (jint) 0);
-  return TRUE;
+                              postWindowEventID,
+                              (jint) AWT_WINDOW_GAINED_FOCUS,
+                              (jobject) NULL, (jint) 0);
+  return FALSE;
 }
 
 static gboolean
-window_focus_out_cb (GtkWidget * widget __attribute__((unused)),
-		     GdkEventFocus *event __attribute__((unused)),
-		     jobject peer)
+window_focus_out_cb (GtkWidget * widget,
+                    GdkEventFocus *event,
+                    jobject peer)
 {
   (*gdk_env)->CallVoidMethod (gdk_env, peer,
-			      postWindowEventID,
-			      (jint) AWT_WINDOW_LOST_FOCUS,
-			      (jobject) NULL, (jint) 0);
-
-  (*gdk_env)->CallVoidMethod (gdk_env, peer,
-			      postWindowEventID,
-			      (jint) AWT_WINDOW_DEACTIVATED,
-			      (jobject) NULL, (jint) 0);
-  return TRUE;
+                              postWindowEventID,
+                              (jint) AWT_WINDOW_LOST_FOCUS,
+                              (jobject) NULL, (jint) 0);
+  return FALSE;
 }
 
 static gboolean
@@ -675,6 +901,7 @@
 						      gtkwindowpeer,
 						      "postInsetsChangedEvent",
 						      "(IIII)V");
+      id_set = 1;
     }
 
   if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE) == event->atom
@@ -697,3 +924,26 @@
 
   return FALSE;
 }
+
+static GtkLayout *
+find_layout (GtkWindow *window)
+{
+  GList* children;
+  GtkBox* vbox;
+  GtkLayout* layout;
+
+  children = gtk_container_get_children (GTK_CONTAINER (window));
+  vbox = children->data;
+  g_assert (GTK_IS_VBOX (vbox));
+
+  children = gtk_container_get_children (GTK_CONTAINER (vbox));
+  do
+  {
+    layout = children->data;
+    children = children->next;
+  }
+  while (!GTK_IS_LAYOUT (layout) && children != NULL);
+  g_assert (GTK_IS_LAYOUT (layout));
+
+  return layout;
+}
Index: jni/gtk-peer/gthread-jni.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gthread-jni.c,v
retrieving revision 1.3
diff -u -r1.3 gthread-jni.c
--- jni/gtk-peer/gthread-jni.c	8 Oct 2003 15:49:33 -0000	1.3
+++ jni/gtk-peer/gthread-jni.c	6 Sep 2004 16:36:14 -0000
@@ -1,5 +1,5 @@
 /* gthread-jni.c -- JNI threading routines for GLIB
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,130 +40,1166 @@
 /************************************************************************/
 
 /*
- * Julian Dolby (dolby@us.ibm.com)
- * February 7, 2003
+ * @author Julian Dolby (dolby@us.ibm.com)
+ * @date February 7, 2003  implemented for GLIB v.1
+ * 
+ *
+ * @author Steven Augart 
+ * <steve+classpath at augart dot com>, <augart at watson dot ibm dot com>
+ * @date April 30, 2004 -- May 10 2004: Support new functions for Glib v.2,
+ * fix cond_wait to free and re-acquire the mutex,
+ * replaced trylock stub implementation with a full one.
  *
  *  This code implements the GThreadFunctions interface for GLIB using 
  * Java threading primitives.  All of the locking and conditional variable
  * functionality required by GThreadFunctions is implemented using the
  * monitor and wait/notify functionality of Java objects.  The thread-
- * local fucntionality uses the java.lang.ThreadLocal class. 
+ * local functionality uses the java.lang.ThreadLocal class. 
+ *
+ *  Classpath's AWT support uses GTK+ peers.  GTK+ uses GLIB.  GLIB by default
+ * uses the platform's native threading model -- pthreads in most cases.  If
+ * the Java runtime doesn't use the native threading model, then it needs this
+ * code in order to use Classpath's (GTK+-based) AWT routines.
  *
- *  This code is designed to be portable in that it makes no assumptions
+ *  This code should be portable; I believe it makes no assumptions
  * about the underlying VM beyond that it implements the JNI functionality
  * that this code uses.
  *
- *  The one piece that does not really work is trylock for mutexes.  The
- * Java locking model does not include such functionality, and I do not
- * see how to implement it without knowing something about how the VM
- * implements locking.  
+ *  Currently, use of this code is governed by the configuration option
+ * --enable-portable-native-sync.  We will soon add a VM hook so the VM can
+ * select which threading model it wants to use at run time; at that point,
+ * the configuration option will go away.
+ *
+ * The code in this file uses only JNI 1.1, except for one JNI 1.2 function:
+ * GetEnv, in the JNI Invocation API.  (There seems to be no way around using
+ * GetEnv).
+ *
+ * ACKNOWLEDGEMENT:
+ * 
+ *  I would like to thank Mark Wielaard for his kindness in spending at least
+ * six hours of his own time in reviewing this code and correcting my GNU
+ * coding and commenting style.  --Steve Augart
+ *
  *
  * NOTES:
  *
- *  I have tested it only on JikesRVM---the CVS head as of early February
- * 2003.
+ *  This code has been tested with Jikes RVM and with Kaffe.
  *
- *  Currently, use of this code is governed by the configuration option
- * --enable-portable-native-sync
+ *  This code should have proper automated unit tests.  I manually tested it
+ *  by running an application that uses AWT. --Steven Augart
  *
+ * MINOR NIT:
+ *
+ *  - Using a jboolean in the arglist to "throw()" and "rethrow()"
+ *    triggers many warnings from GCC's -Wconversion operation, because that
+ *    is not the same as the conversion (upcast to an int) that would occur in
+ *    the absence of a prototype.
+ *    
+ *    It would be very slightly more efficient to just pass the jboolean, but
+ *    is not worth the clutter of messages.  The right solution would be to
+ *    turn off the -Wconversion warning for just this file, *except* that
+ *    -Wconversion also warns you against constructs such as:
+ *        unsigned u = -1;
+ *    and that is a useful warning.  So I went from a "jboolean" to a
+ *    "gboolean"  (-Wconversion is not enabled by default for GNU Classpath,
+ *    but it is in my own CFLAGS, which, for gcc 3.3.3, read: -pipe -ggdb3 -W
+ *    -Wall -Wbad-function-cast -Wcast-align -Wpointer-arith -Wcast-qual
+ *    -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
+ *    -fkeep-static-consts -fkeep-inline-functions -Wundef -Wwrite-strings
+ *    -Wno-aggregate-return -Wmissing-noreturn -Wnested-externs -Wtrigraphs
+ *    -Wconversion -Wsign-compare -Wno-float-equal -Wmissing-format-attribute
+ *    -Wno-unreachable-code -Wdisabled-optimization )
  */
 
+#include <config.h>
+
+/************************************************************************/
+/* Configuration							*/
+/************************************************************************/
+
+/** Tracing and Reporting  **/
+#define TRACE_API_CALLS	    0	/* announce entry and exit into each method,
+				   by printing to stderr. */
+
+#define TRACE_MONITORS      0	/* Every enterMonitor() and exitMonitor() goes
+				   to stderr. */
+
+/** Trouble handling.  There is a discussion below of this.  **/ 
+#define EXPLAIN_TROUBLE	    1	/* Describe any unexpected trouble that
+				   happens.  This is a superset
+				   of EXPLAIN_BROKEN, and if set trumps an
+				   unset EXPLAIN_BROKEN.  It is not a strict
+				   superset, since at the moment there is no
+				   TROUBLE that is not also BROKEN.   
+
+				   Use criticalMsg() to describe the problem.
+				 */
+
+#define EXPLAIN_BROKEN	    1	/* Describe trouble that is serious enough to
+				   be BROKEN.  (Right now all trouble is at
+				   least BROKEN.) */
+
+/* There is no EXPLAIN_BADLY_BROKEN definition.  We always explain
+   BADLY_BROKEN trouble, since there is no other way to report it.  */
+
+
+/** Error Handling  **/
+#define DIE_IF_BROKEN	    1	/* Dies if serious trouble happens.  There is
+				   really no non-serious trouble, except
+				   possibly problems that arise during
+				   pthread_create, which are reported by a
+				   GError.
+
+				   If you do not set DIE_IF_BROKEN, then
+				   trouble will raise a Java RuntimeException.
+				   We probably do want to die right away,
+				   since anything that's BROKEN really
+				   indicates a programming error or a
+				   system-wide error, and that's what the glib
+				   documentation says you should do in case of
+				   that kind of error in a glib-style
+				   function.  But it does work to turn this
+				   off.  */
+
+#if  DIE_IF_BROKEN
+#define DIE_IF_BADLY_BROKEN 1	/* DIE_IF_BROKEN implies DIE_IF_BADLY_BROKEN */
+#else
+#define DIE_IF_BADLY_BROKEN 1	/* Die if the system is badly broken --
+				   that is, if we have further trouble while
+				   attempting to throw an exception
+				   upwards, or if we are unable to generate
+				   one of the classes we'll need in order to
+				   throw wrapped exceptions upward.
+
+				   If unset, we will print a warning message,
+				   and limp along anyway.  Not that the system
+				   is likely to work.  */
+#endif
+
+/** Performance tuning parameters **/
+
+#define ENABLE_EXPENSIVE_ASSERTIONS 0	/* Enable expensive assertions? */
+
+#define DELETE_LOCAL_REFS   1	/* Whether to delete local references.   
+
+				   JNI only guarantees that there wil be 16
+				   available.  (Jikes RVM provides an number
+				   only limited by VM memory.)
+
+				   Jikes RVM will probably perform faster if
+				   this is turned off, but other VMs may need
+				   this to be turned on in order to perform at
+				   all, or might need it if things change.
+
+				   Remember, we don't know how many of those
+				   local refs might have already been used up
+				   by higher layers of JNI code that end up
+				   calling g_thread_self(),
+				   g_thread_set_private(), and so on.
+
+				   We set this to 1 for GNU Classpath, since
+				   one of our principles is "always go for the
+				   most robust implementation" */
+
+#define  HAVE_JNI_VERSION_1_2   0 /* Assume we don't.  We could
+				     dynamically check for this.  We will
+				     assume JNI 1.2 in later versions of
+				     Classpath.  
+
+                                     As it stands, the code in this file
+                                     already needs one JNI 1.2 function:
+                                     GetEnv, in the JNI Invocation API.
+
+				     TODO This code hasn't been tested yet.
+				     And really hasn't been implemented yet.
+				     */ 
 
 /************************************************************************/
 /* Global data				     				*/
 /************************************************************************/
 
+#if defined HAVE_STDINT_H
+#include <stdint.h>		/* provides intptr_t */
+#elif defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <stdio.h>		/* snprintf */
+#include <stdarg.h>		/* va_list */
 #include "gthread-jni.h"
+#include <assert.h>		/* assert() */
+
+/* For Java thread priority constants. */
+#include <gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h>
+
+/* Since not all JNI header generators actually define constants we
+ define them here explicitly. */
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY 1
+#endif
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY 5
+#endif
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY 10
+#endif
+
+/*  The VM handle.  This is set in
+    Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit */
+JavaVM *the_vm;
 
-/*  The VM handle.  This is set in GtkToolkitMain.gtkInit */
-JavaVM *gdk_vm;
+/* Unions used for type punning. */
+union env_union
+{
+  void **void_env;
+  JNIEnv **jni_env;
+};
+
+union func_union
+{
+  void *void_func;
+  GThreadFunc g_func;
+};
+
+/* Forward Declarations for Functions  */
+static int threadObj_set_priority (JNIEnv * env, jobject threadObj,
+				   GThreadPriority gpriority);
+static void fatalMsg (const char fmt[], ...)
+     __attribute__ ((format (printf, 1, 2)))
+     __attribute__ ((noreturn));
+
+static void criticalMsg (const char fmt[], ...)
+     __attribute__ ((format (printf, 1, 2)));
 
+static void tracing (const char fmt[], ...)
+     __attribute__ ((format (printf, 1, 2)));
+
+static jint javaPriorityLevel (GThreadPriority priority)
+     __attribute__ ((const));
 
 /************************************************************************/
-/* Utilities to reflect exceptions back to the VM			*/
+/* Trouble-handling, including utilities to reflect exceptions		*/
+/* back to the VM.  Also some status reporting.				*/
 /************************************************************************/
 
-/*  This function checks for a pending exception, and rethrows it with
+/* How are we going to handle problems?
+
+   There are several approaches:
+
+   1)  Report them with the GError mechanism.
+
+       (*thread_create)() is the only one of these functions that takes a
+       GError pointer.  And the only G_THREAD error defined maps onto EAGAIN.
+       We don't have any errors in our (*thread_create)() implementation that
+       can be mapped to EAGAIN.  So this idea is a non-starter.
+
+   2)  Reflect the exception back to the VM, wrapped in a RuntimeException.
+       This will fail sometimes, if we're so broken (BADLY_BROKEN) that we
+       fail to throw the exception. 
+
+   3)  Abort execution.  This is what the glib functions themselves do for
+       errors that they can't report via GError.
+
+       Enable DIE_IF_BROKEN and/or DIE_IF_BADLY_BROKEN to
+       make this the default for BROKEN and/or BADLY_BROKEN trouble.
+
+   4) Display messages to stderr.  We always do this for BADLY_BROKEN
+      trouble.  The glib functions do that for errors they can't report via
+      GError. 
+
+   There are some complications.
+
+   When I attempted to report a problem in g_thread_self() using g_critical (a
+   macro around g_log(), I found that g_log in turn looks for thread-private
+   data and calls g_thread_self() again.
+
+   We got a segfault, probably due to stack overflow.  So, this code doesn't
+   use the g_critical() and g_error() functions any more.  Nor do we use
+   g_assert(); we use the C library's assert() instead.
+*/
+
+
+#define WHERE __FILE__ ":" G_STRINGIFY(__LINE__) ": "
+
+/* This is portable to older compilers that lack variable-argument macros.
+   This used to be just g_critical(), but then we ran into the error reporting
+   problem discussed above.
+*/
+static void
+fatalMsg (const char fmt[], ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fputs ("\nAborting execution\n", stderr);
+  abort ();
+}
+
+
+static void
+criticalMsg (const char fmt[], ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  putc ('\n', stderr);
+}
+
+/* Unlike the other two, this one does not append a newline.  This is only
+   used if one of the TRACE_ macros is defined.  */
+static void
+tracing (const char fmt[], ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+}
+
+#define assert_not_reached()						\
+  do									\
+    {									\
+      fputs(WHERE "You should never get here.  Aborting execution.\n", 	\
+	    stderr);							\
+      abort();								\
+    }									\
+  while(0)
+
+
+#if DIE_IF_BADLY_BROKEN
+#define BADLY_BROKEN fatalMsg
+#else
+#define BADLY_BROKEN criticalMsg
+/* So, the user may still attempt to recover, even though we do not advise
+   this. */
+#endif
+
+/* I find it so depressing to have to use C without varargs macros. */
+#define BADLY_BROKEN_MSG WHERE "Something fundamental"		\
+	" to GNU Classpath's AWT JNI broke while we were trying to pass up a Java error message"
+
+#define BADLY_BROKEN0()				\
+    BADLY_BROKEN(BADLY_BROKEN_MSG);
+#define	    BADLY_BROKEN1(msg)			\
+    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg)
+#define	    BADLY_BROKEN2(msg, arg)			\
+    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg)
+#define	    BADLY_BROKEN3(msg, arg, arg2) 		\
+    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2)
+#define	    BADLY_BROKEN4(msg, arg, arg2, arg3) 		\
+    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2, arg3)
+
+#define DELETE_LOCAL_REF(env, ref) 		\
+  do 						\
+    {						\
+      if ( DELETE_LOCAL_REFS )			\
+	{					\
+	  (*env)->DeleteLocalRef (env, ref);	\
+	  (ref) = NULL;				\
+	}					\
+    }						\
+  while(0)
+
+/* Cached info for Exception-wrapping */
+
+jclass runtimeException_class;	/* java.lang.RuntimeException */
+jmethodID runtimeException_ctor; /* constructor for it */
+
+
+/* Throw a new RuntimeException.  It may wrap around an existing exception.
+   1 if we did rethrow, -1 if we had trouble while rethrowing.
+   isBroken is always true in this case. */
+static int
+throw (JNIEnv * env, jthrowable cause, const char *message,
+       gboolean isBroken, const char *file, int line)
+{
+  jstring jmessage;
+  gboolean describedException = FALSE;	/* Did we already describe the
+					   exception to stderr or the
+					   equivalent?   */
+  jthrowable wrapper;
+
+  /* allocate local message in Java */
+  const char fmt[] = "In AWT JNI, %s (at %s:%d)";
+  size_t len = strlen (message) + strlen (file) + sizeof fmt + 25;
+  char *buf;
+
+  if (EXPLAIN_TROUBLE || (isBroken && EXPLAIN_BROKEN))
+    {
+      criticalMsg ("%s:%d: AWT JNI failure%s: %s\n", file, line,
+		   isBroken ? " (BROKEN)" : "", message);
+      if (cause)
+	{
+	  jthrowable currentException = (*env)->ExceptionOccurred (env);
+
+	  if (cause == currentException)
+	    {
+	      criticalMsg ("Description follows to System.err:");
+	      (*env)->ExceptionDescribe (env);
+	      /* ExceptionDescribe has the side-effect of clearing the pending
+	         exception; relaunch it.  */
+	      describedException = TRUE;
+
+	      if ((*env)->Throw (env, cause))
+		{
+		  BADLY_BROKEN1
+		    ("Relaunching an exception with Throw failed.");
+		  return -1;
+		}
+	    }
+	  else
+	    {
+	      DELETE_LOCAL_REF (env, currentException);
+	      criticalMsg (WHERE
+			   "currentException != cause; something else happened"
+			   " while handling an exception.");
+	    }
+	}
+    }				/* if (EXPLAIN_TROUBLE) */
+
+  if (isBroken && DIE_IF_BROKEN)
+    fatalMsg ("%s:%d: Aborting execution; BROKEN: %s\n", file, line, message);
+
+  if ((buf = malloc (len)))
+    {
+      memset (buf, 0, len);
+      snprintf (buf, len, fmt, message, file, line);
+      jmessage = (*env)->NewStringUTF (env, buf);
+      free (buf);
+    }
+  else
+    {
+      jmessage = NULL;
+    }
+
+  /* Create the RuntimeException wrapper object and throw it.  It is OK for
+     CAUSE to be NULL. */
+  wrapper = (jthrowable) (*env)->NewObject
+    (env, runtimeException_class, runtimeException_ctor, jmessage, cause);
+  DELETE_LOCAL_REF (env, jmessage);
+
+  if (!wrapper)
+    {
+      /* I think this should only happen:
+         - if there are bugs in my JNI code, or
+         - if the VM is broken, or 
+         - if we run out of memory. 
+       */
+      if (EXPLAIN_TROUBLE)
+	{
+	  criticalMsg (WHERE "GNU Classpath: JNI NewObject() could not create"
+		       " a new java.lang.RuntimeException.");
+	  criticalMsg ("We were trying to warn about the following"
+		       " previous failure:");
+	  criticalMsg ("%s:%d: %s", file, line, message);
+	  criticalMsg ("The latest (NewObject()) exception's description"
+		       " follows, to System.err:");
+	  (*env)->ExceptionDescribe (env);
+	}
+      BADLY_BROKEN1 ("Failure of JNI NewObject()"
+		     " to make a java.lang.RuntimeException");
+      return -1;
+    }
+
+
+  /* throw it */
+  if ((*env)->Throw (env, wrapper))
+    {
+      /* Throw() should just never fail, unless we're in such severe trouble
+         that we might as well die. */
+      BADLY_BROKEN1
+	("GNU Classpath: Failure of JNI Throw to report an Exception");
+      return -1;
+    }
+
+  DELETE_LOCAL_REF (env, wrapper);
+  return 1;
+}
+
+
+
+/* Rethrow an exception we received, wrapping it with a RuntimeException.  1
+   if we did rethrow, -1 if we had trouble while rethrowing.
+   CAUSE should be identical to the most recent exception that happened, so
+   that ExceptionDescribe will work.  (Otherwise nix.) */
+static int
+rethrow (JNIEnv * env, jthrowable cause, const char *message,
+	 gboolean isBroken, const char *file, int line)
+{
+  assert (cause);
+  return throw (env, cause, message, isBroken, file, line);
+}
+
+
+/* This function checks for a pending exception, and rethrows it with
  * a wrapper RuntimeException to deal with possible type problems (in
  * case some calling piece of code does not expect the exception being
  * thrown) and to include the given extra message.
+ *
+ * Returns 0 if no problems found (so no exception thrown), 1 if we rethrew an
+ * exception.   Returns -1 on failure. 
  */
-static void maybe_rethrow(JNIEnv *gdk_env, char *message, char *file, int line) {
-  jthrowable cause;
+static int
+maybe_rethrow (JNIEnv * env, const char *message, gboolean isBroken,
+	       const char *file, int line)
+{
+  jthrowable cause = (*env)->ExceptionOccurred (env);
+  int ret = 0;
 
   /* rethrow if an exception happened */
-  if ((cause = (*gdk_env)->ExceptionOccurred(gdk_env)) != NULL) {
-    jstring jmessage;
-  jclass obj_class;
-    jobject obj;
-    jmethodID ctor;
-
-    /* allocate local message in Java */
-    int len = strlen(message) + strlen(file) + 25;
-    char buf[ len ];
-    bzero(buf, len);
-    sprintf(buf, "%s (at %s:%d)", message, file, line);
-    jmessage = (*gdk_env)->NewStringUTF(gdk_env, buf);
-    
-    /* create RuntimeException wrapper object */
-    obj_class = (*gdk_env)->FindClass (gdk_env, "java/lang/RuntimeException");
-    ctor = (*gdk_env)->GetMethodID(gdk_env, obj_class, "<init>", "(Ljava/langString;Ljava/lang/Throwable)V");
-    obj = (*gdk_env)->NewObject (gdk_env, obj_class, ctor, jmessage, cause);
-
-    /* throw it */
-    (*gdk_env)->Throw(gdk_env, (jthrowable)obj);
+  if (cause)
+    {
+      ret = rethrow (env, cause, message, isBroken, file, line);
+      DELETE_LOCAL_REF (env, cause);
+    }
+
+  return 0;
+}
+
+/* MAYBE_TROUBLE() is used to include a source location in the exception
+   message. Once we have run maybe_rethrow, if there WAS trouble, 
+   return TRUE, else FALSE.   
+
+   MAYBE_TROUBLE() is actually never used; all problems that throw exceptions
+   are BROKEN, at least.  Nothing is recoverable :(.  See the discussion of
+   possible errors at thread_create_jni_impl().  */
+#define MAYBE_TROUBLE(_env, _message)				\
+	maybe_rethrow(_env, _message, FALSE, __FILE__, __LINE__)
+
+/* MAYBE_TROUBLE(), but something would be BROKEN if it were true. */
+#define MAYBE_BROKEN(_env, _message)				\
+	maybe_rethrow(_env, _message, TRUE, __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), TROUBLE() is never used. */
+#define TROUBLE(_env, _message)						\
+	rethrow(_env, (*env)->ExceptionOccurred (env), _message, FALSE, \
+		__FILE__, __LINE__)
+
+#define BROKEN(_env, _message)						\
+	rethrow (_env, (*env)->ExceptionOccurred (env), _message, TRUE, \
+		 __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), NEW_TROUBLE() is never used. */
+#define NEW_TROUBLE(_env, _message)					\
+	throw (_env, NULL,  _message, FALSE, __FILE__, __LINE__)
+
+#define NEW_BROKEN(_env, _message)				\
+	throw (_env, NULL, _message, TRUE, __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), RETHROW_CAUSE() is never used. */
+#define RETHROW_CAUSE(_env, _cause, _message)				\
+	rethrow (_env, _cause, _message, FALSE, __FILE__, __LINE__)
+
+#define BROKEN_CAUSE(_env, _cause, _message)				\
+	rethrow (_env, _cause, _message, TRUE, __FILE__, __LINE__)
+
+/* Macros to handle the possibility that someone might have called one of the
+   GThreadFunctions API functions with a Java exception pending.  It is
+   generally discouraged to continue to use JNI after a Java exception has
+   been raised.  Sun's JNI book advises that one trap JNI errors immediately
+   and not continue with an exception pending.
+
+   These are #if'd out for these reasons:
+
+   1) They do not work in the C '89 subset that Classpath is currently 
+      (2004 May 10) sticking to; HIDE_OLD_TROUBLE() includes a declaration
+      that should be in scope for the rest of the function, so it needs a
+      language version that lets you mix declarations and statements.  (This
+      could be worked around if it were important.)
+
+   2) They chew up more time and resources.  
+
+   3) There does not ever seem to be old trouble -- the assertion in
+      HIDE_OLD_TROUBLE never goes off. 
+
+   You will want to re-enable them if this code needs to be used in a context
+   where old exceptions might be pending when the GThread functions are
+   called.
+
+   The implementations in this file are responsible for skipping around calls
+   to SHOW_OLD_TROUBLE() if they've raised exceptions during the call.  So, if
+   we reach SHOW_OLD_TROUBLE, we are guaranteed that there are no exceptions
+   pending. */
+#if 1
+#define HIDE_OLD_TROUBLE(env)				\
+    assert ( NULL == (*env)->ExceptionOccurred (env) )
+
+#define SHOW_OLD_TROUBLE()	\
+    assert ( NULL == (*env)->ExceptionOccurred (env) )
+#else  /* 0 */
+#define HIDE_OLD_TROUBLE(env)					\
+   jthrowable savedTrouble = (*env)->ExceptionOccurred (env);	\
+   (*env)->ExceptionClear (env);
+
+#define SHOW_OLD_TROUBLE() do 					\
+{								\
+  assert ( NULL == (*env)->ExceptionOccurred (env) )		\
+  if (savedTrouble) 						\
+    {								\
+      if ((*env)->Throw (env, savedTrouble)) 			\
+	  BADLY_BROKEN ("ReThrowing the savedTrouble failed");	\
+    }								\
+  DELETE_LOCAL_REF (env, savedTrouble);				\
+} while(0)
+
+#endif /* 0 */
+
+/* Set up the cache of jclass and jmethodID primitives we need
+   in order to throw new exceptions and rethrow exceptions.  We do this
+   independently of the other caching.  We need to have this cache set up
+   first, so that we can then report errors properly. 
+
+   If any errors while setting up the error cache, the world is BADLY_BROKEN.
+
+   May be called more than once.
+
+   Returns -1 if the cache was not initialized properly, 1 if it was.  
+*/
+static int
+setup_exception_cache (JNIEnv * env)
+{
+  static int exception_cache_initialized = 0;	/* -1 for trouble, 1 for proper
+						   init.  */
+
+  jclass lcl_class;		/* a class used for local refs */
+
+  if (exception_cache_initialized)
+    return exception_cache_initialized;
+  lcl_class = (*env)->FindClass (env, "java/lang/RuntimeException");
+  if ( ! lcl_class )
+    {
+      BADLY_BROKEN1 ("Broken Class library or VM?"
+		     "  Couldn't find java/lang/RuntimeException");
+      return exception_cache_initialized = -1;
+    }
+  /* Pin it down. */
+  runtimeException_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!runtimeException_class)
+    {
+      BADLY_BROKEN1 ("Serious trouble: could not turn"
+		     " java.lang.RuntimeException into a global reference");
+      return exception_cache_initialized = -1;
+    }
+
+  runtimeException_ctor = 
+    (*env)->GetMethodID (env, runtimeException_class, "<init>",
+			   "(Ljava/lang/String;Ljava/lang/Throwable;)V");
+  if ( ! runtimeException_ctor )
+    {
+      BADLY_BROKEN1 ("Serious trouble: classpath couldn't find a"
+		     " two-arg constructor for java/lang/RuntimeException");
+      return exception_cache_initialized = -1;
+    }
+
+  return exception_cache_initialized = 1;
+}
+
+
+/**********************************************************/
+/***** The main cache *************************************/
+/**********************************************************/
+
+/** This is a cache of all classes, methods, and field IDs that we use during
+   the run.  We maintain a permanent global reference to each of the classes
+   we cache, since otherwise the (local) jclass that refers to that class
+   would go out of scope and possibly be reused in further calls.
+
+   The permanent global reference also achieves the secondary goal of
+   protecting the validity of the methods and field IDs in case the classes
+   were otherwise unloaded and then later loaded again.  Obviously, this will
+   never happen to classes such as java.lang.Thread and java.lang.Object, but
+   the primary reason for maintaining permanent global refs is sitll valid.
+
+   The code in jnilink.c has a similar objective.  TODO: Consider using that
+   code instead.
+
+   --Steven Augart
+*/
+
+/* All of these are cached classes and method IDs: */
+/* java.lang.Object */
+static jclass obj_class;		/* java.lang.Object */
+static jmethodID obj_ctor;		/* no-arg Constructor for java.lang.Object */
+static jmethodID obj_notify_mth;	/* java.lang.Object.notify() */
+static jmethodID obj_notifyall_mth;	/* java.lang.Object.notifyall() */
+static jmethodID obj_wait_mth;		/* java.lang.Object.wait() */
+static jmethodID obj_wait_nanotime_mth; /* java.lang.Object.wait(JI) */
+
+/* GThreadMutex and its methods */
+static jclass mutex_class;
+static jmethodID mutex_ctor;
+static jfieldID mutex_lockForPotentialLockers_fld;
+static jfieldID mutex_potentialLockers_fld;
+
+/* java.lang.Thread and its methods*/
+static jclass thread_class;		/* java.lang.Thread */
+static jmethodID thread_current_mth;	/* Thread.currentThread() */
+static jmethodID thread_equals_mth;	/* Thread.equals() */
+static jmethodID thread_join_mth;	/* Thread.join() */
+static jmethodID thread_setPriority_mth; /* Thread.setPriority() */
+static jmethodID thread_stop_mth;	/* Thread.stop() */
+static jmethodID thread_yield_mth;	/* Thread.yield() */
+
+/* java.lang.ThreadLocal and its methods */
+static jclass threadlocal_class;	/* java.lang.ThreadLocal */
+static jmethodID threadlocal_ctor;	/* Its constructor */
+static jmethodID threadlocal_set_mth;	/* ThreadLocal.set() */
+static jmethodID threadlocal_get_mth;	/* ThreadLocal.get() */
+
+/* java.lang.Long and its methods */
+static jclass long_class;		/* java.lang.Long */
+static jmethodID long_ctor;		/* constructor for it: (J) */
+static jmethodID long_longValue_mth;	/* longValue()J */
+
+
+/* GThreadNativeMethodRunner */
+static jclass runner_class;
+static jmethodID runner_ctor;
+static jmethodID runner_threadToThreadID_mth;
+static jmethodID runner_threadIDToThread_mth;
+static jmethodID runner_deRegisterJoinable_mth;
+static jmethodID runner_start_mth;	/* Inherited Thread.start() */
+
+
+/* java.lang.InterruptedException */
+static jclass interrupted_exception_class;
+
+
+
+
+/* Returns a negative value if there was trouble during initialization.
+   Returns a positive value of the cache was initialized correctly.
+   Never returns zero. */
+static int
+setup_cache (JNIEnv * env)
+{
+  jclass lcl_class;
+  static int initialized = 0;	/* 1 means initialized, 0 means uninitialized,
+				   -1 means mis-initialized */
+
+  if (initialized)
+    return initialized;
+
+  /* make sure we can report on trouble */
+  if (setup_exception_cache (env) < 0)
+    return initialized = -1;
+
+#ifdef JNI_VERSION_1_2
+  if (HAVE_JNI_VERSION_1_2)
+    assert ( ! (*env)->ExceptionCheck (env));
+  else
+#endif
+    assert ( ! (*env)->ExceptionOccurred (env));
+
+  /* java.lang.Object and its methods */
+  lcl_class = (*env)->FindClass (env, "java/lang/Object");
+  if (!lcl_class)
+    {
+      BROKEN (env, "cannot find java.lang.Object");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  obj_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!obj_class)
+    {
+      BROKEN (env, "Cannot get a global reference to java.lang.Object");
+      return initialized = -1;
+    }
+
+  obj_ctor = (*env)->GetMethodID (env, obj_class, "<init>", "()V");
+  if (!obj_ctor)
+    {
+      BROKEN (env, "cannot find constructor for java.lang.Object");
+      return initialized = -1;
+    }
+
+  obj_notify_mth = (*env)->GetMethodID (env, obj_class, "notify", "()V");
+  if ( ! obj_notify_mth )
+    {
+      BROKEN (env, "cannot find java.lang.Object.notify()V");
+      return initialized = -1;
+    }
+
+  obj_notifyall_mth =
+    (*env)->GetMethodID (env, obj_class, "notifyAll", "()V");
+  if ( ! obj_notifyall_mth)
+    {
+      BROKEN (env, "cannot find java.lang.Object.notifyall()V");
+      return initialized = -1;
+    }
+
+  obj_wait_mth = (*env)->GetMethodID (env, obj_class, "wait", "()V");
+  if ( ! obj_wait_mth )
+    {
+      BROKEN (env, "cannot find Object.<wait()V>");
+      return initialized = -1;
+    }
+
+  obj_wait_nanotime_mth = 
+    (*env)->GetMethodID (env, obj_class, "wait", "(JI)V");
+  if ( ! obj_wait_nanotime_mth )
+    {
+      BROKEN (env, "cannot find Object.<wait(JI)V>");
+      return initialized = -1;
+    }
+
+  /* GThreadMutex and its methods */
+  lcl_class = (*env)->FindClass (env, "gnu/java/awt/peer/gtk/GThreadMutex");
+  if ( ! lcl_class)
+    {
+      BROKEN (env, "cannot find gnu.java.awt.peer.gtk.GThreadMutex");
+      return initialized = -1;
+    }
+  /* Pin it down. */
+  mutex_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if ( ! mutex_class)
+    {
+      BROKEN (env, "Cannot get a global reference to GThreadMutex");
+      return initialized = -1;
+    }
+
+  mutex_ctor = (*env)->GetMethodID (env, mutex_class, "<init>", "()V");
+  if ( ! mutex_ctor)
+    {
+      BROKEN (env, "cannot find zero-arg constructor for GThreadMutex");
+      return initialized = -1;
+    }
+
+  mutex_potentialLockers_fld = (*env)->GetFieldID
+    (env, mutex_class, "potentialLockers", "I");
+  if ( ! mutex_class )
+    {
+      BROKEN (env, "cannot find GThreadMutex.potentialLockers");
+      return initialized = -1;
+    }
+
+  if (! (mutex_lockForPotentialLockers_fld = (*env)->GetFieldID
+	 (env, mutex_class, "lockForPotentialLockers", "Ljava/lang/Object;")))
+    {
+      BROKEN (env, "cannot find GThreadMutex.lockForPotentialLockers");
+      return initialized = -1;
+    }
+
+
+  /* java.lang.Thread */
+  if (! (lcl_class = (*env)->FindClass (env, "java/lang/Thread")))
+    {
+      BROKEN (env, "cannot find java.lang.Thread");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  thread_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!thread_class)
+    {
+      BROKEN (env, "Cannot get a global reference to java.lang.Thread");
+      return initialized = -1;
+    }
+
+  thread_current_mth =
+    (*env)->GetStaticMethodID (env, thread_class, "currentThread",
+			       "()Ljava/lang/Thread;");
+  if (!thread_current_mth)
+    {
+      BROKEN (env, "cannot find Thread.currentThread() method");
+      return initialized = -1;
+    }
+
+  thread_equals_mth = 
+    (*env)->GetMethodID (env, thread_class, "equals", "(Ljava/lang/Object;)Z");
+  if (!thread_equals_mth)
+    {
+      BROKEN (env, "cannot find Thread.equals() method");
+      return initialized = -1;
+    }
+
+  thread_join_mth = (*env)->GetMethodID (env, thread_class, "join", "()V");
+  if (!thread_join_mth)
+    {
+      BROKEN (env, "cannot find Thread.join() method");
+      return initialized = -1;
+    }
+
+  thread_stop_mth = (*env)->GetMethodID (env, thread_class, "stop", "()V");
+  if ( ! thread_stop_mth )
+    {
+      BROKEN (env, "cannot find Thread.stop() method");
+      return initialized = -1;
+    }
+
+  thread_setPriority_mth = 
+    (*env)->GetMethodID (env, thread_class, "setPriority", "(I)V");
+  if ( ! thread_setPriority_mth )
+    {
+      BROKEN (env, "cannot find Thread.setPriority() method");
+      return initialized = -1;
+    }
+
+  thread_yield_mth = 
+    (*env)->GetStaticMethodID (env, thread_class, "yield", "()V");
+  if ( ! thread_yield_mth )
+    {
+      BROKEN (env, "cannot find Thread.yield() method");
+      return initialized = -1;
+    }
+
+  /* java.lang.ThreadLocal */
+  lcl_class = (*env)->FindClass (env, "java/lang/ThreadLocal");
+  if ( ! lcl_class )
+    {
+      BROKEN (env, "cannot find class java.lang.ThreadLocal");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  threadlocal_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if ( ! threadlocal_class )
+    {
+      BROKEN (env, "Cannot get a global reference to java.lang.ThreadLocal");
+      return initialized = -1;
+    }
+
+  threadlocal_ctor = (*env)->GetMethodID (env, threadlocal_class, 
+                                          "<init>", "()V");
+  if ( ! threadlocal_ctor )
+    {
+      BROKEN (env, "cannot find ThreadLocal.<init>()V");
+      return initialized = -1;
+    }
+  
+  threadlocal_get_mth = (*env)->GetMethodID (env, threadlocal_class,
+                                             "get", "()Ljava/lang/Object;");
+  if ( ! threadlocal_get_mth )
+    {
+      BROKEN (env, "cannot find java.lang.ThreadLocal.get()Object");
+      return initialized = -1;
     }
+
+  threadlocal_set_mth = (*env)->GetMethodID (env, threadlocal_class,
+                                             "set", "(Ljava/lang/Object;)V");
+  if ( ! threadlocal_set_mth )
+    {
+      BROKEN (env, "cannot find ThreadLocal.set(Object)V");
+      return initialized = -1;
+    }
+
+  /* java.lang.Long */
+  lcl_class = (*env)->FindClass (env, "java/lang/Long");
+  if ( ! lcl_class )
+    {
+      BROKEN (env, "cannot find class java.lang.Long");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  long_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!long_class)
+    {
+      BROKEN (env, "Cannot get a global reference to java.lang.Long");
+      return initialized = -1;
+    }
+
+  long_ctor = (*env)->GetMethodID (env, long_class, "<init>", "(J)V");
+  if (!long_ctor)
+    {
+      BROKEN (env, "cannot find method java.lang.Long.<init>(J)V");
+      return initialized = -1;
+    }
+
+  long_longValue_mth =
+    (*env)->GetMethodID (env, long_class, "longValue", "()J");
+  if (!long_longValue_mth)
+    {
+      BROKEN (env, "cannot find method java.lang.Long.longValue()J");
+      return initialized = -1;
+    }
+
+
+  /* GThreadNativeMethodRunner */
+  lcl_class = 
+    (*env)->FindClass (env,
+                       "gnu/java/awt/peer/gtk/GThreadNativeMethodRunner");
+  if ( ! lcl_class )
+    {
+      BROKEN (env,
+	      "cannot find gnu.java.awt.peer.gtk.GThreadNativeMethodRunner");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  runner_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!runner_class)
+    {
+      BROKEN (env,
+	      "Cannot get a global reference to the class GThreadNativeMethodRunner");
+      return initialized = -1;
+    }
+
+  runner_ctor = (*env)->GetMethodID (env, runner_class, "<init>", "(JJZ)V");
+  if ( ! runner_ctor )
+    {
+      BROKEN (env,
+	      "cannot find method GThreadNativeMethodRunner.<init>(JJZ)");
+      return initialized = -1;
+    }
+      
+  runner_start_mth = (*env)->GetMethodID (env, runner_class, "start", "()V");
+  if ( ! runner_start_mth )
+    {
+      BROKEN (env, "cannot find method GThreadNativeMethodRunner.start()V");
+      return initialized = -1;
+    }
+
+
+  runner_threadToThreadID_mth = 
+    (*env)->GetStaticMethodID (env, runner_class,
+                               "threadToThreadID", "(Ljava/lang/Thread;)I");
+  if ( ! runner_threadToThreadID_mth )
+    {
+      BROKEN (env,
+	      "cannot find method GThreadNativeMethodRunner.threadToThreadID(java.lang.Thread)I");
+      return initialized = -1;
+    }
+
+
+  runner_threadIDToThread_mth = 
+    (*env)->GetStaticMethodID (env, runner_class,
+                               "threadIDToThread", "(I)Ljava/lang/Thread;");
+  if ( ! runner_threadIDToThread_mth )
+    {
+      BROKEN (env,
+	      "cannot find method GThreadNativeMethodRunner.threadIDToThread(I)java.lang.Thread");
+      return initialized = -1;
+    }
+
+
+  runner_deRegisterJoinable_mth =
+    (*env)->GetStaticMethodID (env, runner_class, "deRegisterJoinable",
+			       "(Ljava/lang/Thread;)V");
+  if (!runner_deRegisterJoinable_mth)
+    {
+      BROKEN (env,
+	      "cannot find method GThreadNativeMethodRunner.deRegisterJoinable(java.lang.Thread)V");
+      return initialized = -1;
+    }
+
+
+  /* java.lang.InterruptedException */
+  lcl_class = (*env)->FindClass (env, "java/lang/InterruptedException");
+  if ( ! lcl_class )
+    {
+      BROKEN (env, "cannot find class java.lang.InterruptedException");
+      return initialized = -1;
+    }
+
+  /* Pin it down. */
+  interrupted_exception_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+  DELETE_LOCAL_REF (env, lcl_class);
+  if (!interrupted_exception_class)
+    {
+      BROKEN (env, "Cannot make a global reference"
+	      " to java.lang.InterruptedException");
+      return initialized = -1;
+    }
+
+#ifdef JNI_VERSION_1_2
+  if (HAVE_JNI_VERSION_1_2)
+    assert ( ! (*env)->ExceptionCheck (env));
+  else
+#endif
+    assert ( ! (*env)->ExceptionOccurred (env));
+
+
+  return initialized = 1;
 }
 
-/* This macro is used to include a source location in the exception message */
-#define MAYBE_RETHROW(_class, _message) \
-maybe_rethrow(_class, _message, __FILE__, __LINE__)
+
+
 
 
 /************************************************************************/
 /* Utilities to allocate and free java.lang.Objects			*/
 /************************************************************************/
 
-/*  Both the mutexes and the condition variables are java.lang.Object objects,
+/* The condition variables are java.lang.Object objects,
  * which this method allocates and returns a global ref.  Note that global
  * refs must be explicitly freed (isn't C fun?).
  */
-static jobject *allocatePlainObject() {
-  jclass obj_class;
-  jobject *obj;
-  JNIEnv *gdk_env;
-  jmethodID ctor;
-
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
-
-  obj_class = (*gdk_env)->FindClass (gdk_env, "java/lang/Object");
-  MAYBE_RETHROW(gdk_env, "cannot find Object");
-
-  ctor = (*gdk_env)->GetMethodID(gdk_env, obj_class, "<init>", "()V");
-  MAYBE_RETHROW(gdk_env, "cannot find constructor");
-
-  obj = (jobject *) g_malloc (sizeof (jobject));
-  *obj = (*gdk_env)->NewObject (gdk_env, obj_class, ctor);
-  MAYBE_RETHROW(gdk_env, "cannot allocate object");
-  
-  *obj = (*gdk_env)->NewGlobalRef (gdk_env, *obj);
-  MAYBE_RETHROW(gdk_env, "cannot make global ref");
+static jobject
+allocatePlainObject (JNIEnv * env)
+{
+  jobject lcl_obj, global_obj;
+
+  lcl_obj = (*env)->NewObject (env, obj_class, obj_ctor);
+  if (!lcl_obj)
+    {
+      BROKEN (env, "cannot allocate object");
+      return NULL;
+    }
 
-  return obj;
+  global_obj = (*env)->NewGlobalRef (env, lcl_obj);
+  DELETE_LOCAL_REF (env, lcl_obj);
+  if (!global_obj)
+    {
+      NEW_BROKEN (env, "cannot make global ref for a new plain Java object");
+      /* Deliberate fall-through */
+    }
+
+  return global_obj;
 }
 
-/*  Frees a Java object given a global ref (isn't C fun?) */
-static void freePlainObject(jobject *obj) {
-  JNIEnv *gdk_env;
+/*  Frees any Java object given a global ref (isn't C fun?) */
+static void
+freeObject (JNIEnv * env, jobject obj)
+{
+  if (obj)
+    {
+      (*env)->DeleteGlobalRef (env, obj);
+      /* DeleteGlobalRef can never fail */
+    }
+}
 
-  if (obj) {
-    (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
 
-    (*gdk_env)->DeleteGlobalRef (gdk_env, *obj);
-    MAYBE_RETHROW(gdk_env, "cannot delete global ref");
-  
-    g_free (obj);
-  }
+/************************************************************************/
+/* Utilities to allocate and free Java mutexes				*/
+/************************************************************************/
+
+/* The mutexes are gnu.java.awt.peer.gtk.GThreadMutex objects,
+ * which this method allocates and returns a global ref.  Note that global
+ * refs must be explicitly freed (isn't C fun?).
+ *
+ * Free this with freeObject()
+ */
+static jobject
+allocateMutexObject (JNIEnv * env)
+{
+  jobject lcl_obj, global_obj;
+
+  lcl_obj = (*env)->NewObject (env, mutex_class, mutex_ctor);
+  if (!lcl_obj)
+    {
+      BROKEN (env, "cannot allocate a GThreadMutex");
+      return NULL;
+    }
+
+  global_obj = (*env)->NewGlobalRef (env, lcl_obj);
+  DELETE_LOCAL_REF (env, lcl_obj);
+  if (!global_obj)
+    {
+      NEW_BROKEN (env, "cannot make global ref");
+      /* Deliberate fallthrough */
+    }
+
+  return global_obj;
 }
 
 
@@ -172,195 +1208,746 @@
 /************************************************************************/
 
 /* Lock a Java object */
-static void takeLock(JNIEnv *gdk_env, void *mutex) {
-  (*gdk_env)->MonitorEnter (gdk_env, *((jobject *)mutex));
-  MAYBE_RETHROW(gdk_env, "cannot get lock");
+#define ENTER_MONITOR(env, m)			\
+    enterMonitor(env, m, G_STRINGIFY(m))
+
+/* Return -1 on failure, 0 on success. */
+static int
+enterMonitor (JNIEnv * env, jobject monitorObj, const char monName[])
+{
+  if (TRACE_MONITORS)
+    tracing ("  <MonitorEnter(%s)>", monName);
+  assert (monitorObj);
+  if ((*env)->MonitorEnter (env, monitorObj) < 0)
+    {
+      BROKEN (env, "cannot enter monitor");
+      return -1;
+    }
+  return 0;
 }
 
+
 /* Unlock a Java object */
-static void releaseLock(JNIEnv *gdk_env, void *mutex) {
-    (*gdk_env)->MonitorExit (gdk_env, *((jobject *)mutex));
-  MAYBE_RETHROW(gdk_env, "cannot release lock");
+#define EXIT_MONITOR(env, m)			\
+    exitMonitor(env, m, G_STRINGIFY(m))
+
+static int
+exitMonitor (JNIEnv * env, jobject mutexObj, const char monName[])
+{
+  if (TRACE_MONITORS)
+    tracing (" <MonitorExit(%s)>", monName);
+  assert (mutexObj);
+  if ((*env)->MonitorExit (env, mutexObj) < 0)
+    {
+      BROKEN (env, "cannot exit monitor ");
+      return -1;
+    }
+  return 0;
+}
+
+
+/************************************************************************/
+/* Miscellaneous utilities		     				*/
+/************************************************************************/
+
+/* Get the Java Thread object that corresponds to a particular thread ID. 
+   A negative thread Id gives us a null object.
+
+   Returns a local reference. 
+*/
+static jobject
+getThreadFromThreadID (JNIEnv * env, gpointer gThreadID)
+{
+  jint threadNum = (jint) gThreadID;
+  jobject thread;
+
+  if (threadNum < 0)
+    {
+      NEW_BROKEN (env, "getThreadFromThreadID asked to look up"
+		       " a negative thread index");
+      return NULL;
+    }
+
+  thread = (*env)->CallStaticObjectMethod
+    (env, runner_class, runner_threadIDToThread_mth, threadNum);
+
+  if (MAYBE_BROKEN (env, "cannot get Thread for threadID "))
+    return NULL;
+
+  return thread;
+}
+
+/** Return the unique threadID of THREAD.
+
+   Error handling: Return (gpointer) -1 on all failures, 
+   and propagate an exception. 
+*/
+static gpointer
+getThreadIDFromThread (JNIEnv * env, jobject thread)
+{
+  jint threadNum;
+
+  if (ENABLE_EXPENSIVE_ASSERTIONS)
+    assert ((*env)->IsInstanceOf (env, thread, thread_class));
+
+  HIDE_OLD_TROUBLE (env);
+
+  threadNum = (*env)->CallStaticIntMethod
+    (env, runner_class, runner_threadToThreadID_mth, thread);
+
+  if (MAYBE_BROKEN (env, "cannot get ThreadID for a Thread "))
+    {
+      threadNum = -1;
+      goto done;
+    }
+
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  return (gpointer) threadNum;
+}
+
+
+/************************************************************************/
+/* The Actual JNI functions that we pass to the function vector.	*/
+/************************************************************************/
+
+
+/************************************************************************/
+/* Mutex Functions                                                  	*/
+/************************************************************************/
+
+/*** Mutex Utilities  ****/
+struct mutexObj_cache
+{
+  jobject lockForPotentialLockersObj;	/* Lock for the potentialLockers
+					   field.  Local reference. */
+  jobject lockObj;		/* The real lock we use.  This is a GLOBAL
+				   reference and must not be freed. */
+};
+
+/* Initialize the cache of sub-locks for a particular mutex object.
+
+  -1 on error, 0 on success.  The caller is not responsible for freeing the
+   partially-populated cache in case of failure (but in practice does anyway)
+   (This actually never fails, though, since GetObjectField allegedly never
+   fails.)  
+
+   Guaranteed to leave all fields of the cache initialized, even if only to
+   zero. 
+*/
+static int
+populate_mutexObj_cache (JNIEnv * env, jobject mutexObj,
+			 struct mutexObj_cache *mcache)
+{
+  mcache->lockObj = mutexObj;	/* the mutexObj is its own lock.  */
+  assert (mcache->lockObj);
+
+  mcache->lockForPotentialLockersObj = (*env)->GetObjectField
+    (env, mutexObj, mutex_lockForPotentialLockers_fld);
+  /* GetObjectField can never fail. */
+
+  /*  Retrieving a NULL object could only happen if we somehow got a
+      a mutex object that was not properly intialized. */ 
+  assert (mcache->lockForPotentialLockersObj);
+
+  return 0;
 }
 
-/* Create a mutex, which is a java.lang.Object for us */
-static GMutex *g_mutex_new_jni_impl (void) {
-  return (GMutex*) allocatePlainObject();
+
+/* Clean out the mutexObj_cache, even if it was never populated. */
+static void
+clean_mutexObj_cache (JNIEnv * env, struct mutexObj_cache *mcache)
+{
+  /* OK to pass NULL refs to DELETE_LOCAL_REF */
+  DELETE_LOCAL_REF (env, mcache->lockForPotentialLockersObj);
+  /* mcache->lockObj is a GLOBAL reference. */
+  mcache->lockObj = NULL;
+}
+
+/* -1 on failure, 0 on success.
+   The mutexObj_cache is already populated for this particular object. */
+static int
+mutexObj_lock (JNIEnv * env, jobject mutexObj, struct mutexObj_cache *mcache)
+{
+  jint potentialLockers;
+
+  if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj))
+    return -1;
+
+  assert(mutexObj);
+  potentialLockers = 
+    (*env)->GetIntField (env, mutexObj, mutex_potentialLockers_fld);
+  /* GetIntField() never fails. */
+
+  ++potentialLockers;
+
+  (*env)->SetIntField
+    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+
+  if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj))
+    return -1;
+
+  if (ENTER_MONITOR (env, mcache->lockObj))
+    return -1;
+
+  SHOW_OLD_TROUBLE ();
+
+  return 0;
+}
+
+/* Unlock a GMutex, once we're already in JNI and have already gotten the
+   mutexObj for it.  This skips the messages that TRACE_API_CALLS would
+   print.
+
+   Returns -1 on error, 0 on success. */
+static int
+mutexObj_unlock (JNIEnv * env, jobject mutexObj,
+		 struct mutexObj_cache *mcache)
+{
+  jint potentialLockers;
+  int ret = -1;			/* assume failure until we suceed.  */
+
+  /* Free the lock first, so that someone waiting for the lock can get it
+     ASAP. */
+  /* This is guaranteed not to block. */
+  if (EXIT_MONITOR (env, mcache->lockObj) < 0)
+    goto done;
+
+  /* Kick down potentialLockers by one.  We do this AFTER we free the lock, so
+     that we hold it no longer than necessary. */
+  if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)
+    goto done;
+
+  potentialLockers = (*env)->GetIntField
+    (env, mutexObj, mutex_potentialLockers_fld);
+  /* GetIntField never fails */
+
+  assert (potentialLockers >= 1);
+  --potentialLockers;
+
+  (*env)->SetIntField
+    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+  /* Never fails, so the JNI book says. */
+
+  /* Clean up. */
+  if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)
+    goto done;
+  ret = 0;
+
+done:
+  return ret;
+}
+
+/*** Mutex Implementations ****/
+
+/* Create a mutex, which is a java.lang.Object for us.
+   In case of failure, we'll return NULL.  Which will implicitly 
+   cause future calls to fail. */
+static GMutex *
+mutex_new_jni_impl (void)
+{
+  jobject mutexObj;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("mutex_new_jni_impl()");
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  if (setup_cache (env) < 0)
+    {
+      mutexObj = NULL;
+      goto done;
+    }
+
+  mutexObj = allocateMutexObject (env);
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> %p \n", mutexObj);
+
+  return (GMutex *) mutexObj;
+
 }
 
 /* Lock a mutex. */
-static void g_mutex_lock_jni_impl (GMutex *mutex __attribute__((unused))) {
-  JNIEnv *gdk_env;
+static void
+mutex_lock_jni_impl (GMutex * mutex)
+{
+  struct mutexObj_cache mcache;
+  jobject mutexObj = (jobject) mutex;
+  JNIEnv *env;
+  union env_union e;
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+  if (TRACE_API_CALLS)
+    tracing ("mutex_lock_jni_impl( mutexObj = %p )", mutexObj);
 
-  takeLock(gdk_env, mutex);
+  assert (mutexObj);
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  if (setup_cache (env) < 0)
+    goto done;
+
+  HIDE_OLD_TROUBLE (env);
+
+  if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+    goto done;
+
+  mutexObj_lock (env, mutexObj, &mcache);
+  /* No need to error check; we've already reported it in any case. */
+
+done:
+  clean_mutexObj_cache (env, &mcache);
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID \n");
 }
 
-/*  Try to lock a mutex.  Actually, do not try because Java objects
- * do not provide such an interface.  To be at least minimally correct,
- * pretend we tried and failed.
- */
-static gboolean g_mutex_trylock_jni_impl
-  (GMutex *mutex __attribute__((unused)))
+
+/*  Try to lock a mutex.  Return TRUE if we succeed, FALSE if we fail.  
+    FALSE on error. */
+static gboolean
+mutex_trylock_jni_impl (GMutex * gmutex)
 {
-  // Shall we implement this in a JikesRVM-specific way under a flag?
-  return FALSE;
+  jobject mutexObj = (jobject) gmutex;
+  jint potentialLockers;
+  gboolean ret = FALSE;
+  JNIEnv *env;
+  union env_union e;
+  struct mutexObj_cache mcache;
+
+  if (TRACE_API_CALLS)
+    tracing ("mutex_trylock_jni_impl(mutexObj=%p)", mutexObj);
+
+  assert (mutexObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+    goto done;
+
+  if (ENTER_MONITOR (env, mcache.lockForPotentialLockersObj))
+    goto done;
+
+  potentialLockers = (*env)->GetIntField
+    (env, mutexObj, mutex_potentialLockers_fld);
+
+  assert (potentialLockers >= 0);
+
+  if (potentialLockers)
+    {
+      /* Already locked.  Clean up and leave. */
+      EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);	
+      /* Ignore any error code from EXIT_MONITOR; there's nothing we could do
+	 at this level, in any case. */
+      goto done;
+    }
+
+  /* Guaranteed not to block. */
+  if (ENTER_MONITOR (env, mcache.lockObj))
+    {
+      /* Clean up the existing lock. */
+      EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);	
+      /* Ignore any error code from EXIT_MONITOR; there's nothing we could do
+	 at this level, in any case. */
+      goto done;
+    }
+  
+
+  /* We have the monitor.  Record that fact. */
+  potentialLockers = 1;
+  (*env)->SetIntField
+    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+  /* Set*Field() never fails */
+
+  ret = TRUE;			/* We have the lock. */
+
+  /* Clean up. */
+  if (EXIT_MONITOR (env, mcache.lockForPotentialLockersObj))
+      goto done;		/* If we fail at this point, still keep the
+				   main lock.  */
+
+  SHOW_OLD_TROUBLE ();
+done:
+  clean_mutexObj_cache (env, &mcache);
+  if (TRACE_API_CALLS)
+    tracing (" ==> %s\n", ret ? "TRUE" : "FALSE");
+  return ret;
 }
 
+
 /* Unlock a mutex. */
-static void g_mutex_unlock_jni_impl (GMutex *mutex) {
-  JNIEnv *gdk_env;
+static void
+mutex_unlock_jni_impl (GMutex * gmutex)
+{
+  jobject mutexObj = (jobject) gmutex;
+  struct mutexObj_cache mcache;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("mutex_unlock_jni_impl(mutexObj=%p)", mutexObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  assert (mutexObj);
+
+  if ( populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+    goto done;
+
+  (void) mutexObj_unlock (env, mutexObj, &mcache);
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+  SHOW_OLD_TROUBLE ();
 
-  releaseLock(gdk_env, mutex);
+done:
+  clean_mutexObj_cache (env, &mcache);
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
-/* Free a mutex (isn't C fun?) */
-static void g_mutex_free_jni_impl (GMutex *mutex)
+
+
+/* Free a mutex (isn't C fun?).  OK this time for it to be NULL.  
+   No failure conditions, for a change.  */
+static void
+mutex_free_jni_impl (GMutex * mutex)
 {
-  freePlainObject( (jobject*)mutex );
+  jobject mutexObj = (jobject) mutex;
+  JNIEnv *env;
+  union env_union e;
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  if (TRACE_API_CALLS)
+    tracing ("mutex_free_jni_impl(%p)", mutexObj);
+
+  freeObject (env, mutexObj);
+
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
 
+
+
 /************************************************************************/
 /* Condition variable code		     				*/
 /************************************************************************/
 
 /* Create a new condition variable.  This is a java.lang.Object for us. */
-static GCond *g_cond_new_jni_impl () {
-  return (GCond*)allocatePlainObject();
+static GCond *
+cond_new_jni_impl (void)
+{
+  jobject condObj;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("mutex_free_jni_impl()");
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  condObj = allocatePlainObject (env);
+
+  if (TRACE_API_CALLS)
+    tracing (" ==> %p\n", condObj);
+
+  return (GCond *) condObj;
 }
 
 /*  Signal on a condition variable.  This is simply calling Object.notify
  * for us.
  */
-static void g_cond_signal_jni_impl (GCond *cond) {
-  jclass lcl_class;
-  jmethodID signal_mth;
-  JNIEnv *gdk_env;
+static void
+cond_signal_jni_impl (GCond * gcond)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject condObj = (jobject) gcond;
+
+  if (TRACE_API_CALLS)
+    tracing ("cond_signal_jni_impl(condObj = %p)", condObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
-
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Object");
-  MAYBE_RETHROW(gdk_env, "cannot find Object");
-  
-  signal_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "notify", "()V");
-  MAYBE_RETHROW(gdk_env, "cannot find Object.<notify>");
+  assert (condObj);
 
   /* Must have locked an object to call notify */
-  takeLock(gdk_env, cond);
+  if (ENTER_MONITOR (env, condObj))
+    goto done;
+
+  (*env)->CallVoidMethod (env, condObj, obj_notify_mth);
+  if (MAYBE_BROKEN (env, "cannot signal mutex with Object.notify()"))
+    {
+      if (EXIT_MONITOR (env, condObj))
+	BADLY_BROKEN1 ("Failed to unlock a monitor; the VM may deadlock.");
+      goto done;
+    }
 
-  (*gdk_env)->CallVoidMethod(gdk_env, *(jobject*)cond, signal_mth);
-  MAYBE_RETHROW(gdk_env, "cannot signal mutex");
+  EXIT_MONITOR (env, condObj);
 
-  releaseLock(gdk_env, cond);
+  SHOW_OLD_TROUBLE ();
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
 /*  Broadcast to all waiting on a condition variable.  This is simply 
  * calling Object.notifyAll for us.
  */
-static void g_cond_broadcast_jni_impl (GCond *cond) {
-  jclass lcl_class;
-  jmethodID bcast_mth;
-  JNIEnv *gdk_env;
+static void
+cond_broadcast_jni_impl (GCond * gcond)
+{
+  jobject condObj = (jobject) gcond;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("cond_broadcast_jni_impl(condObj=%p)", condObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+  assert (condObj);
+  /* Must have locked an object to call notifyAll */
+  if (ENTER_MONITOR (env, condObj))
+    goto done;
 
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Object");
-  MAYBE_RETHROW(gdk_env, "cannot find Object");
-  
-  bcast_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "notifyAll", "()V");
-  MAYBE_RETHROW(gdk_env, "cannot find Object.<notifyAll>");
+  (*env)->CallVoidMethod (env, condObj, obj_notifyall_mth);
+  if (MAYBE_BROKEN (env, "cannot broadcast to mutex with Object.notify()"))
+    {
+      EXIT_MONITOR (env, condObj);
+      goto done;
+    }
 
-  /* Must have locked an object to call notifyAll */
-  takeLock(gdk_env, cond);
+  EXIT_MONITOR (env, condObj);
 
-  (*gdk_env)->CallVoidMethod(gdk_env, *(jobject*)cond, bcast_mth);
-  MAYBE_RETHROW(gdk_env, "cannot broadcast to mutex");
+  SHOW_OLD_TROUBLE ();
 
-  releaseLock(gdk_env, cond);
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
 
-/*  Wait on a condition variable.  For us, this simply means call
+/* Wait on a condition variable.  For us, this simply means calling
  * Object.wait.
+ *
+ * Throws a Java exception on trouble; may leave the mutexes set arbitrarily.
+ * XXX TODO: Further improve error recovery.
  */
-static void g_cond_wait_jni_impl
-  (GCond *cond, GMutex *mutex __attribute__((unused)))
+static void
+cond_wait_jni_impl (GCond * gcond, GMutex * gmutex)
 {
-  jclass lcl_class;
-  jmethodID wait_mth;
-  JNIEnv *gdk_env;
-
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
-
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Object");
-  MAYBE_RETHROW(gdk_env, "cannot find Object");
-  
-  wait_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "wait", "()V");
-  MAYBE_RETHROW(gdk_env, "cannot find Object.<wait>");
-
-  /* Must have locked an object to call wait */
-  takeLock(gdk_env, cond);
-
-  (*gdk_env)->CallVoidMethod(gdk_env, *(jobject*)cond, wait_mth);
-  MAYBE_RETHROW(gdk_env, "cannot wait on mutex");
+  struct mutexObj_cache cache;
+  jobject condObj = (jobject) gcond;
+  jobject mutexObj = (jobject) gmutex;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("cond_wait_jni_impl(condObj=%p, mutexObj=%p)",
+	     condObj, mutexObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  assert (condObj);
+  assert (mutexObj);
+  /* Must have locked a Java object to call wait on it */
+  if (ENTER_MONITOR (env, condObj) < 0)
+    goto done;
+
+  /* Our atomicity is now guaranteed; we're protected by the Java monitor on
+     condObj.  Unlock the GMutex. */
+  if (mutexObj_unlock (env, mutexObj, &cache))
+    goto done;
+
+  (*env)->CallVoidMethod (env, condObj, obj_wait_mth);
+  if (MAYBE_BROKEN (env, "cannot wait on condObj"))
+    {
+      EXIT_MONITOR (env, condObj);	/* ignore err checking */
+      goto done;
+    }
 
-  releaseLock(gdk_env, cond);
+  /* Re-acquire the lock on the GMutex.  Do this while we're protected by the
+     Java monitor on condObj. */
+  if (mutexObj_lock (env, mutexObj, &cache))
+    goto done;
+
+  EXIT_MONITOR (env, condObj);
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
-/*  Wait on a condition vairable until a timeout.  This is a little tricky
+
+/** Wait on a condition variable until a timeout.  This is a little tricky
  * for us.  We first call Object.wait(J) giving it the appropriate timeout
  * value.  On return, we check whether an InterruptedException happened.  If
- * so, that is Java-speak for wait timing out.
+ * so, that is Java-speak for wait timing out.  
+ * 
+ * We return FALSE if we timed out.  Return TRUE if the condition was
+ * signalled first, before we timed out.
+ *
+ * In case of trouble we throw a Java exception.  Whether we return FALSE or
+ * TRUE depends upon whether the condition was raised before the trouble
+ * happened. 
+ *
+ * I believe that this function goes to the proper lengths to try to unlock
+ * all of the locked mutexes and monitors, as appropriate, and that it further
+ * tries to make sure that the thrown exception is the current one, not any
+ * future cascaded one from something like a failure to unlock the monitors.
  */
 static gboolean
-g_cond_timed_wait_jni_impl
-  (GCond *cond, GMutex *mutex __attribute__((unused)),
-   GTimeVal *end_time)
+cond_timed_wait_jni_impl (GCond * gcond, GMutex * gmutex, GTimeVal * end_time)
 {
-  jclass lcl_class;
-  jmethodID wait_mth;
-  JNIEnv *gdk_env;
-  jlong time;
+  JNIEnv *env;
+  union env_union e;
+  jlong time_millisec;
+  jint time_nanosec;
   jthrowable cause;
+  jobject condObj = (jobject) gcond;
+  jobject mutexObj = (jobject) gmutex;
+  gboolean condRaised = FALSE;	/*  Condition has not been raised yet. */
+  struct mutexObj_cache cache;
+  gboolean interrupted;
+
+  if (TRACE_API_CALLS)
+    {
+      tracing ("cond_timed_wait_jni_impl(cond=%p, mutex=%p,"
+	       " end_time=< sec=%lu, usec=%lu >)", condObj, mutexObj,
+	       (unsigned long) end_time->tv_sec,
+	       (unsigned long) end_time->tv_usec);
+    }
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
 
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Object");
-  MAYBE_RETHROW(gdk_env, "cannot find Object");
-  
-  wait_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "wait", "(J)V");
-  MAYBE_RETHROW(gdk_env, "cannot find Object.<wait(J)>");
-  
-  time = end_time->tv_sec*1000;
-  time += end_time->tv_usec/1000;
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  time_millisec = end_time->tv_sec * 1000 + end_time->tv_usec / 1000;
+  time_nanosec = 1000 * (end_time->tv_usec % 1000);
 
   /* Must have locked an object to call wait */
-  takeLock(gdk_env, cond);
+  if (ENTER_MONITOR (env, condObj) < 0)
+    goto done;
+
+  if (mutexObj_unlock (env, mutexObj, &cache) < 0)
+    {
+      if (EXIT_MONITOR (env, condObj) < 0)
+	criticalMsg
+	  ("Unable to unlock an existing lock on a condition; your proram may deadlock");
+      goto done;
+    }
+
+
+  (*env)->CallVoidMethod (env, condObj, obj_wait_nanotime_mth,
+			  time_millisec, time_nanosec);
+
+  /* If there was trouble, save that fact, and the reason for the trouble.  We
+     want to respond to this condition as fast as possible. */
+  cause = (*env)->ExceptionOccurred (env);
+
+  if ( ! cause )
+    {
+      condRaised = TRUE;	/* condition was signalled */
+    }
+  else if ((*env)->IsInstanceOf (env, cause, interrupted_exception_class))
+    {
+      condRaised = FALSE;	/* Condition was not raised before timeout.
+				   (This is redundant with the initialization
+				   of condRaised above) */
+      (*env)->ExceptionClear (env);	/* Clear the InterruptedException. */
+      cause = NULL;		/* no pending cause now.  */
+    }
+  else
+    {
+      interrupted = FALSE;	/* Trouble, but not because of
+				   InterruptedException.  Assume the condition
+				   was not raised. */
+      /* Leave condRaised set to FALSE */
+    }
+
+  /* Irrespective of whether there is a pending problem to report, go ahead
+     and try to clean up.  This may end up throwing an exception that is
+     different from the one that was thrown by the call to Object.wait().
+     So we will override it with the first exception (don't want to have
+     cascading problems). */
+  if (mutexObj_lock (env, mutexObj, &cache) && !cause)
+    {
+      cause = (*env)->ExceptionOccurred (env);
+      assert (cause);
+    }
 
-  (*gdk_env)->CallVoidMethod(gdk_env, *(jobject*)cond, wait_mth, time);
+  if (EXIT_MONITOR (env, condObj) && !cause)
+    {
+      cause = (*env)->ExceptionOccurred (env);
+      assert (cause);
+    }
 
-  if ((cause = (*gdk_env)->ExceptionOccurred(gdk_env)) != NULL) {
-    jclass intr = (*gdk_env)->FindClass (gdk_env, "java.lang.InterruptedException");
-    if ( (*gdk_env)->IsInstanceOf(gdk_env, cause, intr) ) {
-      releaseLock(gdk_env, cond);
-  return FALSE;
-    } else {
-      MAYBE_RETHROW(gdk_env, "error in timed wait");
+  if (cause)			/* Raise the first cause. */
+    {
+      BROKEN_CAUSE (env, cause, "error in timed wait or during its cleanup");
+      goto done;
     }
-  }
 
-  releaseLock(gdk_env, cond);
+  SHOW_OLD_TROUBLE ();
 
-  return TRUE;
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> condRaised = %s\n", condRaised ? "TRUE" : "FALSE");
+  return condRaised;
 }
 
-/* Free a condition variable.  (isn't C fun?) */
-static void g_cond_free_jni_impl (GCond *cond) {
-  freePlainObject( (jobject*)cond );
+
+/* Free a condition variable.  (isn't C fun?).  Can not fail. */
+static void
+cond_free_jni_impl (GCond * cond)
+{
+  jobject condObj = (jobject) cond;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("cond_free_jni_impl(condObj = %p)", condObj);
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  freeObject (env, condObj);
+
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
 }
 
 
@@ -368,132 +1955,638 @@
 /* Thread-local data code		     				*/
 /************************************************************************/
 
-/*  Create a new thread-local key.  We use java.lang.ThreadLocal objects
- * for this.
+/* Create a new thread-local key.  We use java.lang.ThreadLocal objects
+ * for this.  This returns the pointer representation of a Java global
+ * reference. 
+ * 
+ * We will throw a Java exception and return NULL in case of failure.
  */
-static GPrivate *g_private_new_jni_impl
-  (GDestroyNotify notify __attribute__((unused)))
+static GPrivate *
+private_new_jni_impl (GDestroyNotify notify __attribute__ ((unused)))
 {
-  jclass lcl_class;
-  jobject *local;
-  JNIEnv *gdk_env;
-  jmethodID ctor;
-
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+  JNIEnv *env;
+  union env_union e;
+  jobject lcl_key;
+  jobject global_key;
+  GPrivate *gkey = NULL;	/* Error return code */
+
+  if (TRACE_API_CALLS)
+    tracing ("private_new_jni_impl()");
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  lcl_key = (*env)->NewObject (env, threadlocal_class, threadlocal_ctor);
+  if ( ! lcl_key )
+    {
+      BROKEN (env, "cannot allocate a ThreadLocal");
+      goto done;
+    }
 
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.ThreadLocal");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal");
+  global_key = ((*env)->NewGlobalRef (env, lcl_key));
+  DELETE_LOCAL_REF (env, lcl_key);
+  if ( ! global_key)
+    {
+      NEW_BROKEN (env, "cannot create a GlobalRef to a new ThreadLocal");
+      goto done;
+    }
 
-  ctor = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "<init>", "()V");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal.<init>");
+  gkey = (GPrivate *) global_key;
+  SHOW_OLD_TROUBLE ();
 
-  local = (jobject *) g_malloc (sizeof (jobject));
-  *local = (*gdk_env)->NewObject(gdk_env, lcl_class, ctor);
-  MAYBE_RETHROW(gdk_env, "cannot allocate a ThreadLocal");
-  
-  *local = ((*gdk_env)->NewGlobalRef (gdk_env, *local));
-  MAYBE_RETHROW(gdk_env, "cannot create a GlobalRef");
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> %p\n", (void *) gkey);
 
-  return (GPrivate*) local;
+  return gkey;
 }
 
 /*  Get this thread's value for a thread-local key.  This is simply
- * ThreadLocal.get for us.
+ * ThreadLocal.get for us.  Return NULL if no value.  (I can't think of
+ * anything else to do.)
  */
-static gpointer g_private_get_jni_impl (GPrivate *private) {
-  jclass lcl_class;
-  jobject lcl_obj;
-  JNIEnv *gdk_env;
-  jmethodID get_mth;
-  jclass int_class;
-  jmethodID val_mth;
-  jint int_val;
-
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+static gpointer
+private_get_jni_impl (GPrivate * gkey)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject val_wrapper;
+  jobject keyObj = (jobject) gkey;
+  gpointer thread_specific_data = NULL;	/* Init to the error-return value */
+
+  jlong val;
+
+  if (TRACE_API_CALLS)
+    tracing ("private_get_jni_impl(keyObj=%p)", keyObj);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  val_wrapper = (*env)->CallObjectMethod (env, keyObj, threadlocal_get_mth);
+  if (MAYBE_BROKEN (env, "cannot find thread-local object"))
+    goto done;
+
+  if (! val_wrapper ) 
+    {
+      /* It's Java's "null" object.  No ref found.  This is OK; we must never
+         have set a value in this thread.  Note that this next statement is
+         not necessary, strictly speaking, since we're already initialized to
+         NULL.  A good optimizing C compiler will detect that and optimize out
+         this statement. */
+      thread_specific_data = NULL;
+      goto done;
+    }
 
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.ThreadLocal");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal");
+  val = (*env)->CallLongMethod (env, val_wrapper, long_longValue_mth);
 
-  get_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "get", "()Ljava/lang/Object;");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal.<get>");
+  if (MAYBE_BROKEN (env, "cannot get thread local value"))
+    goto done;
 
-  lcl_obj = (*gdk_env)->CallObjectMethod(gdk_env, *(jobject*)private, get_mth);
-  MAYBE_RETHROW(gdk_env, "cannot find thread-local object");
+  thread_specific_data = (gpointer) (intptr_t) val;
 
-  int_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Integer");
-  MAYBE_RETHROW(gdk_env, "cannot find Integer");
+  /* Only re-raise the old pending exception if a new one hasn't come along to
+     supersede it.  */
+  SHOW_OLD_TROUBLE ();
 
-  val_mth = (*gdk_env)->GetMethodID(gdk_env, int_class, "intValue", "()I");
-  MAYBE_RETHROW(gdk_env, "cannot find Integer.<intValue>");
+done:
 
-  int_val = (*gdk_env)->CallIntMethod(gdk_env, lcl_obj, val_mth);
-  MAYBE_RETHROW(gdk_env, "cannot get thread local value");
+  if (TRACE_API_CALLS)
+    tracing (" ==> %p\n", thread_specific_data);
 
-  return (gpointer) int_val;
+  return thread_specific_data;
 }
 
-/*  Set this thread's value for a thread-local key.  This is simply
- * ThreadLocal.set for us.
+/* Set this thread's value for a thread-local key.  This is simply
+ * ThreadLocal.set() for us.
  */
-static void g_private_set_jni_impl (GPrivate *private, gpointer data) {
-  jclass lcl_class, int_class;
-  jobject lcl_obj;
-  JNIEnv *gdk_env;
-  jmethodID new_int, set_mth;
+static void
+private_set_jni_impl (GPrivate * gkey, gpointer thread_specific_data)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject val_wrapper;
+  jobject keyObj = (jobject) gkey;
+
+
+  if (TRACE_API_CALLS)
+    tracing ("private_set_jni_impl(keyObj=%p, thread_specific_data=%p)",
+	     keyObj, thread_specific_data);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  /* We are just going to always use a Java long to represent a C pointer.
+     Otherwise all of the code would end up being conditionalized for various
+     pointer sizes, and that seems like too much of a hassle, in order to save
+     a paltry few bytes, especially given the horrendous overhead of JNI in
+     any case. 
+   */
+
+  val_wrapper = (*env)->NewObject (env, long_class, long_ctor,
+				   (jlong) (intptr_t) thread_specific_data);
+  if ( ! val_wrapper )
+    {
+      BROKEN (env, "cannot create a java.lang.Long");
+      goto done;
+    }
+
+  /* At this point, we now have set lcl_obj as a numeric class that wraps
+     around the thread-specific data we were given. */
+  (*env)->CallVoidMethod (env, keyObj, threadlocal_set_mth, val_wrapper);
+  if (MAYBE_BROKEN (env, "cannot set thread local value"))
+    goto done;
+
+  SHOW_OLD_TROUBLE ();
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
+}
+
+
+/** Create an object of type gnu.java.awt.peer.gtk.GThreadNativeMethodRunner.
+    Run it.
+
+    We need to create joinable threads.  We handle the notion of a joinable
+    thread by determining whether or not we are going to maintain a permanent
+    hard reference to it until it croaks.
+
+    Posix does not appear to have a Java-like concept of daemon threads, where
+    the JVM will exit when there are only daemon threads running.
+
+    Error handling: 
+
+    To quote from the glib guide:
+       "GError should only be used to report recoverable runtime errors, never
+        to report programming errors."   
+
+    So how do we consider the failure to create a thread?  Well, each of the
+    failure cases in this function are discussed, and none of them are really
+    recoverable.
+
+    The glib library is really designed so that you should fail
+    catastrophically in case of "programming errors".  The only error defined
+    for the GThread functions is G_THREAD_ERROR_AGAIN, and that for
+    thread_create.
+
+    Most of these GThread functions could fail if we run out of memory, for
+    example, but the only one capable of reporting that fact is
+    thread_create. */
+static void
+thread_create_jni_impl (GThreadFunc	    func,
+			gpointer            data,
+			gulong              stack_size __attribute__((unused)),
+			gboolean            joinable,
+			gboolean            bound __attribute__((unused)),
+			GThreadPriority     gpriority,
+			/* This prototype is horrible.  threadIDp is actually
+			   a gpointer to the thread's thread-ID.  Which is, 
+			   of course, itself a gpointer-typed value.  Ouch. */ 
+			gpointer            threadIDp, 
+			/* Do not touch the GError stuff unless you have
+			   RECOVERABLE trouble.   There is no recoverable
+			   trouble in this implementation.  */ 
+			GError	      **errorp __attribute__((unused)))
+{
+  JNIEnv *env;
+  union env_union e;
+  union func_union f;
+  jboolean jjoinable = joinable;
+  jobject newThreadObj;
+  gpointer threadID;		/* to be filled in */
+
+  if (TRACE_API_CALLS)
+    {
+      f.g_func = func;
+      tracing ("thread_create_jni_impl(func=%p, data=%p, joinable=%s,"
+               " threadIDp=%p, *(int *) threadIDp = %d)",
+               f.void_func, data, joinable ? "TRUE" : "FALSE",
+               threadIDp, *(int *) threadIDp);
+    }
 
-  (*gdk_vm)->GetEnv(gdk_vm, (void **)&gdk_env, JNI_VERSION_1_1);
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    {
+      /*  The failed call to setup the cache is certainly not recoverable;
+	  not appropriate for G_THREAD_ERROR_AGAIN.  */
+      *(gpointer *) threadIDp = NULL;
+      goto done;
+    }
+  HIDE_OLD_TROUBLE (env);
 
-  int_class = (*gdk_env)->FindClass (gdk_env, "java.lang.Integer");
-  MAYBE_RETHROW(gdk_env, "cannot find Integer");
+  /* If a thread is joinable, then notify its constructor.  The constructor
+     will enter a hard reference for it, and the hard ref. won't go away until
+     the thread has been joined. */
+  newThreadObj = 
+    (*env)->NewObject (env, runner_class, runner_ctor, 
+                       (jlong) (intptr_t) func, (jlong) (intptr_t) data, 
+                       jjoinable);
+  if ( ! newThreadObj )
+    {
+      BROKEN (env, "creating a new thread failed in the constructor");
+      *(gpointer *) threadIDp = NULL;
+      /*  The failed call to the constructor does not throw any errors such
+	  that G_THREAD_ERROR_AGAIN is appropriate.  No other recoverable
+	  errors defined.  Once again, we go back to the VM. */
+      goto done;
+    }
 
-  new_int = (*gdk_env)->GetMethodID(gdk_env, int_class, "<init>", "(I)V");
-  MAYBE_RETHROW(gdk_env, "cannot find Integer.<init>");
+  if (threadObj_set_priority (env, newThreadObj, gpriority) < 0)
+    {
+      *(gpointer *) threadIDp = NULL;
+      /* None of these possible exceptions from Thread.setPriority() are
+	 recoverable, so they are not appropriate for EAGAIN.  So we should
+	 fail. */  
+      goto done;
+    }
+
+  (*env)->CallVoidMethod (env, runner_class, runner_start_mth);
 
-  lcl_obj = (*gdk_env)->NewObject(gdk_env, int_class, new_int, (jint)data);
-  MAYBE_RETHROW(gdk_env, "cannot create an Integer");
+  if (MAYBE_BROKEN (env, "starting a new thread failed"))
+    {
+      *(gpointer *) threadIDp = NULL;
+      /* The only exception Thread.start() throws is
+	 IllegalStateException.  And that would indicate a programming error. 
+
+	 So there are no situations such that G_THREAD_ERROR_AGAIN would be
+	 OK. 
+
+	 So, we don't use g_set_error() here to perform any error reporting.
+	 */
+      goto done;
+    }
 
-  lcl_class = (*gdk_env)->FindClass (gdk_env, "java.lang.ThreadLocal");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal");
+  threadID = getThreadIDFromThread (env, newThreadObj);
 
-  set_mth = (*gdk_env)->GetMethodID(gdk_env, lcl_class, "set", "(Ljava/lang/Object;)V");
-  MAYBE_RETHROW(gdk_env, "cannot find ThreadLocal.<set>");
+  *(gpointer *) threadIDp = threadID;
+  SHOW_OLD_TROUBLE ();
 
-  (*gdk_env)->CallVoidMethod(gdk_env, *(jobject*)private, set_mth, lcl_obj);
-  MAYBE_RETHROW(gdk_env, "cannot set thread local value");
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> (threadID = %p) \n", threadID);
 }
 
 
+/* Wraps a call to g_thread_yield. */
+static void
+thread_yield_jni_impl (void)
+{
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("thread_yield_jni_impl()");
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  (*env)->CallStaticVoidMethod (env, thread_class, thread_yield_mth);
+  if (MAYBE_BROKEN (env, "Thread.yield() failed"))
+    goto done;
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
+}
+
+
+static void
+thread_join_jni_impl (gpointer threadID)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject threadObj = NULL;
+
+  if ( TRACE_API_CALLS )
+    tracing ("thread_join_jni_impl(threadID=%p) ", threadID);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+  HIDE_OLD_TROUBLE (env);
+
+  threadObj = getThreadFromThreadID (env, threadID);
+  if ( ! threadObj )		/* Already reported with BROKEN  */
+    goto done;
+
+  (*env)->CallVoidMethod (env, threadObj, thread_join_mth);
+  if (MAYBE_BROKEN (env, "Thread.join() failed"))
+    goto done;
+
+
+  (*env)->CallStaticVoidMethod
+    (env, runner_class, runner_deRegisterJoinable_mth, threadObj);
+  if (MAYBE_BROKEN (env, "Thread.deRegisterJoinableThread() failed"))
+    goto done;
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  DELETE_LOCAL_REF (env, threadObj);
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID \n");
+}
+
+/* Terminate the current thread.  Unlike pthread_exit(), here we do not need
+   to bother with a return value or exit value for the thread which is about
+   to croak.  (The gthreads abstraction doesn't use it.)  However, we *do*
+   need to bail immediately.  We handle this with Thread.stop(), which is
+   a deprecated method.
+
+   It's deprecated since we might leave objects protected by monitors in
+   half-constructed states on the way out -- Thread.stop() throws a
+   ThreadDeath exception, which is usually unchecked.  There is no good
+   solution that I can see. */ 
+static void
+thread_exit_jni_impl (void)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject this_thread;
+
+  if (TRACE_API_CALLS)
+    tracing ("thread_exit_jni_impl() ");
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    goto done;
+
+  HIDE_OLD_TROUBLE (env);
+
+  this_thread = (*env)->
+    CallStaticObjectMethod (env, thread_class, thread_current_mth);
+
+  if ( ! this_thread )
+    {
+      BROKEN (env, "cannot get current thread");
+      goto done;
+    }
+
+  (*env)->CallVoidMethod (env, this_thread, thread_stop_mth);
+  if (MAYBE_BROKEN (env, "cannot call Thread.stop() on current thread"))
+    goto done;
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID \n");
+}
+
+
+/* Translate a GThreadPriority to a Java priority level. */
+static jint
+javaPriorityLevel (GThreadPriority priority)
+{
+  /* We have these fields in java.lang.Thread to play with:
+
+     static int MIN_PRIORITY     The minimum priority that a thread can have.
+     static int NORM_PRIORITY    The default priority that is assigned to a 
+     thread.
+     static int MAX_PRIORITY     The maximum priority that a thread can have.
+
+     We get these from the header file generated by javah, even though they're
+     documented as being 1, 5, and 10.
+   */
+  static const jint minJPri	= 
+    gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY;
+  static const jint normJPri	= 
+    gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY;
+  static const jint maxJPri	= 
+    gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY;
+
+  switch (priority)
+    {
+    case G_THREAD_PRIORITY_LOW:
+      return minJPri;
+      break;
+
+    default:
+      assert_not_reached ();
+      /* Deliberate fall-through if assertions are turned off; also shuts up
+         GCC warnings if they're turned on.   */
+    case G_THREAD_PRIORITY_NORMAL:
+      return normJPri;
+      break;
+
+    case G_THREAD_PRIORITY_HIGH:
+      return (normJPri + maxJPri) / 2;
+      break;
+
+    case G_THREAD_PRIORITY_URGENT:
+      return maxJPri;
+      break;
+    }
+}
+
+
+/** It would be safe not to implement this, according to the JNI docs, since
+    not all platforms do thread priorities.  However, we might as well
+    provide the hint for those who want it. 
+*/
+static void
+thread_set_priority_jni_impl (gpointer gThreadID, GThreadPriority gpriority)
+{
+  jobject threadObj = NULL;
+  JNIEnv *env;
+  union env_union e;
+
+  if (TRACE_API_CALLS)
+    tracing ("thread_set_priority_jni_impl(gThreadID=%p, gpriority = %u) ",
+	     gThreadID, gpriority);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  if (setup_cache (env) < 0)
+    goto done;
+
+  HIDE_OLD_TROUBLE (env);
+
+
+  threadObj = getThreadFromThreadID (env, gThreadID);
+  if ( ! threadObj)		/* Reported with BROKEN already.  */
+    goto done;
+
+  if (threadObj_set_priority (env, threadObj, gpriority))
+    goto done;
+
+  SHOW_OLD_TROUBLE ();
+
+done:
+  DELETE_LOCAL_REF (env, threadObj);
+
+  if (TRACE_API_CALLS)
+    tracing (" ==> VOID\n");
+}
+
+
+/** It would be safe not to implement this, according to the JNI docs, since
+    not all platforms do thread priorities.  However, we might as well
+    provide the hint for those who want it.
+
+    -1 on failure, 0 on success. */
+static int
+threadObj_set_priority (JNIEnv * env, jobject threadObj,
+			GThreadPriority gpriority)
+{
+  jint javaPriority = javaPriorityLevel (gpriority);
+  (*env)->CallVoidMethod (env, threadObj, thread_setPriority_mth,
+			  javaPriority);
+  return MAYBE_BROKEN (env, "Thread.setPriority() failed");
+}
+
+
+/** Return the result of Thread.currentThread(), a static method. */
+static void
+thread_self_jni_impl (/* Another confusing glib prototype.  This is
+			 actually  a gpointer to the thread's thread-ID.
+			 Which is, of course, a gpointer. */
+		      gpointer my_thread_IDp)
+{
+  JNIEnv *env;
+  union env_union e;
+  jobject this_thread;
+  gpointer my_threadID;
+
+  if (TRACE_API_CALLS)
+    tracing ("thread_self_jni_impl(my_thread_IDp=%p)", my_thread_IDp);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+
+  if (setup_cache (env) < 0)
+    return;
+
+  HIDE_OLD_TROUBLE (env);
+
+  this_thread = (*env)->
+    CallStaticObjectMethod (env, thread_class, thread_current_mth);
+  if (! this_thread )
+    {
+      BROKEN (env, "cannot get current thread");
+      my_threadID = NULL;
+      goto done;
+    }
+
+  my_threadID = getThreadIDFromThread (env, this_thread);
+  SHOW_OLD_TROUBLE ();
+
+done:
+  if (TRACE_API_CALLS)
+    tracing (" ==> (my_threadID = %p) \n", my_threadID);
+
+  *(gpointer *) my_thread_IDp = my_threadID;
+}
+
+
+static gboolean
+thread_equal_jni_impl (gpointer thread1, gpointer thread2)
+{
+  JNIEnv *env;
+  union env_union e;
+
+  gpointer threadID1 = *(gpointer *) thread1;
+  gpointer threadID2 = *(gpointer *) thread2;
+
+  jobject thread1_obj = NULL;
+  jobject thread2_obj = NULL;
+  gboolean ret;
+
+  if (TRACE_API_CALLS)
+    tracing ("thread_equal_jni_impl(threadID1=%p, threadID2=%p)",
+	     threadID1, threadID2);
+
+  e.jni_env = &env;
+  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);
+  if (setup_cache (env) < 0)
+    {
+      ret = FALSE;		/* what is safer?  We really don't ever want
+				   to return from here.  */
+      goto done;
+    }
+
+  HIDE_OLD_TROUBLE (env);
+  thread1_obj = getThreadFromThreadID (env, threadID1);
+  thread2_obj = getThreadFromThreadID (env, threadID2);
+
+  ret = (*env)->CallBooleanMethod (env, thread1_obj,
+				   thread_equals_mth, thread2_obj);
+
+  if (MAYBE_BROKEN (env, "Thread.equals() failed"))
+    {
+      ret = FALSE;
+      goto done;
+    }
+
+  SHOW_OLD_TROUBLE ();
+
+
+done:
+  DELETE_LOCAL_REF (env, thread1_obj);
+  DELETE_LOCAL_REF (env, thread2_obj);
+
+  if (TRACE_API_CALLS)
+    tracing (" ==> %s\n", ret ? "TRUE" : "FALSE");
+
+  return ret;
+}
+
+
+
+
 /************************************************************************/
 /* GLIB interface			     				*/
 /************************************************************************/
 
 /* set of function pointers to give to glib. */
-GThreadFunctions g_thread_jni_functions =
-{
-  g_mutex_new_jni_impl,	      /* mutex_new */
-  g_mutex_lock_jni_impl,      /* mutex_lock */
-  g_mutex_trylock_jni_impl,   /* mutex_try_lock */
-  g_mutex_unlock_jni_impl,    /* mutex_unlock */
-  g_mutex_free_jni_impl,      /* mutex_free */
-  g_cond_new_jni_impl,        /* cond_new */
-  g_cond_signal_jni_impl,     /* cond_signal */
-  g_cond_broadcast_jni_impl,  /* cond_broadcast */
-  g_cond_wait_jni_impl,       /* cond_wait */
-  g_cond_timed_wait_jni_impl, /* cond_timed_wait */
-  g_cond_free_jni_impl,       /* cond_free */
-  g_private_new_jni_impl,     /* private_new */
-  g_private_get_jni_impl,     /* private_get */
-  g_private_set_jni_impl,     /* private_set */
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL
+GThreadFunctions portable_native_sync_jni_functions = {
+  mutex_new_jni_impl,		/* mutex_new */
+  mutex_lock_jni_impl,		/* mutex_lock */
+  mutex_trylock_jni_impl,	/* mutex_trylock */
+  mutex_unlock_jni_impl,	/* mutex_unlock */
+  mutex_free_jni_impl,		/* mutex_free */
+  cond_new_jni_impl,		/* cond_new */
+  cond_signal_jni_impl,		/* cond_signal */
+  cond_broadcast_jni_impl,	/* cond_broadcast */
+  cond_wait_jni_impl,		/* cond_wait */
+  cond_timed_wait_jni_impl,	/* cond_timed_wait */
+  cond_free_jni_impl,		/* cond_free */
+  private_new_jni_impl,		/* private_new */
+  private_get_jni_impl,		/* private_get */
+  private_set_jni_impl,		/* private_set */
+  thread_create_jni_impl,	/* thread_create */
+  thread_yield_jni_impl,	/* thread_yield */
+  thread_join_jni_impl,		/* thread_join */
+  thread_exit_jni_impl,		/* thread_exit */
+  thread_set_priority_jni_impl,	/* thread_set_priority */
+  thread_self_jni_impl,		/* thread_self */
+  thread_equal_jni_impl,	/* thread_equal */
 };
+
 
-/* ??? */
-void gdk_threads_wake () {
-
-}
+/* Keep c-font-lock-extra-types in alphabetical order. */
+/* Local Variables: */
+/* c-file-style: "gnu" */
+/* c-font-lock-extra-types: ("\\sw+_t" "gboolean" "GError" "gpointer"
+   "GPrivate" "GThreadFunc" "GThreadFunctions" "GThreadPriority" 
+   "gulong" 
+   "JNIEnv" 
+   "jboolean" "jclass" "jfieldID" "jint" "jlong" "jmethodID" "jobject" "jstring" "jthrowable" ) */
+/* End: */
Index: jni/gtk-peer/gthread-jni.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gthread-jni.h,v
retrieving revision 1.2
diff -u -r1.2 gthread-jni.h
--- jni/gtk-peer/gthread-jni.h	30 Jun 2003 23:53:29 -0000	1.2
+++ jni/gtk-peer/gthread-jni.h	6 Sep 2004 16:36:15 -0000
@@ -42,7 +42,7 @@
 #include <glib.h>
 #include "gtkpeer.h"
 
-extern GThreadFunctions g_thread_jni_functions;
-extern JavaVM *gdk_vm;
+extern GThreadFunctions portable_native_sync_jni_functions;
+extern JavaVM *the_vm;
 
 #endif /* __GTHREADJNI_H__ */
Index: jni/gtk-peer/gtkcairopeer.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gtkcairopeer.h,v
retrieving revision 1.1
diff -u -r1.1 gtkcairopeer.h
--- jni/gtk-peer/gtkcairopeer.h	31 Dec 2003 08:58:31 -0000	1.1
+++ jni/gtk-peer/gtkcairopeer.h	6 Sep 2004 16:36:15 -0000
@@ -71,7 +71,8 @@
   GdkWindow *win;
   GdkPixbuf *drawbuf;
   char *pattern_pixels;
-  cairo_surface_t *pattern;
+  cairo_surface_t *pattern_surface;
+  cairo_pattern_t *pattern;
   gboolean debug;
 };
 
Index: jni/gtk-peer/gtkpeer.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gtkpeer.h,v
retrieving revision 1.12
diff -u -r1.12 gtkpeer.h
--- jni/gtk-peer/gtkpeer.h	23 Dec 2003 19:24:00 -0000	1.12
+++ jni/gtk-peer/gtkpeer.h	6 Sep 2004 16:36:15 -0000
@@ -91,6 +91,20 @@
     (*env)->DeleteGlobalRef (env, *globRefPtr); \
     free (globRefPtr);} while (0)
 
+extern struct state_table *native_pixbufdecoder_state_table;
+
+#define NSA_PB_INIT(env, clazz) \
+  native_pixbufdecoder_state_table = init_state_table (env, clazz)
+
+#define NSA_GET_PB_PTR(env, obj) \
+  get_state (env, obj, native_pixbufdecoder_state_table)
+
+#define NSA_SET_PB_PTR(env, obj, ptr) \
+  set_state (env, obj, native_pixbufdecoder_state_table, (void *)ptr)
+
+#define NSA_DEL_PB_PTR(env, obj) \
+  remove_state_slot (env, obj, native_pixbufdecoder_state_table)
+
 #endif /* JVM_SUN */
 
 struct graphics
@@ -118,14 +132,14 @@
 
 #define SYNTHETIC_EVENT_MASK (1 << 10)
 
-#define AWT_SHIFT_MASK   (1 << 0)
-#define AWT_CTRL_MASK    (1 << 1)
-#define AWT_META_MASK    (1 << 2)
-#define AWT_ALT_MASK     (1 << 3)
-
-#define AWT_BUTTON1_MASK (1 << 4)
-#define AWT_BUTTON2_MASK AWT_ALT_MASK
-#define AWT_BUTTON3_MASK AWT_META_MASK
+#define AWT_SHIFT_DOWN_MASK   (1 << 6)
+#define AWT_CTRL_DOWN_MASK    (1 << 7)
+#define AWT_META_DOWN_MASK    (1 << 8)
+#define AWT_ALT_DOWN_MASK     (1 << 9)
+
+#define AWT_BUTTON1_DOWN_MASK (1 << 10)
+#define AWT_BUTTON2_DOWN_MASK (1 << 11)
+#define AWT_BUTTON3_DOWN_MASK (1 << 12)
 
 #define MULTI_CLICK_TIME   250
 /* as opposed to a MULTI_PASS_TIME :) */
@@ -361,8 +375,8 @@
 #define VK_ALT_GRAPH 65406
 #define VK_UNDEFINED 0
 
-#define AWT_FOCUS_LOST 1004
-#define AWT_FOCUS_GAINED 1005
+#define AWT_FOCUS_GAINED 1004
+#define AWT_FOCUS_LOST 1005
 
 #define AWT_WINDOW_OPENED 200
 #define AWT_WINDOW_CLOSING 201
@@ -385,6 +399,35 @@
 #define AWT_STYLE_BOLD   1
 #define AWT_STYLE_ITALIC 2
 
+/* From java.awt.SystemColor */
+#define AWT_DESKTOP                  0
+#define AWT_ACTIVE_CAPTION           1
+#define AWT_ACTIVE_CAPTION_TEXT      2
+#define AWT_ACTIVE_CAPTION_BORDER    3
+#define AWT_INACTIVE_CAPTION         4
+#define AWT_INACTIVE_CAPTION_TEXT    5
+#define AWT_INACTIVE_CAPTION_BORDER  6
+#define AWT_WINDOW                   7
+#define AWT_WINDOW_BORDER            8
+#define AWT_WINDOW_TEXT              9
+#define AWT_MENU                    10
+#define AWT_MENU_TEXT               11
+#define AWT_TEXT                    12
+#define AWT_TEXT_TEXT               13
+#define AWT_TEXT_HIGHLIGHT          14
+#define AWT_TEXT_HIGHLIGHT_TEXT     15
+#define AWT_TEXT_INACTIVE_TEXT      16
+#define AWT_CONTROL                 17
+#define AWT_CONTROL_TEXT            18
+#define AWT_CONTROL_HIGHLIGHT       19
+#define AWT_CONTROL_LT_HIGHLIGHT    20
+#define AWT_CONTROL_SHADOW          21
+#define AWT_CONTROL_DK_SHADOW       22
+#define AWT_SCROLLBAR               23
+#define AWT_INFO                    24
+#define AWT_INFO_TEXT               25
+#define AWT_NUM_COLORS              26
+
 extern jmethodID setBoundsCallbackID;
 
 extern jmethodID postActionEventID;
@@ -406,6 +449,8 @@
 extern jmethodID gdkColorID;
 extern JNIEnv *gdk_env;
 
+extern double dpi_conversion_factor;
+
 extern GtkWindowGroup *global_gtk_window_group;
 
 void awt_event_handler (GdkEvent *event);
@@ -428,4 +473,19 @@
   const char *label;
 };
 
+#define DEBUG_LOCKING 0
+
+#if DEBUG_LOCKING
+#define gdk_threads_enter()                       \
+{                                                 \
+  g_print ("lock: %s, %d\n", __FILE__, __LINE__); \
+  gdk_threads_enter ();                           \
+}
+#define gdk_threads_leave()                         \
+{                                                   \
+  g_print ("unlock: %s, %d\n", __FILE__, __LINE__); \
+  gdk_threads_leave ();                             \
+}
+#endif
+
 #endif /* __GTKPEER_H */
