diff options
author | fitzsim <fitzsim@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-09 16:07:07 +0000 |
---|---|---|
committer | fitzsim <fitzsim@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-09 16:07:07 +0000 |
commit | 48591d852fc71f04d7083dcb0b37cf27b5d6942b (patch) | |
tree | 0802013820f309170e8ae5584b09e9672bab2cb6 /libjava/classpath/javax | |
parent | 5f2bd98fb3528fa948341bdac3f4c4ac9a177595 (diff) | |
download | gcc-48591d852fc71f04d7083dcb0b37cf27b5d6942b.tar.gz |
2006-06-09 Thomas Fitzsimmons <fitzsim@redhat.com>
* java/lang/String.java, classpath/native/jni/classpath/jcl.h,
classpath/native/jni/qt-peer/eventmethods.h,
classpath/native/jni/qt-peer/qtmenupeer.cpp,
classpath/native/jni/qt-peer/.cvsignore,
classpath/native/jni/gtk-peer/gdkdisplay.h,
classpath/native/jni/gtk-peer/cairographics2d.h,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c,
classpath/native/jni/gtk-peer/.cvsignore,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c,
classpath/native/jni/gtk-peer/gtkpeer.h,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c,
classpath/native/jni/gtk-peer/Makefile.am,
classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c,
classpath/native/jawt/Makefile.am,
classpath/native/jawt/.cvsignore,
classpath/native/target/Linux/Makefile.in,
classpath/native/plugin/gcjwebplugin.cc,
classpath/native/plugin/Makefile.am,
classpath/native/plugin/.cvsignore,
classpath/resource/Makefile.in,
classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java,
classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,
classpath/gnu/java/awt/peer/gtk/CairoSurface.java,
classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java,
classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java,
classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,
classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java,
classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java,
classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java,
classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,
classpath/gnu/java/awt/peer/gtk/GdkGraphics.java,
classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,
classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java,
classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java,
classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java,
classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java,
classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java,
classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java,
classpath/gnu/java/awt/peer/gtk/GtkImage.java,
classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java,
classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java,
classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java,
classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java,
classpath/gnu/java/awt/peer/swing/SwingComponent.java,
classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java,
classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java,
classpath/gnu/java/awt/peer/swing/SwingFramePeer.java,
classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java,
classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java,
classpath/gnu/java/awt/print/JavaPrinterJob.java,
classpath/gnu/java/awt/print/PostScriptGraphics2D.java,
classpath/gnu/java/awt/print/SpooledDocument.java,
classpath/gnu/java/awt/print/JavaPrinterGraphics.java,
classpath/gnu/java/awt/BitwiseXORComposite.java,
classpath/gnu/java/awt/font/GNUGlyphVector.java,
classpath/gnu/java/awt/font/opentype/NameDecoder.java,
classpath/gnu/java/awt/java2d/RasterGraphics.java,
classpath/gnu/java/awt/java2d/TexturePaintContext.java,
classpath/gnu/java/awt/java2d/PolyEdge.java,
classpath/gnu/java/awt/java2d/AbstractGraphics2D.java,
classpath/gnu/java/awt/java2d/AlphaCompositeContext.java,
classpath/gnu/java/awt/java2d/ImagePaint.java,
classpath/gnu/java/awt/Buffers.java,
classpath/gnu/classpath/Configuration.java.in,
classpath/gnu/javax/swing/text/html/CombinedAttributes.java,
classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java,
classpath/gnu/javax/swing/text/html/parser/htmlAttributeSet.java,
classpath/gnu/javax/swing/text/html/parser/SmallHtmlAttributeSet.java,
classpath/gnu/javax/swing/text/html/ImageViewIconFactory.java,
classpath/tools/toolwrapper.c,
classpath/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java,
classpath/tools/gnu/classpath/tools/native2ascii/Messages.java,
classpath/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java,
classpath/tools/gnu/classpath/tools/getopt/OptionGroup.java,
classpath/tools/gnu/classpath/tools/getopt/OptionException.java,
classpath/tools/gnu/classpath/tools/getopt/Messages.java,
classpath/tools/gnu/classpath/tools/getopt/Option.java,
classpath/tools/gnu/classpath/tools/getopt/Parser.java,
classpath/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java,
classpath/tools/gnu/classpath/tools/jarsigner/JarSigner.java,
classpath/tools/gnu/classpath/tools/jarsigner/Main.java,
classpath/tools/gnu/classpath/tools/jarsigner/Messages.java,
classpath/tools/gnu/classpath/tools/jarsigner/package.html,
classpath/tools/gnu/classpath/tools/keytool/ListCmd.java,
classpath/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java,
classpath/tools/gnu/classpath/tools/keytool/ExportCmd.java,
classpath/tools/gnu/classpath/tools/keytool/GenKeyCmd.java,
classpath/tools/gnu/classpath/tools/keytool/Messages.java,
classpath/tools/gnu/classpath/tools/keytool/package.html,
classpath/tools/gnu/classpath/tools/keytool/Command.java,
classpath/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java,
classpath/tools/gnu/classpath/tools/keytool/Main.java,
classpath/tools/gnu/classpath/tools/keytool/DeleteCmd.java,
classpath/tools/gnu/classpath/tools/keytool/CertReqCmd.java,
classpath/tools/gnu/classpath/tools/keytool/SelfCertCmd.java,
classpath/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java,
classpath/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java,
classpath/tools/gnu/classpath/tools/keytool/ImportCmd.java,
classpath/tools/gnu/classpath/tools/keytool/PrintCertCmd.java,
classpath/tools/gnu/classpath/tools/rmi/registry/package.html,
classpath/tools/gnu/classpath/tools/rmi/RMIC.txt,
classpath/tools/gnu/classpath/tools/rmi/RMIC.java,
classpath/tools/gnu/classpath/tools/appletviewer/ErrorApplet.java,
classpath/tools/gnu/classpath/tools/appletviewer/AppletClassLoader.java,
classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletContext.java,
classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletContext.java,
classpath/tools/gnu/classpath/tools/appletviewer/AppletSecurityManager.java,
classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletContext.java,
classpath/tools/gnu/classpath/tools/appletviewer/AppletWarning.java,
classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletViewer.java,
classpath/tools/gnu/classpath/tools/appletviewer/AppletTag.java,
classpath/tools/gnu/classpath/tools/appletviewer/ConsoleDialog.java,
classpath/tools/gnu/classpath/tools/appletviewer/Main.java,
classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletWindow.java,
classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletViewer.java,
classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java,
classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletWindow.java,
classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletStub.java,
classpath/tools/gnu/classpath/tools/serialver/Messages.java,
classpath/tools/gnu/classpath/tools/serialver/SerialVer.java,
classpath/tools/gnu/classpath/tools/jar/Creator.java,
classpath/tools/gnu/classpath/tools/jar/Entry.java,
classpath/tools/gnu/classpath/tools/jar/Lister.java,
classpath/tools/gnu/classpath/tools/jar/Main.java,
classpath/tools/gnu/classpath/tools/jar/Updater.java,
classpath/tools/gnu/classpath/tools/jar/Messages.java,
classpath/tools/gnu/classpath/tools/jar/Extractor.java,
classpath/tools/gnu/classpath/tools/jar/Action.java,
classpath/tools/gnu/classpath/tools/jar/Indexer.java,
classpath/tools/gnu/classpath/tools/jar/WorkSet.java,
classpath/tools/gnu/classpath/tools/giop/GRMIC.txt,
classpath/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java,
classpath/tools/gnu/classpath/tools/giop/GRMIC.java,
classpath/tools/Makefile.am, classpath/tools/jarsigner.in,
classpath/tools/keytool.in, classpath/tools/appletviewer.in,
classpath/tools/.cvsignore, classpath/configure.ac,
classpath/javax/swing/JTabbedPane.java,
classpath/javax/swing/AbstractButton.java,
classpath/javax/swing/JViewport.java,
classpath/javax/swing/KeyboardManager.java,
classpath/javax/swing/JMenuItem.java,
classpath/javax/swing/JMenuBar.java,
classpath/javax/swing/MenuSelectionManager.java,
classpath/javax/swing/JOptionPane.java,
classpath/javax/swing/JSpinner.java,
classpath/javax/swing/JCheckBoxMenuItem.java,
classpath/javax/swing/JEditorPane.java,
classpath/javax/swing/JFormattedTextField.java,
classpath/javax/swing/JTree.java,
classpath/javax/swing/CellRendererPane.java,
classpath/javax/swing/JScrollPane.java,
classpath/javax/swing/tree/VariableHeightLayoutCache.java,
classpath/javax/swing/tree/TreeNode.java,
classpath/javax/swing/tree/FixedHeightLayoutCache.java,
classpath/javax/swing/tree/DefaultTreeCellEditor.java,
classpath/javax/swing/tree/TreePath.java,
classpath/javax/swing/tree/RowMapper.java,
classpath/javax/swing/tree/DefaultMutableTreeNode.java,
classpath/javax/swing/tree/DefaultTreeModel.java,
classpath/javax/swing/tree/AbstractLayoutCache.java,
classpath/javax/swing/tree/TreeSelectionModel.java,
classpath/javax/swing/tree/DefaultTreeSelectionModel.java,
classpath/javax/swing/tree/DefaultTreeCellRenderer.java,
classpath/javax/swing/tree/ExpandVetoException.java,
classpath/javax/swing/JList.java,
classpath/javax/swing/table/JTableHeader.java,
classpath/javax/swing/table/AbstractTableModel.java,
classpath/javax/swing/table/DefaultTableModel.java,
classpath/javax/swing/table/TableCellEditor.java,
classpath/javax/swing/table/TableCellRenderer.java,
classpath/javax/swing/ProgressMonitor.java,
classpath/javax/swing/JToolBar.java,
classpath/javax/swing/TransferHandler.java,
classpath/javax/swing/DefaultCellEditor.java,
classpath/javax/swing/DefaultButtonModel.java,
classpath/javax/swing/JLayeredPane.java,
classpath/javax/swing/text/DefaultEditorKit.java,
classpath/javax/swing/text/DefaultCaret.java,
classpath/javax/swing/text/FieldView.java,
classpath/javax/swing/text/JTextComponent.java,
classpath/javax/swing/text/TextAction.java,
classpath/javax/swing/text/StyleContext.java,
classpath/javax/swing/text/html/HTMLDocument.java,
classpath/javax/swing/text/html/MinimalHTMLWriter.java,
classpath/javax/swing/text/html/ImageView.java,
classpath/javax/swing/text/html/HTMLEditorKit.java,
classpath/javax/swing/text/AbstractWriter.java,
classpath/javax/swing/text/GapContent.java,
classpath/javax/swing/text/Utilities.java,
classpath/javax/swing/text/PlainView.java,
classpath/javax/swing/UIManager.java,
classpath/javax/swing/JSplitPane.java,
classpath/javax/swing/JComponent.java,
classpath/javax/swing/SwingUtilities.java,
classpath/javax/swing/border/AbstractBorder.java,
classpath/javax/swing/border/CompoundBorder.java,
classpath/javax/swing/border/TitledBorder.java,
classpath/javax/swing/border/MatteBorder.java,
classpath/javax/swing/border/BevelBorder.java,
classpath/javax/swing/RepaintManager.java,
classpath/javax/swing/JTable.java,
classpath/javax/swing/UIDefaults.java,
classpath/javax/swing/DefaultDesktopManager.java,
classpath/javax/swing/JMenu.java,
classpath/javax/swing/JLabel.java,
classpath/javax/swing/JSlider.java,
classpath/javax/swing/plaf/basic/BasicToolBarUI.java,
classpath/javax/swing/plaf/basic/BasicButtonUI.java,
classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java,
classpath/javax/swing/plaf/basic/BasicTextAreaUI.java,
classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java,
classpath/javax/swing/plaf/basic/BasicSpinnerUI.java,
classpath/javax/swing/plaf/basic/BasicSliderUI.java,
classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java,
classpath/javax/swing/plaf/basic/BasicComboPopup.java,
classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java,
classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java,
classpath/javax/swing/plaf/basic/BasicProgressBarUI.java,
classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java,
classpath/javax/swing/plaf/basic/BasicPanelUI.java,
classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java,
classpath/javax/swing/plaf/basic/BasicTreeUI.java,
classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java,
classpath/javax/swing/plaf/basic/BasicFileChooserUI.java,
classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,
classpath/javax/swing/plaf/basic/BasicComboBoxUI.java,
classpath/javax/swing/plaf/basic/BasicListUI.java,
classpath/javax/swing/plaf/basic/BasicIconFactory.java,
classpath/javax/swing/plaf/basic/BasicTextUI.java,
classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,
classpath/javax/swing/plaf/basic/BasicDirectoryModel.java,
classpath/javax/swing/plaf/basic/BasicRootPaneUI.java,
classpath/javax/swing/plaf/basic/BasicTableUI.java,
classpath/javax/swing/plaf/basic/SharedUIDefaults.java,
classpath/javax/swing/plaf/multi/MultiComboBoxUI.java,
classpath/javax/swing/plaf/multi/MultiListUI.java,
classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java,
classpath/javax/swing/plaf/multi/MultiFileChooserUI.java,
classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java,
classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java,
classpath/javax/swing/plaf/multi/MultiLookAndFeel.java,
classpath/javax/swing/plaf/metal/MetalSliderUI.java,
classpath/javax/swing/plaf/metal/MetalIconFactory.java,
classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java,
classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java,
classpath/javax/swing/plaf/metal/MetalLookAndFeel.java,
classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java,
classpath/javax/swing/plaf/metal/MetalSeparatorUI.java,
classpath/javax/swing/plaf/metal/MetalBorders.java,
classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java,
classpath/javax/swing/plaf/metal/MetalScrollBarUI.java,
classpath/javax/swing/plaf/metal/MetalRootPaneUI.java,
classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java,
classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java,
classpath/javax/swing/plaf/metal/MetalToolTipUI.java,
classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java,
classpath/javax/swing/plaf/metal/MetalFileChooserUI.java,
classpath/javax/swing/plaf/metal/MetalUtils.java,
classpath/javax/swing/plaf/metal/MetalComboBoxButton.java,
classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java,
classpath/javax/swing/plaf/metal/MetalButtonUI.java,
classpath/javax/swing/JPopupMenu.java,
classpath/javax/swing/JProgressBar.java,
classpath/javax/swing/WindowConstants.java,
classpath/javax/swing/JFrame.java,
classpath/javax/swing/JFileChooser.java,
classpath/javax/swing/JComboBox.java,
classpath/javax/swing/event/EventListenerList.java,
classpath/javax/swing/ListSelectionModel.java,
classpath/javax/swing/JScrollBar.java,
classpath/java/text/SimpleDateFormat.java,
classpath/java/text/NumberFormat.java,
classpath/java/text/class-dependencies.conf,
classpath/java/awt/image/ColorModel.java,
classpath/java/awt/image/BufferedImage.java,
classpath/java/awt/Window.java,
classpath/java/awt/ContainerOrderFocusTraversalPolicy.java,
classpath/java/awt/LightweightDispatcher.java,
classpath/java/awt/EventDispatchThread.java,
classpath/java/awt/BasicStroke.java,
classpath/java/awt/ColorPaintContext.java,
classpath/java/awt/Container.java,
classpath/java/awt/TexturePaint.java,
classpath/java/awt/Component.java, classpath/java/awt/Font.java,
classpath/java/awt/GraphicsConfiguration.java,
classpath/java/awt/DefaultKeyboardFocusManager.java,
classpath/java/awt/print/PrinterJob.java,
classpath/java/awt/im/InputContext.java,
classpath/java/awt/dnd/DragGestureRecognizer.java,
classpath/java/awt/Toolkit.java,
classpath/java/awt/font/GraphicAttribute.java,
classpath/java/awt/font/ImageGraphicAttribute.java,
classpath/java/awt/font/GlyphVector.java,
classpath/java/awt/font/GlyphMetrics.java,
classpath/java/awt/font/ShapeGraphicAttribute.java,
classpath/java/awt/Graphics2D.java,
classpath/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h,
classpath/include/gnu_java_awt_peer_gtk_ComponentGraphics.h,
classpath/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h,
classpath/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h,
classpath/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h,
classpath/include/config.h.in,
classpath/include/gnu_java_awt_peer_gtk_GdkTextLayout.h,
classpath/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h,
classpath/include/gnu_java_awt_peer_gtk_GdkFontPeer.h,
classpath/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h,
classpath/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h,
classpath/include/gnu_java_awt_peer_gtk_GtkImage.h,
classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h,
classpath/include/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.h:
Merge from GNU Classpath HEAD.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114510 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/javax')
134 files changed, 8353 insertions, 3365 deletions
diff --git a/libjava/classpath/javax/swing/AbstractButton.java b/libjava/classpath/javax/swing/AbstractButton.java index 348daece174..9b2b526f30b 100644 --- a/libjava/classpath/javax/swing/AbstractButton.java +++ b/libjava/classpath/javax/swing/AbstractButton.java @@ -1,5 +1,5 @@ /* AbstractButton.java -- Provides basic button functionality. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -274,7 +274,7 @@ public abstract class AbstractButton extends JComponent protected ChangeListener changeListener; /** - * The time in miliseconds in which clicks get coalesced into a single + * The time in milliseconds in which clicks get coalesced into a single * <code>ActionEvent</code>. */ long multiClickThreshhold; @@ -445,7 +445,7 @@ public abstract class AbstractButton extends JComponent * {@link AccessibleState#FOCUSED}, {@link AccessibleState#PRESSED} and * {@link AccessibleState#CHECKED}. * - * @return the curren state of this accessible object + * @return the current state of this accessible object */ public AccessibleStateSet getAccessibleStateSet() { @@ -651,8 +651,8 @@ public abstract class AbstractButton extends JComponent * Returns the minimum accessible value for the AccessibleAbstractButton, * which is <code>0</code>. * - * @return the maxinimum accessible value for the AccessibleAbstractButton, - * which is <code>1</code> + * @return the minimimum accessible value for the AccessibleAbstractButton, + * which is <code>0</code> */ public Number getMinimumAccessibleValue() { diff --git a/libjava/classpath/javax/swing/CellRendererPane.java b/libjava/classpath/javax/swing/CellRendererPane.java index b3d6f6a7364..764a4c500b5 100644 --- a/libjava/classpath/javax/swing/CellRendererPane.java +++ b/libjava/classpath/javax/swing/CellRendererPane.java @@ -93,7 +93,7 @@ public class CellRendererPane extends Container implements Accessible */ public CellRendererPane() { - // Nothing to do here. + setVisible(false); } /** diff --git a/libjava/classpath/javax/swing/DefaultButtonModel.java b/libjava/classpath/javax/swing/DefaultButtonModel.java index 7ecf3b85fc6..2be18cc8aac 100644 --- a/libjava/classpath/javax/swing/DefaultButtonModel.java +++ b/libjava/classpath/javax/swing/DefaultButtonModel.java @@ -1,5 +1,5 @@ /* DefaultButtonModel.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -63,7 +63,7 @@ import javax.swing.event.EventListenerList; * 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 + * armed and pressed" 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. @@ -371,7 +371,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable if (e) stateMask = stateMask | ENABLED; else - stateMask = stateMask & (~ENABLED); + stateMask = stateMask & (~ENABLED) & (~ARMED) & (~PRESSED); // notify interested ChangeListeners fireStateChanged(); @@ -555,21 +555,21 @@ public class DefaultButtonModel implements ButtonModel, Serializable * one model in a given group can have their "selected" property be * <code>true</code> at a time. * - * @param g The new "group" property + * @param g The new "group" property (<code>null</code> permitted). + * + * @see #getGroup() */ public void setGroup(ButtonGroup g) { - if (group != g) - { - group = g; - fireStateChanged(); - } + group = g; } /** * Returns the current value of the model's "group" property. * * @return The value of the "group" property + * + * @see #setGroup(ButtonGroup) */ public ButtonGroup getGroup() { diff --git a/libjava/classpath/javax/swing/DefaultCellEditor.java b/libjava/classpath/javax/swing/DefaultCellEditor.java index 9c951d39530..16ed1ec6842 100644 --- a/libjava/classpath/javax/swing/DefaultCellEditor.java +++ b/libjava/classpath/javax/swing/DefaultCellEditor.java @@ -313,7 +313,24 @@ public class DefaultCellEditor { JComboBox c = (JComboBox) editorComponent; return value = c.getSelectedItem(); - } + } + + /** + * Returns true to indicate that the editing cell can be selected. If the + * check box is not editable, expands it. If it is editable, brings + * focus to the editor field. + * + * @param event unused in default method + * + * @return true always + */ + public boolean shouldSelectCell(EventObject event) + { + JComboBox c = (JComboBox) editorComponent; + if (!c.isEditable) + c.showPopup(); + return true; + } } /** diff --git a/libjava/classpath/javax/swing/DefaultDesktopManager.java b/libjava/classpath/javax/swing/DefaultDesktopManager.java index 0304461ad4e..11f03a715c4 100644 --- a/libjava/classpath/javax/swing/DefaultDesktopManager.java +++ b/libjava/classpath/javax/swing/DefaultDesktopManager.java @@ -400,8 +400,8 @@ public class DefaultDesktopManager implements DesktopManager, Serializable dragCache.width, dragCache.height); pane = null; dragCache = null; + component.repaint(); } - component.repaint(); } /** @@ -463,8 +463,8 @@ public class DefaultDesktopManager implements DesktopManager, Serializable dragCache.width, dragCache.height); pane = null; dragCache = null; + component.repaint(); } - component.repaint(); } /** @@ -481,13 +481,6 @@ public class DefaultDesktopManager implements DesktopManager, Serializable 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(); } /** diff --git a/libjava/classpath/javax/swing/JCheckBoxMenuItem.java b/libjava/classpath/javax/swing/JCheckBoxMenuItem.java index 815244259be..3222d189f37 100644 --- a/libjava/classpath/javax/swing/JCheckBoxMenuItem.java +++ b/libjava/classpath/javax/swing/JCheckBoxMenuItem.java @@ -1,5 +1,5 @@ /* JCheckBoxMenuItem.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -204,7 +204,7 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, /** * This method overrides JComponent.requestFocus with an empty * implementation, since JCheckBoxMenuItems should not - * receve focus in general. + * receive focus in general. */ public void requestFocus() { @@ -212,16 +212,28 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, } /** - * A string that describes this JCheckBoxMenuItem. Normally only used - * for debugging. + * Returns a string describing the attributes for the + * <code>JCheckBoxMenuItem</code> component, for use in debugging. The + * return value is guaranteed to be non-<code>null</code>, but the format + * of the string may vary between implementations. * - * @return A string describing this JCheckBoxMenuItem + * @return A string describing the attributes of the + * <code>JCheckBoxMenuItem</code>. */ protected String paramString() { - return "JCheckBoxMenuItem"; + // calling super seems to be sufficient to match the reference + // implementation here... + return super.paramString(); } + /** + * Returns the object that provides accessibility features for this + * <code>JCheckBoxMenuItem</code> component. + * + * @return The accessible context (an instance of + * {@link AccessibleJCheckBoxMenuItem}). + */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) @@ -231,20 +243,29 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, } /** - * Accessibility support for <code>JCheckBoxMenuItem</code>. + * Provides the accessibility features for the <code>JCheckBoxMenuItem</code> + * component. + * + * @see JCheckBoxMenuItem#getAccessibleContext() */ protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem { private static final long serialVersionUID = 1079958073579370777L; /** - * Creates a new AccessibleJCheckBoxMenuItem object. + * Creates a new <code>AccessibleJCheckBoxMenuItem</code> instance. */ protected AccessibleJCheckBoxMenuItem() { // Nothing to do here. } + /** + * Returns the accessible role for the <code>JCheckBoxMenuItem</code> + * component. + * + * @return {@link AccessibleRole#CHECK_BOX}. + */ public AccessibleRole getAccessibleRole() { return AccessibleRole.CHECK_BOX; diff --git a/libjava/classpath/javax/swing/JComboBox.java b/libjava/classpath/javax/swing/JComboBox.java index 175237a775a..efb04592b50 100644 --- a/libjava/classpath/javax/swing/JComboBox.java +++ b/libjava/classpath/javax/swing/JComboBox.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.ItemSelectable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -60,6 +58,8 @@ 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.ComboPopup; /** * A component that allows a user to select any item in its list and @@ -675,7 +675,7 @@ public class JComboBox extends JComponent implements ItemSelectable, } else throw new RuntimeException("Unable to remove the items because the data " - +"model it is not an instance of " + + "model it is not an instance of " + "MutableComboBoxModel."); } @@ -848,7 +848,7 @@ public class JComboBox extends JComponent implements ItemSelectable, { PopupMenuListener[] listeners = getPopupMenuListeners(); PopupMenuEvent e = new PopupMenuEvent(this); - for(int i = 0; i < listeners.length; i++) + for (int i = 0; i < listeners.length; i++) listeners[i].popupMenuCanceled(e); } @@ -862,7 +862,7 @@ public class JComboBox extends JComponent implements ItemSelectable, { PopupMenuListener[] listeners = getPopupMenuListeners(); PopupMenuEvent e = new PopupMenuEvent(this); - for(int i = 0; i < listeners.length; i++) + for (int i = 0; i < listeners.length; i++) listeners[i].popupMenuWillBecomeInvisible(e); } @@ -876,7 +876,7 @@ public class JComboBox extends JComponent implements ItemSelectable, { PopupMenuListener[] listeners = getPopupMenuListeners(); PopupMenuEvent e = new PopupMenuEvent(this); - for(int i = 0; i < listeners.length; i++) + for (int i = 0; i < listeners.length; i++) listeners[i].popupMenuWillBecomeVisible(e); } @@ -1246,34 +1246,102 @@ public class JComboBox extends JComponent implements ItemSelectable, // Nothing to do here. } + /** + * Returns the number of accessible children of this object. The + * implementation of AccessibleJComboBox delegates this call to the UI + * of the associated JComboBox. + * + * @return the number of accessible children of this object + * + * @see ComponentUI#getAccessibleChildrenCount(JComponent) + */ public int getAccessibleChildrenCount() - throws NotImplementedException { - return 0; + ComponentUI ui = getUI(); + int count; + if (ui != null) + count = ui.getAccessibleChildrenCount(JComboBox.this); + else + count = super.getAccessibleChildrenCount(); + return count; } - public Accessible getAccessibleChild(int value0) - throws NotImplementedException + /** + * Returns the number of accessible children of this object. The + * implementation of AccessibleJComboBox delegates this call to the UI + * of the associated JComboBox. + * + * @param index the index of the accessible child to fetch + * + * @return the number of accessible children of this object + * + * @see ComponentUI#getAccessibleChild(JComponent, int) + */ + public Accessible getAccessibleChild(int index) { - return null; + ComponentUI ui = getUI(); + Accessible child = null; + if (ui != null) + child = ui.getAccessibleChild(JComboBox.this, index); + else + child = super.getAccessibleChild(index); + return child; } + /** + * Returns the AccessibleSelection object associated with this object. + * AccessibleJComboBoxes handle their selection themselves, so this + * always returns <code>this</code>. + * + * @return the AccessibleSelection object associated with this object + */ public AccessibleSelection getAccessibleSelection() - throws NotImplementedException { - return null; + return this; } - public Accessible getAccessibleSelection(int value0) - throws NotImplementedException + /** + * Returns the accessible selection from this AccssibleJComboBox. + * + * @param index the index of the selected child to fetch + * + * @return the accessible selection from this AccssibleJComboBox + */ + public Accessible getAccessibleSelection(int index) { - return null; + // Get hold of the actual popup. + Accessible popup = getUI().getAccessibleChild(JComboBox.this, 0); + Accessible selected = null; + if (popup != null && popup instanceof ComboPopup) + { + ComboPopup cPopup = (ComboPopup) popup; + // Query the list for the currently selected child. + JList l = cPopup.getList(); + AccessibleContext listCtx = l.getAccessibleContext(); + if (listCtx != null) + { + AccessibleSelection s = listCtx.getAccessibleSelection(); + if (s != null) + { + selected = s.getAccessibleSelection(index); + } + } + } + return selected; } - public boolean isAccessibleChildSelected(int value0) - throws NotImplementedException + /** + * Returns <code>true</code> if the accessible child with the specified + * <code>index</code> is selected, <code>false</code> otherwise. + * + * @param index the index of the accessible child + * + * @return <code>true</code> if the accessible child with the specified + * <code>index</code> is selected, <code>false</code> otherwise + */ + public boolean isAccessibleChildSelected(int index) { - return false; + return getSelectedIndex() == index; } /** @@ -1286,58 +1354,121 @@ public class JComboBox extends JComponent implements ItemSelectable, return AccessibleRole.COMBO_BOX; } + /** + * Returns the accessible action associated to this accessible object. + * AccessibleJComboBox implements its own AccessibleAction, so this + * method returns <code>this</code>. + * + * @return the accessible action associated to this accessible object + */ public AccessibleAction getAccessibleAction() - throws NotImplementedException { - return null; + return this; } - public String getAccessibleActionDescription(int value0) - throws NotImplementedException + /** + * Returns the description of the specified action. AccessibleJComboBox + * implements 1 action (toggle the popup menu) and thus returns + * <code>UIManager.getString("ComboBox.togglePopupText")</code> + * + * @param actionIndex the index of the action for which to return the + * description + * + * @return the description of the specified action + */ + public String getAccessibleActionDescription(int actionIndex) { - return null; + return UIManager.getString("ComboBox.togglePopupText"); } + /** + * Returns the number of accessible actions that can be performed by + * this object. AccessibleJComboBox implement s one accessible action + * (toggle the popup menu), so this method always returns <code>1</code>. + * + * @return the number of accessible actions that can be performed by + * this object + */ public int getAccessibleActionCount() - throws NotImplementedException { - return 0; + return 1; } - public boolean doAccessibleAction(int value0) - throws NotImplementedException + /** + * Performs the accessible action with the specified index. + * AccessibleJComboBox has 1 accessible action + * (<code>actionIndex == 0</code>), which is to toggle the + * popup menu. All other action indices have no effect and return + * <code<>false</code>. + * + * @param actionIndex the index of the action to perform + * + * @return <code>true</code> if the action has been performed, + * <code>false</code> otherwise + */ + public boolean doAccessibleAction(int actionIndex) { - return false; + boolean actionPerformed = false; + if (actionIndex == 0) + { + setPopupVisible(! isPopupVisible()); + actionPerformed = true; + } + return actionPerformed; } + /** + * Returns the number of selected accessible children of this object. This + * returns <code>1</code> if the combobox has a selected entry, + * <code>0</code> otherwise. + * + * @return the number of selected accessible children of this object + */ public int getAccessibleSelectionCount() - throws NotImplementedException { - return 0; + Object sel = getSelectedItem(); + int count = 0; + if (sel != null) + count = 1; + return count; } - public void addAccessibleSelection(int value0) - throws NotImplementedException + /** + * Sets the current selection to the specified <code>index</code>. + * + * @param index the index to set as selection + */ + public void addAccessibleSelection(int index) { - // TODO: Implement this properly. + setSelectedIndex(index); } - public void removeAccessibleSelection(int value0) - throws NotImplementedException + /** + * Removes the specified index from the current selection. + * + * @param index the index to remove from the selection + */ + public void removeAccessibleSelection(int index) { - // TODO: Implement this properly. + if (getSelectedIndex() == index) + clearAccessibleSelection(); } + /** + * Clears the current selection. + */ public void clearAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + setSelectedIndex(-1); } + /** + * Multiple selection is not supported by AccessibleJComboBox, so this + * does nothing. + */ public void selectAllAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + // Nothing to do here. } } } diff --git a/libjava/classpath/javax/swing/JComponent.java b/libjava/classpath/javax/swing/JComponent.java index d916d05837e..b217bc78867 100644 --- a/libjava/classpath/javax/swing/JComponent.java +++ b/libjava/classpath/javax/swing/JComponent.java @@ -760,13 +760,6 @@ public abstract class JComponent extends Container implements Serializable public static final int WHEN_IN_FOCUSED_WINDOW = 2; /** - * Indicates if this component is completely dirty or not. This is used - * by the RepaintManager's - * {@link RepaintManager#isCompletelyDirty(JComponent)} method. - */ - boolean isCompletelyDirty = false; - - /** * Indicates if the opaque property has been set by a client program or by * the UI. * @@ -1763,11 +1756,6 @@ public abstract class JComponent extends Container implements Serializable paintComponent(g2); paintBorder(g2); paintChildren(g2); - Rectangle clip = g2.getClipBounds(); - if (clip == null - || (clip.x == 0 && clip.y == 0 && clip.width == getWidth() - && clip.height == getHeight())) - RepaintManager.currentManager(this).markCompletelyClean(this); } } } @@ -2373,6 +2361,19 @@ public abstract class JComponent extends Container implements Serializable } } + /** + * Returns the input map associated with this component for the given + * state/condition. + * + * @param condition the state (one of {@link #WHEN_FOCUSED}, + * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} and + * {@link #WHEN_IN_FOCUSED_WINDOW}). + * + * @return The input map. + * @throws IllegalArgumentException if <code>condition</code> is not one of + * the specified values. + * @since 1.3 + */ public final InputMap getInputMap(int condition) { enableEvents(AWTEvent.KEY_EVENT_MASK); @@ -2395,10 +2396,20 @@ public abstract class JComponent extends Container implements Serializable case UNDEFINED_CONDITION: default: - return null; + throw new IllegalArgumentException("Invalid 'condition' argument: " + + condition); } } + /** + * Returns the input map associated with this component for the + * {@link #WHEN_FOCUSED} state. + * + * @return The input map. + * + * @since 1.3 + * @see #getInputMap(int) + */ public final InputMap getInputMap() { return getInputMap(WHEN_FOCUSED); @@ -3554,6 +3565,7 @@ public abstract class JComponent extends Container implements Serializable Rectangle currentClip = clip; Component found = this; Container parent = this; + while (parent != null && !(parent instanceof Window)) { Container newParent = parent.getParent(); @@ -3569,15 +3581,42 @@ public abstract class JComponent extends Container implements Serializable parent = newParent; continue; } - // If the parent is not optimizedDrawingEnabled, we must paint the - // parent. + + // If the parent is not optimizedDrawingEnabled, we must check if the + // parent or some neighbor overlaps the current clip. + + // This is the current clip converted to the parent's coordinate + // system. TODO: We can do this more efficiently by succesively + // cumulating the parent-child translations. Rectangle target = SwingUtilities.convertRectangle(found, currentClip, newParent); - found = newParent; - currentClip = target; + + // We have an overlap if either: + // - The new parent itself doesn't completely cover the clip + // (this can be the case with viewports). + // - If some higher-level (than the current) children of the new parent + // intersect the target rectangle. + Rectangle parentRect = SwingUtilities.getLocalBounds(newParent); + boolean haveOverlap = + ! SwingUtilities.isRectangleContainingRectangle(parentRect, target); + if (! haveOverlap) + { + Component[] children = newParent.getComponents(); + for (int i = 0; children[i] != parent && !haveOverlap; i++) + { + Rectangle childRect = children[i].getBounds(); + haveOverlap = target.intersects(childRect); + } + } + if (haveOverlap) + { + found = newParent; + currentClip = target; + } parent = newParent; } + //System.err.println("overlapfree parent: " + found); return found; } diff --git a/libjava/classpath/javax/swing/JEditorPane.java b/libjava/classpath/javax/swing/JEditorPane.java index 73b775738de..4ae3c5a1c6b 100644 --- a/libjava/classpath/javax/swing/JEditorPane.java +++ b/libjava/classpath/javax/swing/JEditorPane.java @@ -1,5 +1,5 @@ /* JEditorPane.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -538,8 +538,8 @@ public class JEditorPane extends JTextComponent public JEditorPane(URL url) throws IOException { - init (); - setEditorKit (createEditorKitForContentType("text/html"));; + init(); + setEditorKit(createEditorKitForContentType("text/html"));; setPage(url); } @@ -581,7 +581,7 @@ public class JEditorPane extends JTextComponent // TODO: Have to handle the case where a ClassLoader was specified // when the EditorKit was registered EditorKit e = null; - String className = (String)registerMap.get(type); + String className = (String) registerMap.get(type); if (className != null) { try diff --git a/libjava/classpath/javax/swing/JFileChooser.java b/libjava/classpath/javax/swing/JFileChooser.java index 7da3a132dbe..64f9bd0f4e6 100644 --- a/libjava/classpath/javax/swing/JFileChooser.java +++ b/libjava/classpath/javax/swing/JFileChooser.java @@ -1,5 +1,5 @@ /* JFileChooser.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,10 +37,9 @@ exception statement from your version. */ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.Component; import java.awt.Frame; +import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -389,6 +388,13 @@ public class JFileChooser extends JComponent implements Accessible * @see #setSelectedFile(File) */ private File selectedFile; + + /** + * The drag enabled property. + * @see #setDragEnabled(boolean) + * @see #getDragEnabled() + */ + private boolean dragEnabled; /** * Creates a new <code>JFileChooser</code> object. @@ -487,26 +493,31 @@ public class JFileChooser extends JComponent implements Accessible } /** - * DOCUMENT ME! - * - * @param b DOCUMENT ME! + * Sets the dragEnabled property, this disables/enables automatic drag + * handling (drag and drop) on this component. The default value of the + * dragEnabled property is false. + * + * Some look and feels might not support automatic drag and drop; they + * will ignore this property. + * + * @param b - the new dragEnabled value */ public void setDragEnabled(boolean b) - throws NotImplementedException { - // FIXME: Implement + if (b && GraphicsEnvironment.isHeadless()) + throw new HeadlessException(); + + dragEnabled = b; } /** - * DOCUMENT ME! + * Returns true if dragging is enabled. * - * @return DOCUMENT ME! + * @return true if dragging is enabled. */ public boolean getDragEnabled() - throws NotImplementedException { - // FIXME: Implement - return false; + return dragEnabled; } /** @@ -1514,19 +1525,60 @@ public class JFileChooser extends JComponent implements Accessible } /** - * DOCUMENT ME! + * Returns a string describing the attributes for the + * <code>JFileChooser</code> component, for use in debugging. The return + * value is guaranteed to be non-<code>null</code>, but the format of the + * string may vary between implementations. * - * @return DOCUMENT ME! + * @return A string describing the attributes of the + * <code>JFileChooser</code>. */ protected String paramString() { - return "JFileChooser"; + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",approveButtonText="); + if (approveButtonText != null) + sb.append(approveButtonText); + sb.append(",currentDirectory="); + if (currentDir != null) + sb.append(currentDir); + sb.append(",dialogTitle="); + if (dialogTitle != null) + sb.append(dialogTitle); + sb.append(",dialogType="); + if (dialogType == OPEN_DIALOG) + sb.append("OPEN_DIALOG"); + if (dialogType == SAVE_DIALOG) + sb.append("SAVE_DIALOG"); + if (dialogType == CUSTOM_DIALOG) + sb.append("CUSTOM_DIALOG"); + sb.append(",fileSelectionMode="); + if (fileSelectionMode == FILES_ONLY) + sb.append("FILES_ONLY"); + if (fileSelectionMode == DIRECTORIES_ONLY) + sb.append("DIRECTORIES_ONLY"); + if (fileSelectionMode == FILES_AND_DIRECTORIES) + sb.append("FILES_AND_DIRECTORIES"); + sb.append(",returnValue="); + if (retval == APPROVE_OPTION) + sb.append("APPROVE_OPTION"); + if (retval == CANCEL_OPTION) + sb.append("CANCEL_OPTION"); + if (retval == ERROR_OPTION) + sb.append("ERROR_OPTION"); + sb.append(",selectedFile="); + if (selectedFile != null) + sb.append(selectedFile); + sb.append(",useFileHiding=").append(fileHiding); + return sb.toString(); } /** - * Returns the accessible context. + * Returns the object that provides accessibility features for this + * <code>JFileChooser</code> component. * - * @return The accessible context. + * @return The accessible context (an instance of + * {@link AccessibleJFileChooser}). */ public AccessibleContext getAccessibleContext() { @@ -1536,16 +1588,26 @@ public class JFileChooser extends JComponent implements Accessible } /** - * Accessibility support for JFileChooser + * Provides the accessibility features for the <code>JFileChooser</code> + * component. */ protected class AccessibleJFileChooser extends JComponent.AccessibleJComponent { + /** + * Creates a new instance of <code>AccessibleJFileChooser</code>. + */ protected AccessibleJFileChooser() { // Nothing to do here. } + /** + * Returns the accessible role for the <code>JFileChooser</code> + * component. + * + * @return {@link AccessibleRole#FILE_CHOOSER}. + */ public AccessibleRole getAccessibleRole() { return AccessibleRole.FILE_CHOOSER; diff --git a/libjava/classpath/javax/swing/JFormattedTextField.java b/libjava/classpath/javax/swing/JFormattedTextField.java index 761955d6dd9..05475255038 100644 --- a/libjava/classpath/javax/swing/JFormattedTextField.java +++ b/libjava/classpath/javax/swing/JFormattedTextField.java @@ -101,11 +101,11 @@ public class JFormattedTextField extends JTextField * @throws CloneNotSupportedException if the Object's class doesn't support * the {@link Cloneable} interface */ - protected Object clone () + protected Object clone() throws CloneNotSupportedException { // Clone this formatter. - AbstractFormatter newFormatter = (AbstractFormatter)super.clone(); + AbstractFormatter newFormatter = (AbstractFormatter) super.clone(); // And remove the association to the JFormattedTextField. newFormatter.textField = null; @@ -119,7 +119,7 @@ public class JFormattedTextField extends JTextField * @return <code>null</code>. Should be subclassed by formatters that want * to install custom Actions on the JFormattedTextField. */ - protected Action[] getActions () + protected Action[] getActions() { return null; } @@ -132,7 +132,7 @@ public class JFormattedTextField extends JTextField * @return <code>null</code>. Should be subclassed by formatters * that want to restrict Document mutations. */ - protected DocumentFilter getDocumentFilter () + protected DocumentFilter getDocumentFilter() { // Subclasses should override this if they want to install a // DocumentFilter. @@ -146,7 +146,7 @@ public class JFormattedTextField extends JTextField * @return the JFormattedTextField on which this formatter is currently * installed */ - protected JFormattedTextField getFormattedTextField () + protected JFormattedTextField getFormattedTextField() { return textField; } @@ -159,7 +159,7 @@ public class JFormattedTextField extends JTextField * @return <code>null</code>. Subclassed by formatters that want to restrict * cursor location within the JFormattedTextField. */ - protected NavigationFilter getNavigationFilter () + protected NavigationFilter getNavigationFilter() { // This should be subclassed if the formatter wants to install // a NavigationFilter on the JFormattedTextField. @@ -199,7 +199,7 @@ public class JFormattedTextField extends JTextField // Set the DocumentFilter for the field's Document. if (doc instanceof AbstractDocument) - ((AbstractDocument)doc).setDocumentFilter(getDocumentFilter()); + ((AbstractDocument) doc).setDocumentFilter(getDocumentFilter()); // Set the NavigationFilter. textField.setNavigationFilter(getNavigationFilter()); @@ -221,12 +221,12 @@ public class JFormattedTextField extends JTextField * This resets the DocumentFilter, NavigationFilter, and any additional * Actions (returned by <code>getActions()</code>). */ - public void uninstall () + public void uninstall() { // Set the DocumentFilter for the field's Document. Document doc = textField.getDocument(); if (doc instanceof AbstractDocument) - ((AbstractDocument)doc).setDocumentFilter(null); + ((AbstractDocument) doc).setDocumentFilter(null); textField.setNavigationFilter(null); // FIXME: Have to remove the Actions from getActions() this.textField = null; @@ -236,7 +236,7 @@ public class JFormattedTextField extends JTextField * Invoke this method when invalid values are entered. This forwards the * call to the JFormattedTextField. */ - protected void invalidEdit () + protected void invalidEdit() { textField.invalidEdit(); } @@ -247,7 +247,7 @@ public class JFormattedTextField extends JTextField * * @param valid the new state for the <code>editValid</code> property */ - protected void setEditValid (boolean valid) + protected void setEditValid(boolean valid) { textField.editValid = valid; } @@ -259,7 +259,7 @@ public class JFormattedTextField extends JTextField * @return an Object that <code>text</code> represented * @throws ParseException if there is an error in the conversion */ - public abstract Object stringToValue (String text) + public abstract Object stringToValue(String text) throws ParseException; /** @@ -270,7 +270,7 @@ public class JFormattedTextField extends JTextField * @return a String to be displayed * @throws ParseException if there is an error in the conversion */ - public abstract String valueToString (Object value) + public abstract String valueToString(Object value) throws ParseException; } @@ -280,12 +280,12 @@ public class JFormattedTextField extends JTextField */ public abstract static class AbstractFormatterFactory { - public AbstractFormatterFactory () + public AbstractFormatterFactory() { // Do nothing here. } - public abstract AbstractFormatter getFormatter (JFormattedTextField tf); + public abstract AbstractFormatter getFormatter(JFormattedTextField tf); } /** The possible focusLostBehavior options **/ @@ -315,7 +315,7 @@ public class JFormattedTextField extends JTextField * properly configure this text field to edit a particular type * of value. */ - public JFormattedTextField () + public JFormattedTextField() { this((AbstractFormatterFactory) null, null); } @@ -328,7 +328,7 @@ public class JFormattedTextField extends JTextField * @param format the Format that this JFormattedTextField should be able * to handle */ - public JFormattedTextField (Format format) + public JFormattedTextField(Format format) { this (); setFormatterFactory(getAppropriateFormatterFactory(format)); @@ -341,9 +341,9 @@ public class JFormattedTextField extends JTextField * * @param formatter the formatter to use for this JFormattedTextField */ - public JFormattedTextField (AbstractFormatter formatter) + public JFormattedTextField(AbstractFormatter formatter) { - this(new DefaultFormatterFactory (formatter)); + this(new DefaultFormatterFactory(formatter)); } /** @@ -351,7 +351,7 @@ public class JFormattedTextField extends JTextField * * @param factory the formatter factory to use for this JFormattedTextField */ - public JFormattedTextField (AbstractFormatterFactory factory) + public JFormattedTextField(AbstractFormatterFactory factory) { setFormatterFactory(factory); } @@ -363,7 +363,7 @@ public class JFormattedTextField extends JTextField * @param factory the initial formatter factory for this JFormattedTextField * @param value the initial value for the text field */ - public JFormattedTextField (AbstractFormatterFactory factory, Object value) + public JFormattedTextField(AbstractFormatterFactory factory, Object value) { setFormatterFactory(factory); setValue(value); @@ -375,7 +375,7 @@ public class JFormattedTextField extends JTextField * * @param value the initial value for this JFormattedTextField */ - public JFormattedTextField (Object value) + public JFormattedTextField(Object value) { setValue(value); } @@ -387,13 +387,13 @@ public class JFormattedTextField extends JTextField * @return a DefaultFormatterFactory whose defaultFormatter is appropriate * for the given Format. */ - private AbstractFormatterFactory getAppropriateFormatterFactory (Format format) + private AbstractFormatterFactory getAppropriateFormatterFactory(Format format) { AbstractFormatter newFormatter; if (format instanceof DateFormat) - newFormatter = new DateFormatter((DateFormat)format); + newFormatter = new DateFormatter((DateFormat) format); else if (format instanceof NumberFormat) - newFormatter = new NumberFormatter ((NumberFormat)format); + newFormatter = new NumberFormatter ((NumberFormat) format); else newFormatter = new InternationalFormatter(format); @@ -406,7 +406,7 @@ public class JFormattedTextField extends JTextField * * @throws ParseException if the formatter cannot format the current value */ - public void commitEdit () + public void commitEdit() throws ParseException { if (formatter == null) @@ -427,7 +427,7 @@ public class JFormattedTextField extends JTextField * * @return an array of Actions that this text field supports */ - public Action[] getActions () + public Action[] getActions() { // FIXME: Add JFormattedTextField specific actions // These are related to committing or cancelling edits. @@ -449,7 +449,7 @@ public class JFormattedTextField extends JTextField * Returns the current formatter used for this JFormattedTextField. * @return the current formatter used for this JFormattedTextField */ - public AbstractFormatter getFormatter () + public AbstractFormatter getFormatter() { return formatter; } @@ -459,12 +459,12 @@ public class JFormattedTextField extends JTextField * JFormattedTextField. * @return the factory currently used to generate formatters */ - public AbstractFormatterFactory getFormatterFactory () + public AbstractFormatterFactory getFormatterFactory() { return formatterFactory; } - public String getUIClassID () + public String getUIClassID() { return "FormattedTextFieldUI"; } @@ -475,7 +475,7 @@ public class JFormattedTextField extends JTextField * valid edits and allows invalid input to be temporarily displayed. * @return the last committed valid value */ - public Object getValue () + public Object getValue() { return value; } @@ -484,7 +484,7 @@ public class JFormattedTextField extends JTextField * This method is used to provide feedback to the user when an invalid value * is input during editing. */ - protected void invalidEdit () + protected void invalidEdit() { UIManager.getLookAndFeel().provideErrorFeedback(this); } @@ -494,7 +494,7 @@ public class JFormattedTextField extends JTextField * managed by the current formatted. * @return true if the value being edited is valid. */ - public boolean isEditValid () + public boolean isEditValid() { return editValid; } @@ -506,7 +506,7 @@ public class JFormattedTextField extends JTextField * * @param evt the FocusEvent */ - protected void processFocusEvent (FocusEvent evt) + protected void processFocusEvent(FocusEvent evt) { super.processFocusEvent(evt); // Let the formatterFactory change the formatter for this text field @@ -561,7 +561,7 @@ public class JFormattedTextField extends JTextField * @param formatter the AbstractFormatter to use for formatting the value for * this JFormattedTextField */ - protected void setFormatter (AbstractFormatter formatter) + protected void setFormatter(AbstractFormatter formatter) { AbstractFormatter oldFormatter = null; @@ -585,7 +585,7 @@ public class JFormattedTextField extends JTextField * @param factory the AbstractFormatterFactory that will be used to generate * formatters for this JFormattedTextField */ - public void setFormatterFactory (AbstractFormatterFactory factory) + public void setFormatterFactory(AbstractFormatterFactory factory) { if (formatterFactory == factory) return; @@ -606,7 +606,7 @@ public class JFormattedTextField extends JTextField * * @param newValue the value to be formatted and displayed */ - public void setValue (Object newValue) + public void setValue(Object newValue) { if (value == newValue) return; diff --git a/libjava/classpath/javax/swing/JFrame.java b/libjava/classpath/javax/swing/JFrame.java index d2512056085..1371525ddf2 100644 --- a/libjava/classpath/javax/swing/JFrame.java +++ b/libjava/classpath/javax/swing/JFrame.java @@ -1,5 +1,5 @@ /* JFrame.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -86,6 +86,8 @@ public class JFrame extends Frame /** * A flag for {@link #setDefaultCloseOperation(int)}, indicating that the * application should be exited, when this <code>JFrame</code> is closed. + * Note that in version 1.4, the equivalent constant has been added to + * {@link WindowConstants}. * * @since 1.3 */ @@ -93,7 +95,7 @@ public class JFrame extends Frame private static final long serialVersionUID = -3362141868504252139L; private static boolean defaultLookAndFeelDecorated; - private int close_action = HIDE_ON_CLOSE; + private int closeAction = HIDE_ON_CLOSE; protected AccessibleContext accessibleContext; protected JRootPane rootPane; @@ -102,12 +104,20 @@ public class JFrame extends Frame */ protected boolean rootPaneCheckingEnabled = false; + /** + * Creates a new frame with an empty string for the title. + */ public JFrame() { - super("JFrame"); + super(""); frameInit(); } + /** + * Creates a new <code>JFrame</code> with the specified title. + * + * @param title the frame title (<code>null</code> permitted). + */ public JFrame(String title) { super(title); @@ -147,7 +157,8 @@ public class JFrame extends Frame protected void frameInit() { - super.setLayout(new BorderLayout(1, 1)); + super.setLayout(new BorderLayout()); + setBackground(UIManager.getDefaults().getColor("control")); enableEvents(AWTEvent.WINDOW_EVENT_MASK); getRootPane(); // will do set/create @@ -289,6 +300,12 @@ public class JFrame extends Frame return defaultLookAndFeelDecorated; } + /** + * Returns the object that provides accessibility features for this + * <code>JFrame</code>. + * + * @return The accessible context (an instance of {@link AccessibleJFrame}). + */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) @@ -296,14 +313,39 @@ public class JFrame extends Frame return accessibleContext; } + /** + * Returns a code for the default operation when the frame is closed. The + * default value is {@link WindowConstants#HIDE_ON_CLOSE}. + * + * @return One of: {@link WindowConstants#DO_NOTHING_ON_CLOSE}, + * {@link WindowConstants#HIDE_ON_CLOSE}, + * {@link WindowConstants#DISPOSE_ON_CLOSE}, {@link #EXIT_ON_CLOSE}. + * + * @see #setDefaultCloseOperation(int) + */ public int getDefaultCloseOperation() { - return close_action; + return closeAction; } + /** + * Returns a string describing the attributes for the <code>JFrame</code>, + * for use in debugging. The return value is guaranteed to be + * non-<code>null</code>, but the format may vary between implementations. + * + * @return A string describing the attributes of the <code>JFrame</code>. + */ protected String paramString() { - return "JFrame"; + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",defaultCloseOperation="); + sb.append(SwingUtilities.convertWindowConstantToString( + getDefaultCloseOperation())); + sb.append(",rootPane="); + if (rootPane != null) + sb.append(rootPane); + sb.append(",rootPaneCheckingEnabled=").append(rootPaneCheckingEnabled); + return sb.toString(); } protected void processWindowEvent(WindowEvent e) @@ -313,7 +355,7 @@ public class JFrame extends Frame { case WindowEvent.WINDOW_CLOSING: { - switch (close_action) + switch (closeAction) { case EXIT_ON_CLOSE: { @@ -346,17 +388,22 @@ public class JFrame extends Frame } /** - * 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 + * Sets the default operation that is performed when this frame is closed. + * 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. + * <code>SecurityException</code>. + * + * @param operation a code for the operation (one of: + * {@link WindowConstants#DO_NOTHING_ON_CLOSE}, + * {@link WindowConstants#HIDE_ON_CLOSE}, + * {@link WindowConstants#DISPOSE_ON_CLOSE} and + * {@link WindowConstants#EXIT_ON_CLOSE}). + * + * @throws IllegalArgumentException if <code>operation</code> is not one of + * the specified codes. + * + * @see #getDefaultCloseOperation() */ public void setDefaultCloseOperation(int operation) { @@ -366,8 +413,9 @@ public class JFrame extends Frame if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE) - throw new IllegalArgumentException("defaultCloseOperation must be EXIT_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE"); + throw new IllegalArgumentException("operation must be EXIT_ON_CLOSE, " + + "HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE"); - close_action = operation; + closeAction = operation; } } diff --git a/libjava/classpath/javax/swing/JLabel.java b/libjava/classpath/javax/swing/JLabel.java index a993fb8f3e0..a5fe3ba1af0 100644 --- a/libjava/classpath/javax/swing/JLabel.java +++ b/libjava/classpath/javax/swing/JLabel.java @@ -1,5 +1,5 @@ /* JLabel.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -50,6 +50,7 @@ import java.awt.event.KeyEvent; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleExtendedComponent; +import javax.accessibility.AccessibleRole; import javax.accessibility.AccessibleText; import javax.swing.plaf.LabelUI; import javax.swing.text.AttributeSet; @@ -62,12 +63,39 @@ public class JLabel extends JComponent implements Accessible, SwingConstants { /** - * Accessibility support for JLabel. + * Provides the accessibility features for the <code>JLabel</code> + * component. */ protected class AccessibleJLabel extends JComponent.AccessibleJComponent implements AccessibleText, AccessibleExtendedComponent { + + /** + * Returns the accessible name. + * + * @return The accessible name. + */ + public String getAccessibleName() + { + if (accessibleName != null) + return accessibleName; + if (text != null) + return text; + else + return super.getAccessibleName(); + } + + /** + * Returns the accessible role for the <code>JLabel</code> component. + * + * @return {@link AccessibleRole#LABEL}. + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.LABEL; + } + /** * Returns the selected text. This is null since JLabels * are not selectable. @@ -297,7 +325,6 @@ public class JLabel extends JComponent implements Accessible, SwingConstants } } - /** DOCUMENT ME! */ private static final long serialVersionUID = 5496508283662221534L; static final String LABEL_PROPERTY = "labeledBy"; @@ -452,14 +479,42 @@ public class JLabel extends JComponent implements Accessible, SwingConstants } /** - * This method is used primarily for debugging purposes and returns a string - * that can be used to represent this label. + * Returns a string describing the attributes for the <code>JLabel</code> + * component, for use in debugging. The return value is guaranteed to be + * non-<code>null</code>, but the format of the string may vary between + * implementations. * - * @return A string to represent this label. + * @return A string describing the attributes of the <code>JLabel</code>. */ protected String paramString() { - return super.paramString(); + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",defaultIcon="); + if (icon != null) + sb.append(icon); + sb.append(",disabledIcon="); + if (disabledIcon != null) + sb.append(disabledIcon); + sb.append(",horizontalAlignment="); + sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString( + horizontalAlignment)); + sb.append(",horizontalTextPosition="); + sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString( + horizontalTextPosition)); + sb.append(",iconTextGap=").append(iconTextGap); + sb.append(",labelFor="); + if (labelFor != null) + sb.append(labelFor); + sb.append(",text="); + if (text != null) + sb.append(text); + sb.append(",verticalAlignment="); + sb.append(SwingUtilities.convertVerticalAlignmentCodeToString( + verticalAlignment)); + sb.append(",verticalTextPosition="); + sb.append(SwingUtilities.convertVerticalAlignmentCodeToString( + verticalTextPosition)); + return sb.toString(); } /** @@ -868,24 +923,25 @@ public class JLabel extends JComponent implements Accessible, SwingConstants { if (c != labelFor) { + Component oldLabelFor = labelFor; + labelFor = c; + firePropertyChange("labelFor", oldLabelFor, labelFor); + // We put the label into the client properties for the labeled // component so that it can be read by the AccessibleJComponent. // The other option would be to reserve a default visible field - // in JComponent, but since this is relativly seldomly used, it + // in JComponent, but since this is relatively seldomly used, it // would be unnecessary waste of memory to do so. - Component oldLabelFor = labelFor; if (oldLabelFor instanceof JComponent) { ((JComponent) oldLabelFor).putClientProperty(LABEL_PROPERTY, null); } - labelFor = c; - if (labelFor instanceof JComponent) + if (labelFor instanceof JComponent) { ((JComponent) labelFor).putClientProperty(LABEL_PROPERTY, this); } - firePropertyChange("labelFor", oldLabelFor, labelFor); } } @@ -902,9 +958,10 @@ public class JLabel extends JComponent implements Accessible, SwingConstants } /** - * DOCUMENT ME! + * Returns the object that provides accessibility features for this + * <code>JLabel</code> component. * - * @return The accessible context. + * @return The accessible context (an instance of {@link AccessibleJLabel}). */ public AccessibleContext getAccessibleContext() { diff --git a/libjava/classpath/javax/swing/JLayeredPane.java b/libjava/classpath/javax/swing/JLayeredPane.java index f887c24506f..11650e721d0 100644 --- a/libjava/classpath/javax/swing/JLayeredPane.java +++ b/libjava/classpath/javax/swing/JLayeredPane.java @@ -147,19 +147,19 @@ public class JLayeredPane extends JComponent implements Accessible public static final String LAYER_PROPERTY = "layeredContainerLayer"; - public static final Integer FRAME_CONTENT_LAYER = new Integer (-30000); + public static final Integer FRAME_CONTENT_LAYER = new Integer(-30000); - public static final Integer DEFAULT_LAYER = new Integer (0); - public static final Integer PALETTE_LAYER = new Integer (100); - public static final Integer MODAL_LAYER = new Integer (200); - public static final Integer POPUP_LAYER = new Integer (300); - public static final Integer DRAG_LAYER = new Integer (400); + public static final Integer DEFAULT_LAYER = new Integer(0); + public static final Integer PALETTE_LAYER = new Integer(100); + public static final Integer MODAL_LAYER = new Integer(200); + public static final Integer POPUP_LAYER = new Integer(300); + public static final Integer DRAG_LAYER = new Integer(400); private Hashtable componentToLayer; // Component -> Layer Number (Integer) public JLayeredPane() { - componentToLayer = new Hashtable (); + componentToLayer = new Hashtable(); setLayout(null); } diff --git a/libjava/classpath/javax/swing/JList.java b/libjava/classpath/javax/swing/JList.java index 55978a4c695..eab6be3c30c 100644 --- a/libjava/classpath/javax/swing/JList.java +++ b/libjava/classpath/javax/swing/JList.java @@ -1475,19 +1475,18 @@ public class JList extends JComponent implements Accessible, Scrollable } /** - * Returns all the values in the list's {@link #model} property which - * are selected, according to the list's {@link #selectionModel} property. - * + * 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 #setSelectedValue */ public Object[] getSelectedValues() { - int [] idx = getSelectedIndices(); - Object [] v = new Object[idx.length]; + int[] idx = getSelectedIndices(); + Object[] v = new Object[idx.length]; for (int i = 0; i < idx.length; ++i) - v[i] = getModel().getElementAt(i); + v[i] = getModel().getElementAt(idx[i]); return v; } diff --git a/libjava/classpath/javax/swing/JMenu.java b/libjava/classpath/javax/swing/JMenu.java index 37ed1485481..02cb20eab57 100644 --- a/libjava/classpath/javax/swing/JMenu.java +++ b/libjava/classpath/javax/swing/JMenu.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.Component; import java.awt.Point; import java.awt.event.KeyEvent; @@ -48,6 +46,7 @@ import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Serializable; +import java.util.ArrayList; import java.util.EventListener; import javax.accessibility.Accessible; @@ -811,7 +810,9 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement return accessibleContext; } - // FIXME: This inner class is a complete stub and needs to be implemented. + /** + * Implements support for assisitive technologies for <code>JMenu</code>. + */ protected class AccessibleJMenu extends AccessibleJMenuItem implements AccessibleSelection { @@ -822,69 +823,245 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement // Nothing to do here. } + /** + * Returns the number of accessible children of this object. + * + * @return the number of accessible children of this object + */ public int getAccessibleChildrenCount() - throws NotImplementedException { - return 0; + Component[] children = getMenuComponents(); + int count = 0; + for (int i = 0; i < children.length; i++) + { + if (children[i] instanceof Accessible) + count++; + } + return count; } - public Accessible getAccessibleChild(int value0) - throws NotImplementedException + /** + * Returns the accessible child with the specified <code>index</code>. + * + * @param index the index of the child to fetch + * + * @return the accessible child with the specified <code>index</code> + */ + public Accessible getAccessibleChild(int index) { - return null; + Component[] children = getMenuComponents(); + int count = 0; + Accessible found = null; + for (int i = 0; i < children.length; i++) + { + if (children[i] instanceof Accessible) + { + if (count == index) + { + found = (Accessible) children[i]; + break; + } + count++; + } + } + return found; } + /** + * Returns the accessible selection of this object. AccessibleJMenus handle + * their selection themselves, so we always return <code>this</code> here. + * + * @return the accessible selection of this object + */ public AccessibleSelection getAccessibleSelection() - throws NotImplementedException { - return null; + return this; } - public Accessible getAccessibleSelection(int value0) - throws NotImplementedException + /** + * Returns the selected accessible child with the specified + * <code>index</code>. + * + * @param index the index of the accessible selected child to return + * + * @return the selected accessible child with the specified + * <code>index</code> + */ + public Accessible getAccessibleSelection(int index) { - return null; + Accessible selected = null; + // Only one item can be selected, which must therefore have index == 0. + if (index == 0) + { + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + MenuElement[] me = msm.getSelectedPath(); + if (me != null) + { + for (int i = 0; i < me.length; i++) + { + if (me[i] == JMenu.this) + { + // This JMenu is selected, find and return the next + // JMenuItem in the path. + do + { + if (me[i] instanceof Accessible) + { + selected = (Accessible) me[i]; + break; + } + i++; + } while (i < me.length); + } + if (selected != null) + break; + } + } + } + return selected; } - public boolean isAccessibleChildSelected(int value0) - throws NotImplementedException + /** + * Returns <code>true</code> if the accessible child with the specified + * index is selected, <code>false</code> otherwise. + * + * @param index the index of the accessible child to check + * + * @return <code>true</code> if the accessible child with the specified + * index is selected, <code>false</code> otherwise + */ + public boolean isAccessibleChildSelected(int index) { - return false; + boolean selected = false; + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + MenuElement[] me = msm.getSelectedPath(); + if (me != null) + { + Accessible toBeFound = getAccessibleChild(index); + for (int i = 0; i < me.length; i++) + { + if (me[i] == toBeFound) + { + selected = true; + break; + } + } + } + return selected; } + /** + * Returns the accessible role of this object, which is + * {@link AccessibleRole#MENU} for the AccessibleJMenu. + * + * @return the accessible role of this object + */ public AccessibleRole getAccessibleRole() { return AccessibleRole.MENU; } + /** + * Returns the number of selected accessible children. This will be + * <code>0</code> if no item is selected, or <code>1</code> if an item + * is selected. AccessibleJMenu can have maximum 1 selected item. + * + * @return the number of selected accessible children + */ public int getAccessibleSelectionCount() - throws NotImplementedException { - return 0; + int count = 0; + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + MenuElement[] me = msm.getSelectedPath(); + if (me != null) + { + for (int i = 0; i < me.length; i++) + { + if (me[i] == JMenu.this) + { + if (i + 1 < me.length) + { + count = 1; + break; + } + } + } + } + return count; } - public void addAccessibleSelection(int value0) - throws NotImplementedException + /** + * Selects the accessible child with the specified index. + * + * @param index the index of the accessible child to select + */ + public void addAccessibleSelection(int index) { - // TODO: Implement this properly. + Accessible child = getAccessibleChild(index); + if (child != null && child instanceof JMenuItem) + { + JMenuItem mi = (JMenuItem) child; + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + msm.setSelectedPath(createPath(JMenu.this)); + } } - public void removeAccessibleSelection(int value0) - throws NotImplementedException + /** + * Removes the item with the specified index from the selection. + * + * @param index the index of the selected item to remove from the selection + */ + public void removeAccessibleSelection(int index) { - // TODO: Implement this properly. + Accessible child = getAccessibleChild(index); + if (child != null) + { + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + MenuElement[] oldSelection = msm.getSelectedPath(); + for (int i = 0; i < oldSelection.length; i++) + { + if (oldSelection[i] == child) + { + // Found the specified child in the selection. Remove it + // from the selection. + MenuElement[] newSel = new MenuElement[i - 1]; + System.arraycopy(oldSelection, 0, newSel, 0, i - 1); + msm.setSelectedPath(newSel); + break; + } + } + } } + /** + * Removes all possibly selected accessible children of this object from + * the selection. + */ public void clearAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + MenuSelectionManager msm = MenuSelectionManager.defaultManager(); + MenuElement[] oldSelection = msm.getSelectedPath(); + for (int i = 0; i < oldSelection.length; i++) + { + if (oldSelection[i] == JMenu.this) + { + // Found this menu in the selection. Remove all children from + // the selection. + MenuElement[] newSel = new MenuElement[i]; + System.arraycopy(oldSelection, 0, newSel, 0, i); + msm.setSelectedPath(newSel); + break; + } + } } + /** + * AccessibleJMenu don't support multiple selection, so this method + * does nothing. + */ public void selectAllAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + // Nothing to do here. } } @@ -939,4 +1116,44 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement } } + /** + * Creates an array to be feeded as argument to + * {@link MenuSelectionManager#setSelectedPath(MenuElement[])} for the + * specified element. This has the effect of selecting the specified element + * and all its parents. + * + * @param leaf the leaf element for which to create the selected path + * + * @return the selected path array + */ + MenuElement[] createPath(JMenu leaf) + { + ArrayList path = new ArrayList(); + MenuElement[] array = null; + Component current = leaf.getPopupMenu(); + while (true) + { + if (current instanceof JPopupMenu) + { + JPopupMenu popupMenu = (JPopupMenu) current; + path.add(0, popupMenu); + current = popupMenu.getInvoker(); + } + else if (current instanceof JMenu) + { + JMenu menu = (JMenu) current; + path.add(0, menu); + current = menu.getParent(); + } + else if (current instanceof JMenuBar) + { + JMenuBar menuBar = (JMenuBar) current; + path.add(0, menuBar); + array = new MenuElement[path.size()]; + array = (MenuElement[]) path.toArray(array); + break; + } + } + return array; + } } diff --git a/libjava/classpath/javax/swing/JMenuBar.java b/libjava/classpath/javax/swing/JMenuBar.java index 18e47dcd96d..35f129377f1 100644 --- a/libjava/classpath/javax/swing/JMenuBar.java +++ b/libjava/classpath/javax/swing/JMenuBar.java @@ -370,10 +370,30 @@ public class JMenuBar extends JComponent implements Accessible, MenuElement { MenuElement[] subElements = new MenuElement[getComponentCount()]; + int j = 0; + boolean doResize = false; + MenuElement menu; for (int i = 0; i < getComponentCount(); i++) - subElements[i] = (MenuElement) getMenu(i); + { + menu = getMenu(i); + if (menu != null) + { + subElements[j++] = (MenuElement) menu; + } + else + doResize = true; + } - return subElements; + if (! doResize) + return subElements; + else + { + MenuElement[] subElements2 = new MenuElement[j]; + for (int i = 0; i < j; i++) + subElements2[i] = subElements[i]; + + return subElements2; + } } /** @@ -522,6 +542,9 @@ public class JMenuBar extends JComponent implements Accessible, MenuElement KeyEvent e, int condition, boolean pressed) { + if (menuElement == null) + return false; + // First check the menuElement itself, if it's a JComponent if (menuElement instanceof JComponent && ((JComponent) menuElement).processKeyBinding(ks, e, condition, diff --git a/libjava/classpath/javax/swing/JMenuItem.java b/libjava/classpath/javax/swing/JMenuItem.java index 272c1cfe6ce..90d54b1d30a 100644 --- a/libjava/classpath/javax/swing/JMenuItem.java +++ b/libjava/classpath/javax/swing/JMenuItem.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.Component; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; @@ -51,6 +49,7 @@ import java.util.EventListener; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; +import javax.accessibility.AccessibleState; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.MenuDragMouseEvent; @@ -673,7 +672,7 @@ public class JMenuItem extends AbstractButton implements Accessible, } /** - * Returns a string describing the attributes for the <code>JToolTip</code> + * Returns a string describing the attributes for the <code>JMenuItem</code> * component, for use in debugging. The return value is guaranteed to be * non-<code>null</code>, but the format of the string may vary between * implementations. @@ -696,7 +695,11 @@ public class JMenuItem extends AbstractButton implements Accessible, public AccessibleContext getAccessibleContext() { if (accessibleContext == null) - accessibleContext = new AccessibleJMenuItem(); + { + AccessibleJMenuItem ctx = new AccessibleJMenuItem(); + addChangeListener(ctx); + accessibleContext = ctx; + } return accessibleContext; } @@ -712,6 +715,11 @@ public class JMenuItem extends AbstractButton implements Accessible, { private static final long serialVersionUID = 6748924232082076534L; + private boolean armed; + private boolean focusOwner; + private boolean pressed; + private boolean selected; + /** * Creates a new <code>AccessibleJMenuItem</code> instance. */ @@ -720,10 +728,99 @@ public class JMenuItem extends AbstractButton implements Accessible, //super(component); } + /** + * Receives notification when the menu item's state changes and fires + * appropriate property change events to registered listeners. + * + * @param event the change event + */ public void stateChanged(ChangeEvent event) - throws NotImplementedException { - // TODO: What should be done here, if anything? + // This is fired in all cases. + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + Boolean.FALSE, Boolean.TRUE); + + ButtonModel model = getModel(); + + // Handle the armed property. + if (model.isArmed()) + { + if (! armed) + { + armed = true; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + AccessibleState.ARMED, null); + } + } + else + { + if (armed) + { + armed = false; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + null, AccessibleState.ARMED); + } + } + + // Handle the pressed property. + if (model.isPressed()) + { + if (! pressed) + { + pressed = true; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + AccessibleState.PRESSED, null); + } + } + else + { + if (pressed) + { + pressed = false; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + null, AccessibleState.PRESSED); + } + } + + // Handle the selected property. + if (model.isSelected()) + { + if (! selected) + { + selected = true; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + AccessibleState.SELECTED, null); + } + } + else + { + if (selected) + { + selected = false; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + null, AccessibleState.SELECTED); + } + } + + // Handle the focusOwner property. + if (isFocusOwner()) + { + if (! focusOwner) + { + focusOwner = true; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + AccessibleState.FOCUSED, null); + } + } + else + { + if (focusOwner) + { + focusOwner = false; + firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + null, AccessibleState.FOCUSED); + } + } } /** diff --git a/libjava/classpath/javax/swing/JOptionPane.java b/libjava/classpath/javax/swing/JOptionPane.java index 0bef12b61fc..f9490553834 100644 --- a/libjava/classpath/javax/swing/JOptionPane.java +++ b/libjava/classpath/javax/swing/JOptionPane.java @@ -1,5 +1,5 @@ /* JOptionPane.java - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,14 +38,20 @@ exception statement from your version. */ package javax.swing; +import java.awt.AWTEvent; +import java.awt.ActiveEvent; import java.awt.Component; +import java.awt.Container; +import java.awt.EventQueue; import java.awt.Frame; +import java.awt.MenuComponent; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseMotionAdapter; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; -import javax.swing.event.InternalFrameAdapter; -import javax.swing.event.InternalFrameEvent; import javax.swing.plaf.OptionPaneUI; /** @@ -57,17 +63,15 @@ import javax.swing.plaf.OptionPaneUI; public class JOptionPane extends JComponent implements Accessible { /** - * DOCUMENT ME! + * Provides the accessibility features for the <code>JOptionPane</code> + * component. */ - // FIXME: This inner class is a complete stub and needs to be implemented - // properly. protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent { - /** DOCUMENT ME! */ private static final long serialVersionUID = 686071432213084821L; /** - * Creates a new AccessibleJOptionPane object. + * Creates a new <code>AccessibleJOptionPane</code> instance. */ protected AccessibleJOptionPane() { @@ -86,7 +90,6 @@ public class JOptionPane extends JComponent implements Accessible } } - /** DOCUMENT ME! */ private static final long serialVersionUID = 5231143276678566796L; /** The value returned when cancel option is selected. */ @@ -431,9 +434,11 @@ public class JOptionPane extends JComponent implements Accessible } /** - * DOCUMENT ME! + * Returns the object that provides accessibility features for this + * <code>JOptionPane</code> component. * - * @return DOCUMENT ME! + * @return The accessible context (an instance of + * {@link AccessibleJOptionPane}). */ public AccessibleContext getAccessibleContext() { @@ -1529,31 +1534,64 @@ public class JOptionPane extends JComponent implements Accessible */ private static void startModal(JInternalFrame f) { - synchronized (f) - { - final JInternalFrame tmp = f; - tmp.toFront(); - - f.addInternalFrameListener(new InternalFrameAdapter() - { - public void internalFrameClosed(InternalFrameEvent e) - { - synchronized (tmp) - { - tmp.removeInternalFrameListener(this); - tmp.notifyAll(); - } - } - }); - try - { - while (! f.isClosed()) - f.wait(); - } - catch (InterruptedException ignored) - { - // Ignore this Exception. - } - } + // We need to add an additional glasspane-like component directly + // below the frame, which intercepts all mouse events that are not + // directed at the frame itself. + JPanel modalInterceptor = new JPanel(); + modalInterceptor.setOpaque(false); + JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f); + lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue()); + modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight()); + modalInterceptor.addMouseListener(new MouseAdapter(){}); + modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){}); + lp.add(modalInterceptor); + f.toFront(); + + // We need to explicitly dispatch events when we are blocking the event + // dispatch thread. + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + try + { + while (! f.isClosed()) + { + if (EventQueue.isDispatchThread()) + { + // The getNextEventMethod() issues wait() when no + // event is available, so we don't need do explicitly wait(). + AWTEvent ev = queue.getNextEvent(); + // This mimics EventQueue.dispatchEvent(). We can't use + // EventQueue.dispatchEvent() directly, because it is + // protected, unfortunately. + if (ev instanceof ActiveEvent) + ((ActiveEvent) ev).dispatch(); + else if (ev.getSource() instanceof Component) + ((Component) ev.getSource()).dispatchEvent(ev); + else if (ev.getSource() instanceof MenuComponent) + ((MenuComponent) ev.getSource()).dispatchEvent(ev); + // Other events are ignored as per spec in + // EventQueue.dispatchEvent + } + else + { + // Give other threads a chance to become active. + Thread.yield(); + } + } + } + catch (InterruptedException ex) + { + // If we get interrupted, then leave the modal state. + } + finally + { + // Clean up the modal interceptor. + lp.remove(modalInterceptor); + + // Remove the internal frame from its parent, so it is no longer + // lurking around and clogging memory. + Container parent = f.getParent(); + if (parent != null) + parent.remove(f); + } } } diff --git a/libjava/classpath/javax/swing/JPopupMenu.java b/libjava/classpath/javax/swing/JPopupMenu.java index a54bd777fd4..c7890ea0e1e 100644 --- a/libjava/classpath/javax/swing/JPopupMenu.java +++ b/libjava/classpath/javax/swing/JPopupMenu.java @@ -52,6 +52,7 @@ import java.util.EventListener; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; +import javax.swing.event.MenuKeyListener; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import javax.swing.plaf.PopupMenuUI; @@ -410,6 +411,36 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement } /** + * Adds a MenuKeyListener to the popup. + * + * @param l - the listener to add. + */ + public void addMenuKeyListener(MenuKeyListener l) + { + listenerList.add(MenuKeyListener.class, l); + } + + /** + * Removes a MenuKeyListener from the popup. + * + * @param l - the listener to remove. + */ + public void removeMenuKeyListener(MenuKeyListener l) + { + listenerList.remove(MenuKeyListener.class, l); + } + + /** + * Returns array of getMenuKeyListeners that are listening to JPopupMenu. + * + * @return array of getMenuKeyListeners that are listening to JPopupMenu + */ + public MenuKeyListener[] getMenuKeyListeners() + { + return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class)); + } + + /** * Adds popupMenuListener to listen for PopupMenuEvents fired * by the JPopupMenu * diff --git a/libjava/classpath/javax/swing/JProgressBar.java b/libjava/classpath/javax/swing/JProgressBar.java index db936f64a34..ed2d0088d06 100644 --- a/libjava/classpath/javax/swing/JProgressBar.java +++ b/libjava/classpath/javax/swing/JProgressBar.java @@ -53,15 +53,14 @@ import javax.swing.event.ChangeListener; import javax.swing.plaf.ProgressBarUI; /** - * 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. - * + * A component that displays a visual indicator of the progress of a task. The + * component has two modes: determinate and indeterminate. In determinate mode, + * the <code>JProgressBar</code> fills a percentage of its bar based on its + * current value. In indeterminate mode, it creates box and bounces it between + * its bounds. * <p> - * JProgressBars have the following properties: + * This component has the following properties: * </p> - * * <table> * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr> * <tr><td> borderPainted </td><td> progressBar </td><td> yes </td></tr> @@ -193,33 +192,67 @@ public class JProgressBar extends JComponent implements SwingConstants, private static final long serialVersionUID = 1980046021813598781L; - /** Whether the ProgressBar is determinate. */ + /** + * A flag that determines the mode (<code>true</code> for indeterminate, + * <code>false</code> for determinate). + */ private transient boolean indeterminate = false; - /** The orientation of the ProgressBar. Always set by constructor. */ + /** + * The orientation of the <code>JProgressBar</code> + * ({@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}). + * Defaults to {@link SwingConstants#HORIZONTAL}. + * @see #setOrientation(int) + */ protected int orientation; - /** Whether borders should be painted. */ + /** + * A flag the controls whether or not the component's border is painted. + * The default is <code>true</code>. + * @see #setBorderPainted(boolean) + */ protected boolean paintBorder = true; - /** The model describing this ProgressBar. */ + /** + * The model defining the bounds and current value for the progress bar. + * @see #setModel(BoundedRangeModel) + */ protected BoundedRangeModel model; - /** The string that is displayed by the ProgressBar. */ + /** + * A custom string for display in the progress bar. If this is + * <code>null</code>, a default string will be generated. + * @see #setString(String) + */ protected String progressString; - /** Whether the string should be painted. */ + /** + * A flag that controls whether a string is displayed within the progress + * bar. + * @see #setStringPainted(boolean) + */ protected boolean paintString = false; - /** The static changeEvent passed to all ChangeListeners. */ + /** + * A single change event reused for all events. + * @see #fireStateChanged() + */ protected transient ChangeEvent changeEvent; - /** The ChangeListener that listens to the model. */ + /** + * The listener that is registered with the model. */ protected ChangeListener changeListener; /** - * Creates a new horizontally oriented JProgressBar object - * with a minimum of 0 and a maximum of 100. + * Creates a new <code>JProgressBar</code> with default attributes. The + * following defaults are used: + * <p> + * <ul> + * <li><code>value</code>: 0;</li> + * <li><code>minimum</code>: 0;</li> + * <li><code>maximum</code>: 100;</li> + * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> + * </ul> */ public JProgressBar() { @@ -227,13 +260,20 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Creates a new <code>JProgressBar</code> with the specified + * <code>orientation</code>. The following defaults are used: + * <p> + * <ul> + * <li><code>value</code>: 0;</li> + * <li><code>minimum</code>: 0;</li> + * <li><code>maximum</code>: 100;</li> + * </ul> * - * @throws IllegalArgumentException if <code>orientation</code> is not either - * {@link #HORIZONTAL} or {@link #VERTICAL}. + * @param orientation the orientation ({@link #HORIZONTAL} or + * {@link #VERTICAL}). + * + * @throws IllegalArgumentException if <code>orientation</code> is not one of + * the specified values. */ public JProgressBar(int orientation) { @@ -241,11 +281,16 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Creates a new <code>JProgressBar</code> with the specified value range. + * The following defaults are used: + * <p> + * <ul> + * <li><code>value</code>: <code>minimum</code>;</li> + * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> + * </ul> + * + * @param minimum the lower bound of the value range. + * @param maximum the upper bound of the value range. */ public JProgressBar(int minimum, int maximum) { @@ -253,15 +298,20 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Creates a new <code>JProgressBar</code> with the specified range and + * orientation. The following defaults are used: + * <p> + * <ul> + * <li><code>value</code>: <code>minimum</code>;</li> + * </ul> + * + * @param minimum the lower bound of the value range. + * @param maximum the upper bound of the value range. + * @param orientation the orientation ({@link #HORIZONTAL} or + * {@link #VERTICAL}). * - * @throws IllegalArgumentException if <code>orientation</code> is not either - * {@link #HORIZONTAL} or {@link #VERTICAL}. + * @throws IllegalArgumentException if <code>orientation</code> is not one of + * the specified values. */ public JProgressBar(int orientation, int minimum, int maximum) { @@ -276,10 +326,14 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * Creates a new horizontally oriented JProgressBar object - * with the given model. - * - * @param model The model to be used with the JProgressBar. + * Creates a new <code>JProgressBar</code> with the specified model. The + * following defaults are used: + * <p> + * <ul> + * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> + * </ul> + * + * @param model the model (<code>null</code> not permitted). */ public JProgressBar(BoundedRangeModel model) { @@ -291,9 +345,12 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method returns the current value of the JProgressBar. + * Returns the current value for the <code>JProgressBar</code>. This value + * is fetched from the model. * - * @return The current value of the JProgressBar. + * @return The current value. + * + * @see #setValue(int) */ public int getValue() { @@ -301,9 +358,20 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method sets the value of the JProgressBar. + * Sets the current value for the <code>JProgressBar</code>. The value is + * stored in the component's <code>model</code> (see {@link #getModel()}). + * If the new value is different to the old value, a {@link ChangeEvent} is + * sent to the model's registered listeners. In turn, this triggers a call + * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> + * to this component's registered listeners. + * <p> + * If <code>value</code> is outside the range <code>minimum</code> to + * <code>maximum</code>, it will be set to the nearest of those boundary + * values. * - * @param value The value of the JProgressBar. + * @param value the new value. + * + * @see #getValue() */ public void setValue(int value) { @@ -311,23 +379,29 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method paints the border of the JProgressBar + * Paints the component's border, but only if {@link #isBorderPainted()} + * returns <code>true</code>. * - * @param graphics The graphics object to paint with. + * @param graphics the graphics object to paint with. + * + * @see #setBorderPainted(boolean) */ protected void paintBorder(Graphics graphics) { Border border = getBorder(); if (paintBorder && border != null) - border.paintBorder(this, graphics, 0, 0, - getWidth(), - getHeight()); + border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight()); } /** - * This method returns the orientation of the JProgressBar. + * Returns the orientation of the <code>JProgressBar</code> component, which + * is either {@link SwingConstants#HORIZONTAL} or + * {@link SwingConstants#VERTICAL}. The default orientation is + * <code>HORIZONTAL</code>. * - * @return The orientation of the JProgressBar. + * @return The orientation. + * + * @see #setOrientation(int) */ public int getOrientation() { @@ -335,12 +409,17 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method changes the orientation property. The orientation of the - * JProgressBar can be either horizontal or vertical. + * Sets the orientation for this <code>JProgressBar</code> component and, + * if the value changes, sends a {@link PropertyChangeEvent} (with the + * property name <code>"orientation"</code>) to all registered listeners. * - * @param orientation The orientation of the JProgressBar. + * @param orientation the orientation ({@link #HORIZONTAL} or + * {@link #VERTICAL}). + * * @throws IllegalArgumentException if <code>orientation</code> is not - * either {@link #HORIZONTAL} or {@link #VERTICAL}. + * one of the listed values. + * + * @see #getOrientation() */ public void setOrientation(int orientation) { @@ -349,17 +428,21 @@ public class JProgressBar extends JComponent implements SwingConstants, + " is not a legal orientation"); if (this.orientation != orientation) { - int oldOrientation = this.orientation; - this.orientation = orientation; - firePropertyChange("orientation", oldOrientation, - this.orientation); + int oldOrientation = this.orientation; + this.orientation = orientation; + firePropertyChange("orientation", oldOrientation, this.orientation); } } /** - * This method returns whether the progressString will be painted. + * Returns the flag that controls whether or not the string returned by + * {@link #getString()} is displayed by the <code>JProgressBar</code> + * component. * - * @return Whether the string is painted. + * @return <code>true</code> if the string should be displayed, and + * <code>false</code> otherwise. + * + * @see #setStringPainted(boolean) */ public boolean isStringPainted() { @@ -367,28 +450,37 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method changes the stringPainted property. + * Sets the flag that controls whether or not the string returned by + * {@link #getString()} is displayed by the <code>JProgressBar</code> + * component. If the flag value changes, a {@link PropertyChangeEvent} (with + * the property name <code>"stringPainted"</code>) is sent to all registered + * listeners. * - * @param painted Whether the string is painted. + * @param painted the new flag value. + * + * @see #isStringPainted() + * @see #setString(String) */ public void setStringPainted(boolean painted) { if (paintString != painted) { - boolean oldPainted = paintString; - paintString = painted; - firePropertyChange("stringPainted", oldPainted, - paintString); + boolean oldPainted = paintString; + paintString = painted; + firePropertyChange("stringPainted", 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. + * Returns the string that is painted on the <code>JProgressBar</code> if + * {@link #isStringPainted()} returns <code>true</code>. If no string has + * been explicitly set, this method will return a string displaying the + * value of {@link #getPercentComplete()}. * - * @return The string that is painted. + * @return The string. + * + * @see #setString(String) + * @see #setStringPainted(boolean) */ public String getString() { @@ -399,12 +491,16 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Sets the string to display within the progress bar and, if the new value + * is different to the old value, sends a {@link PropertyChangeEvent} (with + * the property name <code>"string"</code>) to all registered listeners. If + * the string is set to <code>null</code>, {@link #getString()} will return + * a default string. * - * @param string The string to be painted. + * @param string the string (<code>null</code> permitted). + * + * @see #getString() + * @see #setStringPainted(boolean) */ public void setString(String string) { @@ -412,32 +508,35 @@ public class JProgressBar extends JComponent implements SwingConstants, string != progressString) || (string != null && ! string.equals(progressString))) { - String oldString = progressString; - progressString = string; - firePropertyChange("string", oldString, progressString); + String oldString = progressString; + progressString = string; + firePropertyChange("string", oldString, progressString); } } /** - * This method returns the percent of the bar - * that is "complete". (This is the amount value / (max - min)). + * Returns the current value expressed as a percentage. This is calculated + * as <code>(value - min) / (max - min)</code>. * - * @return DOCUMENT ME! + * @return The percentage (a value in the range 0.0 to 1.0). */ public double getPercentComplete() { if (getMaximum() == getMinimum()) return 1.0; else - return (double) (model.getValue() - model.getMinimum()) / (model - .getMaximum() - - model.getMinimum()); + return (double) (model.getValue() - model.getMinimum()) + / (model.getMaximum() - model.getMinimum()); } /** - * This method returns whether the border is painted. + * Returns a flag that controls whether or not the component's border is + * painted. The default value is <code>true</code>. * - * @return Whether the border is painted. + * @return <code>true</code> if the component's border should be painted, + * and <code>false</code> otherwise. + * + * @see #setBorderPainted(boolean) */ public boolean isBorderPainted() { @@ -445,25 +544,30 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method changes the borderPainted property. + * Sets the flag that controls whether or not the component's border is + * painted. If the flag value is changed, this method sends a + * {@link PropertyChangeEvent} (with the property name "borderPainted") to + * all registered listeners. * - * @param painted Whether the border is painted. + * @param painted the new flag value. + * + * @see #isBorderPainted() + * @see #paintBorder */ public void setBorderPainted(boolean painted) { if (painted != paintBorder) { - boolean oldPainted = paintBorder; - paintBorder = painted; - firePropertyChange("borderPainted", oldPainted, - paintBorder); + boolean oldPainted = paintBorder; + paintBorder = painted; + firePropertyChange("borderPainted", oldPainted, paintBorder); } } /** - * This method returns the JProgressBar's UI delegate. + * Returns the UI delegate for this <code>JProgressBar</code>. * - * @return This JProgressBar's UI delegate. + * @return The UI delegate. */ public ProgressBarUI getUI() { @@ -471,9 +575,9 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method changes the UI property for this JProgressBar. + * Sets the UI delegate for this component. * - * @param ui The new UI delegate. + * @param ui the new UI delegate. */ public void setUI(ProgressBarUI ui) { @@ -481,8 +585,8 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method reverts the UI delegate for this JProgressBar - * to the default for this Look and Feel. + * Sets this <code>JProgressBar</code>'s UI delegate to the default + * (obtained from the {@link UIManager}) for the current look and feel. */ public void updateUI() { @@ -490,11 +594,11 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method returns the identifier to allow the UIManager - * to pick the correct class to act as the UI for - * this JProgressBar. + * Returns the suffix (<code>"ProgressBarUI"</code> in this case) used to + * determine the class name for a UI delegate that can provide the look and + * feel for a <code>JProgressBar</code>. * - * @return The UIClassID: "ProgressBarUI". + * @return <code>"ProgressBarUI"</code>. */ public String getUIClassID() { @@ -502,27 +606,33 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method returns a ChangeListener that gets registered - * model. By default, the ChangeListener, propagates the - * ChangeEvents to the ChangeListeners of the JProgressBar. + * Creates a new {@link ChangeListener} that calls + * {@link #fireStateChanged()} whenever it receives a {@link ChangeEvent} + * (typically from the component's <code>model</code>). This listener is + * registered with the progress bar's model, so that changes made to the + * model directly will automatically result in the progress bar's listeners + * being notified also. * - * @return A new ChangeListener. + * @return A new listener. */ protected ChangeListener createChangeListener() { return new ChangeListener() { - public void stateChanged(ChangeEvent ce) - { - fireStateChanged(); - } + public void stateChanged(ChangeEvent ce) + { + fireStateChanged(); + } }; } /** - * This method adds a ChangeListener to this JProgressBar. + * Registers a listener with this component so that it will receive + * notification of component state changes. * - * @param listener The ChangeListener to add to this JProgressBar. + * @param listener the listener. + * + * @see #removeChangeListener(ChangeListener) */ public void addChangeListener(ChangeListener listener) { @@ -530,9 +640,12 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method removes a ChangeListener from this JProgressBar. + * Deregisters a listener so that it no longer receives notification of + * component state changes. * - * @param listener The ChangeListener to remove from this JProgressBar. + * @param listener the listener. + * + * @see #addChangeListener(ChangeListener) */ public void removeChangeListener(ChangeListener listener) { @@ -540,10 +653,12 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method returns an array of all ChangeListeners listening to this - * progress bar. + * Returns an array of the listeners that are registered with this component. + * The array may be empty, but is never <code>null</code>. * - * @return An array of ChangeListeners listening to this progress bar. + * @return An array of listeners. + * + * @since 1.4 */ public ChangeListener[] getChangeListeners() { @@ -551,9 +666,10 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Sends a {@link ChangeEvent} to all registered listeners to indicate that + * the state of the <code>JProgressBar</code> has changed. + * + * @see #createChangeListener() */ protected void fireStateChanged() { @@ -562,15 +678,17 @@ public class JProgressBar extends JComponent implements SwingConstants, 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); + if (changeListeners[i] == ChangeListener.class) + ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent); } } /** - * This method returns the model used with this JProgressBar. + * Returns the model for the <code>JProgressBar</code>. * - * @return The model used with this JProgressBar. + * @return The model (never <code>null</code>). + * + * @see #setModel(BoundedRangeModel) */ public BoundedRangeModel getModel() { @@ -578,25 +696,32 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method changes the model property for this JProgressBar. + * Sets the model for the <code>JProgressBar</code> and sends a + * {@link ChangeEvent} to all registered listeners. * - * @param model The model to use with this JProgressBar. + * @param model the model (<code>null</code> not permitted). + * + * @see #getModel() */ public void setModel(BoundedRangeModel model) { if (model != this.model) { this.model.removeChangeListener(changeListener); - this.model = model; - this.model.addChangeListener(changeListener); - fireStateChanged(); + this.model = model; + this.model.addChangeListener(changeListener); + fireStateChanged(); } } /** - * This method returns the minimum value of this JProgressBar. + * Returns the minimum value for the <code>JProgressBar</code>. This defines + * the lower bound for the current value, and is stored in the component's + * <code>model</code>. * - * @return The minimum value of this JProgressBar. + * @return The minimum value. + * + * @see #setMinimum(int) */ public int getMinimum() { @@ -604,9 +729,16 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method sets the minimum value of this JProgressBar. - * - * @param minimum The minimum value of this JProgressBar. + * Sets the minimum value for the <code>JProgressBar</code>. The value is + * stored in the component's <code>model</code> (see {@link #getModel()}). + * If the new value is different to the old value, a {@link ChangeEvent} is + * sent to the model's registered listeners. In turn, this triggers a call + * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> + * to this component's registered listeners. + * + * @param minimum the minimum value. + * + * @see #getMinimum() */ public void setMinimum(int minimum) { @@ -614,9 +746,13 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method returns the maximum value of this JProgressBar. + * Returns the maximum value for the <code>JProgressBar</code>. This defines + * the upper bound for the current value, and is stored in the component's + * <code>model</code>. * - * @return The maximum value of this JProgressBar. + * @return The maximum value. + * + * @see #setMaximum(int) */ public int getMaximum() { @@ -624,9 +760,16 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * This method sets the maximum value of this JProgressBar. + * Sets the maximum value for the <code>JProgressBar</code>. The value is + * stored in the component's <code>model</code> (see {@link #getModel()}). + * If the new value is different to the old value, a {@link ChangeEvent} is + * sent to the model's registered listeners. In turn, this triggers a call + * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> + * to this component's registered listeners. * - * @param maximum The maximum value of this JProgressBar. + * @param maximum the maximum value. + * + * @see #getMaximum() */ public void setMaximum(int maximum) { @@ -659,29 +802,40 @@ public class JProgressBar extends JComponent implements SwingConstants, } /** - * 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. + * Sets the flag that controls the mode for this <code>JProgressBar</code> + * (<code>true</code> for indeterminate mode, and <code>false</code> for + * determinate mode). If the flag value changes, this method sends a + * {@link PropertyChangeEvent} (with the property name + * <code>"indeterminate"</code>) to all registered listeners. + * <p> + * If the <code>JProgressBar</code> 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 + * <code>JProgressBar</code> is ignored. * - * @param newValue Whether the JProgressBar is indeterminate. + * @param flag the new flag value. + * + * @see #isIndeterminate() + * @since 1.4 */ - public void setIndeterminate(boolean newValue) + public void setIndeterminate(boolean flag) { - if (indeterminate != newValue) + if (indeterminate != flag) { - boolean olddeter = indeterminate; - indeterminate = newValue; - firePropertyChange("indeterminate", olddeter, - indeterminate); + indeterminate = flag; + firePropertyChange("indeterminate", !flag, indeterminate); } } /** - * This method returns whether the JProgressBar is indeterminate. + * Returns a flag that indicates the mode for this <code>JProgressBar</code> + * (<code>true</code> for indeterminate mode, and <code>false</code> for + * determinate mode). * - * @return Whether this JProgressBar is indeterminate. + * @return A flag indicating the mode for the <code>JProgressBar</code>. + * + * @see #setIndeterminate(boolean) + * @since 1.4 */ public boolean isIndeterminate() { diff --git a/libjava/classpath/javax/swing/JScrollBar.java b/libjava/classpath/javax/swing/JScrollBar.java index bca2468738b..bf0803ab5a1 100644 --- a/libjava/classpath/javax/swing/JScrollBar.java +++ b/libjava/classpath/javax/swing/JScrollBar.java @@ -643,14 +643,24 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible } /** - * A string that describes this JScrollBar. Normally only used - * for debugging. + * Returns a string describing the attributes for the <code>JScrollBar</code> + * component, for use in debugging. The return value is guaranteed to be + * non-<code>null</code>, but the format of the string may vary between + * implementations. * - * @return A string describing this JScrollBar. + * @return A string describing the attributes of the <code>JScrollBar</code>. */ protected String paramString() { - return "JScrollBar"; + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",blockIncrement=").append(blockIncrement); + sb.append(",orientation="); + if (this.orientation == JScrollBar.HORIZONTAL) + sb.append("HORIZONTAL"); + else + sb.append("VERTICAL"); + sb.append(",unitIncrement=").append(unitIncrement); + return sb.toString(); } /** diff --git a/libjava/classpath/javax/swing/JScrollPane.java b/libjava/classpath/javax/swing/JScrollPane.java index 09e37378be9..45df1d9190e 100644 --- a/libjava/classpath/javax/swing/JScrollPane.java +++ b/libjava/classpath/javax/swing/JScrollPane.java @@ -170,7 +170,8 @@ public class JScrollPane extends JComponent return columnHeader; } - public Component getCorner(String key) { + public Component getCorner(String key) + { if (getComponentOrientation() == ComponentOrientation.LEFT_TO_RIGHT) { @@ -247,7 +248,7 @@ public class JScrollPane extends JComponent if (viewportBorder == null) { if (getViewport() == null) - return new Rectangle(0,0,0,0); + return new Rectangle(0, 0, 0, 0); else return getViewport().getBounds(); } @@ -255,8 +256,7 @@ public class JScrollPane extends JComponent { Insets i = viewportBorder.getBorderInsets(getViewport()); if (getViewport() == null) - return new Rectangle(0,0, - i.left+i.right, i.top+i.bottom); + return new Rectangle(0, 0, i.left + i.right, i.top + i.bottom); else { Rectangle b = getViewport().getBounds(); diff --git a/libjava/classpath/javax/swing/JSlider.java b/libjava/classpath/javax/swing/JSlider.java index ed94c4ecc19..8a06d4f0116 100644 --- a/libjava/classpath/javax/swing/JSlider.java +++ b/libjava/classpath/javax/swing/JSlider.java @@ -227,13 +227,13 @@ public class JSlider extends JComponent implements SwingConstants, Accessible, } /** Whether or not this slider paints its ticks. */ - private transient boolean paintTicks = false; + private transient boolean paintTicks; /** 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; + private transient boolean paintLabels; /** * A dictionary of (Integer, Component) pairs where each Component is a @@ -251,7 +251,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible, protected int minorTickSpacing; /** Whether the slider snaps its values to ticks. */ - protected boolean snapToTicks = false; + protected boolean snapToTicks; /** The orientation (horizontal or vertical) of the slider. */ protected int orientation = HORIZONTAL; diff --git a/libjava/classpath/javax/swing/JSpinner.java b/libjava/classpath/javax/swing/JSpinner.java index 70045ed5307..16a210600cd 100644 --- a/libjava/classpath/javax/swing/JSpinner.java +++ b/libjava/classpath/javax/swing/JSpinner.java @@ -106,7 +106,7 @@ public class JSpinner extends JComponent add(ftf); ftf.setValue(spinner.getValue()); ftf.addPropertyChangeListener(this); - if(getComponentOrientation().isLeftToRight()) + if (getComponentOrientation().isLeftToRight()) ftf.setHorizontalAlignment(JTextField.RIGHT); else ftf.setHorizontalAlignment(JTextField.LEFT); diff --git a/libjava/classpath/javax/swing/JSplitPane.java b/libjava/classpath/javax/swing/JSplitPane.java index c1151219854..2747686a31a 100644 --- a/libjava/classpath/javax/swing/JSplitPane.java +++ b/libjava/classpath/javax/swing/JSplitPane.java @@ -108,7 +108,7 @@ public class JSplitPane extends JComponent implements Accessible /** * Returns an object that provides access to the current, minimum and - * maximum values for the {@link JSlider}. Since this class implements + * maximum values for the {@link JSplitPane}. Since this class implements * {@link AccessibleValue}, it returns itself. * * @return The accessible value. @@ -136,9 +136,9 @@ public class JSplitPane extends JComponent implements Accessible * listeners. If the supplied value is <code>null</code>, this method * does nothing and returns <code>false</code>. * - * @param value the new slider value (<code>null</code> permitted). + * @param value the new divider location (<code>null</code> permitted). * - * @return <code>true</code> if the slider value is updated, and + * @return <code>true</code> if the divider location value is updated, and * <code>false</code> otherwise. */ public boolean setCurrentAccessibleValue(Number value) @@ -699,7 +699,8 @@ public class JSplitPane extends JComponent implements Accessible * @param proportionalLocation A double that describes the location of the * divider. * - * @throws IllegalArgumentException DOCUMENT ME! + * @throws IllegalArgumentException if <code>proportionalLocation</code> is + * not in the range from 0.0 to 1.0 inclusive. */ public void setDividerLocation(double proportionalLocation) { diff --git a/libjava/classpath/javax/swing/JTabbedPane.java b/libjava/classpath/javax/swing/JTabbedPane.java index 34ab8eeaa66..7e2864b8a44 100644 --- a/libjava/classpath/javax/swing/JTabbedPane.java +++ b/libjava/classpath/javax/swing/JTabbedPane.java @@ -1,5 +1,5 @@ /* JTabbedPane.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Component; import java.awt.Point; @@ -53,6 +51,7 @@ import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; import javax.accessibility.AccessibleSelection; +import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -79,8 +78,6 @@ public class JTabbedPane extends JComponent implements Serializable, /** * Accessibility support for <code>JTabbedPane</code>. */ - // FIXME: This inner class is a complete stub and must be implemented - // properly. protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent implements AccessibleSelection, ChangeListener { @@ -99,14 +96,17 @@ public class JTabbedPane extends JComponent implements Serializable, /** * Receives notification when the selection state of the - * <code>JTabbedPane</code> changes. + * <code>JTabbedPane</code> changes and fires appropriate property change + * events to interested listeners. * * @param e the change event describing the change */ public void stateChanged(ChangeEvent e) - throws NotImplementedException { - // Implement this properly. + // I couldn't figure out what else should be done here. + Object source = e.getSource(); + firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, + null, source); } /** @@ -116,9 +116,8 @@ public class JTabbedPane extends JComponent implements Serializable, * @return the accessible role of the <code>JTabbedPane</code> */ public AccessibleRole getAccessibleRole() - throws NotImplementedException { - return null; + return AccessibleRole.PAGE_TAB_LIST; } /** @@ -129,9 +128,8 @@ public class JTabbedPane extends JComponent implements Serializable, * <code>JTabbedPane</code> */ public int getAccessibleChildrenCount() - throws NotImplementedException { - return 0; + return getTabCount(); } /** @@ -158,9 +156,8 @@ public class JTabbedPane extends JComponent implements Serializable, * @return the current selection state of the <code>JTabbedPane</code> */ public AccessibleSelection getAccessibleSelection() - throws NotImplementedException { - return null; + return this; } /** @@ -175,90 +172,99 @@ public class JTabbedPane extends JComponent implements Serializable, * this location */ public Accessible getAccessibleAt(Point p) - throws NotImplementedException { - return null; + int tabIndex = indexAtLocation(p.x, p.y); + if (tabIndex >= 0) + return getAccessibleChild(tabIndex); + else + return getAccessibleSelection(0); } /** - * The number of selected child components of the - * <code>JTabbedPane</code>. This will be <code>0</code> if the - * <code>JTabbedPane</code> has no children, or <code>1</code> otherwise, - * since there is always exactly one tab selected. + * Returns the number of selected child components of the + * <code>JTabbedPane</code>. The reference implementation appears + * to return <code>1</code> always and we do the same. * - * @return number of selected child components of the - * <code>JTabbedPane</code> + * @return <code>1</code> */ public int getAccessibleSelectionCount() - throws NotImplementedException { - return 0; + return 1; } /** - * DOCUMENT ME! + * Returns the selected tab, or <code>null</code> if there is no + * selection. * - * @param i DOCUMENT ME! + * @param i the selection index (ignored here). * - * @return DOCUMENT ME! + * @return The selected tab, or <code>null</code>. */ public Accessible getAccessibleSelection(int i) - throws NotImplementedException { - return null; + Accessible result = null; + int selected = getSelectedIndex(); + if (selected >= 0) + result = (Page) tabs.get(selected); + return result; } /** - * DOCUMENT ME! + * Returns <code>true</code> if the specified child is selected, + * and <code>false</code> otherwise. * - * @param i DOCUMENT ME! + * @param i the child index. * - * @return DOCUMENT ME! + * @return A boolean. */ public boolean isAccessibleChildSelected(int i) - throws NotImplementedException { - return false; + return i == getSelectedIndex(); } /** - * DOCUMENT ME! + * Selects the specified tab. * - * @param i DOCUMENT ME! + * @param i the index of the item to select. */ public void addAccessibleSelection(int i) - throws NotImplementedException { - // TODO: Implement this properly. + setSelectedIndex(i); } /** - * DOCUMENT ME! + * Does nothing - it makes no sense to remove a selection for a + * tabbed pane, since one tab must always be selected. * - * @param i DOCUMENT ME! + * @param i the item index. + * + * @see #addAccessibleSelection(int) */ public void removeAccessibleSelection(int i) - throws NotImplementedException { - // TODO: Implement this properly. + // do nothing } /** - * DOCUMENT ME! + * Does nothing - it makes no sense to clear the selection for + * a tabbed pane, since one tab must always be selected. + * + * @see #addAccessibleSelection(int) */ public void clearAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + // do nothing } /** - * DOCUMENT ME! + * Does nothing - it makes no sense to select all for a tabbed + * pane, since only one tab can be selected at a time. + * + * @see #addAccessibleSelection(int) */ public void selectAllAccessibleSelection() - throws NotImplementedException { - // TODO: Implement this properly. + // do nothing } } @@ -267,7 +273,6 @@ public class JTabbedPane extends JComponent implements Serializable, */ protected class ModelListener implements ChangeListener, Serializable { - /** DOCUMENT ME! */ private static final long serialVersionUID = 497359819958114132L; /** @@ -446,7 +451,6 @@ public class JTabbedPane extends JComponent implements Serializable, return title; } - /** DOCUMENT ME! */ private static final long serialVersionUID = 1614381073220130939L; /** @@ -598,6 +602,19 @@ public class JTabbedPane extends JComponent implements Serializable, } /** + * Returns the accessible name for this tab. + * + * @return The accessible name. + */ + public String getAccessibleName() + { + if (accessibleName != null) + return accessibleName; + else + return title; + } + + /** * Returns the accessible role of this tab, which is always * {@link AccessibleRole#PAGE_TAB}. * @@ -608,18 +625,31 @@ public class JTabbedPane extends JComponent implements Serializable, return AccessibleRole.PAGE_TAB; } + /** + * Returns the accessible state set of this object. + * + * @return the accessible state set of this object + */ public AccessibleStateSet getAccessibleStateSet() - throws NotImplementedException { - // FIXME: Implement this properly. - return null; + AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext(); + AccessibleStateSet state = parentCtx.getAccessibleStateSet(); + state.add(AccessibleState.SELECTABLE); + if (component == getSelectedComponent()) + state.add(AccessibleState.SELECTED); + return state; } + /** + * Returns the index of this tab inside its parent. + * + * @return the index of this tab inside its parent + */ public int getAccessibleIndexInParent() - throws NotImplementedException { - // FIXME: Implement this properly. - return 0; + // TODO: Not sure if the title is unambiguous, but I can't figure + // another way of doing this. + return indexOfTab(title); } /** @@ -1623,25 +1653,45 @@ public class JTabbedPane extends JComponent implements Serializable, } /** - * This method returns a string representation of this JTabbedPane. It is - * mainly used for debugging purposes. + * Returns a string describing the attributes for the + * <code>JTabbedPane</code> component, for use in debugging. The return + * value is guaranteed to be non-<code>null</code>, but the format of the + * string may vary between implementations. * - * @return A string representation of this JTabbedPane. + * @return A string describing the attributes of the + * <code>JTabbedPane</code>. */ protected String paramString() { - return "JTabbedPane"; + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",tabPlacement="); + if (tabPlacement == TOP) + sb.append("TOP"); + if (tabPlacement == BOTTOM) + sb.append("BOTTOM"); + if (tabPlacement == LEFT) + sb.append("LEFT"); + if (tabPlacement == RIGHT) + sb.append("RIGHT"); + return sb.toString(); } /** - * DOCUMENT ME! + * Returns the object that provides accessibility features for this + * <code>JTabbedPane</code> component. * - * @return DOCUMENT ME! + * @return The accessible context (an instance of + * {@link AccessibleJTabbedPane}). */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) - accessibleContext = new AccessibleJTabbedPane(); + { + AccessibleJTabbedPane ctx = new AccessibleJTabbedPane(); + addChangeListener(ctx); + accessibleContext = ctx; + } + return accessibleContext; } } diff --git a/libjava/classpath/javax/swing/JTable.java b/libjava/classpath/javax/swing/JTable.java index 348534469a8..855530881f5 100644 --- a/libjava/classpath/javax/swing/JTable.java +++ b/libjava/classpath/javax/swing/JTable.java @@ -63,6 +63,7 @@ import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleExtendedTable; import javax.accessibility.AccessibleRole; import javax.accessibility.AccessibleSelection; +import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; import javax.accessibility.AccessibleTable; import javax.accessibility.AccessibleTableModelChange; @@ -165,6 +166,8 @@ public class JTable public AccessibleRole getAccessibleRole() { // TODO: What is the role of the table cell? + // Seems like the RI returns UNKNOWN here for 'normal' cells, might + // be different for special renderers though (not tested yet). return AccessibleRole.UNKNOWN; } @@ -175,8 +178,27 @@ public class JTable */ public AccessibleStateSet getAccessibleStateSet() { - // TODO: What state shoiuld be returned here? - return new AccessibleStateSet(); + AccessibleStateSet state = new AccessibleStateSet(); + + // Figure out the SHOWING state. + Rectangle visibleRect = getVisibleRect(); + Rectangle cellRect = getCellRect(row, column, false); + if (visibleRect.intersects(cellRect)) + state.add(AccessibleState.SHOWING); + + // Figure out SELECTED state. + if (isCellSelected(row, column)) + state.add(AccessibleState.SELECTED); + + // Figure out ACTIVE state. + if (row == getSelectedRow() && column == getSelectedColumn()) + state.add(AccessibleState.ACTIVE); + + // TRANSIENT seems to be always set in the RI. + state.add(AccessibleState.TRANSIENT); + + // TODO: Any other state to handle here? + return state; } /** @@ -594,7 +616,504 @@ public class JTable return lastColumn; } } - + + /** + * The RI returns an instance with this name in + * {@link #getAccessibleColumnHeader()}, this makes sense, so we do the + * same. + */ + private class AccessibleTableHeader + implements AccessibleTable + { + + /** + * The JTableHeader wrapped by this class. + */ + private JTableHeader header; + + /** + * Creates a new instance. + * + * @param h the JTableHeader to wrap + */ + private AccessibleTableHeader(JTableHeader h) + { + header = h; + } + + /** + * Returns the caption for the table header. + * + * @return the caption for the table header + */ + public Accessible getAccessibleCaption() + { + // The RI seems to always return null here, so do we. + return null; + } + + /** + * Sets the caption for the table header. + * + * @param caption the caption to set + */ + public void setAccessibleCaption(Accessible caption) + { + // This seems to be a no-op in the RI, so we do the same. + } + + /** + * Returns the caption for the table header. + * + * @return the caption for the table header + */ + public Accessible getAccessibleSummary() + { + // The RI seems to always return null here, so do we. + return null; + } + + /** + * Sets the summary for the table header. + * + * @param summary the caption to set + */ + public void setAccessibleSummary(Accessible summary) + { + // This seems to be a no-op in the RI, so we do the same. + } + + /** + * Returns the number of rows, which is always 1 for the table header. + * + * @return the number of rows + */ + public int getAccessibleRowCount() + { + return 1; + } + + /** + * Returns the number of columns in the table header. + * + * @return the number of columns in the table header + */ + public int getAccessibleColumnCount() + { + return header.getColumnModel().getColumnCount(); + } + + /** + * Returns the accessible child at the specified row and column. + * The row number is ignored here, and we return an + * AccessibleJTableHeaderCell here with the renderer component as + * component. + * + * @param r the row number + * @param c the column number + * + * @return the accessible child at the specified row and column + */ + public Accessible getAccessibleAt(int r, int c) + { + TableColumn column = header.getColumnModel().getColumn(c); + TableCellRenderer rend = column.getHeaderRenderer(); + if (rend == null) + rend = header.getDefaultRenderer(); + Component comp = + rend.getTableCellRendererComponent(header.getTable(), + column.getHeaderValue(), false, + false, -1, c); + return new AccessibleJTableHeaderCell(header, comp, r, c); + } + + public int getAccessibleRowExtentAt(int r, int c) + { + // TODO Auto-generated method stub + return 0; + } + + public int getAccessibleColumnExtentAt(int r, int c) + { + // TODO Auto-generated method stub + return 0; + } + + public AccessibleTable getAccessibleRowHeader() + { + // TODO Auto-generated method stub + return null; + } + + public void setAccessibleRowHeader(AccessibleTable header) + { + // TODO Auto-generated method stub + + } + + public AccessibleTable getAccessibleColumnHeader() + { + // TODO Auto-generated method stub + return null; + } + + public void setAccessibleColumnHeader(AccessibleTable header) + { + // TODO Auto-generated method stub + + } + + public Accessible getAccessibleRowDescription(int r) + { + // TODO Auto-generated method stub + return null; + } + + public void setAccessibleRowDescription(int r, Accessible description) + { + // TODO Auto-generated method stub + + } + + public Accessible getAccessibleColumnDescription(int c) + { + // TODO Auto-generated method stub + return null; + } + + public void setAccessibleColumnDescription(int c, Accessible description) + { + // TODO Auto-generated method stub + + } + + public boolean isAccessibleSelected(int r, int c) + { + // TODO Auto-generated method stub + return false; + } + + public boolean isAccessibleRowSelected(int r) + { + // TODO Auto-generated method stub + return false; + } + + public boolean isAccessibleColumnSelected(int c) + { + // TODO Auto-generated method stub + return false; + } + + public int[] getSelectedAccessibleRows() + { + // TODO Auto-generated method stub + return null; + } + + public int[] getSelectedAccessibleColumns() + { + // TODO Auto-generated method stub + return null; + } + + } + + /** + * The RI returns an instance of such class for table header cells. This + * makes sense so I added this class. This still needs to be fully + * implemented, I just don't feel motivated enough to do so just now. + */ + private class AccessibleJTableHeaderCell + extends AccessibleContext + implements Accessible, AccessibleComponent + { + + JTableHeader header; + + int columnIndex; + + /** + * + * @param h the table header. + * @param comp + * @param r + * @param c the column index. + */ + private AccessibleJTableHeaderCell(JTableHeader h, Component comp, int r, + int c) + { + header = h; + columnIndex = c; + } + + /** + * Returns the header renderer. + * + * @return The header renderer. + */ + Component getColumnHeaderRenderer() + { + TableColumn tc = header.getColumnModel().getColumn(columnIndex); + TableCellRenderer r = tc.getHeaderRenderer(); + if (r == null) + r = header.getDefaultRenderer(); + return r.getTableCellRendererComponent(header.getTable(), + tc.getHeaderValue(), false, false, -1, columnIndex); + } + + /** + * Returns the accessible role for the table header cell. + * + * @return The accessible role. + */ + public AccessibleRole getAccessibleRole() + { + Component renderer = getColumnHeaderRenderer(); + if (renderer instanceof Accessible) + { + Accessible ac = (Accessible) renderer; + return ac.getAccessibleContext().getAccessibleRole(); + } + return null; + } + + public AccessibleStateSet getAccessibleStateSet() + { + // TODO Auto-generated method stub + return null; + } + + public int getAccessibleIndexInParent() + { + // TODO Auto-generated method stub + return 0; + } + + public int getAccessibleChildrenCount() + { + // TODO Auto-generated method stub + return 0; + } + + public Accessible getAccessibleChild(int i) + { + // TODO Auto-generated method stub + return null; + } + + public Locale getLocale() + { + // TODO Auto-generated method stub + return null; + } + + /** + * Returns the accessible context. + * + * @return <code>this</code>. + */ + public AccessibleContext getAccessibleContext() + { + return this; + } + + public Color getBackground() + { + // TODO Auto-generated method stub + return null; + } + + public void setBackground(Color color) + { + // TODO Auto-generated method stub + + } + + public Color getForeground() + { + // TODO Auto-generated method stub + return null; + } + + public void setForeground(Color color) + { + // TODO Auto-generated method stub + + } + + public Cursor getCursor() + { + // TODO Auto-generated method stub + return null; + } + + public void setCursor(Cursor cursor) + { + // TODO Auto-generated method stub + + } + + public Font getFont() + { + // TODO Auto-generated method stub + return null; + } + + public void setFont(Font font) + { + // TODO Auto-generated method stub + + } + + public FontMetrics getFontMetrics(Font font) + { + // TODO Auto-generated method stub + return null; + } + + public boolean isEnabled() + { + // TODO Auto-generated method stub + return false; + } + + public void setEnabled(boolean b) + { + // TODO Auto-generated method stub + + } + + public boolean isVisible() + { + // TODO Auto-generated method stub + return false; + } + + public void setVisible(boolean b) + { + // TODO Auto-generated method stub + + } + + public boolean isShowing() + { + // TODO Auto-generated method stub + return false; + } + + public boolean contains(Point point) + { + // TODO Auto-generated method stub + return false; + } + + public Point getLocationOnScreen() + { + // TODO Auto-generated method stub + return null; + } + + public Point getLocation() + { + // TODO Auto-generated method stub + return null; + } + + public void setLocation(Point point) + { + // TODO Auto-generated method stub + + } + + public Rectangle getBounds() + { + // TODO Auto-generated method stub + return null; + } + + public void setBounds(Rectangle rectangle) + { + // TODO Auto-generated method stub + + } + + public Dimension getSize() + { + // TODO Auto-generated method stub + return null; + } + + public void setSize(Dimension dimension) + { + // TODO Auto-generated method stub + + } + + public Accessible getAccessibleAt(Point point) + { + // TODO Auto-generated method stub + return null; + } + + public boolean isFocusTraversable() + { + // TODO Auto-generated method stub + return false; + } + + public void requestFocus() + { + // TODO Auto-generated method stub + + } + + public void addFocusListener(FocusListener listener) + { + // TODO Auto-generated method stub + + } + + public void removeFocusListener(FocusListener listener) + { + // TODO Auto-generated method stub + + } + + } + + /** + * The last selected row. This is needed to track the selection in + * {@link #valueChanged(ListSelectionEvent)}. + */ + private int lastSelectedRow; + + /** + * The last selected column. This is needed to track the selection in + * {@link #valueChanged(ListSelectionEvent)}. + */ + private int lastSelectedColumn; + + /** + * The caption of the table. + */ + private Accessible caption; + + /** + * The summary of the table. + */ + private Accessible summary; + + /** + * Accessible descriptions for rows. + */ + private Accessible[] rowDescriptions; + + /** + * Accessible descriptions for columns. + */ + private Accessible[] columnDescriptions; + /** * Creates a new <code>AccessibleJTable</code>. * @@ -605,10 +1124,34 @@ public class JTable getModel().addTableModelListener(this); getSelectionModel().addListSelectionListener(this); getColumnModel().addColumnModelListener(this); - getCellEditor().addCellEditorListener(this); + lastSelectedRow = getSelectedRow(); + lastSelectedColumn = getSelectedColumn(); + TableCellEditor editor = getCellEditor(); + if (editor != null) + editor.addCellEditorListener(this); } /** + * Returns the accessible role for the <code>JTable</code> component. + * + * @return {@link AccessibleRole#TABLE}. + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.TABLE; + } + + /** + * Returns the accessible table. + * + * @return <code>this</code>. + */ + public AccessibleTable getAccessibleTable() + { + return this; + } + + /** * Returns the number of selected items in this table. */ public int getAccessibleSelectionCount() @@ -616,46 +1159,197 @@ public class JTable return getSelectedColumnCount(); } + /** + * Returns the selected accessible object with the specified index + * <code>i</code>. This basically returns the i-th selected cell in the + * table when going though it row-wise, and inside the rows, column-wise. + * + * @param i the index of the selected object to find + * + * @return the selected accessible object with the specified index + * <code>i</code> + */ public Accessible getAccessibleSelection(int i) { - // TODO Auto-generated method stub - return null; + Accessible found = null; + + int[] selectedRows = getSelectedRows(); + int[] selectedColumns = getSelectedColumns(); + int numCols = getColumnCount(); + int numRows = getRowCount(); + + // We have to go through every selected row and column and count until we + // find the specified index. This is potentially inefficient, but I can't + // think of anything better atm. + if (getRowSelectionAllowed() && getColumnSelectionAllowed()) + { + int current = -1; + int newIndex = current; + int lastSelectedRow = -1; + // Go through the selected rows array, don't forget the selected + // cells inside the not-selected rows' columns. + for (int j = 0; i < selectedRows.length; i++) + { + // Handle unselected rows between this selected and the last + // selected row, if any. + int selectedRow = selectedRows[j]; + int r = -1; + int ci = -1; + for (r = lastSelectedRow + 1; + r < selectedRow && current < i; r++) + { + for (ci = 0; ci < selectedColumns.length && current < i; + ci++) + { + current++; + } + } + if (current == i) + { + // We found the cell in the above loops, now get out of here. + found = getAccessibleChild(r * numCols + + selectedColumns[ci]); + break; + } + + // If we're still here, handle the current selected row. + if (current < i && current + numCols >= i) + { + // The cell must be in that row, which one is it? + found = getAccessibleChild(r * numCols + (i - current)); + break; + } + current += numCols; + } + if (found == null) + { + // The cell can still be in the last couple of unselected rows. + int r = 0; + int ci = 0; + for (r = lastSelectedRow + 1; + r < numRows && current < i; r++) + { + for (ci = 0; ci < selectedColumns.length && current < i; + ci++) + { + current++; + } + } + if (current == i) + { + // We found the cell in the above loops, now get out of here. + found = getAccessibleChild(r * numCols + + selectedColumns[ci]); + } + } + } + // One or more rows can be completely selected. + else if (getRowSelectionAllowed()) + { + int c = i % numCols; + int r = selectedRows[i / numCols]; + found = getAccessibleChild(r * numCols + c); + } + // One or more columns can be completely selected. + else if (getRowSelectionAllowed()) + { + int numSelectedColumns = selectedColumns.length; + int c = selectedColumns[i % numSelectedColumns]; + int r = i / numSelectedColumns; + found = getAccessibleChild(r * numCols + c); + } + + return found; } + /** + * Returns <code>true</code> if the accessible child with the index + * <code>i</code> is selected, <code>false</code> otherwise. + * + * @param i the index of the accessible to check + * + * @return <code>true</code> if the accessible child with the index + * <code>i</code> is selected, <code>false</code> otherwise + */ public boolean isAccessibleChildSelected(int i) { - // TODO Auto-generated method stub - return false; + int r = getAccessibleRowAtIndex(i); + int c = getAccessibleColumnAtIndex(i); + return isCellSelected(r, c); } + /** + * Adds the accessible child with the specified index <code>i</code> to the + * selection. + * + * @param i the index of the accessible child to add to the selection + */ public void addAccessibleSelection(int i) { - // TODO Auto-generated method stub - + int r = getAccessibleRowAtIndex(i); + int c = getAccessibleColumnAtIndex(i); + changeSelection(r, c, true, false); } + /** + * Removes the accessible child with the specified index <code>i</code> + * from the current selection. This will only work on tables that have + * cell selection enabled (<code>rowSelectionAllowed == false && + * columnSelectionAllowed == false</code>). + * + * @param i the index of the accessible to be removed from the selection + */ public void removeAccessibleSelection(int i) { - // TODO Auto-generated method stub - + if (! getRowSelectionAllowed() && ! getColumnSelectionAllowed()) + { + int r = getAccessibleRowAtIndex(i); + int c = getAccessibleColumnAtIndex(i); + removeRowSelectionInterval(r, r); + removeColumnSelectionInterval(c, c); + } } + /** + * Deselects all selected accessible children. + */ public void clearAccessibleSelection() { - // TODO Auto-generated method stub - + clearSelection(); } + /** + * Selects all accessible children that can be selected. This will only + * work on tables that support multiple selections and that have individual + * cell selection enabled. + */ public void selectAllAccessibleSelection() { - // TODO Auto-generated method stub - + selectAll(); } + /** + * Receives notification when the row selection changes and fires + * appropriate property change events. + * + * @param event the list selection event + */ public void valueChanged(ListSelectionEvent event) { - // TODO Auto-generated method stub - + firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, + Boolean.FALSE, Boolean.TRUE); + int r = getSelectedRow(); + int c = getSelectedColumn(); + if (r != lastSelectedRow || c != lastSelectedColumn) + { + Accessible o = getAccessibleAt(lastSelectedRow, + lastSelectedColumn); + Accessible n = getAccessibleAt(r, c); + firePropertyChange(AccessibleContext + .ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n); + lastSelectedRow = r; + lastSelectedColumn = c; + } } /** @@ -680,14 +1374,13 @@ public class JTable /** * Receives notification when one or more rows have been inserted into the - * table. + * table and fires appropriate property change events. * * @param event the table model event */ public void tableRowsInserted(TableModelEvent event) { - // TODO: What to do here, if anything? This might be a hook method for - // subclasses... + handleRowChange(event); } /** @@ -698,50 +1391,93 @@ public class JTable */ public void tableRowsDeleted(TableModelEvent event) { - // TODO: What to do here, if anything? This might be a hook method for - // subclasses... + handleRowChange(event); + } + + /** + * Fires a PropertyChangeEvent for inserted or deleted rows. + * + * @param event the table model event + */ + private void handleRowChange(TableModelEvent event) + { + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); + int firstColumn = event.getColumn(); + int lastColumn = event.getColumn(); + if (firstColumn == TableModelEvent.ALL_COLUMNS) + { + firstColumn = 0; + lastColumn = getColumnCount() - 1; + } + AccessibleJTableModelChange change = new AccessibleJTableModelChange + (event.getType(), event.getFirstRow(), event.getLastRow(), + firstColumn, lastColumn); + firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED, + null, change); } public void columnAdded(TableColumnModelEvent event) { - // TODO Auto-generated method stub - + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); + handleColumnChange(AccessibleTableModelChange.INSERT, + event.getFromIndex(), event.getToIndex()); } - public void columnMarginChanged(ChangeEvent event) + public void columnRemoved(TableColumnModelEvent event) { - // TODO Auto-generated method stub - + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); + handleColumnChange(AccessibleTableModelChange.DELETE, + event.getFromIndex(), event.getToIndex()); } public void columnMoved(TableColumnModelEvent event) { - // TODO Auto-generated method stub - + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); + handleColumnChange(AccessibleTableModelChange.DELETE, + event.getFromIndex(), event.getFromIndex()); + handleColumnChange(AccessibleTableModelChange.INSERT, + event.getFromIndex(), event.getToIndex()); } - public void columnRemoved(TableColumnModelEvent event) + /** + * Fires a PropertyChangeEvent for inserted or deleted columns. + * + * @param type the type of change + * @param from the start of the change + * @param to the target of the change + */ + private void handleColumnChange(int type, int from, int to) { - // TODO Auto-generated method stub - + AccessibleJTableModelChange change = + new AccessibleJTableModelChange(type, 0, 0, from, to); + firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED, + null, change); + } + + public void columnMarginChanged(ChangeEvent event) + { + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); } public void columnSelectionChanged(ListSelectionEvent event) { - // TODO Auto-generated method stub - + // AFAICS, nothing is done here. } public void editingCanceled(ChangeEvent event) { - // TODO Auto-generated method stub - + // AFAICS, nothing is done here. } public void editingStopped(ChangeEvent event) { - // TODO Auto-generated method stub - + firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, + null, null); } /** @@ -784,154 +1520,343 @@ public class JTable } } + /** + * Returns the row number of an accessible child (cell) with the specified + * index. + * + * @param index the index of the cell of which the row number is queried + * + * @return the row number of an accessible child (cell) with the specified + * index + */ public int getAccessibleRow(int index) { - // TODO Auto-generated method stub - return 0; + return getAccessibleRowAtIndex(index); } + /** + * Returns the column number of an accessible child (cell) with the + * specified index. + * + * @param index the index of the cell of which the column number is queried + * + * @return the column number of an accessible child (cell) with the + * specified index + */ public int getAccessibleColumn(int index) { - // TODO Auto-generated method stub - return 0; + return getAccessibleColumnAtIndex(index); } + /** + * Returns the index of the accessible child at the specified row and + * column. + * + * @param r the row number + * @param c the column number + * + * @return the index of the accessible child at the specified row and + * column + */ public int getAccessibleIndex(int r, int c) { - // TODO Auto-generated method stub - return 0; + return getAccessibleIndexAt(r, c); } + /** + * Returns the caption of the table. + * + * @return the caption of the table + * + * @see #setAccessibleCaption(Accessible) + */ public Accessible getAccessibleCaption() { - // TODO Auto-generated method stub - return null; + return caption; } - public void setAccessibleCaption(Accessible caption) + /** + * Sets the caption for the table. + * + * @param c the caption to set + */ + public void setAccessibleCaption(Accessible c) { - // TODO Auto-generated method stub - + caption = c; } + /** + * Returns the summary for the table. + * + * @return the summary for the table + */ public Accessible getAccessibleSummary() { - // TODO Auto-generated method stub - return null; + return summary; } - public void setAccessibleSummary(Accessible summary) + /** + * Sets the summary for the table. + * + * @param s the summary to set + */ + public void setAccessibleSummary(Accessible s) { - // TODO Auto-generated method stub - + summary = s; } + /** + * Returns the number of rows in the table. + * + * @return the number of rows in the table + */ public int getAccessibleRowCount() { - // TODO Auto-generated method stub - return 0; + return getRowCount(); } + /** + * Returns the number of columns in the table. + * + * @return the number of columns in the table + */ public int getAccessibleColumnCount() { - // TODO Auto-generated method stub - return 0; + return getColumnCount(); } + /** + * Returns the accessible child at the given index. + * + * @param index the child index. + * + * @return The accessible child. + */ + public Accessible getAccessibleChild(int index) + { + int r = getAccessibleRow(index); + int c = getAccessibleColumn(index); + return getAccessibleAt(r, c); + } + + /** + * Returns the accessible child (table cell) at the specified row and + * column. + * + * @param r the row number + * @param c the column number + * + * @return the accessible child (table cell) at the specified row and + * column + */ public Accessible getAccessibleAt(int r, int c) { - // TODO Auto-generated method stub + TableCellRenderer cellRenderer = getCellRenderer(r, c); + Component renderer = cellRenderer.getTableCellRendererComponent( + JTable.this, getValueAt(r, c), isCellSelected(r, c), false, r, c); + if (renderer instanceof Accessible) + return (Accessible) renderer; return null; } + /** + * Returns the number of rows that the specified cell occupies. The + * standard table cells only occupy one row, so we return <code>1</code> + * here. + * + * @param r the row number + * @param c the column number + * + * @return the number of rows that the specified cell occupies + */ public int getAccessibleRowExtentAt(int r, int c) { - // TODO Auto-generated method stub - return 0; + return 1; } + /** + * Returns the number of columns that the specified cell occupies. The + * standard table cells only occupy one column, so we return <code>1</code> + * here. + * + * @param r the row number + * @param c the column number + * + * @return the number of rows that the specified cell occupies + */ public int getAccessibleColumnExtentAt(int r, int c) { - // TODO Auto-generated method stub - return 0; + return 1; } + /** + * Returns the accessible row header. + * + * @return the accessible row header + */ public AccessibleTable getAccessibleRowHeader() { - // TODO Auto-generated method stub + // The RI seems to always return null here, so do we. return null; } + /** + * Sets the accessible row header. + * + * @param header the header to set + */ public void setAccessibleRowHeader(AccessibleTable header) { - // TODO Auto-generated method stub - + // In the RI this seems to be a no-op. } + /** + * Returns the column header. + * + * @return the column header, or <code>null</code> if there is no column + * header + */ public AccessibleTable getAccessibleColumnHeader() { - // TODO Auto-generated method stub - return null; + JTableHeader h = getTableHeader(); + AccessibleTable header = null; + if (h != null) + header = new AccessibleTableHeader(h); + return header; } + /** + * Sets the accessible column header. The default implementation doesn't + * allow changing the header this way, so this is a no-op. + * + * @param header the accessible column header to set + */ public void setAccessibleColumnHeader(AccessibleTable header) { - // TODO Auto-generated method stub - + // The RI doesn't seem to do anything, so we also do nothing. } + /** + * Returns the accessible description for the row with the specified index, + * or <code>null</code> if no description has been set. + * + * @param r the row for which the description is queried + * + * @return the accessible description for the row with the specified index, + * or <code>null</code> if no description has been set + */ public Accessible getAccessibleRowDescription(int r) { - // TODO Auto-generated method stub - return null; + Accessible descr = null; + if (rowDescriptions != null) + descr = rowDescriptions[r]; + return descr; } + /** + * Sets the accessible description for the row with the specified index. + * + * @param r the row number for which to set the description + * @param description the description to set + */ public void setAccessibleRowDescription(int r, Accessible description) { - // TODO Auto-generated method stub - + if (rowDescriptions == null) + rowDescriptions = new Accessible[getAccessibleRowCount()]; + rowDescriptions[r] = description; } + /** + * Returns the accessible description for the column with the specified + * index, or <code>null</code> if no description has been set. + * + * @param c the column for which the description is queried + * + * @return the accessible description for the column with the specified + * index, or <code>null</code> if no description has been set + */ public Accessible getAccessibleColumnDescription(int c) { - // TODO Auto-generated method stub - return null; + Accessible descr = null; + if (columnDescriptions != null) + descr = columnDescriptions[c]; + return descr; } + /** + * Sets the accessible description for the column with the specified index. + * + * @param c the column number for which to set the description + * @param description the description to set + */ public void setAccessibleColumnDescription(int c, Accessible description) { - // TODO Auto-generated method stub - + if (columnDescriptions == null) + columnDescriptions = new Accessible[getAccessibleRowCount()]; + columnDescriptions[c] = description; } + /** + * Returns <code>true</code> if the accessible child at the specified + * row and column is selected, <code>false</code> otherwise. + * + * @param r the row number of the child + * @param c the column number of the child + * + * @return <code>true</code> if the accessible child at the specified + * row and column is selected, <code>false</code> otherwise + */ public boolean isAccessibleSelected(int r, int c) { - // TODO Auto-generated method stub - return false; + return isCellSelected(r, c); } + /** + * Returns <code>true</code> if the row with the specified index is + * selected, <code>false</code> otherwise. + * + * @param r the row number + * + * @return <code>true</code> if the row with the specified index is + * selected, <code>false</code> otherwise + */ public boolean isAccessibleRowSelected(int r) { - // TODO Auto-generated method stub - return false; + return isRowSelected(r); } + /** + * Returns <code>true</code> if the column with the specified index is + * selected, <code>false</code> otherwise. + * + * @param c the column number + * + * @return <code>true</code> if the column with the specified index is + * selected, <code>false</code> otherwise + */ public boolean isAccessibleColumnSelected(int c) { - // TODO Auto-generated method stub - return false; + return isColumnSelected(c); } + /** + * Returns the indices of all selected rows. + * + * @return the indices of all selected rows + */ public int[] getSelectedAccessibleRows() { - // TODO Auto-generated method stub - return null; + return getSelectedRows(); } + /** + * Returns the indices of all selected columns. + * + * @return the indices of all selected columns + */ public int[] getSelectedAccessibleColumns() { - // TODO Auto-generated method stub - return null; + return getSelectedColumns(); } /** @@ -1017,7 +1942,17 @@ public class JTable /** * The CheckBox that is used for rendering. */ - private final JCheckBox checkBox = new JCheckBox(); + private final JCheckBox checkBox; + + /** + * Creates a new checkbox based boolean cell renderer. The checkbox is + * centered by default. + */ + BooleanCellRenderer() + { + checkBox = new JCheckBox(); + checkBox.setHorizontalAlignment(SwingConstants.CENTER); + } /** * Get the check box. @@ -1223,6 +2158,12 @@ public class JTable private class IconCellRenderer extends DefaultTableCellRenderer { + IconCellRenderer() + { + setHorizontalAlignment(SwingConstants.CENTER); + } + + /** * Returns the component that is used for rendering the value. * @@ -1272,17 +2213,6 @@ public class JTable { setBorder(BorderFactory.createLineBorder(getGridColor(), 2)); } - - /** - * With not this method overridden, the scroll pane scrolls to the - * top left cornec (untranslated position of the caret) after the first - * keystroke. - */ - public void scrollRectToVisible(Rectangle r) - { - // Do nothing here. If the editing session starts outside the visible - // bounds, the editCellAt will scroll. - } } @@ -1335,14 +2265,14 @@ public class JTable * {@link TableCellEditor} objects. This table is consulted by the * FIXME */ - protected Hashtable defaultEditorsByColumnClass; + protected Hashtable defaultEditorsByColumnClass = new Hashtable(); /** * A table mapping {@link java.lang.Class} objects to * {@link TableCellEditor} objects. This table is consulted by the * FIXME */ - protected Hashtable defaultRenderersByColumnClass; + protected Hashtable defaultRenderersByColumnClass = new Hashtable(); /** * The column that is edited, -1 if the table is not edited currently. @@ -1588,6 +2518,27 @@ public class JTable private boolean clientRowHeightSet = false; /** + * Stores the sizes and positions of each row, when using non-uniform row + * heights. Initially the height of all rows is equal and stored in + * {link #rowHeight}. However, when an application calls + * {@link #setRowHeight(int,int)}, the table switches to non-uniform + * row height mode which stores the row heights in the SizeSequence + * object instead. + * + * @see #setRowHeight(int) + * @see #getRowHeight() + * @see #getRowHeight(int) + * @see #setRowHeight(int, int) + */ + private SizeSequence rowHeights; + + /** + * This editor serves just a marker that the value must be simply changed to + * the opposite one instead of starting the editing session. + */ + private transient TableCellEditor booleanInvertingEditor; + + /** * Creates a new <code>JTable</code> instance. */ public JTable () @@ -1719,15 +2670,9 @@ public class JTable if (autoCreateColumnsFromModel) createDefaultColumnsFromModel(); this.columnModel.addColumnModelListener(this); - - this.defaultRenderersByColumnClass = new Hashtable(); - createDefaultRenderers(); - - this.defaultEditorsByColumnClass = new Hashtable(); - createDefaultEditors(); this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS; - this.rowHeight = 16; + setRowHeight(16); this.rowMargin = 1; this.rowSelectionAllowed = true; // this.accessibleContext = new AccessibleJTable(); @@ -1773,7 +2718,10 @@ public class JTable protected void createDefaultEditors() { JCheckBox box = new BooleanCellRenderer().getCheckBox(); - setDefaultEditor(Boolean.class, new DefaultCellEditor(box)); + box.setBorder(BorderFactory.createLineBorder(getGridColor(), 2)); + box.setBorderPainted(true); + booleanInvertingEditor = new DefaultCellEditor(box); + setDefaultEditor(Boolean.class, booleanInvertingEditor); } /** @@ -1871,6 +2819,8 @@ public class JTable */ public void columnMoved (TableColumnModelEvent event) { + if (isEditing()) + editingCanceled(null); revalidate(); repaint(); } @@ -1891,12 +2841,6 @@ public class JTable */ public void columnSelectionChanged (ListSelectionEvent event) { - // Does not make sense for the table with the single column. - if (getColumnCount() < 2) - return; - - int x0 = 0; - // We must limit the indices to the bounds of the JTable's model, because // we might get values of -1 or greater then columnCount in the case // when columns get removed. @@ -1904,17 +2848,39 @@ public class JTable event.getFirstIndex())); int idxn = Math.max(0, Math.min(getColumnCount() - 1, event.getLastIndex())); - int i; - for (i = 0; i < idx0; i++) - x0 += columnModel.getColumn(i).getWidth(); - - int xn = x0; - - for (i = idx0; i <= idxn; i++) - xn += columnModel.getColumn(i).getWidth(); - - repaint(x0, 0, xn-x0, getHeight()); + int minRow = 0; + int maxRow = getRowCount() - 1; + if (getRowSelectionAllowed()) + { + minRow = selectionModel.getMinSelectionIndex(); + maxRow = selectionModel.getMaxSelectionIndex(); + int leadRow = selectionModel.getLeadSelectionIndex(); + if (minRow == -1 && maxRow == -1) + { + minRow = leadRow; + maxRow = leadRow; + } + else + { + // In this case we need to repaint also the range to leadRow, not + // only between min and max. + if (leadRow != -1) + { + minRow = Math.min(minRow, leadRow); + maxRow = Math.max(maxRow, leadRow); + } + } + } + if (minRow != -1 && maxRow != -1) + { + Rectangle first = getCellRect(minRow, idx0, false); + Rectangle last = getCellRect(maxRow, idxn, false); + Rectangle dirty = SwingUtilities.computeUnion(first.x, first.y, + first.width, + first.height, last); + repaint(dirty); + } } /** @@ -1958,7 +2924,13 @@ public class JTable // changed and the flag autoCreateColumnsFromModel is set if ((event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW)) && autoCreateColumnsFromModel) - createDefaultColumnsFromModel(); + { + rowHeights = null; + if (getAutoCreateColumnsFromModel()) + createDefaultColumnsFromModel(); + resizeAndRepaint(); + return; + } // If the structure changes, we need to revalidate, since that might // affect the size parameters of the JTable. Otherwise we only need @@ -1975,6 +2947,8 @@ public class JTable if (last < 0) last = getRowCount() - 1; selectionModel.insertIndexInterval(first, last - first + 1, true); + if (rowHeights != null) + rowHeights.insertEntries(first, last - first + 1, rowHeight); } revalidate(); } @@ -1990,6 +2964,8 @@ public class JTable if (last < 0) last = getRowCount() - 1; selectionModel.removeIndexInterval(first, last); + if (rowHeights != null) + rowHeights.removeEntries(first, last - first + 1); } if (dataModel.getRowCount() == 0) clearSelection(); @@ -2004,14 +2980,19 @@ public class JTable */ public void valueChanged (ListSelectionEvent event) { - // Does not make sense for the table with the single row. - if (getRowCount() < 2) - return; + // If we are in the editing process, end the editing session. + if (isEditing()) + editingStopped(null); - int y_gap = rowMargin; - int y0 = (getRowHeight() + y_gap) * (event.getFirstIndex()); - int yn = (getRowHeight() + y_gap) * (event.getLastIndex()+1); - repaint(0, y0, getWidth(), yn-y0); + // Repaint the changed region. + int first = Math.max(0, Math.min(getRowCount() - 1, event.getFirstIndex())); + int last = Math.max(0, Math.min(getRowCount() - 1, event.getLastIndex())); + Rectangle rect1 = getCellRect(first, 0, false); + Rectangle rect2 = getCellRect(last, getColumnCount() - 1, false); + Rectangle dirty = SwingUtilities.computeUnion(rect2.x, rect2.y, + rect2.width, rect2.height, + rect1); + repaint(dirty); } /** @@ -2053,10 +3034,16 @@ public class JTable if (point != null) { int nrows = getRowCount(); - int height = getRowHeight() + getRowMargin(); + int r; int y = point.y; + if (rowHeights == null) + { + int height = getRowHeight(); + r = y / height; + } + else + r = rowHeights.getIndex(y); - int r = y / height; if (r < 0 || r >= nrows) return -1; else @@ -2086,27 +3073,70 @@ public class JTable int column, boolean includeSpacing) { - int height = getRowHeight(row); - int width = columnModel.getColumn(column).getWidth(); - int x_gap = columnModel.getColumnMargin(); - int y_gap = rowMargin; + Rectangle cellRect = new Rectangle(0, 0, 0, 0); - 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; + // Check for valid range vertically. + if (row >= getRowCount()) + { + cellRect.height = getHeight(); + } + else if (row >= 0) + { + cellRect.height = getRowHeight(row); + if (rowHeights == null) + cellRect.y = row * cellRect.height; + else + cellRect.y = rowHeights.getPosition(row); - for (int i = 0; i < column; ++i) - x += columnModel.getColumn(i).getWidth(); - - Rectangle rect = new Rectangle(); + if (! includeSpacing) + { + // The rounding here is important. + int rMargin = getRowMargin(); + cellRect.y += rMargin / 2; + cellRect.height -= rMargin; + } + } + // else row < 0, y = height = 0 - if (includeSpacing) - rect.setBounds(x, y, width, height +y_gap); + // Check for valid range horizontally. + if (column < 0) + { + if (! getComponentOrientation().isLeftToRight()) + { + cellRect.x = getWidth(); + } + } + else if (column >= getColumnCount()) + { + if (getComponentOrientation().isLeftToRight()) + { + cellRect.x = getWidth(); + } + } else - rect.setBounds(x, y, width - x_gap, height); - return rect; + { + TableColumnModel tcm = getColumnModel(); + if (getComponentOrientation().isLeftToRight()) + { + for (int i = 0; i < column; i++) + cellRect.x += tcm.getColumn(i).getWidth(); + } + else + { + for (int i = tcm.getColumnCount() - 1; i > column; i--) + cellRect.x += tcm.getColumn(i).getWidth(); + } + cellRect.width = tcm.getColumn(column).getWidth(); + if (! includeSpacing) + { + // The rounding here is important. + int cMargin = tcm.getColumnMargin(); + cellRect.x += cMargin / 2; + cellRect.width -= cMargin; + } + } + + return cellRect; } public void clearSelection() @@ -2354,7 +3384,6 @@ public class JTable int row, int column) { - boolean rowSelAllowed = getRowSelectionAllowed(); boolean colSelAllowed = getColumnSelectionAllowed(); boolean isSel = false; @@ -2418,9 +3447,10 @@ public class JTable */ public int getRowHeight(int row) { - // FIXME: return the height of the specified row - // which may be different from the general rowHeight - return rowHeight; + int rh = rowHeight; + if (rowHeights != null) + rh = rowHeights.getSize(row); + return rh; } @@ -2626,6 +3656,17 @@ public class JTable */ public AccessibleContext getAccessibleContext() { + if (accessibleContext == null) + { + AccessibleJTable ctx = new AccessibleJTable(); + addPropertyChangeListener(ctx); + TableColumnModel tcm = getColumnModel(); + tcm.addColumnModelListener(ctx); + tcm.getSelectionModel().addListSelectionListener(ctx); + getSelectionModel().addListSelectionListener(ctx); + + accessibleContext = ctx; + } return accessibleContext; } @@ -2780,9 +3821,14 @@ public class JTable } /** - * Set the value of the {@link #rowHeight} property. + * Sets the height for all rows in the table. If you want to change the + * height of a single row instead, use {@link #setRowHeight(int, int)}. + * + * @param r the height to set for all rows * - * @param r The new value of the rowHeight property + * @see #getRowHeight() + * @see #setRowHeight(int, int) + * @see #getRowHeight(int) */ public void setRowHeight(int r) { @@ -2792,21 +3838,24 @@ public class JTable clientRowHeightSet = true; rowHeight = r; + rowHeights = null; revalidate(); repaint(); } /** - * Sets the value of the rowHeight property for the specified - * row. + * Sets the height of a single row in the table. * - * @param rh is the new rowHeight - * @param row is the row to change the rowHeight of + * @param rh the new row height + * @param row the row to change the height of */ public void setRowHeight(int row, int rh) { - setRowHeight(rh); - // FIXME: not implemented + if (rowHeights == null) + { + rowHeights = new SizeSequence(getRowCount(), rowHeight); + } + rowHeights.setSize(row, rh); } /** @@ -2878,6 +3927,10 @@ public class JTable // Add table as TableModelListener to new model. dataModel.addTableModelListener(this); + // Notify the tableChanged method. + tableChanged(new TableModelEvent(dataModel, + TableModelEvent.HEADER_ROW)); + // Automatically create columns. if (autoCreateColumnsFromModel) createDefaultColumnsFromModel(); @@ -3210,7 +4263,7 @@ public class JTable public void doLayout() { TableColumn resizingColumn = null; - + int ncols = getColumnCount(); if (ncols < 1) return; @@ -3236,7 +4289,7 @@ public class JTable { TableColumn col; TableColumn [] cols; - + switch (getAutoResizeMode()) { case AUTO_RESIZE_LAST_COLUMN: @@ -3298,21 +4351,45 @@ public class JTable TableColumn [] cols = new TableColumn[ncols]; for (int i = 0; i < ncols; ++i) cols[i] = columnModel.getColumn(i); - distributeSpill(cols, spill); + distributeSpill(cols, spill); } if (editorComp!=null) moveToCellBeingEdited(editorComp); - // Repaint fixes the invalid view after the first keystroke if the cell - // editing is started immediately after the program start or cell - // resizing. - repaint(); - if (tableHeader!=null) - tableHeader.repaint(); + int leftBoundary = getLeftResizingBoundary(); + int width = getWidth() - leftBoundary; + repaint(leftBoundary, 0, width, getHeight()); + if (tableHeader != null) + tableHeader.repaint(leftBoundary, 0, width, tableHeader.getHeight()); } /** + * Get the left boundary of the rectangle which changes during the column + * resizing. + */ + int getLeftResizingBoundary() + { + if (tableHeader == null || getAutoResizeMode() == AUTO_RESIZE_ALL_COLUMNS) + return 0; + else + { + TableColumn resizingColumn = tableHeader.getResizingColumn(); + if (resizingColumn == null) + return 0; + + int rc = convertColumnIndexToView(resizingColumn.getModelIndex()); + int p = 0; + + for (int i = 0; i < rc; i++) + p += columnModel.getColumn(i).getWidth(); + + return p; + } + } + + + /** * @deprecated Replaced by <code>doLayout()</code> */ public void sizeColumnsToFit(boolean lastColumnOnly) @@ -3351,6 +4428,10 @@ public class JTable public void setUI(TableUI ui) { super.setUI(ui); + // The editors and renderers must be recreated because they constructors + // may use the look and feel properties. + createDefaultEditors(); + createDefaultRenderers(); } public void updateUI() @@ -3567,6 +4648,10 @@ public class JTable */ public void selectAll() { + // The table is empty - nothing to do! + if (getRowCount() == 0 || getColumnCount() == 0) + return; + // rowLead and colLead store the current lead selection indices int rowLead = selectionModel.getLeadSelectionIndex(); int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex(); @@ -3716,30 +4801,47 @@ public class JTable /** * Programmatically starts editing the specified cell. - * + * * @param row the row of the cell to edit. * @param column the column of the cell to edit. */ - public boolean editCellAt (int row, int column) + public boolean editCellAt(int row, int column) { // Complete the previous editing session, if still active. if (isEditing()) editingStopped(new ChangeEvent("editingStopped")); - - editingRow = row; - editingColumn = column; - setCellEditor(getCellEditor(row, column)); - editorComp = prepareEditor(cellEditor, row, column); + TableCellEditor editor = getCellEditor(row, column); - // Remove the previous editor components, if present. Only one - // editor component at time is allowed in the table. - removeAll(); - add(editorComp); - moveToCellBeingEdited(editorComp); - scrollRectToVisible(editorComp.getBounds()); - editorComp.requestFocusInWindow(); - return true; + // The boolean values are inverted by the single click without the + // real editing session. + if (editor == booleanInvertingEditor && isCellEditable(row, column)) + { + if (Boolean.TRUE.equals(getValueAt(row, column))) + setValueAt(Boolean.FALSE, row, column); + else + setValueAt(Boolean.TRUE, row, column); + return false; + } + else + { + editingRow = row; + editingColumn = column; + + setCellEditor(editor); + editorComp = prepareEditor(cellEditor, row, column); + + // Remove the previous editor components, if present. Only one + // editor component at time is allowed in the table. + removeAll(); + add(editorComp); + moveToCellBeingEdited(editorComp); + scrollRectToVisible(editorComp.getBounds()); + editorComp.requestFocusInWindow(); + + // Deliver the should select event. + return editor.shouldSelectCell(null); + } } /** diff --git a/libjava/classpath/javax/swing/JToolBar.java b/libjava/classpath/javax/swing/JToolBar.java index b576b4f2a31..fe4d2ae2046 100644 --- a/libjava/classpath/javax/swing/JToolBar.java +++ b/libjava/classpath/javax/swing/JToolBar.java @@ -1,5 +1,5 @@ /* JToolBar.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -757,14 +757,28 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible } // addImpl() /** - * This method returns a String description of the JToolBar. + * Returns a string describing the attributes for the <code>JToolBar</code> + * component, for use in debugging. The return value is guaranteed to be + * non-<code>null</code>, but the format of the string may vary between + * implementations. * - * @return A String description of the JToolBar. + * @return A string describing the attributes of the <code>JToolBar</code>. */ protected String paramString() { - return "JToolBar"; - } // paramString() + StringBuffer sb = new StringBuffer(super.paramString()); + sb.append(",floatable=").append(floatable); + sb.append(",margin="); + if (margin != null) + sb.append(margin); + sb.append(",orientation="); + if (orientation == HORIZONTAL) + sb.append("HORIZONTAL"); + else + sb.append(VERTICAL); + sb.append(",paintBorder=").append(paintBorder); + return sb.toString(); + } /** * Returns the object that provides accessibility features for this diff --git a/libjava/classpath/javax/swing/JTree.java b/libjava/classpath/javax/swing/JTree.java index e3b8b7e7ca5..f7583ad69e2 100644 --- a/libjava/classpath/javax/swing/JTree.java +++ b/libjava/classpath/javax/swing/JTree.java @@ -1142,9 +1142,9 @@ public class JTree extends JComponent implements Scrollable, Accessible public boolean isLeaf() { - return (childValue == null || !(childValue instanceof Hashtable - || childValue instanceof Vector || childValue.getClass() - .isArray())); + return childValue == null || !(childValue instanceof Hashtable + || childValue instanceof Vector + || childValue.getClass().isArray()); } public static void createChildren(DefaultMutableTreeNode parent, @@ -1478,7 +1478,7 @@ public class JTree extends JComponent implements Scrollable, Accessible */ public JTree() { - this(createTreeModel(null)); + this(getDefaultTreeModel()); } /** @@ -1509,13 +1509,18 @@ public class JTree extends JComponent implements Scrollable, Accessible public JTree(TreeModel model) { setRootVisible(true); - // The setModel also calls the updateUI - setModel(model); setSelectionModel(new EmptySelectionModel()); selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); // The root node appears expanded by default. - nodeStates.put(new TreePath(model.getRoot()), EXPANDED); + nodeStates = new Hashtable(); + + // Install the UI before installing the model. This way we avoid double + // initialization of lots of UI and model stuff inside the UI and related + // classes. The necessary UI updates are performed via property change + // events to the UI. + updateUI(); + setModel(model); } /** @@ -1897,6 +1902,10 @@ public class JTree extends JComponent implements Scrollable, Accessible if (treeModel == model) return; + // Remove listeners from old model. + if (treeModel != null && treeModelListener != null) + treeModel.removeTreeModelListener(treeModelListener); + // add treeModelListener to the new model if (treeModelListener == null) treeModelListener = createTreeModelListener(); @@ -1905,9 +1914,22 @@ public class JTree extends JComponent implements Scrollable, Accessible TreeModel oldValue = treeModel; treeModel = model; + clearToggledPaths(); + + if (treeModel != null) + { + if (treeModelListener == null) + treeModelListener = createTreeModelListener(); + if (treeModelListener != null) + treeModel.addTreeModelListener(treeModelListener); + Object root = treeModel.getRoot(); + if (root != null && !treeModel.isLeaf(root)) + { + nodeStates.put(new TreePath(root), Boolean.TRUE); + } + } firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model); - updateUI(); } /** @@ -2316,7 +2338,7 @@ public class JTree extends JComponent implements Scrollable, Accessible selectionModel.addSelectionPath(path); } - if (oldValue!=null) + if (oldValue != null) repaint(getPathBounds(oldValue)); firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path); diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java index 2b5d1cd5a2f..7cf393996c3 100644 --- a/libjava/classpath/javax/swing/JViewport.java +++ b/libjava/classpath/javax/swing/JViewport.java @@ -877,7 +877,7 @@ public class JViewport extends JComponent implements Accessible { // If the image has not been scrolled at all, only the changed // clip must be updated in the buffer. - if (dx==0 && dy==0) + if (dx == 0 && dy == 0) g2.setClip(g.getClip()); paintSimple(g2); diff --git a/libjava/classpath/javax/swing/KeyboardManager.java b/libjava/classpath/javax/swing/KeyboardManager.java index 4f778f7330f..f7ac9496c30 100644 --- a/libjava/classpath/javax/swing/KeyboardManager.java +++ b/libjava/classpath/javax/swing/KeyboardManager.java @@ -46,6 +46,7 @@ import java.awt.event.KeyEvent; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; +import java.util.WeakHashMap; /** * This class maintains a mapping from top-level containers to a @@ -65,7 +66,7 @@ class KeyboardManager * A mapping between top level containers and Hashtables that * map KeyStrokes to Components. */ - Hashtable topLevelLookup = new Hashtable(); + WeakHashMap topLevelLookup = new WeakHashMap(); /** * A mapping between top level containers and Vectors of JMenuBars diff --git a/libjava/classpath/javax/swing/ListSelectionModel.java b/libjava/classpath/javax/swing/ListSelectionModel.java index 324c056431b..499362d045b 100644 --- a/libjava/classpath/javax/swing/ListSelectionModel.java +++ b/libjava/classpath/javax/swing/ListSelectionModel.java @@ -1,5 +1,5 @@ /* ListSelectionModel.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,59 +38,295 @@ exception statement from your version. */ package javax.swing; +import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; /** - * The model that is used in {@link JList} to define the selected/not-selected - * cells of that list. + * A model that tracks the selection status of a list of items. Each item in + * the list is identified by a zero-based index only, so the model can be used + * to track the selection status of any type of list. The model + * supports three modes: + * <ul> + * <li><code>SINGLE_SELECTION</code> - only one item in the list may be + * selected;</li> + * <li><code>SINGLE_INTERVAL_SELECTION</code> - only one interval in the list + * may be selected;</li> + * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - any combination of items in + * the list may be selected.</li> + * </ul> + * The model uses an event notification mechanism to notify listeners (see + * {@link ListSelectionListener}) about updates to the selection model. + * <p> + * This model is used to track row selections in the {@link JList} component, + * and row and column selections in the {@link JTable} component. */ public interface ListSelectionModel { - + + /** + * A selection mode in which only one item can be selected. + * + * @see #setSelectionMode(int) + */ int SINGLE_SELECTION = 0; + /** + * A selection mode in which a single interval can be selected (an interval + * is a range containing one or more contiguous items). + * + * @see #setSelectionMode(int) + */ int SINGLE_INTERVAL_SELECTION = 1; + /** + * A selection mode in which any combination of items can be selected. + * + * @see #setSelectionMode(int) + */ int MULTIPLE_INTERVAL_SELECTION = 2; - void setSelectionMode(int a); - + /** + * Sets the selection mode. + * <p> + * FIXME: The spec is silent about what happens to existing selections, for + * example when changing from an interval selection to single selection. + * + * @param mode one of {@link #SINGLE_SELECTION}, + * {@link #SINGLE_INTERVAL_SELECTION} and + * {@link #MULTIPLE_INTERVAL_SELECTION}. + * + * @see #getSelectionMode() + * + * @throws IllegalArgumentException if <code>mode</code> is not one of the + * specified values. + */ + void setSelectionMode(int mode); + + /** + * Returns the selection mode, which is one of {@link #SINGLE_SELECTION}, + * {@link #SINGLE_INTERVAL_SELECTION} and + * {@link #MULTIPLE_INTERVAL_SELECTION}. + * + * @return The selection mode. + * + * @see #setSelectionMode(int) + */ int getSelectionMode(); + /** + * Clears the current selection from the model. If the selection state + * changes (that is, the existing selection is non-empty) a + * {@link ListSelectionEvent} should be sent to all registered listeners. + * <p> + * FIXME: what happens to the anchor and lead selection indices (the spec + * is silent about this)? See: + * <p> + * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4334792 + */ void clearSelection(); + /** + * Returns the lowest selected index, or <code>-1</code> if there is no + * selection. + * + * @return The lowest selected index. + * + * @see #getMaxSelectionIndex() + */ int getMinSelectionIndex(); + /** + * Returns the highest selected index, or <code>-1</code> if there is no + * selection. + * + * @return The highest selected index. + * + * @see #getMinSelectionIndex() + */ int getMaxSelectionIndex(); - boolean isSelectedIndex(int a); - + /** + * Returns <code>true</code> if the specified item is selected, and + * <code>false</code> otherwise. Special note: if <code>index</code> is + * negative, this method should return <code>false</code> (no exception + * should be thrown). + * + * @param index the item index (zero-based). + * + * @return <code>true</code> if the specified item is selected, and + * <code>false</code> otherwise. + */ + boolean isSelectedIndex(int index); + + /** + * Returns <code>true</code> if there is no selection, and <code>false</code> + * otherwise. + * + * @return <code>true</code> if there is no selection, and + * <code>false</code> otherwise. + */ boolean isSelectionEmpty(); - void setSelectionInterval(int index0, int index1); - - void addSelectionInterval(int index0, int index1); - - void removeSelectionInterval(int index0, int index1); - + /** + * Sets the selection interval to the specified range (note that + * <code>anchor</code> can be less than, equal to, or greater than + * <code>lead</code>). If this results in the selection being changed, + * a {@link ListSelectionEvent} is sent to all registered listeners. + * <p> + * If the selection mode is {@link #SINGLE_SELECTION}, only the + * <code>lead</code> item is selected. + * + * @param anchor the anchor index. + * @param lead the lead index. + */ + void setSelectionInterval(int anchor, int lead); + + /** + * Marks the items in the specified interval as selected. The behaviour of + * this method depends on the selection mode: + * <ul> + * <li><code>SINGLE_SELECTION</code> - only the <code>lead</code> item is + * selected;</li> + * <li><code>SINGLE_INTERVAL_SELECTION</code> - the existing selection + * interval is replaced by the specified interval;</li> + * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - the specified interval is + * merged into the currently selected intervals.</li> + * </ul> + * Note that <code>anchor</code> can be less than, equal to, or greater than + * <code>lead</code>. + * + * @param anchor the index of the anchor item + * @param lead the index of the lead item. + */ + void addSelectionInterval(int anchor, int lead); + + /** + * Marks the items in the specified interval as not selected. The behaviour + * of this method depends on the selection mode: + * <ul> + * <li><code>SINGLE_SELECTION</code> - XXX;</li> + * <li><code>SINGLE_INTERVAL_SELECTION</code> - XXX;</li> + * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - XXX.</li> + * </ul> + * Note that <code>anchor</code> can be less than, equal to, or greater than + * <code>lead</code>. + * + * @param anchor the index of the anchor item + * @param lead the index of the lead item. + */ + void removeSelectionInterval(int anchor, int lead); + + /** + * Inserts a new interval containing <code>length</code> items at the + * specified <code>index</code> (the <code>before</code> flag indicates + * whether the range is inserted before or after the existing item at + * <code>index</code>). + * + * FIXME: What is the selection status of the new items? Bug 4870694. + * FIXME: What event is generated? + * + * @param index the index of the item. + * @param length the number of items in the interval to be inserted. + * @param before if <code>true</code>, the interval should be inserted + * before <code>index</code>, otherwise it is inserted after. + * + * @see #removeIndexInterval(int, int) + */ void insertIndexInterval(int index, int length, boolean before); + /** + * Removes the items in the specified range (inclusive) from the selection + * model. This method should be called when an interval is deleted from + * the underlying list. + * + * FIXME: what happens to the lead and anchor indices if they are part of + * the range that is removed? + * FIXME: what event is generated + * + * @param index0 XXX + * @param index1 XXX + * + * @see #insertIndexInterval(int, int, boolean) + */ void removeIndexInterval(int index0, int index1); + /** + * Returns the index of the anchor item. + * + * @return The index of the anchor item. + * + * @see #setAnchorSelectionIndex(int) + */ int getAnchorSelectionIndex(); + /** + * Sets the index of the anchor item. + * + * @param index the item index. + * + * @see #getAnchorSelectionIndex() + */ void setAnchorSelectionIndex(int index); + /** + * Returns the index of the lead item. + * + * @return The index of the lead item. + * + * @see #setLeadSelectionIndex(int) + */ int getLeadSelectionIndex(); + /** + * Sets the index of the lead item. + * + * @param index the item index. + * + * @see #getLeadSelectionIndex() + */ void setLeadSelectionIndex(int index); + /** + * Sets the flag that is passed to listeners for each change notification. + * If a sequence of changes is made to the selection model, this flag should + * be set to <code>true</code> at the start of the sequence, and + * <code>false</code> for the last change - this gives listeners the option + * to ignore interim changes if that is more efficient. + * + * @param valueIsAdjusting the flag value. + * + * @see #getValueIsAdjusting() + */ void setValueIsAdjusting(boolean valueIsAdjusting); + /** + * Returns a flag that is passed to registered listeners when changes are + * made to the model. See the description for + * {@link #setValueIsAdjusting(boolean)} for more information. + * + * @return The flag. + */ boolean getValueIsAdjusting(); + /** + * Registers a listener with the model so that it receives notification + * of changes to the model. + * + * @param listener the listener (<code>null</code> ignored). + * + * @see #removeListSelectionListener(ListSelectionListener) + */ void addListSelectionListener(ListSelectionListener listener); + /** + * Deregisters a listener so that it no longer receives notification of + * changes to the model. If the specified listener is not registered with + * the model, or is <code>null</code>, this method does nothing. + * + * @param listener the listener (<code>null</code> ignored). + * + * @see #addListSelectionListener(ListSelectionListener) + */ void removeListSelectionListener(ListSelectionListener listener); } diff --git a/libjava/classpath/javax/swing/MenuSelectionManager.java b/libjava/classpath/javax/swing/MenuSelectionManager.java index df7b42037db..beafbf44202 100644 --- a/libjava/classpath/javax/swing/MenuSelectionManager.java +++ b/libjava/classpath/javax/swing/MenuSelectionManager.java @@ -258,6 +258,9 @@ public class MenuSelectionManager { MenuElement[] selection = (MenuElement[]) selectedPath.toArray(new MenuElement[selectedPath.size()]); + if (selection.length == 0) + return; + MenuElement[] path; for (int index = selection.length - 1; index >= 0; index--) { diff --git a/libjava/classpath/javax/swing/ProgressMonitor.java b/libjava/classpath/javax/swing/ProgressMonitor.java index 73e36b9ca21..28d22e8a63e 100644 --- a/libjava/classpath/javax/swing/ProgressMonitor.java +++ b/libjava/classpath/javax/swing/ProgressMonitor.java @@ -38,8 +38,10 @@ exception statement from your version. */ package javax.swing; import java.awt.Component; -import java.awt.event.ActionListener; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.accessibility.AccessibleContext; /** * <p>Using this class you can easily monitor tasks where you cannot @@ -62,6 +64,12 @@ import java.awt.event.ActionEvent; */ public class ProgressMonitor { + + /** + * The accessible content for this component + */ + protected AccessibleContext accessibleContext; + /** * parentComponent */ @@ -439,5 +447,14 @@ public class ProgressMonitor timestamp = now; } } - + + /** + * Gets the accessible context. + * + * @return the accessible context. + */ + public AccessibleContext getAccessibleContext() + { + return accessibleContext; + } } diff --git a/libjava/classpath/javax/swing/RepaintManager.java b/libjava/classpath/javax/swing/RepaintManager.java index 345c348db52..4a0581c0e49 100644 --- a/libjava/classpath/javax/swing/RepaintManager.java +++ b/libjava/classpath/javax/swing/RepaintManager.java @@ -47,9 +47,8 @@ import java.awt.Rectangle; import java.awt.Window; import java.awt.image.VolatileImage; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -63,19 +62,20 @@ import java.util.WeakHashMap; * double buffer surface is used by root components to paint * themselves.</p> * - * <p>In general, painting is very confusing in swing. see <a + * <p>See <a * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this * document</a> for more details.</p> * * @author Roman Kennke (kennke@aicas.com) * @author Graydon Hoare (graydon@redhat.com) + * @author Audrius Meskauskas (audriusa@bioinformatics.org) */ public class RepaintManager { /** * The current repaint managers, indexed by their ThreadGroups. */ - private static WeakHashMap currentRepaintManagers; + static WeakHashMap currentRepaintManagers; /** * A rectangle object to be reused in damaged regions calculation. @@ -134,44 +134,6 @@ public class RepaintManager } - /** - * Compares two components using their depths in the component hierarchy. - * A component with a lesser depth (higher level components) are sorted - * before components with a deeper depth (low level components). This is used - * to order paint requests, so that the higher level components are painted - * before the low level components get painted. - * - * @author Roman Kennke (kennke@aicas.com) - */ - private class ComponentComparator implements Comparator - { - - /** - * Compares two components. - * - * @param o1 the first component - * @param o2 the second component - * - * @return a negative integer, if <code>o1</code> is bigger in than - * <code>o2</code>, zero, if both are at the same size and a - * positive integer, if <code>o1</code> is smaller than - * <code>o2</code> - */ - public int compare(Object o1, Object o2) - { - if (o1 instanceof JComponent && o2 instanceof JComponent) - { - JComponent c1 = (JComponent) o1; - Rectangle d1 = (Rectangle) dirtyComponentsWork.get(c1); - JComponent c2 = (JComponent) o2; - Rectangle d2 = (Rectangle) dirtyComponentsWork.get(c2); - return d2.width * d2.height - d1.width * d1.height; - } - throw new ClassCastException("This comparator can only be used with " - + "JComponents"); - } - } - /** * A table storing the dirty regions of components. The keys of this * table are components, the values are rectangles. Each component maps @@ -187,18 +149,13 @@ public class RepaintManager * @see #markCompletelyClean * @see #markCompletelyDirty */ - HashMap dirtyComponents; + private HashMap dirtyComponents; /** * The dirtyComponents which is used in paintDiryRegions to avoid unnecessary * locking. */ - HashMap dirtyComponentsWork; - - /** - * The comparator used for ordered inserting into the repaintOrder list. - */ - private transient Comparator comparator; + private HashMap dirtyComponentsWork; /** * A single, shared instance of the helper class. Any methods which mark @@ -422,6 +379,9 @@ public class RepaintManager { if (w <= 0 || h <= 0 || !component.isShowing()) return; + + Component parent = component.getParent(); + component.computeVisibleRect(rectCache); SwingUtilities.computeIntersection(x, y, w, h, rectCache); @@ -485,8 +445,7 @@ public class RepaintManager public void markCompletelyDirty(JComponent component) { Rectangle r = component.getBounds(); - addDirtyRegion(component, r.x, r.y, r.width, r.height); - component.isCompletelyDirty = true; + addDirtyRegion(component, 0, 0, r.width, r.height); } /** @@ -506,7 +465,6 @@ public class RepaintManager { dirtyComponents.remove(component); } - component.isCompletelyDirty = false; } /** @@ -525,9 +483,13 @@ public class RepaintManager */ public boolean isCompletelyDirty(JComponent component) { - if (! dirtyComponents.containsKey(component)) - return false; - return component.isCompletelyDirty; + boolean retVal = false; + if (dirtyComponents.containsKey(component)) + { + Rectangle dirtyRegion = (Rectangle) dirtyComponents.get(component); + retVal = dirtyRegion.equals(SwingUtilities.getLocalBounds(component)); + } + return retVal; } /** @@ -554,8 +516,8 @@ public class RepaintManager } /** - * Repaint all regions of all components which have been marked dirty in - * the {@link #dirtyComponents} table. + * Repaint all regions of all components which have been marked dirty in the + * {@link #dirtyComponents} table. */ public void paintDirtyRegions() { @@ -571,29 +533,76 @@ public class RepaintManager dirtyComponentsWork = swap; } - ArrayList repaintOrder = new ArrayList(dirtyComponentsWork.size());; - // We sort the components by their size here. This way we have a good - // chance that painting the bigger components also paints the smaller - // components and we don't need to paint them twice. - repaintOrder.addAll(dirtyComponentsWork.keySet()); + // Compile a set of repaint roots. + HashSet repaintRoots = new HashSet(); + Set components = dirtyComponentsWork.keySet(); + for (Iterator i = components.iterator(); i.hasNext();) + { + JComponent dirty = (JComponent) i.next(); + compileRepaintRoots(dirtyComponentsWork, dirty, repaintRoots); + } - if (comparator == null) - comparator = new ComponentComparator(); - Collections.sort(repaintOrder, comparator); repaintUnderway = true; - for (Iterator i = repaintOrder.iterator(); i.hasNext();) + for (Iterator i = repaintRoots.iterator(); i.hasNext();) { JComponent comp = (JComponent) i.next(); - // If a component is marked completely clean in the meantime, then skip - // it. Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp); if (damaged == null || damaged.isEmpty()) continue; comp.paintImmediately(damaged); } + dirtyComponentsWork.clear(); repaintUnderway = false; commitRemainingBuffers(); } + + /** + * Compiles a list of components that really get repainted. This is called + * once for each component in the dirtyComponents HashMap, each time with + * another <code>dirty</code> parameter. This searches up the component + * hierarchy of <code>dirty</code> to find the highest parent that is also + * marked dirty and merges the dirty regions. + * + * @param dirtyRegions the dirty regions + * @param dirty the component for which to find the repaint root + * @param roots the list to which new repaint roots get appended + */ + private void compileRepaintRoots(HashMap dirtyRegions, JComponent dirty, + HashSet roots) + { + Component current = dirty; + Component root = dirty; + + // Search the highest component that is also marked dirty. + Component parent; + while (true) + { + parent = current.getParent(); + if (parent == null || !(parent instanceof JComponent)) + break; + + current = parent; + // We can skip to the next up when this parent is not dirty. + if (dirtyRegions.containsKey(parent)) + { + root = current; + } + } + + // Merge the rectangles of the root and the requested component if + // the are different. + if (root != dirty) + { + Rectangle dirtyRect = (Rectangle) dirtyRegions.get(dirty); + dirtyRect = SwingUtilities.convertRectangle(dirty, dirtyRect, root); + Rectangle rootRect = (Rectangle) dirtyRegions.get(root); + SwingUtilities.computeUnion(dirtyRect.x, dirtyRect.y, dirtyRect.width, + dirtyRect.height, rootRect); + } + + // Adds the root to the roots set. + roots.add(root); + } /** * Get an offscreen buffer for painting a component's image. This image diff --git a/libjava/classpath/javax/swing/SwingUtilities.java b/libjava/classpath/javax/swing/SwingUtilities.java index 9d8e8df38f5..5d02d9bb396 100644 --- a/libjava/classpath/javax/swing/SwingUtilities.java +++ b/libjava/classpath/javax/swing/SwingUtilities.java @@ -1446,4 +1446,157 @@ public class SwingUtilities KeyboardManager km = KeyboardManager.getManager(); return km.processKeyStroke(c, s, ev); } + + /** + * Returns a string representing one of the horizontal alignment codes + * defined in the {@link SwingConstants} interface. The following table + * lists the constants and return values: + * <p> + * <table border="0"> + * <tr> + * <th>Code:</th><th>Returned String:</th> + * </tr> + * <tr> + * <td>{@link SwingConstants#CENTER}</td> + * <td><code>"CENTER"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#LEFT}</td> + * <td><code>"LEFT"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#RIGHT}</td> + * <td><code>"RIGHT"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#LEADING}</td> + * <td><code>"LEADING"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#TRAILING}</td> + * <td><code>"TRAILING"</code></td> + * </tr> + * </table> + * </p> + * If the supplied code is not one of those listed, this methods will throw + * an {@link IllegalArgumentException}. + * + * @param code the code. + * + * @return A string representing the given code. + */ + static String convertHorizontalAlignmentCodeToString(int code) + { + switch (code) + { + case SwingConstants.CENTER: + return "CENTER"; + case SwingConstants.LEFT: + return "LEFT"; + case SwingConstants.RIGHT: + return "RIGHT"; + case SwingConstants.LEADING: + return "LEADING"; + case SwingConstants.TRAILING: + return "TRAILING"; + default: + throw new IllegalArgumentException("Unrecognised code: " + code); + } + } + + /** + * Returns a string representing one of the vertical alignment codes + * defined in the {@link SwingConstants} interface. The following table + * lists the constants and return values: + * <p> + * <table border="0"> + * <tr> + * <th>Code:</th><th>Returned String:</th> + * </tr> + * <tr> + * <td>{@link SwingConstants#CENTER}</td> + * <td><code>"CENTER"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#TOP}</td> + * <td><code>"TOP"</code></td> + * </tr> + * <tr> + * <td>{@link SwingConstants#BOTTOM}</td> + * <td><code>"BOTTOM"</code></td> + * </tr> + * </table> + * </p> + * If the supplied code is not one of those listed, this methods will throw + * an {@link IllegalArgumentException}. + * + * @param code the code. + * + * @return A string representing the given code. + */ + static String convertVerticalAlignmentCodeToString(int code) + { + switch (code) + { + case SwingConstants.CENTER: + return "CENTER"; + case SwingConstants.TOP: + return "TOP"; + case SwingConstants.BOTTOM: + return "BOTTOM"; + default: + throw new IllegalArgumentException("Unrecognised code: " + code); + } + } + + /** + * Returns a string representing one of the default operation codes + * defined in the {@link WindowConstants} interface. The following table + * lists the constants and return values: + * <p> + * <table border="0"> + * <tr> + * <th>Code:</th><th>Returned String:</th> + * </tr> + * <tr> + * <td>{@link WindowConstants#DO_NOTHING_ON_CLOSE}</td> + * <td><code>"DO_NOTHING_ON_CLOSE"</code></td> + * </tr> + * <tr> + * <td>{@link WindowConstants#HIDE_ON_CLOSE}</td> + * <td><code>"HIDE_ON_CLOSE"</code></td> + * </tr> + * <tr> + * <td>{@link WindowConstants#DISPOSE_ON_CLOSE}</td> + * <td><code>"DISPOSE_ON_CLOSE"</code></td> + * </tr> + * <tr> + * <td>{@link WindowConstants#EXIT_ON_CLOSE}</td> + * <td><code>"EXIT_ON_CLOSE"</code></td> + * </tr> + * </table> + * </p> + * If the supplied code is not one of those listed, this method will throw + * an {@link IllegalArgumentException}. + * + * @param code the code. + * + * @return A string representing the given code. + */ + static String convertWindowConstantToString(int code) + { + switch (code) + { + case WindowConstants.DO_NOTHING_ON_CLOSE: + return "DO_NOTHING_ON_CLOSE"; + case WindowConstants.HIDE_ON_CLOSE: + return "HIDE_ON_CLOSE"; + case WindowConstants.DISPOSE_ON_CLOSE: + return "DISPOSE_ON_CLOSE"; + case WindowConstants.EXIT_ON_CLOSE: + return "EXIT_ON_CLOSE"; + default: + throw new IllegalArgumentException("Unrecognised code: " + code); + } + } } diff --git a/libjava/classpath/javax/swing/TransferHandler.java b/libjava/classpath/javax/swing/TransferHandler.java index 830feee8332..40a36b27d24 100644 --- a/libjava/classpath/javax/swing/TransferHandler.java +++ b/libjava/classpath/javax/swing/TransferHandler.java @@ -1,5 +1,5 @@ /* TransferHandler.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,12 +38,14 @@ exception statement from your version. */ package javax.swing; +import gnu.classpath.NotImplementedException; + +import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; -import java.awt.Toolkit; import java.io.Serializable; public class TransferHandler implements Serializable @@ -147,42 +149,48 @@ public class TransferHandler implements Serializable this.sourceActions = property != null ? COPY : NONE; } - public boolean canImport (JComponent c, DataFlavor[] flavors) + public boolean canImport(JComponent c, DataFlavor[] flavors) + throws NotImplementedException { return false; } protected Transferable createTransferable(JComponent c) + throws NotImplementedException { return null; } - public void exportAsDrag (JComponent c, InputEvent e, int action) + public void exportAsDrag(JComponent c, InputEvent e, int action) + throws NotImplementedException { // TODO: Implement this properly } - protected void exportDone (JComponent c, Transferable data, int action) + protected void exportDone(JComponent c, Transferable data, int action) + throws NotImplementedException { // TODO: Implement this properly } public void exportToClipboard(JComponent c, Clipboard clip, int action) + throws NotImplementedException { // TODO: Implement this properly } - public int getSourceActions (JComponent c) + public int getSourceActions(JComponent c) { return sourceActions; } - public Icon getVisualRepresentation (Transferable t) + public Icon getVisualRepresentation(Transferable t) { return visualRepresentation; } - public boolean importData (JComponent c, Transferable t) + public boolean importData(JComponent c, Transferable t) + throws NotImplementedException { return false; } diff --git a/libjava/classpath/javax/swing/UIDefaults.java b/libjava/classpath/javax/swing/UIDefaults.java index 00d9700d0d2..bf5242f6552 100644 --- a/libjava/classpath/javax/swing/UIDefaults.java +++ b/libjava/classpath/javax/swing/UIDefaults.java @@ -96,15 +96,15 @@ public class UIDefaults extends Hashtable } public Object createValue(UIDefaults table) { - InputMapUIResource im = new InputMapUIResource (); - for (int i = 0; 2*i+1 < bind.length; ++i) + InputMapUIResource im = new InputMapUIResource(); + for (int i = 0; 2 * i + 1 < bind.length; ++i) { - Object curr = bind[2*i]; + Object curr = bind[2 * i]; if (curr instanceof KeyStroke) - im.put((KeyStroke) curr, bind[2*i+1]); + im.put((KeyStroke) curr, bind[2 * i + 1]); else im.put(KeyStroke.getKeyStroke((String) curr), - bind[2*i+1]); + bind[2 * i + 1]); } return im; } @@ -128,9 +128,9 @@ public class UIDefaults extends Hashtable public ProxyLazyValue(String s) { final String className = s; - inner = new LazyValue () + inner = new LazyValue() { - public Object createValue (UIDefaults table) + public Object createValue(UIDefaults table) { try { @@ -151,16 +151,16 @@ public class UIDefaults extends Hashtable { final String className = c; final String methodName = m; - inner = new LazyValue () + inner = new LazyValue() { - public Object createValue (UIDefaults table) + public Object createValue(UIDefaults table) { try { return Class - .forName (className) - .getMethod (methodName, new Class[] {}) - .invoke (null, new Object[] {}); + .forName(className) + .getMethod(methodName, new Class[] {}) + .invoke(null, new Object[] {}); } catch (Exception e) { @@ -674,7 +674,7 @@ public class UIDefaults extends Hashtable */ public Class getUIClass(String id, ClassLoader loader) { - String className = (String) get (id); + String className = (String) get(id); if (className == null) return null; try diff --git a/libjava/classpath/javax/swing/UIManager.java b/libjava/classpath/javax/swing/UIManager.java index e1ee28b3f1a..e6f80116321 100644 --- a/libjava/classpath/javax/swing/UIManager.java +++ b/libjava/classpath/javax/swing/UIManager.java @@ -145,18 +145,19 @@ public class UIManager implements Serializable static { String defaultlaf = System.getProperty("swing.defaultlaf"); - try { - if (defaultlaf != null) - { - Class lafClass = Class.forName(defaultlaf); - LookAndFeel laf = (LookAndFeel) lafClass.newInstance(); - setLookAndFeel(laf); - } - else - { - setLookAndFeel(new MetalLookAndFeel()); - } - } + try + { + if (defaultlaf != null) + { + Class lafClass = Class.forName(defaultlaf); + LookAndFeel laf = (LookAndFeel) lafClass.newInstance(); + setLookAndFeel(laf); + } + else + { + setLookAndFeel(new MetalLookAndFeel()); + } + } catch (Exception ex) { System.err.println("cannot initialize Look and Feel: " + defaultlaf); @@ -455,7 +456,7 @@ public class UIManager implements Serializable */ public static Font getFont(Object key, Locale locale) { - return (Font) get(key ,locale); + return (Font) get(key, locale); } /** diff --git a/libjava/classpath/javax/swing/WindowConstants.java b/libjava/classpath/javax/swing/WindowConstants.java index aaa0cb9a3ab..598a61e149b 100644 --- a/libjava/classpath/javax/swing/WindowConstants.java +++ b/libjava/classpath/javax/swing/WindowConstants.java @@ -1,5 +1,5 @@ /* WindowConstants.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,31 +38,42 @@ exception statement from your version. */ package javax.swing; /** - * Defines some constants that are used in Swing's top-level - * containers. - * + * Defines some constants that are used in Swing's top-level containers. See + * the following methods: + * <ul> + * <li>{@link JFrame#setDefaultCloseOperation(int)};</li> + * <li>{@link JInternalFrame#setDefaultCloseOperation(int)};</li> + * <li>{@link JDialog#setDefaultCloseOperation(int)};</li> + * </ul> + * * @author Andrew Selkirk */ public interface WindowConstants { /** - * DO_NOTHING_ON_CLOSE + * Do nothing when the container is closed. */ int DO_NOTHING_ON_CLOSE = 0; /** - * HIDE_ON_CLOSE + * Hide the container when it is closed. */ int HIDE_ON_CLOSE = 1; /** - * DISPOSE_ON_CLOSE + * Dispose the container when it is closed. + * + * @see Window#dispose() */ int DISPOSE_ON_CLOSE = 2; /** - * EXIT_ON_CLOSE + * Exit the application when the container is closed. + * + * @see System#exit(int) + * + * @since 1.4 */ - int EXIT_ON_CLOSE =3; + int EXIT_ON_CLOSE = 3; } diff --git a/libjava/classpath/javax/swing/border/AbstractBorder.java b/libjava/classpath/javax/swing/border/AbstractBorder.java index c995de1c202..16bb238c374 100644 --- a/libjava/classpath/javax/swing/border/AbstractBorder.java +++ b/libjava/classpath/javax/swing/border/AbstractBorder.java @@ -194,6 +194,6 @@ public abstract class AbstractBorder implements Border, Serializable height -= borderInsets.top + borderInsets.bottom; } - return new Rectangle (x, y, width, height); + return new Rectangle(x, y, width, height); } } diff --git a/libjava/classpath/javax/swing/border/BevelBorder.java b/libjava/classpath/javax/swing/border/BevelBorder.java index 403c35c045e..5b4761e9ec8 100644 --- a/libjava/classpath/javax/swing/border/BevelBorder.java +++ b/libjava/classpath/javax/swing/border/BevelBorder.java @@ -479,7 +479,7 @@ public class BevelBorder extends AbstractBorder ((highlightOuter == null) || (highlightOuter.getAlpha() == 255)) && ((highlightInner == null) || (highlightInner.getAlpha() == 255)) && ((shadowInner == null) || (shadowInner.getAlpha() == 255)) - && ((shadowOuter == null) ||(shadowOuter.getAlpha() == 255)); + && ((shadowOuter == null) || (shadowOuter.getAlpha() == 255)); } diff --git a/libjava/classpath/javax/swing/border/CompoundBorder.java b/libjava/classpath/javax/swing/border/CompoundBorder.java index a69c5e20aeb..2ee639cf9a3 100644 --- a/libjava/classpath/javax/swing/border/CompoundBorder.java +++ b/libjava/classpath/javax/swing/border/CompoundBorder.java @@ -178,7 +178,7 @@ public class CompoundBorder extends AbstractBorder Insets borderInsets; if (insets == null) - insets = new Insets (0,0,0,0); + insets = new Insets(0, 0, 0, 0); else insets.left = insets.right = insets.top = insets.bottom = 0; @@ -217,7 +217,7 @@ public class CompoundBorder extends AbstractBorder // the implementation from AbstractBorder. However, we want // to be compatible with the API specification, which overrides // the getBorderInsets(Component) method. - return getBorderInsets (c, null); + return getBorderInsets(c, null); } /** @@ -239,7 +239,7 @@ public class CompoundBorder extends AbstractBorder * * @return The inside border (possibly <code>null</code>). */ - public Border getInsideBorder () + public Border getInsideBorder() { return insideBorder; } diff --git a/libjava/classpath/javax/swing/border/MatteBorder.java b/libjava/classpath/javax/swing/border/MatteBorder.java index 114cac62338..944cd2866db 100644 --- a/libjava/classpath/javax/swing/border/MatteBorder.java +++ b/libjava/classpath/javax/swing/border/MatteBorder.java @@ -1,5 +1,5 @@ /* MatteBorder.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -147,9 +147,6 @@ public class MatteBorder extends EmptyBorder { super(top, left, bottom, right); - if (tileIcon == null) - throw new IllegalArgumentException(); - this.tileIcon = tileIcon; } @@ -375,6 +372,10 @@ public class MatteBorder extends EmptyBorder } return; } + + // If this border has no icon end painting here. + if (tileIcon == null) + return; /* Determine the width and height of the icon. Some icons return * -1 if it is an image whose dimensions have not yet been diff --git a/libjava/classpath/javax/swing/border/TitledBorder.java b/libjava/classpath/javax/swing/border/TitledBorder.java index 38b57542334..56146e01d1b 100644 --- a/libjava/classpath/javax/swing/border/TitledBorder.java +++ b/libjava/classpath/javax/swing/border/TitledBorder.java @@ -45,11 +45,10 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.LineMetrics; -import java.awt.geom.AffineTransform; +import java.awt.Point; +import java.awt.Rectangle; +import javax.swing.SwingUtilities; import javax.swing.UIManager; @@ -464,191 +463,238 @@ public class TitledBorder extends AbstractBorder public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Measurements mes = getMeasurements(c); - Font oldFont = g.getFont(); - Color oldColor = g.getColor(); - - /** - * A local helper class for painting the border without changing - * any pixels inside the rectangle of the title text. - */ - class BorderPainter - { - private Component c; - private Border b; - private int x, y, width, height; - - /** - * Constructs a BorderPainter. - * - * @param c the component whose border is being painted. - * @param b the border object. - * @param x the x coordinate of the rectangle delimiting the border. - * @param y the y coordinate of the rectangle delimiting the border. - * @param width the width of the rectangle delimiting the border. - * @param height the width of the rectangle delimiting the border. - */ - public BorderPainter(Component c, Border b, - int x, int y, int width, int height) - { - this.c = c; - this.b = b; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } + Rectangle borderRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING, + width - (EDGE_SPACING * 2), + height - (EDGE_SPACING * 2)); + Point textLoc = new Point(); + + // Save color and font. + Color savedColor = g.getColor(); + Font savedFont = g.getFont(); + + // The font metrics. + Font font = getFont(c); + g.setFont(font); + FontMetrics fm = c.getFontMetrics(font); + + layoutBorderWithTitle(c, fm, borderRect, textLoc); + paintBorderWithTitle(c, g, x, y, width, height, borderRect, textLoc, fm); + + g.setColor(getTitleColor()); + g.drawString(getTitle(), textLoc.x, textLoc.y); + g.setFont(savedFont); + g.setColor(savedColor); + } + /** + * Calculates the bounding box of the inner border and the location of the + * title string. + * + * @param c the component on which to paint the border + * @param fm the font metrics + * @param borderRect output parameter, holds the bounding box of the inner + * border on method exit + * @param textLoc output parameter, holds the location of the title text + * on method exit + */ + private void layoutBorderWithTitle(Component c, FontMetrics fm, + Rectangle borderRect, + Point textLoc) + { + Border b = getBorder(); + + // The font metrics. + int fontHeight = fm.getHeight(); + int fontDescent = fm.getDescent(); + int fontAscent = fm.getAscent(); + int titleWidth = fm.stringWidth(getTitle()); + + // The base insets. + Insets insets; + if (b == null) + insets = new Insets(0, 0, 0, 0); + else + insets = b.getBorderInsets(c); - /** - * Paints the entire border. - */ - public void paint(Graphics g) - { - if (b != null) - b.paintBorder(c, g, x, y, width, height); - } + // The offset of the border rectangle, dependend on the title placement. + int offset; + // Layout border and text vertically. + int titlePosition = getTitlePosition(); + switch (titlePosition) + { + case ABOVE_BOTTOM: + textLoc.y = borderRect.y + borderRect.height - insets.bottom + - fontDescent - TEXT_SPACING; + break; + case BOTTOM: + borderRect.height -= fontHeight / 2; + textLoc.y = borderRect.y + borderRect.height - fontDescent + + (fontAscent + fontDescent - insets.bottom) / 2; + break; + case BELOW_BOTTOM: + borderRect.height -= fontHeight; + textLoc.y = borderRect.y + borderRect.height + fontAscent + + TEXT_SPACING; + break; + case ABOVE_TOP: + offset = fontAscent + fontDescent + + Math.max(EDGE_SPACING, TEXT_SPACING * 2) - EDGE_SPACING; + borderRect.y += offset; + borderRect.height -= offset; + textLoc.y = borderRect.y - (fontDescent + TEXT_SPACING); + break; + case BELOW_TOP: + textLoc.y = borderRect.y + insets.top + fontAscent + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + default: + offset = Math.max(0, ((fontAscent / 2) + TEXT_SPACING) - EDGE_SPACING); + borderRect.y += offset; + borderRect.height -= offset; + textLoc.y = borderRect.y - fontDescent + + (insets.top + fontAscent + fontDescent) / 2; + break; + } - /** - * Paints the border, clipping the drawing operation to a - * given rectangular area. - */ - private void paint(Graphics g, - int clipX, int clipY, int clipWidth, int clipHeight) + // Layout border and text horizontally. + int justification = getTitleJustification(); + // Adjust justification for LEADING and TRAILING depending on the direction + // of the component. + if (c.getComponentOrientation().isLeftToRight()) { - Shape oldClip = g.getClip(); - try - { - g.clipRect(clipX, clipY, clipWidth, clipHeight); - paint(g); - } - finally - { - g.setClip(oldClip); - } + if (justification == LEADING || justification == DEFAULT_JUSTIFICATION) + justification = LEFT; + else if (justification == TRAILING) + justification = RIGHT; } - - - /** - * Paints the border without affecting a given rectangular area. - * This is used for painting the border without drawing anything - * underneath the title text. - * - * <p>Since we do not want to introduce unnecessary dependencies - * on Java 2D, we perform the clipping without constructive geometry - * (provided by java.awt.geom.Area). Instead, the border’s - * bounding rectangle is split into smaller parts, which are then - * clipped and painted individually.: - * - * <p><pre> - * +--------------------+ +--------------------+ - * | | | 1 | - * | +--------+ | +---+--------+-------+ - * | | hole | | |====> | 2 | hole | 3 | - * | +--------+ | |---+--------+-------+ - * | | | 4 | - * +--------------------+ +--------------------+</pre> - * - */ - public void paintExcept(Graphics g, - int holeX, int holeY, int holeWidth, int holeHeight) + else { - int stripeHeight; - - stripeHeight = holeY - y; - if (stripeHeight > 0) - paint(g, x, y, width, stripeHeight); // patch #1 in the image above - - stripeHeight = holeHeight; - if (stripeHeight > 0) - { - paint(g, x, holeY, holeX - x, stripeHeight); // patches #2 and #3 - paint(g, holeX + holeWidth, holeY, x + width - (holeX + holeWidth), stripeHeight); - } - - stripeHeight = height - (holeY - y + holeHeight); - if (stripeHeight > 0) - paint(g, x, y + height - stripeHeight, width, stripeHeight); // #4 + if (justification == LEADING || justification == DEFAULT_JUSTIFICATION) + justification = RIGHT; + else if (justification == TRAILING) + justification = LEFT; } - }; - - BorderPainter bp; - int textX, textY, borderWidth, borderHeight; - - borderWidth = width - (mes.outerSpacing.left + mes.outerSpacing.right); - borderHeight = height - (mes.outerSpacing.top + mes.outerSpacing.bottom); - bp = new BorderPainter(c, getBorder(), - x + mes.outerSpacing.left, y + mes.outerSpacing.top, - borderWidth, borderHeight); - switch (getRealTitleJustification(c)) + switch (justification) { - case LEFT: - textX = x + EDGE_SPACING + TEXT_INSET_H; - break; - - case CENTER: - textX = x + (borderWidth - mes.textWidth) / 2; - break; - - case RIGHT: - textX = x + borderWidth - (mes.textWidth + TEXT_INSET_H); - break; - - default: - throw new IllegalStateException(); + case CENTER: + textLoc.x = borderRect.x + (borderRect.width - titleWidth) / 2; + break; + case RIGHT: + textLoc.x = borderRect.x + borderRect.width - titleWidth + - TEXT_INSET_H - insets.right; + break; + case LEFT: + default: + textLoc.x = borderRect.x + TEXT_INSET_H + insets.left; } + } - switch (titlePosition) - { - case ABOVE_TOP: - textY = y + EDGE_SPACING; - break; - - case TOP: - case DEFAULT_POSITION: - default: - textY = y + mes.outerSpacing.top + mes.borderInsets.top - mes.textAscent - + mes.lineHeight; - break; - - case BELOW_TOP: - textY = y + mes.outerSpacing.top + mes.borderInsets.top + TEXT_SPACING; - break; - - case ABOVE_BOTTOM: - textY = y + height - mes.outerSpacing.bottom - mes.borderInsets.bottom - - TEXT_SPACING - (mes.textAscent + mes.textDescent); - break; - - case BOTTOM: - case BELOW_BOTTOM: - textY = y + height - (mes.textAscent + mes.textDescent); - break; - } + /** + * Paints the border with the title. + * + * @param c the component to paint on + * @param g the graphics context used for paintin + * @param x the upper left corner of the whole border + * @param y the upper left corner of the whole border + * @param width the width of the whole border + * @param height the width of the whole border + * @param borderRect the bounding box of the inner border + * @param textLoc the location of the border title + * @param fm the font metrics of the title + */ + private void paintBorderWithTitle(Component c, Graphics g, int x, int y, + int width, int height, + Rectangle borderRect, Point textLoc, + FontMetrics fm) + { + Border b = getBorder(); + int fontDescent = fm.getDescent(); + int fontAscent = fm.getAscent(); + int titleWidth = fm.stringWidth(getTitle()); - if (mes.trimmedText == null) - bp.paint(g); - else - { - try + if (b != null) { - g.setFont(mes.font); - g.setColor(getTitleColor()); - g.drawString(mes.trimmedText, textX, textY + mes.textAscent); + // Paint border in segments, when the title is painted above the + // border. + if (((titlePosition == TOP || titlePosition == DEFAULT_POSITION) + && (borderRect.y > textLoc.y - fontAscent)) + || (titlePosition == BOTTOM + && borderRect.y + borderRect.height < textLoc.y + fontDescent)) + { + Rectangle clip = new Rectangle(); + Rectangle saved = g.getClipBounds(); + + // Paint border left from the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(x, y, textLoc.x - x - 1, + height, clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + // Paint border right from the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x + titleWidth + 1, y, + x + width - (textLoc.x + titleWidth + 1), height, clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + if (titlePosition == TOP || titlePosition == DEFAULT_POSITION) + { + // Paint border below the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x - 1, + textLoc.y + fontDescent, + titleWidth + 2, + y + height - textLoc.y - fontDescent, + clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + } + else + { + // Paint border above the text. + clip.setBounds(saved); + SwingUtilities.computeIntersection(textLoc.x - 1, y, + titleWidth + 2, + textLoc.y - fontDescent - y, + clip); + if (! clip.isEmpty()) + { + g.setClip(clip); + b.paintBorder(c, g, borderRect.x, borderRect.y, + borderRect.width, + borderRect.height); + } + + } + g.setClip(saved); + } + else + { + b.paintBorder(c, g, borderRect.x, borderRect.y, borderRect.width, + borderRect.height); + } } - finally - { - g.setFont(oldFont); - g.setColor(oldColor); - } - bp.paintExcept(g, textX, textY, - mes.textWidth, mes.textAscent + mes.textDescent); - } } - - + /** * Measures the width of this border. * @@ -682,7 +728,72 @@ public class TitledBorder extends AbstractBorder */ public Insets getBorderInsets(Component c, Insets insets) { - return getMeasurements(c).getContentInsets(insets); + // Initialize insets with the insets from our border. + Border border = getBorder(); + if (border != null) + { + if (border instanceof AbstractBorder) + { + AbstractBorder aBorder = (AbstractBorder) border; + aBorder.getBorderInsets(c, insets); + } + else + { + Insets i = border.getBorderInsets(c); + insets.top = i.top; + insets.bottom = i.bottom; + insets.left = i.left; + insets.right = i.right; + } + } + else + { + insets.top = 0; + insets.bottom = 0; + insets.left = 0; + insets.right = 0; + } + + // Add spacing. + insets.top += EDGE_SPACING + TEXT_SPACING; + insets.bottom += EDGE_SPACING + TEXT_SPACING; + insets.left += EDGE_SPACING + TEXT_SPACING; + insets.right += EDGE_SPACING + TEXT_SPACING; + + String title = getTitle(); + if (c != null && title != null && !title.equals("")) + { + Font font = getFont(c); + FontMetrics fm = c.getFontMetrics(font); + int ascent = fm.getAscent(); + int descent = fm.getDescent(); + int height = fm.getHeight(); + switch (getTitlePosition()) + { + case ABOVE_BOTTOM: + insets.bottom += ascent + descent + TEXT_SPACING; + break; + case BOTTOM: + insets.bottom += ascent + descent; + break; + case BELOW_BOTTOM: + insets.bottom += height; + break; + case ABOVE_TOP: + insets.top += ascent + descent + + Math.max(EDGE_SPACING, TEXT_SPACING * 2) + - EDGE_SPACING; + break; + case BELOW_TOP: + insets.top += ascent + descent + TEXT_SPACING; + break; + case TOP: + case DEFAULT_POSITION: + default: + insets.top += ascent + descent; + } + } + return insets; } @@ -919,7 +1030,26 @@ public class TitledBorder extends AbstractBorder */ public Dimension getMinimumSize(Component c) { - return getMeasurements(c).getMinimumSize(); + Insets i = getBorderInsets(c); + Dimension minSize = new Dimension(i.left + i.right, i.top + i.bottom); + Font font = getFont(c); + FontMetrics fm = c.getFontMetrics(font); + int titleWidth = fm.stringWidth(getTitle()); + switch (getTitlePosition()) + { + case ABOVE_TOP: + case BELOW_BOTTOM: + minSize.width = Math.max(minSize.width, titleWidth); + break; + case BELOW_TOP: + case ABOVE_BOTTOM: + case TOP: + case BOTTOM: + case DEFAULT_POSITION: + default: + minSize.width += titleWidth; + } + return minSize; } @@ -943,253 +1073,4 @@ public class TitledBorder extends AbstractBorder return new Font("Dialog", Font.PLAIN, 12); } - - /** - * Returns the horizontal alignment of the title text in relation to - * the border, mapping the component-dependent alignment constants - * {@link #LEADING}, {@link #TRAILING} and {@link #DEFAULT_JUSTIFICATION} - * to the correct value according to the embedded component’s - * orientation. - * - * @param c the Component for which this TitledBorder is the border. - * - * @return one of the values {@link #LEFT}, {@link #CENTER}, or {@link - * #RIGHT}. - */ - private int getRealTitleJustification(Component c) - { - switch (titleJustification) - { - case DEFAULT_JUSTIFICATION: - case LEADING: - if ((c == null) || c.getComponentOrientation().isLeftToRight()) - return LEFT; - else - return RIGHT; - - case TRAILING: - if ((c == null) || c.getComponentOrientation().isLeftToRight()) - return RIGHT; - else - return LEFT; - - default: - return titleJustification; - } - } - - - /** - * Performs various measurements for the current state of this TitledBorder - * and the given Component. - * - * @param c the component (<code>null</code> not permitted). - * - * @return Various measurements. - */ - private Measurements getMeasurements(Component c) - { - Measurements m = new Measurements(); - FontMetrics fmet; - - m.font = getFont(c); - fmet = c.getFontMetrics(m.font); - m.border = getBorder(); - if (m.border != null) - m.borderInsets = m.border.getBorderInsets(c); - else - m.borderInsets = new Insets(0, 0, 0, 0); - - if (title != null) - { - m.trimmedText = title.trim(); - if (m.trimmedText.length() == 0) - m.trimmedText = null; - } - - if (m.trimmedText != null) - { - m.textAscent = fmet.getAscent(); - m.textDescent = fmet.getDescent() + fmet.getLeading(); - - FontRenderContext frc = new FontRenderContext(new AffineTransform(), - false, false); - LineMetrics lmet = m.font.getLineMetrics(m.trimmedText, 0, - m.trimmedText.length(), frc); - m.lineHeight = (int) lmet.getStrikethroughOffset(); - - // Fallback in case that LineMetrics is not available/working. - if (m.lineHeight == 0) - m.lineHeight = (int) (0.3333 * (double) m.textAscent); - m.textWidth = fmet.stringWidth(m.trimmedText) + 3; - } - else - { - m.textAscent = 0; - m.textDescent = 0; - } - - m.innerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING, - EDGE_SPACING); - m.outerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING, - EDGE_SPACING); - - switch (titlePosition) - { - case ABOVE_TOP: - m.outerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING; - break; - - case TOP: - m.outerSpacing.top += m.textDescent + m.lineHeight; - m.innerSpacing.top += m.textAscent - m.lineHeight; - break; - - case BELOW_TOP: - m.innerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING; - break; - - case ABOVE_BOTTOM: - m.innerSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING; - break; - - case BOTTOM: - m.innerSpacing.bottom += Math.max(m.textAscent - m.lineHeight, 0); - m.outerSpacing.bottom += m.textDescent + m.lineHeight; - break; - - case BELOW_BOTTOM: - m.outerSpacing.bottom += m.textAscent + m.textDescent; - break; - - default: - m.outerSpacing.top += m.textAscent; - } - - return m; - } - - - /** - * A private helper class for holding the result of measuring the - * distances of a TitledBorder. While it would be possible to cache - * these objects, it does not seem to be worth the effort. Note that - * invalidating the cache would be tricky, especially since there is - * no notification mechanism that would inform the cache when - * border has changed, so it would return different insets. - */ - private static class Measurements - { - /** - * The font used for displaying the title text. Note that it can - * well be that the TitledBorder’s font is <code>null</code>, - * which means that the font is to be retrieved from the current - * LookAndFeel. In this case, this <code>font</code> field will - * contain the result of the retrieval. Therefore, it is safe - * to assume that this <code>font</code> field will never have - * a <code>null</code> value. - */ - Font font; - - - /** - * The number of pixels between the base line and the top of the - * text box. - */ - int textAscent; - - - /** - * The number of pixels between the base line and the bottom of - * the text box. - */ - int textDescent; - - /** - * The number of pixels between the base line and the height where - * a strike-through would be drawn. - */ - int lineHeight; - - /** - * The title text after removing leading and trailing white space - * characters. If the title consists only of white space, the - * value of <code>trimmedText</code> will be <code>null</code>. - */ - String trimmedText; - - - /** - * The width of the trimmed title text in pixels. - */ - int textWidth; - - - /** - * The border that constitutes the interior border - * underneath the title text. - */ - Border border; - - - /** - * The distance between the TitledBorder and the interior border. - */ - Insets outerSpacing; - - /** - * The width of the interior border, as returned by - * <code>border.getBorderInsets()</code>. - */ - Insets borderInsets; - - - /** - * The distance between the interior border and the nested - * Component for which this TitledBorder is a border. - */ - Insets innerSpacing; - - - /** - * Determines the insets of the nested component when it has a - * TitledBorder as its border. Used by {@link - * TitledBorder#getBorderInsets(Component, Insets)}. - * - * @param i an Insets object for storing the results into, or - * <code>null</code> to cause the creation of a - * new instance. - * - * @return the <code>i</code> object, or a new Insets object - * if <code>null</code> was passed for <code>i</code>. - */ - public Insets getContentInsets(Insets i) - { - if (i == null) - i = new Insets(0, 0, 0, 0); - i.left = outerSpacing.left + borderInsets.left + innerSpacing.left; - i.right = outerSpacing.right + borderInsets.right + innerSpacing.right; - i.top = outerSpacing.top + borderInsets.top + innerSpacing.top; - i.bottom = outerSpacing.bottom + borderInsets.bottom + innerSpacing.bottom; - return i; - } - - - /** - * Calculates the minimum size needed for displaying the border - * and its title. Used by {@link TitledBorder#getMinimumSize(Component)}. - * - * @return The minimum size. - */ - public Dimension getMinimumSize() - { - int width; - Insets insets; - - insets = getContentInsets(null); - width = Math.max(insets.left + insets.right, textWidth + 2 - * TEXT_INSET_H); - return new Dimension(width, insets.top + insets.bottom); - } - } } diff --git a/libjava/classpath/javax/swing/event/EventListenerList.java b/libjava/classpath/javax/swing/event/EventListenerList.java index a7fbec44d36..6a2f34ebb3d 100644 --- a/libjava/classpath/javax/swing/event/EventListenerList.java +++ b/libjava/classpath/javax/swing/event/EventListenerList.java @@ -1,5 +1,5 @@ /* EventListenerList.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -187,11 +187,15 @@ public class EventListenerList /** - * Get a list of listenerType/listener pairs - * @return Listener list + * Returns an array containing a sequence of listenerType/listener pairs, one + * for each listener. + * + * @return An array containing the listener types and references. */ public Object[] getListenerList() { + // returning the internal storage is a bad idea, but tests show that the + // reference implementation does this... return listenerList; } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java index 7dbcb91467e..0a537c4bdd8 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java @@ -72,7 +72,7 @@ public class BasicButtonUI extends ButtonUI * A constant added to the defaultTextIconGap to adjust the text * within this particular button. */ - protected int defaultTextShiftOffset = 0; + protected int defaultTextShiftOffset; private int textShiftOffset; @@ -268,10 +268,9 @@ public class BasicButtonUI extends ButtonUI */ public Dimension getPreferredSize(JComponent c) { - AbstractButton b = (AbstractButton)c; - Dimension d = - BasicGraphicsUtils.getPreferredButtonSize - (b, defaultTextIconGap + defaultTextShiftOffset); + AbstractButton b = (AbstractButton) c; + Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, + defaultTextIconGap + defaultTextShiftOffset); return d; } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java index 14dadb85cf9..1010139b8fc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java @@ -1,5 +1,5 @@ /* BasicCheckBoxUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,25 +38,32 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import javax.swing.Icon; +import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * A UI delegate for the {@link JCheckBox} component. + */ public class BasicCheckBoxUI extends BasicRadioButtonUI { - public static ComponentUI createUI(final JComponent c) { + /** + * Returns a UI delegate (that is, an instance of this class) for the + * specified component. + * + * @param c the component (this should be a {@link JCheckBox}). + * + * @return A new instance of <code>BasicCheckBoxUI</code>. + */ + public static ComponentUI createUI(JComponent c) { return new BasicCheckBoxUI(); } - public Icon getDefaultIcon() - { - return UIManager.getIcon("CheckBox.icon"); - } - /** - * Returns the prefix for entries in the {@link UIManager} defaults table. + * Returns the prefix for entries in the {@link UIManager} defaults table + * (<code>"CheckBox."</code> in this case). * * @return "CheckBox." */ diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java index 557eea93f07..ea6f9850435 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -1,5 +1,5 @@ /* BasicComboBoxUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -66,12 +66,14 @@ import javax.swing.CellRendererPane; import javax.swing.ComboBoxEditor; import javax.swing.ComboBoxModel; import javax.swing.DefaultListCellRenderer; +import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; @@ -546,7 +548,7 @@ public class BasicComboBoxUI extends ComboBoxUI } /** - * Unconfigures the editor for this combo nox. This method is not implemented. + * Unconfigures the editor for this combo box. */ protected void unconfigureEditor() { @@ -711,12 +713,14 @@ public class BasicComboBoxUI extends ComboBoxUI } public int getAccessibleChildrenCount(JComponent c) + throws NotImplementedException { // FIXME: Need to implement return 0; } public Accessible getAccessibleChild(JComponent c, int i) + throws NotImplementedException { // FIXME: Need to implement return null; @@ -731,7 +735,9 @@ public class BasicComboBoxUI extends ComboBoxUI * @return true if the specified key is a navigation key and false otherwis */ protected boolean isNavigationKey(int keyCode) + throws NotImplementedException { + // FIXME: Need to implement return false; } @@ -780,9 +786,7 @@ public class BasicComboBoxUI extends ComboBoxUI Insets i = comboBox.getInsets(); int arrowSize = h - (i.top + i.bottom); if (arrowButton != null) - { - arrowSize = arrowButton.getWidth(); - } + arrowSize = arrowButton.getWidth(); return new Rectangle(i.left, i.top, w - (i.left + i.right + arrowSize), h - (i.top + i.left)); } @@ -822,14 +826,12 @@ public class BasicComboBoxUI extends ComboBoxUI if (hasFocus && ! isPopupVisible(comboBox)) { comp = renderer.getListCellRendererComponent(listBox, - comboBox.getSelectedItem(), - -1, true, false); + comboBox.getSelectedItem(), -1, true, false); } else { comp = renderer.getListCellRendererComponent(listBox, - comboBox.getSelectedItem(), - -1, false, false); + comboBox.getSelectedItem(), -1, false, false); Color bg = UIManager.getColor("ComboBox.disabledForeground"); comp.setBackground(bg); } @@ -871,13 +873,9 @@ public class BasicComboBoxUI extends ComboBoxUI { Color saved = g.getColor(); if (comboBox.isEnabled()) - { - g.setColor(UIManager.getColor("UIManager.background")); - } + g.setColor(UIManager.getColor("UIManager.background")); else - { - g.setColor(UIManager.getColor("UIManager.disabledBackground")); - } + g.setColor(UIManager.getColor("UIManager.disabledBackground")); g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); g.setColor(saved); } @@ -897,9 +895,7 @@ public class BasicComboBoxUI extends ComboBoxUI protected Dimension getDefaultSize() { Component comp = DEFAULT_RENDERER.getListCellRendererComponent(listBox, - " ", -1, - false, - false); + " ", -1, false, false); currentValuePane.add(comp); comp.setFont(comboBox.getFont()); Dimension d = comp.getPreferredSize(); @@ -974,19 +970,22 @@ public class BasicComboBoxUI extends ComboBoxUI * by the look and feel. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement. + SwingUtilities.replaceUIInputMap(comboBox, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, + (InputMap) UIManager.get("ComboBox.ancestorInputMap")); + // Install any action maps here. } - + /** * Uninstalls the keyboard actions for the {@link JComboBox} there were * installed by in {@link #installListeners}. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement. + SwingUtilities.replaceUIInputMap(comboBox, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + // Uninstall any action maps here. } /** @@ -1145,9 +1144,7 @@ public class BasicComboBoxUI extends ComboBoxUI ComboBoxModel model = comboBox.getModel(); Object v = model.getSelectedItem(); if (editor != null) - { - comboBox.configureEditor(comboBox.getEditor(), v); - } + comboBox.configureEditor(comboBox.getEditor(), v); comboBox.repaint(); } } @@ -1166,9 +1163,10 @@ public class BasicComboBoxUI extends ComboBoxUI * Invoked whenever key is pressed while JComboBox is in focus. */ public void keyPressed(KeyEvent e) + throws NotImplementedException { - // FIXME: This method calls JComboBox.selectWithKeyChar if the key that was - // pressed is not a navigation key. + // FIXME: This method calls JComboBox.selectWithKeyChar if the key that + // was pressed is not a navigation key. } } @@ -1198,10 +1196,8 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.revalidate(); } if (editor != null) - { - comboBox.configureEditor(comboBox.getEditor(), - comboBox.getSelectedItem()); - } + comboBox.configureEditor(comboBox.getEditor(), + comboBox.getSelectedItem()); comboBox.repaint(); } @@ -1215,9 +1211,7 @@ public class BasicComboBoxUI extends ComboBoxUI int start = e.getIndex0(); int end = e.getIndex1(); if (start == 0 && comboBox.getItemCount() - (end - start + 1) == 0) - { - contentsChanged(e); - } + contentsChanged(e); else if (start != -1 || end != -1) { ListCellRenderer renderer = comboBox.getRenderer(); @@ -1227,10 +1221,8 @@ public class BasicComboBoxUI extends ComboBoxUI // TODO: Optimize using prototype here. for (int i = start; i <= end; ++i) { - Component comp = - renderer.getListCellRendererComponent(listBox, - model.getElementAt(i), - -1, false, false); + Component comp = renderer.getListCellRendererComponent(listBox, + model.getElementAt(i), -1, false, false); currentValuePane.add(comp); comp.setFont(comboBox.getFont()); Dimension dim = comp.getPreferredSize(); @@ -1241,13 +1233,9 @@ public class BasicComboBoxUI extends ComboBoxUI if (displaySize.width < w || displaySize.height < h) { if (displaySize.width < w) - { - displaySize.width = w; - } + displaySize.width = w; if (displaySize.height < h) - { - displaySize.height = h; - } + displaySize.height = h; comboBox.revalidate(); if (editor != null) { @@ -1297,37 +1285,37 @@ public class BasicComboBoxUI extends ComboBoxUI if (e.getPropertyName().equals("enabled")) { - arrowButton.setEnabled(comboBox.isEnabled()); + arrowButton.setEnabled(comboBox.isEnabled()); - if (comboBox.isEditable()) - comboBox.getEditor().getEditorComponent().setEnabled(comboBox - .isEnabled()); + if (comboBox.isEditable()) + comboBox.getEditor().getEditorComponent().setEnabled( + comboBox.isEnabled()); } else if (e.getPropertyName().equals("editable")) { - if (comboBox.isEditable()) - { - configureEditor(); - addEditor(); - } - else - { - unconfigureEditor(); - removeEditor(); - } - - comboBox.revalidate(); - comboBox.repaint(); + if (comboBox.isEditable()) + { + configureEditor(); + addEditor(); + } + else + { + unconfigureEditor(); + removeEditor(); + } + + comboBox.revalidate(); + comboBox.repaint(); } else if (e.getPropertyName().equals("dataModel")) { - // remove ListDataListener from old model and add it to new model - ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue(); - if (oldModel != null) - oldModel.removeListDataListener(listDataListener); + // remove ListDataListener from old model and add it to new model + ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue(); + if (oldModel != null) + oldModel.removeListDataListener(listDataListener); - if ((ComboBoxModel) e.getNewValue() != null) - comboBox.getModel().addListDataListener(listDataListener); + if ((ComboBoxModel) e.getNewValue() != null) + comboBox.getModel().addListDataListener(listDataListener); } else if (e.getPropertyName().equals("font")) { @@ -1339,7 +1327,7 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.repaint(); } - // FIXME: Need to handle changes in other bound properties. + // FIXME: Need to handle changes in other bound properties. } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java index d4eabc60264..0d822955bbc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Component; import java.awt.Dimension; @@ -294,9 +292,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup * This method uninstalls keyboard actions installed by the UI. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement + // Nothing to do here. } /** @@ -559,12 +556,11 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup } /** - * DOCUMENT ME! + * Installs the keyboard actions. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement + // Nothing to do here } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java index a694f328049..ef7a880c2ac 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -227,16 +227,16 @@ public class BasicDirectoryModel extends AbstractListModel if (aTrav == bTrav) { - String aname = a.getName().toLowerCase(); - String bname = b.getName().toLowerCase(); - return ((aname.compareTo(bname) < 0) ? true : false); + String aname = a.getName().toLowerCase(); + String bname = b.getName().toLowerCase(); + return (aname.compareTo(bname) < 0) ? true : false; } else { - if (aTrav) - return true; - else - return false; + if (aTrav) + return true; + else + return false; } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java index daa97708390..9adb0c642ba 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -365,10 +365,10 @@ public class BasicFileChooserUI extends FileChooserUI { /** DOCUMENT ME! */ - private Object lastSelected = null; + private Object lastSelected; /** DOCUMENT ME! */ - private JList list = null; + private JList list; /** * Creates a new DoubleClickListener object. diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java index 6debd649509..cad0d0e8abe 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java @@ -56,8 +56,14 @@ public class BasicIconFactory implements Serializable private static class DummyIcon implements Icon { - public int getIconHeight() { return 10; } - public int getIconWidth() { return 10; } + 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(); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java index 7ec3aa074bd..6beac6c971b 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -1,5 +1,5 @@ /* BasicInternalFrameUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.AWTEvent; import java.awt.Color; import java.awt.Component; @@ -52,12 +50,16 @@ import java.awt.LayoutManager; import java.awt.LayoutManager2; 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.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.beans.PropertyVetoException; +import javax.swing.AbstractAction; +import javax.swing.ActionMap; import javax.swing.DefaultDesktopManager; import javax.swing.DesktopManager; import javax.swing.JComponent; @@ -73,6 +75,7 @@ import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import javax.swing.event.MouseInputAdapter; import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InternalFrameUI; import javax.swing.plaf.UIResource; @@ -168,10 +171,9 @@ public class BasicInternalFrameUI extends InternalFrameUI implements SwingConstants { /** - * If true, the cursor is being already shown in the alternative "resize" - * shape. + * The current shape of the cursor. */ - transient boolean showingResizeCursor; + transient int showingCursor; /** FIXME: Use for something. */ protected final int RESIZE_NONE = 0; @@ -187,7 +189,7 @@ public class BasicInternalFrameUI extends InternalFrameUI /** Cache rectangle that can be reused. */ private transient Rectangle cacheRect = new Rectangle(); - + /** * This method is called when the mouse is clicked. * @@ -195,6 +197,20 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public void mouseClicked(MouseEvent e) { + // Do minimization/maximization when double-clicking in the title pane. + if (e.getSource() == titlePane && e.getClickCount() == 2) + try + { + if (frame.isMaximizable() && ! frame.isMaximum()) + frame.setMaximum(true); + else if (frame.isMaximum()) + frame.setMaximum(false); + } + catch (PropertyVetoException pve) + { + // We do nothing if the attempt has been vetoed. + } + // There is nothing to do when the mouse is clicked // on the border. } @@ -223,34 +239,34 @@ public class BasicInternalFrameUI extends InternalFrameUI { switch (direction) { - case NORTH: + case Cursor.N_RESIZE_CURSOR: cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height - min.height), b.width, b.height - y); break; - case NORTH_EAST: + case Cursor.NE_RESIZE_CURSOR: cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height - - min.height), x, + - min.height), x + 1, b.height - y); break; - case EAST: - cacheRect.setBounds(b.x, b.y, x, b.height); + case Cursor.E_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, x + 1, b.height); break; - case SOUTH_EAST: - cacheRect.setBounds(b.x, b.y, x, y); + case Cursor.SE_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, x + 1, y + 1); break; - case SOUTH: - cacheRect.setBounds(b.x, b.y, b.width, y); + case Cursor.S_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, b.width, y + 1); break; - case SOUTH_WEST: + case Cursor.SW_RESIZE_CURSOR: cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), - b.y, b.width - x, y); + b.y, b.width - x, y + 1); break; - case WEST: + case Cursor.W_RESIZE_CURSOR: cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), b.y, b.width - x, b.height); break; - case NORTH_WEST: + case Cursor.NW_RESIZE_CURSOR: cacheRect.setBounds( Math.min(b.x + x, b.x + b.width - min.width), Math.min(b.y + y, b.y + b.height - min.height), @@ -260,6 +276,7 @@ public class BasicInternalFrameUI extends InternalFrameUI dm.resizeFrame(frame, cacheRect.x, cacheRect.y, Math.max(min.width, cacheRect.width), Math.max(min.height, cacheRect.height)); + setCursor(e); } else if (e.getSource() == titlePane) { @@ -277,11 +294,10 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public void mouseExited(MouseEvent e) { - // Reset the cursor shape. - if (showingResizeCursor) + if (showingCursor != Cursor.DEFAULT_CURSOR) { frame.setCursor(Cursor.getDefaultCursor()); - showingResizeCursor = false; + showingCursor = Cursor.DEFAULT_CURSOR; } } @@ -293,53 +309,36 @@ public class BasicInternalFrameUI extends InternalFrameUI public void mouseMoved(MouseEvent e) { // Turn off the resize cursor if we are in the frame header. - if (showingResizeCursor && e.getSource() != frame) + if (showingCursor != Cursor.DEFAULT_CURSOR && e.getSource() != frame) { frame.setCursor(Cursor.getDefaultCursor()); - showingResizeCursor = false; + showingCursor = Cursor.DEFAULT_CURSOR; } else if (e.getSource()==frame && frame.isResizable()) { - int cursor; - switch (sectionOfClick(e.getX(), e.getY())) - { - case NORTH: - cursor = Cursor.N_RESIZE_CURSOR; - break; - case NORTH_EAST: - cursor = Cursor.NE_RESIZE_CURSOR; - break; - case EAST: - cursor = Cursor.E_RESIZE_CURSOR; - break; - case SOUTH_EAST: - cursor = Cursor.SE_RESIZE_CURSOR; - break; - case SOUTH: - cursor = Cursor.S_RESIZE_CURSOR; - break; - case SOUTH_WEST: - cursor = Cursor.SW_RESIZE_CURSOR; - break; - case WEST: - cursor = Cursor.W_RESIZE_CURSOR; - break; - case NORTH_WEST: - cursor = Cursor.NW_RESIZE_CURSOR; - break; - default: - cursor = Cursor.DEFAULT_CURSOR; - } - + setCursor(e); + } + } + + /** + * Set the mouse cursor, how applicable. + * + * @param e the current mouse event. + */ + void setCursor(MouseEvent e) + { + int cursor = sectionOfClick(e.getX(), e.getY()); + if (cursor != showingCursor) + { Cursor resize = Cursor.getPredefinedCursor(cursor); frame.setCursor(resize); - showingResizeCursor = true; + showingCursor = cursor; } } /** * This method is called when the mouse is pressed. - * + * * @param e The MouseEvent. */ public void mousePressed(MouseEvent e) @@ -383,6 +382,8 @@ public class BasicInternalFrameUI extends InternalFrameUI dm.endDraggingFrame(frame); frame.putClientProperty("bufferedDragging", null); } + + setCursor(e); } /** @@ -392,30 +393,31 @@ public class BasicInternalFrameUI extends InternalFrameUI * @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). + * @return The cursor constant, determining the resizing 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; + int corner = InternalFrameBorder.cornerSize; + + if (x < corner && y < corner) + return Cursor.NW_RESIZE_CURSOR; + else if (x > b.width - corner && y < corner) + return Cursor.NE_RESIZE_CURSOR; + else if (x > b.width - corner && y > b.height - corner) + return Cursor.SE_RESIZE_CURSOR; + else if (x < corner && y > b.height - corner) + return Cursor.SW_RESIZE_CURSOR; + else if (y < corner) + return Cursor.N_RESIZE_CURSOR; + else if (x < corner) + return Cursor.W_RESIZE_CURSOR; + else if (y > b.height - corner) + return Cursor.S_RESIZE_CURSOR; + else if (x > b.width - corner) + return Cursor.E_RESIZE_CURSOR; + + return Cursor.DEFAULT_CURSOR; } } @@ -992,14 +994,18 @@ public class BasicInternalFrameUI extends InternalFrameUI /** * This helper class is the border for the JInternalFrame. */ - private class InternalFrameBorder extends AbstractBorder implements + class InternalFrameBorder extends AbstractBorder implements UIResource { - /** The width of the border. */ - private static final int bSize = 5; + /** + * The width of the border. + */ + static final int bSize = 5; - /** The size of the corners. */ - private static final int offset = 10; + /** + * The size of the corners (also used by the mouse listener). + */ + static final int cornerSize = 10; /** * This method returns whether the border is opaque. @@ -1069,10 +1075,12 @@ public class BasicInternalFrameUI extends InternalFrameUI 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.fill3DRect(0, cornerSize, bSize, b.height - 2 * cornerSize, false); + g.fill3DRect(cornerSize, 0, b.width - 2 * cornerSize, bSize, false); + g.fill3DRect(cornerSize, b.height - bSize, b.width - 2 * cornerSize, + bSize, false); + g.fill3DRect(b.width - bSize, cornerSize, bSize, + b.height - 2 * cornerSize, false); g.translate(-x, -y); g.setColor(saved); @@ -1080,6 +1088,23 @@ public class BasicInternalFrameUI extends InternalFrameUI } /** + * This action triggers the system menu. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class ShowSystemMenuAction + extends AbstractAction + { + public void actionPerformed(ActionEvent e) + { + if (titlePane != null) + { + titlePane.showSystemMenu(); + } + } + } + + /** * The MouseListener that is responsible for dragging and resizing the * JInternalFrame in response to MouseEvents. */ @@ -1220,9 +1245,17 @@ public class BasicInternalFrameUI extends InternalFrameUI * This method installs the keyboard actions for the JInternalFrame. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Implement. + ActionMapUIResource am = new ActionMapUIResource(); + am.put("showSystemMenu", new ShowSystemMenuAction()); + + // The RI impl installs the audio actions as parent of the UI action map, + // so do we. + BasicLookAndFeel blaf = (BasicLookAndFeel) UIManager.getLookAndFeel(); + ActionMap audioActionMap = blaf.getAudioActionMap(); + am.setParent(audioActionMap); + + SwingUtilities.replaceUIActionMap(frame, am); } /** @@ -1303,9 +1336,10 @@ public class BasicInternalFrameUI extends InternalFrameUI * This method uninstalls the keyboard actions for the JInternalFrame. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Implement. + SwingUtilities.replaceUIActionMap(frame, null); + SwingUtilities.replaceUIInputMap(frame, JComponent.WHEN_IN_FOCUSED_WINDOW, + null); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java index d9bc0676dd9..44f6a408984 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java @@ -218,11 +218,12 @@ public class BasicListUI extends ListUI class ListAction extends AbstractAction { - public void actionPerformed (ActionEvent e) + public void actionPerformed(ActionEvent e) { int lead = list.getLeadSelectionIndex(); int max = list.getModel().getSize() - 1; - DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel(); + DefaultListSelectionModel selModel + = (DefaultListSelectionModel) list.getSelectionModel(); String command = e.getActionCommand(); // Do nothing if list is empty if (max == -1) @@ -260,9 +261,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -273,9 +273,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -286,9 +285,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -299,9 +297,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -309,32 +306,31 @@ public class BasicListUI extends ListUI } else if (command.equals("selectNextRowExtendSelection")) { - selModel.setLeadSelectionIndex(Math.min(lead + 1,max)); + selModel.setLeadSelectionIndex(Math.min(lead + 1, max)); } else if (command.equals("selectFirstRow")) { list.setSelectedIndex(0); } else if (command.equals("selectFirstRowChangeLead")) - { - selModel.moveLeadSelectionIndex(0); - } + { + selModel.moveLeadSelectionIndex(0); + } else if (command.equals("selectFirstRowExtendSelection")) { selModel.setLeadSelectionIndex(0); } else if (command.equals("selectPreviousRowExtendSelection")) { - selModel.setLeadSelectionIndex(Math.max(0,lead - 1)); + selModel.setLeadSelectionIndex(Math.max(0, lead - 1)); } else if (command.equals("scrollUp")) { int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -349,9 +345,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -451,9 +446,9 @@ public class BasicListUI extends ListUI if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) list.setSelectedIndex(index); else if (list.isSelectedIndex(index)) - list.removeSelectionInterval(index,index); + list.removeSelectionInterval(index, index); else - list.addSelectionInterval(index,index); + list.addSelectionInterval(index, index); } else list.setSelectedIndex(index); @@ -1006,14 +1001,14 @@ public class BasicListUI extends ListUI // Register key bindings in the UI InputMap-ActionMap pair for (int i = 0; i < keys.length; i++) { - KeyStroke stroke = (KeyStroke)keys[i]; + KeyStroke stroke = (KeyStroke) keys[i]; String actionString = (String) focusInputMap.get(stroke); parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(), stroke.getModifiers()), actionString); - parentActionMap.put (actionString, - new ActionListenerProxy(action, actionString)); + parentActionMap.put(actionString, + new ActionListenerProxy(action, actionString)); } // Register the new InputMap-ActionMap as the parents of the list's // InputMap and ActionMap diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java index 78c16ef08ae..5a08b2a3982 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -1,5 +1,5 @@ /* BasicLookAndFeel.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -1147,14 +1147,16 @@ public abstract class BasicLookAndFeel extends LookAndFeel "F8", "startResize", "END", "selectMax", "HOME", "selectMin", - "LEFT", "negativeIncremnent", + "LEFT", "negativeIncrement", "KP_UP", "negativeIncrement", "KP_DOWN", "positiveIncrement", "UP", "negativeIncrement", "RIGHT", "positiveIncrement", "KP_LEFT", "negativeIncrement", "DOWN", "positiveIncrement", - "KP_RIGHT", "positiveIncrement" + "KP_RIGHT", "positiveIncrement", + "shift ctrl pressed TAB", "focusOutBackward", + "ctrl pressed TAB", "focusOutForward" }), "SplitPane.background", new ColorUIResource(light), "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null), diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java index 88bca3b53ce..91bf614340d 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -977,7 +977,7 @@ public class BasicOptionPaneUI extends OptionPaneUI case JOptionPane.OK_CANCEL_OPTION: return new Object[] { OK_STRING, CANCEL_STRING }; case JOptionPane.DEFAULT_OPTION: - return (optionPane.getWantsInput() ) ? + return (optionPane.getWantsInput()) ? new Object[] { OK_STRING, CANCEL_STRING } : ( optionPane.getMessageType() == JOptionPane.QUESTION_MESSAGE ) ? new Object[] { YES_STRING, NO_STRING, CANCEL_STRING } : diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java index 4f535f653cc..458f10204f0 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java @@ -1,5 +1,5 @@ /* BasicPanelUI.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,33 +44,68 @@ import javax.swing.LookAndFeel; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PanelUI; +/** + * A UI delegate for the {@link JPanel} component. + */ public class BasicPanelUI extends PanelUI { - public static ComponentUI createUI(JComponent x) + /** + * A UI delegate that can be shared by all panels (because the delegate is + * stateless). + */ + static BasicPanelUI sharedUI; + + /** + * Returns a UI delegate for the specified component. + * + * @param panel the panel. + */ + public static ComponentUI createUI(JComponent panel) { - return new BasicPanelUI(); + if (sharedUI == null) + sharedUI = new BasicPanelUI(); + return sharedUI; } + /** + * Installs this UI delegate in the specified component. + * + * @param c the component (should be a {@link JPanel}, <code>null</code> not + * permitted). + */ public void installUI(JComponent c) { super.installUI(c); if (c instanceof JPanel) { - JPanel p = (JPanel) c; - installDefaults(p); + JPanel p = (JPanel) c; + installDefaults(p); } } + /** + * Installs the defaults for this UI delegate in the specified panel. + * + * @param p the panel (<code>null</code> not permitted). + */ protected void installDefaults(JPanel p) { LookAndFeel.installColorsAndFont(p, "Panel.background", "Panel.foreground", "Panel.font"); + + // A test against the reference implementation shows that this method will + // install a border if one is defined in the UIDefaults table (even though + // the BasicLookAndFeel doesn't actually define a "Panel.border"). This + // test was written after discovering that a null argument to + // uninstallDefaults throws a NullPointerException in + // LookAndFeel.uninstallBorder()... + LookAndFeel.installBorder(p, "Panel.border"); } /** - * Uninstalls this UI from the JPanel. + * Uninstalls this UI delegate from the specified component. * - * @param c the JPanel from which to uninstall this UI + * @param c the component (<code>null</code> not permitted). */ public void uninstallUI(JComponent c) { @@ -78,13 +113,20 @@ public class BasicPanelUI extends PanelUI } /** - * Uninstalls the UI defaults that have been install through - * {@link #installDefaults}. + * Uninstalls the UI defaults for the specified panel. * - * @param p the panel from which to uninstall the UI defaults + * @param p the panel (<code>null</code> not permitted). */ protected void uninstallDefaults(JPanel p) { - // Nothing to do here. + // Tests on the reference implementation showed this method: + // (1) doesn't actually remove the installed colors and font installed + // by installDefaults(), it isn't necessary; + // (2) throws a NullPointerException in LookAndFeel.uninstallBorder() if + // p is null. Strangely, no border is installed by the + // BasicLookAndFeel - perhaps this is needed by another LAF? + + LookAndFeel.uninstallBorder(p); } + } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java index d3674664d4c..2518a91997a 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java @@ -52,6 +52,7 @@ import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; +import java.awt.geom.AffineTransform; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -725,26 +726,22 @@ public class BasicProgressBarUI extends ProgressBarUI protected void paintString(Graphics g, int x, int y, int width, int height, int amountFull, Insets b) { - // FIXME: We do not support vertical text painting because Java2D is needed - // for this. - if (progressBar.getOrientation() == JProgressBar.VERTICAL) - return; - - // We want to place in the exact center of the bar. + String str = progressBar.getString(); + int full = getAmountFull(b, width, height); Point placement = getStringPlacement(g, progressBar.getString(), - x + b.left, y + b.top, + x + b.left, y + b.top, width - b.left - b.right, height - b.top - b.bottom); - Color savedColor = g.getColor(); Shape savedClip = g.getClip(); FontMetrics fm = g.getFontMetrics(progressBar.getFont()); - int full = getAmountFull(b, width, height); - String str = progressBar.getString(); - - // We draw this string two times with different clips so that the text - // over the filled area is painted with selectionForeground and over - // the clear area with selectionBackground. + + if (progressBar.getOrientation() == JProgressBar.VERTICAL) + { + AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2); + g.setFont(progressBar.getFont().deriveFont(rotate)); + } + g.setColor(getSelectionForeground()); g.setClip(0, 0, full + b.left, height); g.drawString(str, placement.x, placement.y + fm.getAscent()); @@ -756,9 +753,9 @@ public class BasicProgressBarUI extends ProgressBarUI } /** - * This method sets the current animation index. If the index - * is greater than the number of frames, it resets to 0. - * + * 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) diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java index a66fa28e610..64a1deca572 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -1,5 +1,5 @@ /* BasicRadioButtonUI.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -167,9 +167,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI } if (text != null) paintText(g, b, tr, text); - // TODO: Figure out what is the size parameter? if (b.hasFocus() && b.isFocusPainted() && m.isEnabled()) - paintFocus(g, tr, null); + paintFocus(g, tr, c.getSize()); } /** @@ -177,9 +176,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI * * @param g the graphics context * @param tr the rectangle for the text label - * @param size the size (??) + * @param size the size of the <code>JRadioButton</code> component. */ - // TODO: Figure out what for is the size parameter. protected void paintFocus(Graphics g, Rectangle tr, Dimension size) { Color focusColor = UIManager.getColor(getPropertyPrefix() + ".focus"); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java index 933db4c6bc2..e20bc2bb3db 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java @@ -215,9 +215,8 @@ public class BasicRootPaneUI extends RootPaneUI JComponent.WHEN_IN_FOCUSED_WINDOW); if (newValue != null) { - Object[] keybindings = - (Object[]) UIManager.get - ("RootPane.defaultButtonWindowKeyBindings"); + Object[] keybindings = (Object[]) UIManager.get( + "RootPane.defaultButtonWindowKeyBindings"); LookAndFeel.loadKeyBindings(im, keybindings); } else diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java index e6a4eaf4fc1..03fb2255e88 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -1,5 +1,5 @@ /* BasicScrollPaneUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,6 +45,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; +import java.awt.event.ActionEvent; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.MouseWheelEvent; @@ -52,20 +53,31 @@ import java.awt.event.MouseWheelListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; +import javax.swing.JSlider; import javax.swing.JViewport; import javax.swing.LookAndFeel; import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneLayout; import javax.swing.Scrollable; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ScrollPaneUI; +/** + * A UI delegate for the {@link JScrollPane} component. + */ public class BasicScrollPaneUI extends ScrollPaneUI implements ScrollPaneConstants { @@ -236,7 +248,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI final Rectangle rect = new Rectangle(); /** - * Scroll with the mouse whell. + * Scroll with the mouse wheel. * * @author Audrius Meskauskas (audriusa@Bioinformatics.org) */ @@ -311,7 +323,11 @@ public class BasicScrollPaneUI extends ScrollPaneUI } /** - * Get the scroll bar value or null if there is no such scroll bar. + * Get the scroll bar value or 0 if there is no such scroll bar. + * + * @param bar the scroll bar (<code>null</code> permitted). + * + * @return The scroll bar value, or 0. */ final int getValue(JScrollBar bar) { @@ -478,6 +494,197 @@ public class BasicScrollPaneUI extends ScrollPaneUI v.getComponent(i).addMouseWheelListener(mouseWheelListener); } + InputMap getInputMap(int condition) + { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + return (InputMap) UIManager.get("ScrollPane.ancestorInputMap"); + return null; + } + + /** + * Returns the action map for the {@link JScrollPane}. All scroll panes + * share a single action map which is created the first time this method is + * called, then stored in the UIDefaults table for subsequent access. + * + * @return The shared action map. + */ + ActionMap getActionMap() + { + ActionMap map = (ActionMap) UIManager.get("ScrollPane.actionMap"); + + if (map == null) // first time here + { + map = createActionMap(); + if (map != null) + UIManager.put("Slider.actionMap", map); + } + return map; + } + + /** + * Creates the action map shared by all {@link JSlider} instances. + * This method is called once by {@link #getActionMap()} when it + * finds no action map in the UIDefaults table...after the map is + * created, it gets added to the defaults table so that subsequent + * calls to {@link #getActionMap()} will return the same shared + * instance. + * + * @return The action map. + */ + ActionMap createActionMap() + { + ActionMap map = new ActionMapUIResource(); + map.put("scrollLeft", + new AbstractAction("scrollLeft") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollEnd", + new AbstractAction("scrollEnd") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb1 = sp.getHorizontalScrollBar(); + if (sb1.isVisible()) + { + sb1.setValue(sb1.getMaximum()); + } + JScrollBar sb2 = sp.getVerticalScrollBar(); + if (sb2.isVisible()) + { + sb2.setValue(sb2.getMaximum()); + } + } + } + ); + map.put("unitScrollUp", + new AbstractAction("unitScrollUp") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollLeft", + new AbstractAction("unitScrollLeft") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollUp", + new AbstractAction("scrollUp") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollRight", + new AbstractAction("scrollRight") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollHome", + new AbstractAction("scrollHome") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb1 = sp.getHorizontalScrollBar(); + if (sb1.isVisible()) + { + sb1.setValue(sb1.getMinimum()); + } + JScrollBar sb2 = sp.getVerticalScrollBar(); + if (sb2.isVisible()) + { + sb2.setValue(sb2.getMinimum()); + } + } + } + ); + map.put("scrollDown", + new AbstractAction("scrollDown") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollDown", + new AbstractAction("unitScrollDown") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollRight", + new AbstractAction("unitScrollRight") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + return map; + } + /** * Installs additional keyboard actions on the scrollpane. This is a hook * method provided to subclasses in order to install their own keyboard @@ -486,13 +693,30 @@ public class BasicScrollPaneUI extends ScrollPaneUI * @param sp the scrollpane to install keyboard actions on */ protected void installKeyboardActions(JScrollPane sp) - throws NotImplementedException { - // TODO: Is this only a hook method or should we actually do something - // here? If the latter, than figure out what and implement this. + InputMap keyMap = getInputMap( + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + SwingUtilities.replaceUIInputMap(sp, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap); + ActionMap map = getActionMap(); + SwingUtilities.replaceUIActionMap(sp, map); } /** + * Uninstalls all keyboard actions from the JScrollPane that have been + * installed by {@link #installKeyboardActions}. This is a hook method + * provided to subclasses to add their own keyboard actions. + * + * @param sp the scrollpane to uninstall keyboard actions from + */ + protected void uninstallKeyboardActions(JScrollPane sp) + { + SwingUtilities.replaceUIActionMap(sp, null); + SwingUtilities.replaceUIInputMap(sp, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + } + + /** * Creates and returns the change listener for the horizontal scrollbar. * * @return the change listener for the horizontal scrollbar @@ -536,6 +760,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI * Creates and returns the mouse wheel listener for the scrollpane. * * @return the mouse wheel listener for the scrollpane + * + * @since 1.4 */ protected MouseWheelListener createMouseWheelListener() { @@ -545,7 +771,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI public void uninstallUI(final JComponent c) { super.uninstallUI(c); - this.uninstallDefaults((JScrollPane)c); + this.uninstallDefaults((JScrollPane) c); uninstallListeners((JScrollPane) c); installKeyboardActions((JScrollPane) c); } @@ -574,23 +800,9 @@ public class BasicScrollPaneUI extends ScrollPaneUI } - /** - * Uninstalls all keyboard actions from the JScrollPane that have been - * installed by {@link #installKeyboardActions}. This is a hook method - * provided to subclasses to add their own keyboard actions. - * - * @param sp the scrollpane to uninstall keyboard actions from - */ - protected void uninstallKeyboardActions(JScrollPane sp) - throws NotImplementedException - { - // TODO: Is this only a hook method or should we actually do something - // here? If the latter, than figure out what and implement this. - } - public Dimension getMinimumSize(JComponent c) { - JScrollPane p = (JScrollPane ) c; + JScrollPane p = (JScrollPane) c; ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout(); return sl.minimumLayoutSize(c); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java index 137ab55a607..0569768a627 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Component; import java.awt.ComponentOrientation; @@ -70,6 +68,7 @@ import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JSlider; import javax.swing.LookAndFeel; +import javax.swing.RepaintManager; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.UIManager; @@ -209,9 +208,9 @@ public class BasicSliderUI extends SliderUI * @param e A {@link FocusEvent}. */ public void focusGained(FocusEvent e) - throws NotImplementedException { - // FIXME: implement. + slider.repaint(); + hasFocus = true; } /** @@ -221,9 +220,9 @@ public class BasicSliderUI extends SliderUI * @param e A {@link FocusEvent}. */ public void focusLost(FocusEvent e) - throws NotImplementedException { - // FIXME: implement. + slider.repaint(); + hasFocus = false; } } @@ -592,6 +591,9 @@ public class BasicSliderUI extends SliderUI /** The focus color. */ private transient Color focusColor; + + /** True if the slider has focus. */ + private transient boolean hasFocus; /** * Creates a new Basic look and feel Slider UI. @@ -1548,9 +1550,11 @@ public class BasicSliderUI extends SliderUI paintTicks(g); if (slider.getPaintLabels()) paintLabels(g); - - //FIXME: Paint focus. + paintThumb(g); + + if (hasFocus) + paintFocus(g); } /** @@ -1602,7 +1606,7 @@ public class BasicSliderUI extends SliderUI Color saved_color = g.getColor(); g.setColor(getFocusColor()); - + g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height); g.setColor(saved_color); @@ -1989,7 +1993,7 @@ public class BasicSliderUI extends SliderUI public void paintThumb(Graphics g) { Color saved_color = g.getColor(); - + Point a = new Point(thumbRect.x, thumbRect.y); Point b = new Point(a); Point c = new Point(a); @@ -1997,11 +2001,11 @@ public class BasicSliderUI extends SliderUI Point e = new Point(a); Polygon bright; - Polygon light; // light shadow - Polygon dark; // dark shadow + Polygon light; // light shadow + Polygon dark; // dark shadow Polygon all; - // This will be in X-dimension if the slider is inverted and y if it isn't. + // This will be in X-dimension if the slider is inverted and y if it isn't. int turnPoint; if (slider.getOrientation() == JSlider.HORIZONTAL) @@ -2016,13 +2020,15 @@ public class BasicSliderUI extends SliderUI bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x }, new int[] { b.y, a.y, e.y, d.y }, 4); - dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, - new int[] { b.y, c.y - 1, d.y }, 3); - - light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 }, - new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3); - - all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 }, + dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, new int[] { b.y, + c.y - 1, + d.y }, 3); + + light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 }, + new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3); + + all = new Polygon( + new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 }, new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y }, 5); } @@ -2038,15 +2044,16 @@ public class BasicSliderUI extends SliderUI bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x }, new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4); - dark = new Polygon(new int[] { c.x, d.x, e.x }, - new int[] { c.y, d.y, e.y }, 3); + dark = new Polygon(new int[] { c.x, d.x, e.x }, new int[] { c.y, d.y, + e.y }, 3); - light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1}, - new int[] { c.y, d.y - 1, e.y - 1}, 3); - all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, - e.x + 1 }, - new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2, - e.y - 2 }, 6); + light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1 }, + new int[] { c.y, d.y - 1, e.y - 1 }, 3); + all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, + e.x + 1 }, new int[] { a.y + 1, b.y + 1, + c.y - 1, c.y, + d.y - 2, e.y - 2 }, + 6); } g.setColor(Color.WHITE); @@ -2057,7 +2064,7 @@ public class BasicSliderUI extends SliderUI g.setColor(Color.GRAY); g.drawPolyline(light.xpoints, light.ypoints, light.npoints); - + g.setColor(Color.LIGHT_GRAY); g.drawPolyline(all.xpoints, all.ypoints, all.npoints); g.fillPolygon(all); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java index 465374bfda9..254a9a4fa2b 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java @@ -220,7 +220,7 @@ public class BasicSpinnerUI extends SpinnerUI BasicSpinnerUI.this.spinner.getModel().setValue(next); } - volatile boolean mouseDown = false; + volatile boolean mouseDown; Timer timer = new Timer(50, new ActionListener() { @@ -260,7 +260,7 @@ public class BasicSpinnerUI extends SpinnerUI BasicSpinnerUI.this.spinner.getModel().setValue(prev); } - volatile boolean mouseDown = false; + volatile boolean mouseDown; Timer timer = new Timer(50, new ActionListener() { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java index 694baaddade..2d595597424 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* BasicSplitPaneUI.java -- - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Canvas; import java.awt.Color; import java.awt.Component; @@ -57,11 +55,17 @@ import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; +import javax.swing.ActionMap; +import javax.swing.InputMap; import javax.swing.JComponent; +import javax.swing.JSlider; import javax.swing.JSplitPane; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.UIResource; @@ -676,7 +680,9 @@ public class BasicSplitPaneUI extends SplitPaneUI */ public void focusGained(FocusEvent ev) { - // FIXME: implement. + // repaint the divider because its background color may change due to + // the focus state... + divider.repaint(); } /** @@ -686,7 +692,9 @@ public class BasicSplitPaneUI extends SplitPaneUI */ public void focusLost(FocusEvent ev) { - // FIXME: implement. + // repaint the divider because its background color may change due to + // the focus state... + divider.repaint(); } } @@ -1046,21 +1054,143 @@ public class BasicSplitPaneUI extends SplitPaneUI } /** - * This method installs the keyboard actions for the JSplitPane. + * Returns the input map for the specified condition. + * + * @param condition the condition. + * + * @return The input map. + */ + InputMap getInputMap(int condition) + { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + return (InputMap) UIManager.get("SplitPane.ancestorInputMap"); + return null; + } + + /** + * Returns the action map for the {@link JSplitPane}. All sliders share + * a single action map which is created the first time this method is + * called, then stored in the UIDefaults table for subsequent access. + * + * @return The shared action map. + */ + ActionMap getActionMap() + { + ActionMap map = (ActionMap) UIManager.get("SplitPane.actionMap"); + + if (map == null) // first time here + { + map = createActionMap(); + if (map != null) + UIManager.put("SplitPane.actionMap", map); + } + return map; + } + + /** + * Creates the action map shared by all {@link JSlider} instances. + * This method is called once by {@link #getActionMap()} when it + * finds no action map in the UIDefaults table...after the map is + * created, it gets added to the defaults table so that subsequent + * calls to {@link #getActionMap()} will return the same shared + * instance. + * + * @return The action map. + */ + ActionMap createActionMap() + { + ActionMap map = new ActionMapUIResource(); + map.put("toggleFocus", + new AbstractAction("toggleFocus") { + public void actionPerformed(ActionEvent event) + { + // FIXME: What to do here? + } + } + ); + map.put("startResize", + new AbstractAction("startResize") { + public void actionPerformed(ActionEvent event) + { + splitPane.requestFocus(); + } + } + ); + map.put("selectMax", + new AbstractAction("selectMax") { + public void actionPerformed(ActionEvent event) + { + splitPane.setDividerLocation(1.0); + } + } + ); + map.put("selectMin", + new AbstractAction("selectMin") { + public void actionPerformed(ActionEvent event) + { + splitPane.setDividerLocation(0.0); + } + } + ); + map.put("negativeIncrement", + new AbstractAction("negativeIncrement") { + public void actionPerformed(ActionEvent event) + { + setDividerLocation(splitPane, Math.max(dividerLocation + - KEYBOARD_DIVIDER_MOVE_OFFSET, 0)); + } + } + ); + map.put("positiveIncrement", + new AbstractAction("positiveIncrement") { + public void actionPerformed(ActionEvent event) + { + setDividerLocation(splitPane, dividerLocation + + KEYBOARD_DIVIDER_MOVE_OFFSET); + } + } + ); + map.put("focusOutBackward", + new AbstractAction("focusOutBackward") { + public void actionPerformed(ActionEvent event) + { + // FIXME: implement this + } + } + ); + map.put("focusOutForward", + new AbstractAction("focusOutForward") { + public void actionPerformed(ActionEvent event) + { + // FIXME: implement this + } + } + ); + return map; + } + + /** + * 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() - throws NotImplementedException { - // FIXME: implement. + InputMap keyMap = getInputMap( + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + SwingUtilities.replaceUIInputMap(splitPane, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap); + ActionMap map = getActionMap(); + SwingUtilities.replaceUIActionMap(splitPane, map); } /** * This method reverses the work done in installKeyboardActions. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: implement. + SwingUtilities.replaceUIActionMap(splitPane, null); + SwingUtilities.replaceUIInputMap(splitPane, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 6d9bed331cb..1b5249770ec 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -286,7 +286,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants width = Math.max(min, width); int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width - tabAreaInsets.left - -tabAreaInsets.right); + - tabAreaInsets.right); height += tabAreaHeight; } else @@ -476,7 +476,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants else nextIndex = i + 1; int next = tabRuns[nextIndex]; - int end = (next != 0 ? next - 1 : tabCount - 1); + int end = next != 0 ? next - 1 : tabCount - 1; if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -491,9 +491,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants padTabRun(tabPlacement, start, end, breakAt); } if (tabPlacement == BOTTOM) - y -= (maxTabHeight - tabRunOverlay); + y -= maxTabHeight - tabRunOverlay; else - y += (maxTabHeight - tabRunOverlay); + y += maxTabHeight - tabRunOverlay; } else { @@ -508,9 +508,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants padTabRun(tabPlacement, start, end, breakAt); } if (tabPlacement == RIGHT) - x -= (maxTabWidth - tabRunOverlay); + x -= maxTabWidth - tabRunOverlay; else - x += (maxTabWidth - tabRunOverlay); + x += maxTabWidth - tabRunOverlay; } } @@ -1818,7 +1818,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants next = tabRuns[0]; else next = tabRuns[i + 1]; - int end = (next != 0 ? next - 1 : tabCount - 1); + int end = next != 0 ? next - 1 : tabCount - 1; for (int j = start; j <= end; ++j) { if (j != selectedIndex) @@ -2194,7 +2194,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { case LEFT: x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); - w -= (x - insets.left); + w -= x - insets.left; break; case RIGHT: w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); @@ -2205,7 +2205,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants case TOP: default: y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); - h -= (y - insets.top); + h -= y - insets.top; } // Fill background if necessary. @@ -2410,6 +2410,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ public Rectangle getTabBounds(JTabbedPane pane, int i) { + // Need to re-layout container if tab does not exist. + if (i >= rects.length) + layoutManager.layoutContainer(pane); return rects[i]; } @@ -3015,7 +3018,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { int currRun = getRunForTab(tabCount, tabIndex); int offset; - int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun); + int nextRun = forward ? getNextTabRun(currRun) : getPreviousTabRun(currRun); if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) offset = rects[lastTabInRun(tabCount, nextRun)].y diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java index cfbebda2149..ce8846ff8af 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java @@ -199,10 +199,7 @@ public class BasicTableHeaderUI extends TableHeaderUI */ public void mouseExited(MouseEvent e) { - if (header.getResizingColumn() != null && header.getResizingAllowed()) - endResizing(); - if (header.getDraggedColumn() != null && header.getReorderingAllowed()) - endDragging(null); + // Nothing to do. } /** @@ -363,25 +360,20 @@ public class BasicTableHeaderUI extends TableHeaderUI void endDragging(MouseEvent e) { header.setDraggedColumn(null); - - // Return if the mouse have left the header area while pressed. - if (e == null) - { - header.repaint(draggingHeaderRect); - draggingHeaderRect = null; - return; - } - else - draggingHeaderRect = null; + draggingHeaderRect = null; TableColumnModel model = header.getColumnModel(); // Find where have we dragged the column. int x = e.getX(); int p = 0; - int col = - 1; + + int col = model.getColumnCount()-1; int n = model.getColumnCount(); + // This loop does not find the column if the mouse if out of the + // right boundary of the table header. Then we make this column the + // rightmost column. Scan: for (int i = 0; i < n; i++) { p += model.getColumn(i).getWidth(); @@ -391,8 +383,8 @@ public class BasicTableHeaderUI extends TableHeaderUI break Scan; } } - if (col >= 0) - header.getTable().moveColumn(draggingColumnNumber, col); + + header.getTable().moveColumn(draggingColumnNumber, col); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java index ef491cbf1c6..d3abba217cd 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java @@ -78,6 +78,7 @@ import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TableUI; 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; @@ -228,8 +229,6 @@ public class BasicTableUI extends TableUI if (e.getClickCount() < ce.getClickCountToStart()) return; } - else if (e.getClickCount() < 2) - return; table.editCellAt(row, col); } } @@ -387,10 +386,8 @@ public class BasicTableUI extends TableUI int maxTotalColumnWidth = 0; for (int i = 0; i < table.getColumnCount(); i++) maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth(); - if (maxTotalColumnWidth == 0 || table.getRowCount() == 0) - return null; - return new Dimension(maxTotalColumnWidth, table.getRowCount()* - (table.getRowHeight()+table.getRowMargin())); + + return new Dimension(maxTotalColumnWidth, getHeight()); } /** @@ -408,16 +405,45 @@ public class BasicTableUI extends TableUI int minTotalColumnWidth = 0; for (int i = 0; i < table.getColumnCount(); i++) minTotalColumnWidth += table.getColumnModel().getColumn(i).getMinWidth(); - if (minTotalColumnWidth == 0 || table.getRowCount() == 0) - return null; - return new Dimension(minTotalColumnWidth, table.getRowCount()*table.getRowHeight()); + + return new Dimension(minTotalColumnWidth, getHeight()); } + /** + * Returns the preferred size for the table of that UI. + * + * @param comp ignored, the <code>table</code> field is used instead + * + * @return the preferred size for the table of that UI + */ public Dimension getPreferredSize(JComponent comp) { - int width = table.getColumnModel().getTotalColumnWidth(); - int height = table.getRowCount() * (table.getRowHeight()+table.getRowMargin()); - return new Dimension(width, height); + int prefTotalColumnWidth = 0; + for (int i = 0; i < table.getColumnCount(); i++) + { + TableColumn col = table.getColumnModel().getColumn(i); + prefTotalColumnWidth += col.getPreferredWidth(); + } + return new Dimension(prefTotalColumnWidth, getHeight()); + } + + /** + * Returns the table height. This helper method is used by + * {@link #getMinimumSize(JComponent)}, {@link #getPreferredSize(JComponent)} + * and {@link #getMaximumSize(JComponent)} to determine the table height. + * + * @return the table height + */ + private int getHeight() + { + int height = 0; + int rowCount = table.getRowCount(); + if (rowCount > 0 && table.getColumnCount() > 0) + { + Rectangle r = table.getCellRect(rowCount - 1, 0, true); + height = r.y + r.height; + } + return height; } protected void installDefaults() @@ -428,7 +454,6 @@ public class BasicTableUI extends TableUI table.setSelectionForeground(UIManager.getColor("Table.selectionForeground")); table.setSelectionBackground(UIManager.getColor("Table.selectionBackground")); table.setOpaque(true); - rendererPane = new CellRendererPane(); } protected void installKeyboardActions() @@ -1188,6 +1213,9 @@ public class BasicTableUI extends TableUI public void installUI(JComponent comp) { table = (JTable)comp; + rendererPane = new CellRendererPane(); + table.add(rendererPane); + installDefaults(); installKeyboardActions(); installListeners(); @@ -1197,7 +1225,11 @@ public class BasicTableUI extends TableUI { uninstallListeners(); uninstallKeyboardActions(); - uninstallDefaults(); + uninstallDefaults(); + + table.remove(rendererPane); + rendererPane = null; + table = null; } /** @@ -1257,7 +1289,6 @@ public class BasicTableUI extends TableUI } Rectangle bounds = table.getCellRect(r0, c0, false); - // The left boundary of the area being repainted. int left = bounds.x; @@ -1278,9 +1309,9 @@ public class BasicTableUI extends TableUI bounds.x += widths[c] + columnMargin; } bounds.x = left; - bounds.y += table.getRowHeight(r) + rowMargin; + bounds.y += table.getRowHeight(r); // Update row height for tables with custom heights. - bounds.height = table.getRowHeight(r + 1); + bounds.height = table.getRowHeight(r + 1) - rowMargin; } bottom = bounds.y - rowMargin; @@ -1311,7 +1342,7 @@ public class BasicTableUI extends TableUI { // The horizontal grid is draw below the cells, so we // add before drawing. - y += table.getRowHeight(r) + rowMargin; + y += table.getRowHeight(r); gfx.drawLine(left, y, p2.x, y); } gfx.setColor(save); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java index 93e119b31fa..3f5aa27cf40 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java @@ -73,7 +73,7 @@ public class BasicTextAreaUI extends BasicTextUI */ public View create(Element elem) { - JTextArea comp = (JTextArea)getComponent(); + JTextArea comp = (JTextArea) getComponent(); if (comp.getLineWrap()) { if (comp.getWrapStyleWord()) @@ -105,7 +105,7 @@ public class BasicTextAreaUI extends BasicTextUI */ protected void propertyChange(PropertyChangeEvent ev) { - JTextArea comp = (JTextArea)getComponent(); + JTextArea comp = (JTextArea) getComponent(); if (ev.getPropertyName() == "lineWrap" || ev.getPropertyName() == "wrapStyleWord") { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java index 3b620f04989..b058175a454 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Container; import java.awt.Dimension; @@ -64,10 +62,12 @@ import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.plaf.ActionMapUIResource; +import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TextUI; import javax.swing.plaf.UIResource; import javax.swing.text.AbstractDocument; @@ -734,18 +734,8 @@ public abstract class BasicTextUI extends TextUI // load any bindings for the newer InputMap / ActionMap interface SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, - getInputMap(JComponent.WHEN_FOCUSED)); - SwingUtilities.replaceUIActionMap(textComponent, createActionMap()); - - ActionMap parentActionMap = new ActionMapUIResource(); - Action[] actions = textComponent.getActions(); - for (int j = 0; j < actions.length; j++) - { - Action currAction = actions[j]; - parentActionMap.put(currAction.getValue(Action.NAME), currAction); - } - - SwingUtilities.replaceUIActionMap(textComponent, parentActionMap); + getInputMap()); + SwingUtilities.replaceUIActionMap(textComponent, getActionMap()); } /** @@ -753,40 +743,71 @@ public abstract class BasicTextUI extends TextUI * * @return an ActionMap to be installed on the text component */ - ActionMap createActionMap() + private ActionMap getActionMap() + { + // Note: There are no .actionMap entries in the standard L&Fs. However, + // with the RI it is possible to install action maps via such keys, so + // we must load them too. It can be observed that when there is no + // .actionMap entry in the UIManager, one gets installed after a text + // component of that type has been loaded. + String prefix = getPropertyPrefix(); + String amName = prefix + ".actionMap"; + ActionMap am = (ActionMap) UIManager.get(amName); + if (am == null) + { + am = createActionMap(); + UIManager.put(amName, am); + } + + ActionMap map = new ActionMapUIResource(); + map.setParent(am); + + return map; + } + + /** + * Creates a default ActionMap for text components that have no UI default + * for this (the standard for the built-in L&Fs). The ActionMap is copied + * from the text component's getActions() method. + * + * @returna default ActionMap + */ + private ActionMap createActionMap() { - Action[] actions = textComponent.getActions(); ActionMap am = new ActionMapUIResource(); - for (int i = 0; i < actions.length; ++i) + Action[] actions = textComponent.getActions(); + for (int i = actions.length - 1; i >= 0; i--) { - String name = (String) actions[i].getValue(Action.NAME); - if (name != null) - am.put(name, actions[i]); + Action action = actions[i]; + am.put(action.getValue(Action.NAME), action); } + // Add TransferHandler's actions here. They don't seem to be in the + // JTextComponent's default actions, and I can't make up a better place + // to add them. + Action copyAction = TransferHandler.getCopyAction(); + am.put(copyAction.getValue(Action.NAME), copyAction); + Action cutAction = TransferHandler.getCutAction(); + am.put(cutAction.getValue(Action.NAME), cutAction); + Action pasteAction = TransferHandler.getPasteAction(); + am.put(pasteAction.getValue(Action.NAME), pasteAction); + return am; } /** * Gets the input map for the specified <code>condition</code>. * - * @param condition the condition for the InputMap - * * @return the InputMap for the specified condition */ - InputMap getInputMap(int condition) + private InputMap getInputMap() { + InputMap im = new InputMapUIResource(); String prefix = getPropertyPrefix(); - switch (condition) - { - case JComponent.WHEN_IN_FOCUSED_WINDOW: - // FIXME: is this the right string? nobody seems to use it. - return (InputMap) UIManager.get(prefix + ".windowInputMap"); - case JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: - return (InputMap) UIManager.get(prefix + ".ancestorInputMap"); - default: - case JComponent.WHEN_FOCUSED: - return (InputMap) UIManager.get(prefix + ".focusInputMap"); - } + InputMap shared = + (InputMap) SharedUIDefaults.get(prefix + ".focusInputMap"); + if (shared != null) + im.setParent(shared); + return im; } /** @@ -831,9 +852,9 @@ public abstract class BasicTextUI extends TextUI * this UI. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Uninstall keyboard actions here. + SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, null); + SwingUtilities.replaceUIActionMap(textComponent, null); } /** @@ -1041,7 +1062,12 @@ public abstract class BasicTextUI extends TextUI Rectangle l1 = modelToView(t, p0, firstBias); Rectangle l2 = modelToView(t, p1, secondBias); - if (l1.y == l2.y) + if (l1 == null || l2 == null) + { + // Unable to determine the start or end of the selection. + t.repaint(); + } + else if (l1.y == l2.y) { SwingUtilities.computeUnion(l2.x, l2.y, l2.width, l2.height, l1); t.repaint(l1); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java index 896ea0c89dc..921648670df 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java @@ -1,5 +1,5 @@ /* BasicToggleButtonUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,21 +44,35 @@ import java.awt.Rectangle; import javax.swing.AbstractButton; import javax.swing.JComponent; +import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * A UI delegate for the {@link JToggleButton} component. + */ public class BasicToggleButtonUI extends BasicButtonUI { - public static ComponentUI createUI(final JComponent component) + + /** + * Returns a UI delegate for the specified component. + * + * @param component the component (should be an instance of + * {@link JToggleButton}). + * + * @return An instance of <code>BasicToggleButtonUI</code>. + */ + public static ComponentUI createUI(JComponent component) { return new BasicToggleButtonUI(); } /** - * Returns the prefix for the UI defaults property for this UI class. - * This is 'ToggleButton' for this class. + * Returns the prefix for entries in the {@link UIManager} defaults table + * (<code>"ToggleButton."</code> in this case). * - * @return the prefix for the UI defaults property + * @return <code>"ToggleButton."</code> */ protected String getPropertyPrefix() { @@ -89,15 +103,10 @@ public class BasicToggleButtonUI extends BasicButtonUI else vr = SwingUtilities.getLocalBounds(b); 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); + b.getText(), currentIcon(b), b.getVerticalAlignment(), + b.getHorizontalAlignment(), b.getVerticalTextPosition(), + b.getHorizontalTextPosition(), vr, ir, tr, b.getIconTextGap() + + defaultTextShiftOffset); if ((b.getModel().isArmed() && b.getModel().isPressed()) || b.isSelected()) diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java index 80fec6a775a..eabac157036 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java @@ -1,5 +1,5 @@ /* BasicToolBarUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -75,11 +75,12 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; -import javax.swing.border.EtchedBorder; +import javax.swing.border.CompoundBorder; import javax.swing.event.MouseInputListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ToolBarUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicBorders.ButtonBorder; /** * This is the Basic Look and Feel UI class for JToolBar. @@ -310,8 +311,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected Border createNonRolloverBorder() { - return new EtchedBorder(); - } + Border b = UIManager.getBorder("ToolBar.nonrolloverBorder"); + + if (b == null) + { + b = new CompoundBorder( + new ButtonBorder(UIManager.getColor("Button.shadow"), + UIManager.getColor("Button.darkShadow"), + UIManager.getColor("Button.light"), + UIManager.getColor("Button.highlight")), + BasicBorders.getMarginBorder()); + } + + return b; } /** * This method creates a new PropertyChangeListener for the JToolBar. @@ -331,18 +343,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected Border createRolloverBorder() { - return new EtchedBorder() + Border b = UIManager.getBorder("ToolBar.rolloverBorder"); + + if (b == null) { - 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); - } - } - }; + b = new CompoundBorder( + new ButtonBorder(UIManager.getColor("Button.shadow"), + UIManager.getColor("Button.darkShadow"), + UIManager.getColor("Button.light"), + UIManager.getColor("Button.highlight")), + BasicBorders.getMarginBorder()); + } + + return b; } /** @@ -745,6 +758,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants * @param direction The direction to give focus to. */ protected void navigateFocusedComp(int direction) + throws NotImplementedException { // FIXME: Implement. } @@ -761,6 +775,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants { AbstractButton b = (AbstractButton) c; b.setRolloverEnabled(false); + + // Save old border in hashtable. + borders.put(b, b.getBorder()); + b.setBorder(nonRolloverBorder); } } @@ -772,11 +790,11 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected void setBorderToNormal(Component c) { - if (c instanceof JButton) + if (c instanceof AbstractButton) { - JButton b = (JButton) c; - Border border = (Border) borders.get(b); - b.setBorder(border); + AbstractButton b = (AbstractButton) c; + b.setRolloverEnabled(true); + b.setBorder((Border) borders.remove(b)); } } @@ -787,11 +805,15 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected void setBorderToRollover(Component c) { - if (c instanceof JButton) + if (c instanceof AbstractButton) { - JButton b = (JButton) c; - b.setRolloverEnabled(true); - b.setBorder(rolloverBorder); + AbstractButton b = (AbstractButton) c; + b.setRolloverEnabled(false); + + // Save old border in hashtable. + borders.put(b, b.getBorder()); + + b.setBorder(rolloverBorder); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java index be61ccaec22..8cbea7f592d 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java @@ -38,6 +38,7 @@ package javax.swing.plaf.basic; +import gnu.classpath.NotImplementedException; import gnu.javax.swing.tree.GnuPath; import java.awt.Color; @@ -48,7 +49,6 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; import java.awt.Label; -import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -80,7 +80,6 @@ import javax.swing.JComponent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTree; -import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -96,7 +95,6 @@ import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TreeUI; import javax.swing.tree.AbstractLayoutCache; import javax.swing.tree.DefaultTreeCellEditor; @@ -251,6 +249,9 @@ public class BasicTreeUI /** The max height of the nodes in the tree. */ int maxHeight = 0; + + /** The hash color. */ + Color hashColor; /** Listeners */ PropertyChangeListener propertyChangeListener; @@ -279,6 +280,11 @@ public class BasicTreeUI * not the double mouse click) on the selected tree node. */ Timer startEditTimer; + + /** + * The zero size icon, used for expand controls, if they are not visible. + */ + static Icon nullIcon; /** * The special value of the mouse event is sent indicating that this is not @@ -298,17 +304,6 @@ public class BasicTreeUI nodeDimensions = createNodeDimensions(); configureLayoutCache(); - propertyChangeListener = createPropertyChangeListener(); - focusListener = createFocusListener(); - treeSelectionListener = createTreeSelectionListener(); - mouseListener = createMouseListener(); - keyListener = createKeyListener(); - selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener(); - componentListener = createComponentListener(); - cellEditorListener = createCellEditorListener(); - treeExpansionListener = createTreeExpansionListener(); - treeModelListener = createTreeModelListener(); - editingRow = - 1; lastSelectedRow = - 1; } @@ -331,7 +326,7 @@ public class BasicTreeUI */ protected Color getHashColor() { - return UIManager.getColor("Tree.hash"); + return hashColor; } /** @@ -341,8 +336,7 @@ public class BasicTreeUI */ protected void setHashColor(Color color) { - // FIXME: Putting something in the UIDefaults map is certainly wrong. - UIManager.put("Tree.hash", color); + hashColor = color; } /** @@ -505,9 +499,22 @@ public class BasicTreeUI */ protected void setModel(TreeModel model) { - tree.setModel(model); + completeEditing(); + + if (treeModel != null && treeModelListener != null) + treeModel.removeTreeModelListener(treeModelListener); + treeModel = tree.getModel(); - treeState.setModel(treeModel); + + if (treeModel != null && treeModelListener != null) + treeModel.addTreeModelListener(treeModelListener); + + if (treeState != null) + { + treeState.setModel(treeModel); + updateLayoutCacheExpandedNodes(); + updateSize(); + } } /** @@ -547,7 +554,13 @@ public class BasicTreeUI */ protected void setShowsRootHandles(boolean newValue) { - tree.setShowsRootHandles(newValue); + completeEditing(); + updateDepthOffset(); + if (treeState != null) + { + treeState.invalidateSizes(); + updateSize(); + } } /** @@ -673,6 +686,20 @@ public class BasicTreeUI treeState.setRowHeight(maxHeight); return maxHeight; } + + /** + * Get the tree node icon. + */ + Icon getNodeIcon(TreePath path) + { + Object node = path.getLastPathComponent(); + if (treeModel.isLeaf(node)) + return UIManager.getIcon("Tree.leafIcon"); + else if (treeState.getExpandedState(path)) + return UIManager.getIcon("Tree.openIcon"); + else + return UIManager.getIcon("Tree.closedIcon"); + } /** * Returns the path for passed in row. If row is not visible null is returned. @@ -801,7 +828,11 @@ public class BasicTreeUI */ protected void prepareForUIInstall() { - // TODO: Implement this properly. + lastSelectedRow = -1; + preferredSize = new Dimension(); + largeModel = tree.isLargeModel(); + preferredSize = new Dimension(); + setModel(tree.getModel()); } /** @@ -810,7 +841,14 @@ public class BasicTreeUI */ protected void completeUIInstall() { - // TODO: Implement this properly. + setShowsRootHandles(tree.getShowsRootHandles()); + updateRenderer(); + updateDepthOffset(); + setSelectionModel(tree.getSelectionModel()); + treeState = createLayoutCache(); + treeSelectionModel.setRowMapper(treeState); + configureLayoutCache(); + updateSize(); } /** @@ -819,7 +857,7 @@ public class BasicTreeUI */ protected void completeUIUninstall() { - // TODO: Implement this properly. + tree = null; } /** @@ -972,15 +1010,14 @@ public class BasicTreeUI */ protected TreeCellEditor createDefaultCellEditor() { - if (currentCellRenderer != null) - return new DefaultTreeCellEditor( - tree, - (DefaultTreeCellRenderer) currentCellRenderer, - cellEditor); - return new DefaultTreeCellEditor( - tree, - (DefaultTreeCellRenderer) createDefaultCellRenderer(), - cellEditor); + DefaultTreeCellEditor ed; + if (currentCellRenderer != null + && currentCellRenderer instanceof DefaultTreeCellRenderer) + ed = new DefaultTreeCellEditor(tree, + (DefaultTreeCellRenderer) currentCellRenderer); + else + ed = new DefaultTreeCellEditor(tree, null); + return ed; } /** @@ -1077,7 +1114,7 @@ public class BasicTreeUI */ protected void updateLayoutCacheExpandedNodes() { - if (treeModel != null) + if (treeModel != null && treeModel.getRoot() != null) updateExpandedDescendants(new TreePath(treeModel.getRoot())); } @@ -1132,14 +1169,12 @@ public class BasicTreeUI protected void updateRenderer() { if (tree != null) - { - if (tree.getCellRenderer() == null) - { - if (currentCellRenderer == null) - currentCellRenderer = createDefaultCellRenderer(); - tree.setCellRenderer(currentCellRenderer); - } - } + currentCellRenderer = tree.getCellRenderer(); + + if (currentCellRenderer == null) + currentCellRenderer = createDefaultCellRenderer(); + + updateCellEditor(); } /** @@ -1206,6 +1241,7 @@ public class BasicTreeUI rightChildIndent = UIManager.getInt("Tree.rightChildIndent"); leftChildIndent = UIManager.getInt("Tree.leftChildIndent"); + totalChildIndent = rightChildIndent + leftChildIndent; setRowHeight(UIManager.getInt("Tree.rowHeight")); tree.setRowHeight(getRowHeight()); tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand")); @@ -1218,40 +1254,103 @@ public class BasicTreeUI */ protected void installKeyboardActions() { - InputMap focusInputMap = (InputMap) UIManager.get("Tree.focusInputMap"); - InputMapUIResource parentInputMap = new InputMapUIResource(); - ActionMap parentActionMap = new ActionMapUIResource(); + InputMap focusInputMap = + (InputMap) SharedUIDefaults.get("Tree.focusInputMap"); + SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED, + focusInputMap); + InputMap ancestorInputMap = + (InputMap) SharedUIDefaults.get("Tree.ancestorInputMap"); + SwingUtilities.replaceUIInputMap(tree, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, + ancestorInputMap); + action = new TreeAction(); - Object keys[] = focusInputMap.allKeys(); - for (int i = 0; i < keys.length; i++) - { - parentInputMap.put( - KeyStroke.getKeyStroke( - ((KeyStroke) keys[i]).getKeyCode(), - convertModifiers(((KeyStroke) keys[i]).getModifiers())), - (String) focusInputMap.get((KeyStroke) keys[i])); - - parentInputMap.put( - KeyStroke.getKeyStroke( - ((KeyStroke) keys[i]).getKeyCode(), - ((KeyStroke) keys[i]).getModifiers()), - (String) focusInputMap.get((KeyStroke) keys[i])); - - parentActionMap.put( - (String) focusInputMap.get((KeyStroke) keys[i]), - new ActionListenerProxy( - action, - (String) focusInputMap.get((KeyStroke) keys[i]))); + SwingUtilities.replaceUIActionMap(tree, getActionMap()); + } + /** + * Creates and returns the shared action map for JTrees. + * + * @return the shared action map for JTrees + */ + private ActionMap getActionMap() + { + ActionMap am = (ActionMap) UIManager.get("Tree.actionMap"); + if (am == null) + { + am = createDefaultActions(); + UIManager.getLookAndFeelDefaults().put("Tree.actionMap", am); } + return am; + } + + /** + * Creates the default actions when there are none specified by the L&F. + * + * @return the default actions + */ + private ActionMap createDefaultActions() + { + ActionMapUIResource am = new ActionMapUIResource(); + Action action; + + action= new TreeAction(); + am.put(action.getValue(Action.NAME), action); + + // TreeHomeAction. + action= new TreeHomeAction(-1, "selectFirst"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(-1, "selectFirstChangeLead"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(-1, "selectFirstExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLast"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLastChangeLead"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLastExtendSelection"); + am.put(action.getValue(Action.NAME), action); + + // TreeIncrementAction. + action = new TreeIncrementAction(-1, "selectPrevious"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(-1, "selectPreviousExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(-1, "selectPreviousChangeLead"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNext"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNextExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNextChangeLead"); + am.put(action.getValue(Action.NAME), action); + + // TreeTraverseAction. + action = new TreeTraverseAction(-1, "selectParent"); + am.put(action.getValue(Action.NAME), action); + action = new TreeTraverseAction(1, "selectChild"); + am.put(action.getValue(Action.NAME), action); + + // TreeToggleAction. + action = new TreeToggleAction("toggleAndAnchor"); + am.put(action.getValue(Action.NAME), action); - parentInputMap.setParent(tree.getInputMap( - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent()); - parentActionMap.setParent(tree.getActionMap().getParent()); - tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent( - parentInputMap); - tree.getActionMap().setParent(parentActionMap); + // TreePageAction. + action = new TreePageAction(-1, "scrollUpChangeSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(-1, "scrollUpExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(-1, "scrollUpChangeLead"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownChangeSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownChangeLead"); + am.put(action.getValue(Action.NAME), action); + + return am; } /** @@ -1295,16 +1394,41 @@ public class BasicTreeUI */ protected void installListeners() { + propertyChangeListener = createPropertyChangeListener(); tree.addPropertyChangeListener(propertyChangeListener); + + focusListener = createFocusListener(); tree.addFocusListener(focusListener); + + treeSelectionListener = createTreeSelectionListener(); tree.addTreeSelectionListener(treeSelectionListener); + + mouseListener = createMouseListener(); tree.addMouseListener(mouseListener); + + keyListener = createKeyListener(); tree.addKeyListener(keyListener); - tree.addPropertyChangeListener(selectionModelPropertyChangeListener); + + selectionModelPropertyChangeListener = + createSelectionModelPropertyChangeListener(); + if (treeSelectionModel != null + && selectionModelPropertyChangeListener != null) + { + treeSelectionModel.addPropertyChangeListener + (selectionModelPropertyChangeListener); + } + + componentListener = createComponentListener(); tree.addComponentListener(componentListener); + + treeExpansionListener = createTreeExpansionListener(); tree.addTreeExpansionListener(treeExpansionListener); + + treeModelListener = createTreeModelListener(); if (treeModel != null) treeModel.addTreeModelListener(treeModelListener); + + cellEditorListener = createCellEditorListener(); } /** @@ -1315,27 +1439,15 @@ public class BasicTreeUI public void installUI(JComponent c) { tree = (JTree) c; - treeModel = tree.getModel(); prepareForUIInstall(); - super.installUI(c); installDefaults(); installComponents(); installKeyboardActions(); installListeners(); - - setCellEditor(createDefaultCellEditor()); - createdCellEditor = true; - isEditing = false; - - setModel(tree.getModel()); - treeSelectionModel = tree.getSelectionModel(); - setRootVisible(tree.isRootVisible()); - treeState.setRootVisible(tree.isRootVisible()); - completeUIInstall(); } - + /** * Uninstall the defaults for the tree */ @@ -1353,11 +1465,12 @@ public class BasicTreeUI */ public void uninstallUI(JComponent c) { + completeEditing(); + prepareForUIUninstall(); uninstallDefaults(); uninstallKeyboardActions(); uninstallListeners(); - tree = null; uninstallComponents(); completeUIUninstall(); } @@ -1590,6 +1703,9 @@ public class BasicTreeUI protected void completeEditing(boolean messageStop, boolean messageCancel, boolean messageTree) { + if (! stopEditingInCompleteEditing || editingComponent == null) + return; + if (messageStop) { getCellEditor().stopCellEditing(); @@ -1675,7 +1791,7 @@ public class BasicTreeUI int mouseY) { if (isLocationInExpandControl(path, mouseX, mouseY)) - toggleExpandState(path); + handleExpandControlClick(path, mouseX, mouseY); } /** @@ -1694,16 +1810,17 @@ public class BasicTreeUI int mouseY) { boolean cntlClick = false; - int row = getRowForPath(tree, path); - - if (! isLeaf(row)) + if (! treeModel.isLeaf(path.getLastPathComponent())) { - Rectangle bounds = getPathBounds(tree, path); - - if (hasControlIcons() - && (mouseX < bounds.x) - && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap))) - cntlClick = true; + int width = 8; // Only guessing. + Icon expandedIcon = getExpandedIcon(); + if (expandedIcon != null) + width = expandedIcon.getIconWidth(); + + Insets i = tree.getInsets(); + int left = getRowX(tree.getRowForPath(path), path.getPathCount() - 1) + -getRightChildIndent() - width / 2 + i.left; + cntlClick = mouseX >= left && mouseX <= left + width; } return cntlClick; } @@ -1786,7 +1903,14 @@ public class BasicTreeUI */ protected boolean isToggleEvent(MouseEvent event) { - return true; + boolean toggle = false; + if (SwingUtilities.isLeftMouseButton(event)) + { + int clickCount = tree.getToggleClickCount(); + if (clickCount > 0 && event.getClickCount() == clickCount) + toggle = true; + } + return toggle; } /** @@ -1831,7 +1955,8 @@ public class BasicTreeUI { // This is an ordinary event that just selects the clicked row. tree.setSelectionPath(path); - tree.setAnchorSelectionPath(path); + if (isToggleEvent(event)) + toggleExpandState(path); } } @@ -1969,7 +2094,32 @@ public class BasicTreeUI */ public void componentMoved(ComponentEvent e) { - // TODO: What should be done here, if anything? + if (timer == null) + { + JScrollPane scrollPane = getScrollPane(); + if (scrollPane == null) + updateSize(); + else + { + // Determine the scrollbar that is adjusting, if any, and + // start the timer for that. If no scrollbar is adjusting, + // we simply call updateSize(). + scrollBar = scrollPane.getVerticalScrollBar(); + if (scrollBar == null || !scrollBar.getValueIsAdjusting()) + { + // It's not the vertical scrollbar, try the horizontal one. + scrollBar = scrollPane.getHorizontalScrollBar(); + if (scrollBar != null && scrollBar.getValueIsAdjusting()) + startTimer(); + else + updateSize(); + } + else + { + startTimer(); + } + } + } } /** @@ -1978,7 +2128,12 @@ public class BasicTreeUI */ protected void startTimer() { - // TODO: Implement this properly. + if (timer == null) + { + timer = new Timer(200, this); + timer.setRepeats(true); + } + timer.start(); } /** @@ -1988,7 +2143,13 @@ public class BasicTreeUI */ protected JScrollPane getScrollPane() { - return null; + JScrollPane found = null; + Component p = tree.getParent(); + while (p != null && !(p instanceof JScrollPane)) + p = p.getParent(); + if (p instanceof JScrollPane) + found = (JScrollPane) p; + return found; } /** @@ -1999,7 +2160,14 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent ae) { - // TODO: Implement this properly. + if (scrollBar == null || !scrollBar.getValueIsAdjusting()) + { + if (timer != null) + timer.stop(); + updateSize(); + timer = null; + scrollBar = null; + } } } @@ -2080,7 +2248,7 @@ public class BasicTreeUI { repaintLeadRow(); } - + /** * Repaint the lead row. */ @@ -2122,6 +2290,7 @@ public class BasicTreeUI * @param e the key typed */ public void keyTyped(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2132,6 +2301,7 @@ public class BasicTreeUI * @param e the key pressed */ public void keyPressed(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2142,6 +2312,7 @@ public class BasicTreeUI * @param e the key released */ public void keyReleased(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2170,94 +2341,29 @@ public class BasicTreeUI */ public void mousePressed(MouseEvent e) { - // Any mouse click cancels the previous waiting edit action, initiated - // by the single click on the selected node. - if (startEditTimer != null) - { - startEditTimer.stop(); - startEditTimer = null; - } - - Point click = e.getPoint(); - TreePath path = getClosestPathForLocation(tree, click.x, click.y); - if (path != null) + if (tree != null && tree.isEnabled()) { - Rectangle bounds = getPathBounds(tree, path); - int row = getRowForPath(tree, path); - - // Cancel the editing session if clicked on the different row. - if (tree.isEditing() && row != editingRow) - cancelEditing(tree); - - boolean cntlClick = isLocationInExpandControl(path, click.x, click.y); - - boolean isLeaf = isLeaf(row); - - TreeCellRenderer tcr = getCellRenderer(); - Icon icon; - if (isLeaf) - icon = UIManager.getIcon("Tree.leafIcon"); - else if (tree.isExpanded(path)) - icon = UIManager.getIcon("Tree.openIcon"); - else - icon = UIManager.getIcon("Tree.closedIcon"); - - if (tcr instanceof DefaultTreeCellRenderer) - { - Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon(); - if (tmp != null) - icon = tmp; - } + // Maybe stop editing and return. + if (isEditing(tree) && tree.getInvokesStopCellEditing() + && !stopEditing(tree)) + return; - // add gap*2 for the space before and after the text - if (icon != null) - bounds.width += icon.getIconWidth() + gap * 2; + int x = e.getX(); + int y = e.getY(); + TreePath path = getClosestPathForLocation(tree, x, y); - boolean inBounds = bounds.contains(click.x, click.y); - if ((inBounds || cntlClick) && tree.isVisible(path)) + if (path != null) { - if (inBounds) - { - TreePath currentLead = tree.getLeadSelectionPath(); - if (currentLead != null && currentLead.equals(path) - && e.getClickCount() == 1 && tree.isEditable()) - { - // Schedule the editing session. - final TreePath editPath = path; - - if (startEditTimer != null) - startEditTimer.stop(); - - startEditTimer = new Timer(WAIT_TILL_EDITING, - new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - startEditing(editPath, EDIT); - } - }); - startEditTimer.setRepeats(false); - startEditTimer.start(); - } - else - { - if (e.getClickCount() == 2 && ! isLeaf(row)) - toggleExpandState(path); - else - selectPathForEvent(path, e); - } - } + Rectangle bounds = getPathBounds(tree, path); + if (SwingUtilities.isLeftMouseButton(e)) + checkForClickInExpandControl(path, x, y); - if (cntlClick) + if (x > bounds.x && x <= (bounds.x + bounds.width)) { - handleExpandControlClick(path, click.x, click.y); - if (cellEditor != null) - cellEditor.cancelCellEditing(); - tree.scrollPathToVisible(path); + if (! startEditing(path, e)) + selectPathForEvent(path, e); } - else if (tree.isEditable()) - startEditing(path, e); } } } @@ -2271,6 +2377,7 @@ public class BasicTreeUI * @param e is the mouse event that occured */ public void mouseDragged(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2282,6 +2389,7 @@ public class BasicTreeUI * @param e the mouse event that occured */ public void mouseMoved(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2292,6 +2400,7 @@ public class BasicTreeUI * @param e is the mouse event that occured */ public void mouseReleased(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2332,6 +2441,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseClicked(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2342,6 +2452,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mousePressed(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2352,6 +2463,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseReleased(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2362,6 +2474,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseEntered(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2372,6 +2485,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseExited(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2385,6 +2499,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseDragged(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2396,6 +2511,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseMoved(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2404,6 +2520,7 @@ public class BasicTreeUI * Removes event from the source */ protected void removeFromSource() + throws NotImplementedException { // TODO: Implement this properly. } @@ -2450,10 +2567,11 @@ public class BasicTreeUI if (s != null) { + TreePath path = treeState.getPathForRow(row); size.x = getRowX(row, depth); size.width = SwingUtilities.computeStringWidth(fm, s); - size.width = size.width + getCurrentControlIcon(null).getIconWidth() - + gap; + size.width = size.width + getCurrentControlIcon(path).getIconWidth() + + gap + getNodeIcon(path).getIconWidth(); size.height = getMaxHeight(tree); size.y = size.height * row; } @@ -2468,8 +2586,7 @@ public class BasicTreeUI */ protected int getRowX(int row, int depth) { - int iw = getCurrentControlIcon(null).getIconWidth(); - return depth * (rightChildIndent + iw/2); + return BasicTreeUI.this.getRowX(row, depth); } }// NodeDimensionsHandler @@ -2511,8 +2628,14 @@ public class BasicTreeUI } else if (property.equals(JTree.TREE_MODEL_PROPERTY)) { - treeModel = tree.getModel(); - treeModel.addTreeModelListener(treeModelListener); + setModel(tree.getModel()); + } + else if (property.equals(JTree.CELL_RENDERER_PROPERTY)) + { + setCellRenderer(tree.getCellRenderer()); + // Update layout. + if (treeState != null) + treeState.invalidateSizes(); } } } @@ -2540,45 +2663,38 @@ public class BasicTreeUI * the property that has changed. */ public void propertyChange(PropertyChangeEvent event) + throws NotImplementedException { // TODO: What should be done here, if anything? } } /** - * ActionListener that invokes cancelEditing when action performed. + * The action to cancel editing on this tree. */ public class TreeCancelEditingAction extends AbstractAction { - /** - * Constructor + * Creates the new tree cancel editing action. + * + * @param name the name of the action (used in toString). */ public TreeCancelEditingAction(String name) { - // TODO: Implement this properly. + super(name); } /** - * Invoked when an action occurs. + * Invoked when an action occurs, cancels the cell editing (if the + * tree cell is being edited). * * @param e event that occured */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. - } - - /** - * Returns true if the action is enabled. - * - * @return true if the action is enabled, false otherwise - */ - public boolean isEnabled() - { - // TODO: Implement this properly. - return false; + if (isEnabled() && tree.isEditing()) + tree.cancelEditing(); } } @@ -2606,6 +2722,8 @@ public class BasicTreeUI { validCachedPreferredSize = false; treeState.setExpandedState(event.getPath(), true); + // The maximal cell height may change + maxHeight = 0; tree.revalidate(); tree.repaint(); } @@ -2619,6 +2737,8 @@ public class BasicTreeUI { validCachedPreferredSize = false; treeState.setExpandedState(event.getPath(), false); + // The maximal cell height may change + maxHeight = 0; tree.revalidate(); tree.repaint(); } @@ -2636,14 +2756,16 @@ public class BasicTreeUI protected int direction; /** - * Constructor + * Creates a new TreeHomeAction instance. * - * @param direction - it is home or end - * @param name is the name of the direction + * @param dir the direction to go to, <code>-1</code> for home, + * <code>1</code> for end + * @param name the name of the action */ - public TreeHomeAction(int direction, String name) + public TreeHomeAction(int dir, String name) { - // TODO: Implement this properly + direction = dir; + putValue(Action.NAME, name); } /** @@ -2653,7 +2775,61 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly + if (tree != null) + { + String command = (String) getValue(Action.NAME); + if (command.equals("selectFirst")) + { + ensureRowsAreVisible(0, 0); + tree.setSelectionInterval(0, 0); + } + if (command.equals("selectFirstChangeLead")) + { + ensureRowsAreVisible(0, 0); + tree.setLeadSelectionPath(getPathForRow(tree, 0)); + } + if (command.equals("selectFirstExtendSelection")) + { + ensureRowsAreVisible(0, 0); + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + tree.setSelectionInterval(0, 0); + else + { + int anchorRow = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(0, anchorRow); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(getPathForRow(tree, 0)); + } + } + else if (command.equals("selectLast")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + tree.setSelectionInterval(end, end); + } + else if (command.equals("selectLastChangeLead")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + tree.setLeadSelectionPath(getPathForRow(tree, end)); + } + else if (command.equals("selectLastExtendSelection")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + tree.setSelectionInterval(end, end); + else + { + int anchorRow = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(end, anchorRow); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(getPathForRow(tree, end)); + } + } + } } /** @@ -2663,8 +2839,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -2673,21 +2848,24 @@ public class BasicTreeUI * up or down based on direction. */ public class TreeIncrementAction - extends AbstractAction + extends AbstractAction { - /** Specifies the direction to adjust the selection by. */ + /** + * Specifies the direction to adjust the selection by. + */ protected int direction; /** - * Constructor + * Creates a new TreeIncrementAction. * - * @param direction up or down + * @param dir up or down, <code>-1</code> for up, <code>1</code> for down * @param name is the name of the direction */ - public TreeIncrementAction(int direction, String name) + public TreeIncrementAction(int dir, String name) { - // TODO: Implement this properly + direction = dir; + putValue(Action.NAME, name); } /** @@ -2712,7 +2890,7 @@ public class BasicTreeUI boolean hasNext = nextRow < rows; boolean hasPrev = prevRow >= 0 && rows > 0; TreePath newPath; - String command = e.getActionCommand(); + String command = (String) getValue(Action.NAME); if (command.equals("selectPreviousChangeLead") && hasPrev) { @@ -2776,8 +2954,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -2883,6 +3060,7 @@ public class BasicTreeUI public TreePageAction(int direction, String name) { this.direction = direction; + putValue(Action.NAME, name); } /** @@ -2892,7 +3070,94 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. + String command = (String) getValue(Action.NAME); + boolean extendSelection = command.equals("scrollUpExtendSelection") + || command.equals("scrollDownExtendSelection"); + boolean changeSelection = command.equals("scrollUpChangeSelection") + || command.equals("scrollDownChangeSelection"); + + // Disable change lead, unless we are in discontinuous mode. + if (!extendSelection && !changeSelection + && tree.getSelectionModel().getSelectionMode() != + TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) + { + changeSelection = true; + } + + int rowCount = getRowCount(tree); + if (rowCount > 0 && treeSelectionModel != null) + { + Dimension maxSize = tree.getSize(); + TreePath lead = tree.getLeadSelectionPath(); + TreePath newPath = null; + Rectangle visible = tree.getVisibleRect(); + if (direction == -1) // The RI handles -1 as up. + { + newPath = getClosestPathForLocation(tree, visible.x, visible.y); + if (newPath.equals(lead)) // Corner case, adjust one page up. + { + visible.y = Math.max(0, visible.y - visible.height); + newPath = getClosestPathForLocation(tree, visible.x, + visible.y); + } + } + else // +1 is down. + { + visible.y = Math.min(maxSize.height, + visible.y + visible.height - 1); + newPath = getClosestPathForLocation(tree, visible.x, visible.y); + if (newPath.equals(lead)) // Corner case, adjust one page down. + { + visible.y = Math.min(maxSize.height, + visible.y + visible.height - 1); + newPath = getClosestPathForLocation(tree, visible.x, + visible.y); + } + } + + // Determine new visible rect. + Rectangle newVisible = getPathBounds(tree, newPath); + newVisible.x = visible.x; + newVisible.width = visible.width; + if (direction == -1) + { + newVisible.height = visible.height; + } + else + { + newVisible.y -= (visible.height - newVisible.height); + newVisible.height = visible.height; + } + + if (extendSelection) + { + // Extend selection. + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + { + tree.setSelectionPath(newPath); + } + else + { + int newIndex = getRowForPath(tree, newPath); + int anchorIndex = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(Math.min(anchorIndex, newIndex), + Math.max(anchorIndex, newIndex)); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(newPath); + } + } + else if (changeSelection) + { + tree.setSelectionPath(newPath); + } + else // Change lead. + { + tree.setLeadSelectionPath(newPath); + } + + tree.scrollRectToVisible(newVisible); + } } /** @@ -2902,7 +3167,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - return false; + return (tree != null) && tree.isEnabled(); } }// TreePageAction @@ -2958,13 +3223,13 @@ public class BasicTreeUI extends AbstractAction { /** - * Constructor + * Creates a new TreeToggleAction. * * @param name is the name of <code>Action</code> field */ public TreeToggleAction(String name) { - // Nothing to do here. + putValue(Action.NAME, name); } /** @@ -2974,7 +3239,17 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. + int selected = tree.getLeadSelectionRow(); + if (selected != -1 && isLeaf(selected)) + { + TreePath anchorPath = tree.getAnchorSelectionPath(); + TreePath leadPath = tree.getLeadSelectionPath(); + toggleExpandState(getPathForRow(tree, selected)); + // Need to do this, so that the toggling doesn't mess up the lead + // and anchor. + tree.setLeadSelectionPath(leadPath); + tree.setAnchorSelectionPath(anchorPath); + } } /** @@ -2984,7 +3259,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - return false; + return (tree != null) && tree.isEnabled(); } } // TreeToggleAction @@ -3009,6 +3284,7 @@ public class BasicTreeUI public TreeTraverseAction(int direction, String name) { this.direction = direction; + putValue(Action.NAME, name); } /** @@ -3022,7 +3298,8 @@ public class BasicTreeUI if (current == null) return; - if (e.getActionCommand().equals("selectParent")) + String command = (String) getValue(Action.NAME); + if (command.equals("selectParent")) { if (current == null) return; @@ -3042,7 +3319,7 @@ public class BasicTreeUI tree.setSelectionPath(parent); } } - else if (e.getActionCommand().equals("selectChild")) + else if (command.equals("selectChild")) { Object node = current.getLastPathComponent(); int nc = treeModel.getChildCount(node); @@ -3068,8 +3345,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -3094,9 +3370,35 @@ public class BasicTreeUI */ Icon getCurrentControlIcon(TreePath path) { - if (tree.isExpanded(path)) - return expandedIcon; - return collapsedIcon; + if (hasControlIcons()) + { + if (tree.isExpanded(path)) + return expandedIcon; + else + return collapsedIcon; + } + else + { + if (nullIcon == null) + nullIcon = new Icon() + { + public int getIconHeight() + { + return 0; + } + + public int getIconWidth() + { + return 0; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + // No action here. + } + }; + return nullIcon; + } } /** @@ -3323,10 +3625,8 @@ public class BasicTreeUI { if (row != 0) { - Icon icon = getCurrentControlIcon(path); - int iconW = icon.getIconWidth(); paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, - bounds.x - iconW/2 - gap, bounds.x - gap); + bounds.x - leftChildIndent - gap, bounds.x - gap); } } @@ -3379,15 +3679,13 @@ public class BasicTreeUI paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf); - TreeCellRenderer dtcr = tree.getCellRenderer(); - if (dtcr == null) - dtcr = createDefaultCellRenderer(); + TreeCellRenderer dtcr = currentCellRenderer; boolean focused = false; - if (treeSelectionModel!= null) - focused = treeSelectionModel.getLeadSelectionRow() == row - && tree.isFocusOwner(); - + if (treeSelectionModel != null) + focused = treeSelectionModel.getLeadSelectionRow() == row + && tree.isFocusOwner(); + Component c = dtcr.getTreeCellRendererComponent(tree, node, selected, isExpanded, isLeaf, row, focused); @@ -3400,7 +3698,7 @@ public class BasicTreeUI */ protected void prepareForUIUninstall() { - // TODO: Implement this properly. + // Nothing to do here yet. } /** @@ -3440,4 +3738,14 @@ public class BasicTreeUI editingComponent = null; tree.requestFocus(); } + + /** + * Returns the amount to indent the given row + * + * @return amount to indent the given row. + */ + protected int getRowX(int row, int depth) + { + return depth * totalChildIndent; + } } // BasicTreeUI diff --git a/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java b/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java new file mode 100644 index 00000000000..47876491160 --- /dev/null +++ b/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java @@ -0,0 +1,78 @@ +/* SharedUIDefaults.java -- Manages shared instances for UIDefaults + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.plaf.basic; + +import java.util.HashMap; + +import javax.swing.UIManager; + +/** + * Manages shared instances for UI defaults. For example, all Swing components + * of one type usually share one InputMap/ActionMap pair. In order to avoid + * duplication of such objects we store them in a Map here. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class SharedUIDefaults +{ + + /** + * Stores the shared instances, indexed by their UI names + * (i.e. "TextField.InputMap"). + */ + private static HashMap sharedDefaults = new HashMap(); + + /** + * Returns a shared UI defaults object. + * + * @param key the key for the shared object + * + * @return a shared UI defaults object for the specified key + */ + static Object get(String key) + { + Object o = sharedDefaults.get(key); + if (o == null) + { + o = UIManager.get(key); + sharedDefaults.put(key, o); + } + return o; + } +} diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java b/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java index 98a00ee0a0e..7c41180aeae 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalBorders.java @@ -103,7 +103,16 @@ public class MetalBorders private static BasicBorders.MarginBorder marginBorder; /** - * A border used for {@link JButton} components. + * <p>A border used for {@link JButton} components.</p> + * + * <p>This {@link Border} implementation can handle only instances of + * {@link AbstractButton} and their subclasses.</p> + * + * <p>If the Metal Look and Feel's current theme is 'Ocean' the border + * will be painted with a special highlight when the mouse cursor if + * over the button (ie. the property <code>rollover</code> of the + * button's model is <code>true</code>) and is not a <b>direct</b> + * child of a {@link JToolBar}.</p> */ public static class ButtonBorder extends AbstractBorder implements UIResource { @@ -157,8 +166,14 @@ public class MetalBorders { ButtonModel bmodel = null; + // The RI will fail with a ClassCastException in such a situation. + // This code tries to be more helpful. if (c instanceof AbstractButton) bmodel = ((AbstractButton) c).getModel(); + else + throw new IllegalStateException("A ButtonBorder is supposed to work " + + "only with AbstractButton and" + + "subclasses."); Color darkShadow = MetalLookAndFeel.getControlDarkShadow(); Color shadow = MetalLookAndFeel.getControlShadow(); @@ -191,7 +206,7 @@ public class MetalBorders { // The normal border. This is used when the button is not // pressed or the button is not armed. - if (! (bmodel.isPressed() && bmodel.isArmed()) ) + if (! (bmodel.isPressed() && bmodel.isArmed())) { // draw light border g.setColor(light); @@ -246,8 +261,14 @@ public class MetalBorders { ButtonModel bmodel = null; + // The RI will fail with a ClassCastException in such a situation. + // This code tries to be more helpful. if (c instanceof AbstractButton) bmodel = ((AbstractButton) c).getModel(); + else + throw new IllegalStateException("A ButtonBorder is supposed to work " + + "only with AbstractButton and" + + "subclasses."); Color darkShadow = MetalLookAndFeel.getControlDarkShadow(); Color shadow = MetalLookAndFeel.getControlShadow(); @@ -267,8 +288,10 @@ public class MetalBorders g.drawRect(x, y, w - 1, h - 1); g.drawRect(x + 1, y + 1, w - 3, h - 3); } - else if (bmodel.isRollover()) + else if (bmodel.isRollover() && !(c.getParent() instanceof JToolBar)) { + // Paint a bigger border when the mouse is over the button but + // only if it is *not* part of a JToolBar. g.setColor(shadow); g.drawRect(x, y, w - 1, h - 1); g.drawRect(x + 2, y + 2, w - 5, h - 5); @@ -568,12 +591,12 @@ public class MetalBorders { boolean enabledTextBorder; if (c instanceof JTextComponent) - { - JTextComponent tc = (JTextComponent) c; - enabledTextBorder = tc.isEnabled() && tc.isEditable(); - } + { + JTextComponent tc = (JTextComponent) c; + enabledTextBorder = tc.isEnabled() && tc.isEditable(); + } else - enabledTextBorder = false; + enabledTextBorder = false; if (enabledTextBorder) super.paintBorder(c, g, x, y, w, h); @@ -829,35 +852,36 @@ public class MetalBorders { Color dark = MetalLookAndFeel.getPrimaryControlDarkShadow(); Color light = MetalLookAndFeel.getPrimaryControlHighlight(); - if (c instanceof JMenu) { - JMenu menu = (JMenu) c; - if (menu.isSelected()) + if (c instanceof JMenu) { - g.setColor(dark); - g.drawLine(x, y, x, y + h); - g.drawLine(x, y, x + w, y); - g.drawLine(x + w - 2, y + 1, x + w - 2, y + h); - g.setColor(light); - g.drawLine(x + w - 1, y + 1, x + w - 1, y + h); + JMenu menu = (JMenu) c; + if (menu.isSelected()) + { + g.setColor(dark); + g.drawLine(x, y, x, y + h); + g.drawLine(x, y, x + w, y); + g.drawLine(x + w - 2, y + 1, x + w - 2, y + h); + g.setColor(light); + g.drawLine(x + w - 1, y + 1, x + w - 1, y + h); + } } - } else if (c instanceof JMenuItem) - { - JMenuItem item = (JMenuItem) c; - if (item.isArmed()) - { - g.setColor(dark); - g.drawLine(x, y, x + w, y); - g.setColor(light); - g.drawLine(x, y + h - 1, x + w, y + h - 1); - } - else - { - // Normally we draw a light line on the left. - g.setColor(light); - g.drawLine(x, y, x, y + h); - } - } + { + JMenuItem item = (JMenuItem) c; + if (item.isArmed()) + { + g.setColor(dark); + g.drawLine(x, y, x + w, y); + g.setColor(light); + g.drawLine(x, y + h - 1, x + w, y + h - 1); + } + else + { + // Normally we draw a light line on the left. + g.setColor(light); + g.drawLine(x, y, x, y + h); + } + } } /** @@ -1469,8 +1493,8 @@ public class MetalBorders { Border outer = new ButtonBorder(); Border inner = getMarginBorder(); - buttonBorder = new BorderUIResource.CompoundBorderUIResource - (outer, inner); + buttonBorder = new BorderUIResource.CompoundBorderUIResource(outer, + inner); } return buttonBorder; } @@ -1488,8 +1512,8 @@ public class MetalBorders { Border outer = new ToggleButtonBorder(); Border inner = getMarginBorder(); - toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource - (outer, inner); + toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource( + outer, inner); } return toggleButtonBorder; } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java index 83cd3366215..d6cc1bc07f9 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalButtonUI.java @@ -39,6 +39,7 @@ exception statement from your version. */ package javax.swing.plaf.metal; import java.awt.Color; +import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; @@ -48,7 +49,9 @@ import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.JButton; import javax.swing.JComponent; +import javax.swing.JToolBar; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; @@ -121,7 +124,8 @@ public class MetalButtonUI * * @return A new instance of <code>MetalButtonUI</code>. */ - public static ComponentUI createUI(JComponent c) { + public static ComponentUI createUI(JComponent c) + { return new MetalButtonUI(); } @@ -187,7 +191,8 @@ public class MetalButtonUI * @param iconRect the icon bounds. */ protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, - Rectangle textRect, Rectangle iconRect) { + Rectangle textRect, Rectangle iconRect) + { if (b.isEnabled() && b.hasFocus() && b.isFocusPainted()) { Color savedColor = g.getColor(); @@ -235,19 +240,63 @@ public class MetalButtonUI public void update(Graphics g, JComponent c) { AbstractButton b = (AbstractButton) c; - ButtonModel m = b.getModel(); if (b.isContentAreaFilled() && (UIManager.get(getPropertyPrefix() + "gradient") != null) - && ! m.isPressed() && ! m.isArmed() && b.isEnabled() && (b.getBackground() instanceof UIResource)) + updateWidthGradient(g, b, b.getParent()); + else + super.update(g, c); + } + + private void updateWidthGradient(Graphics g, AbstractButton b, Container parent) + { + ButtonModel m = b.getModel(); + String gradientPropertyName = getPropertyPrefix() + "gradient"; + + // Gradient painting behavior depends on whether the button is part of a + // JToolBar. + if (parent instanceof JToolBar) + { + if (! m.isPressed() && ! m.isArmed()) + { + if (m.isRollover()) + { + // Paint the gradient when the mouse cursor hovers over the + // button but is not pressed down. + MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(), + SwingConstants.VERTICAL, + gradientPropertyName); + } + else + { + // If mouse does not hover over the button let the JToolBar + // paint itself at the location where the button is (the button + // is transparent). + + // There where cases where the button was not repainted and + // therefore showed its old state. With this statement it does + // not happen. + b.repaint(); + + Rectangle area = new Rectangle(); + SwingUtilities.calculateInnerArea(b, area); + SwingUtilities.convertRectangle(b, area, b.getParent()); + b.getParent().repaint(area.x, area.y, area.width, area.height); + } + } + + } + else if (! m.isPressed() && ! m.isArmed()) { - MetalUtils.paintGradient(g, 0, 0, c.getWidth(), c.getHeight(), + // When the button is not part of a JToolBar just paint itself with a + // gradient and everything is fine. + MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(), SwingConstants.VERTICAL, - getPropertyPrefix() + "gradient"); - paint(g, c); + gradientPropertyName); } - else - super.update(g, c); + + paint(g, b); } + } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java index b4f6f0a56cd..c7941642e67 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java @@ -52,7 +52,7 @@ public class MetalCheckBoxUI // FIXME: maybe replace by a Map of instances when this becomes stateful /** The shared UI instance for JCheckBoxes. */ - private static MetalCheckBoxUI instance = null; + private static MetalCheckBoxUI instance; /** * Constructs a new instance of MetalCheckBoxUI. diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxButton.java b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxButton.java index 3787a98c3a9..6a528de2b6b 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxButton.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxButton.java @@ -256,9 +256,8 @@ public class MetalComboBoxButton { ListCellRenderer renderer = comboBox.getRenderer(); boolean pressed = this.getModel().isPressed(); - Component comp= renderer.getListCellRendererComponent(listBox, - comboBox.getSelectedItem(), - -1, false, false); + Component comp = renderer.getListCellRendererComponent(listBox, + comboBox.getSelectedItem(), -1, false, false); comp.setFont(rendererPane.getFont()); if (model.isArmed() && model.isPressed()) { diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java index f21c5af6136..944ce394405 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java @@ -48,7 +48,8 @@ import javax.swing.Icon; /** * An icon used by the {@link MetalComboBoxUI} class. */ -public class MetalComboBoxIcon implements Icon, Serializable { +public class MetalComboBoxIcon implements Icon, Serializable +{ /** * Creates a new icon. diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java index cb94c87b846..1219ad9fd11 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -52,12 +52,13 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.text.NumberFormat; - import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; - import java.io.File; +import java.sql.Date; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.List; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; @@ -79,7 +80,6 @@ import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.JToggleButton; -import javax.swing.JViewport; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; @@ -94,12 +94,6 @@ import javax.swing.plaf.basic.BasicFileChooserUI; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; -import java.sql.Date; - -import java.text.DateFormat; - -import java.util.List; - /** * A UI delegate for the {@link JFileChooser} component. This class is only @@ -350,7 +344,7 @@ public class MetalFileChooserUI setDirectorySelected(false); File currentDirectory = filechooser.getCurrentDirectory(); setDirectory(currentDirectory); - boolean hasParent = (currentDirectory.getParentFile() != null); + boolean hasParent = currentDirectory.getParentFile() != null; getChangeToParentDirectoryAction().setEnabled(hasParent); } @@ -648,15 +642,15 @@ public class MetalFileChooserUI FileView v = getFileView(getFileChooser()); File f = (File) value; if (f != null) - { - setText(v.getName(f)); - setIcon(v.getIcon(f)); - } + { + setText(v.getName(f)); + setIcon(v.getIcon(f)); + } else - { - setText(""); - setIcon(null); - } + { + setText(""); + setIcon(null); + } setOpaque(true); if (isSelected) { @@ -962,10 +956,9 @@ public class MetalFileChooserUI { String text = editField.getText(); if (text != null && text != "" && !text.equals(fc.getName(editFile))) - if (editFile.renameTo - (fc.getFileSystemView().createFileObject - (fc.getCurrentDirectory(), text))) - rescanCurrentDirectory(fc); + if (editFile.renameTo(fc.getFileSystemView().createFileObject( + fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); list.remove(editField); } startEditing = false; @@ -1018,7 +1011,7 @@ public class MetalFileChooserUI JFileChooser fc; /** The last selected file. */ - Object lastSelected = null; + Object lastSelected; /** * Stores the current file that is being edited. @@ -1032,10 +1025,8 @@ public class MetalFileChooserUI /** * Creates a new listener. * - * @param table - * the directory/file table - * @param fc - * the JFileChooser + * @param table the directory/file table + * @param fc the JFileChooser */ public TableClickListener(JTable table, JFileChooser fc) { @@ -1051,8 +1042,7 @@ public class MetalFileChooserUI /** * Receives notification of a mouse click event. * - * @param e - * the event. + * @param e the event. */ public void mouseClicked(MouseEvent e) { @@ -1156,10 +1146,9 @@ public class MetalFileChooserUI { String text = editField.getText(); if (text != null && text != "" && !text.equals(fc.getName(editFile))) - if (editFile.renameTo - (fc.getFileSystemView().createFileObject - (fc.getCurrentDirectory(), text))) - rescanCurrentDirectory(fc); + if (editFile.renameTo(fc.getFileSystemView().createFileObject( + fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); table.remove(editField); } startEditing = false; @@ -1636,8 +1625,7 @@ public class MetalFileChooserUI /** * Formats bytes into the appropriate size. * - * @param bytes - - * the number of bytes to convert + * @param bytes the number of bytes to convert * @return a string representation of the size */ private String formatSize(long bytes) @@ -1838,7 +1826,7 @@ public class MetalFileChooserUI /** * Updates the current directory. * - * @param the file chooser to update. + * @param fc the file chooser to update. */ public void rescanCurrentDirectory(JFileChooser fc) { @@ -1966,7 +1954,8 @@ public class MetalFileChooserUI * * @param component the component. */ - public void removeLayoutComponent(Component component) { + public void removeLayoutComponent(Component component) + { // do nothing } } @@ -2072,7 +2061,8 @@ public class MetalFileChooserUI * * @param component the component. */ - public void removeLayoutComponent(Component component) { + public void removeLayoutComponent(Component component) + { // do nothing } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java index d24a0526232..4e4c863c979 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java @@ -617,7 +617,8 @@ public class MetalIconFactory implements Serializable * * @return The width of the icon. */ - public int getIconWidth() { + public int getIconWidth() + { return 16; } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java index f74828e566e..dd0c486396b 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java @@ -95,7 +95,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane String propName = e.getPropertyName(); if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY)) { - title.setIcon( frame.getFrameIcon() ); + title.setIcon(frame.getFrameIcon()); } else if (propName.equals("JInternalFrame.isPalette")) { @@ -387,8 +387,8 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane paintPalette(g); else { - paintTitleBackground(g); - paintChildren(g); + paintTitleBackground(g); + paintChildren(g); Dimension d = getSize(); if (frame.isSelected()) g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); @@ -421,7 +421,8 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane endX = Math.max(closeButton.getX(), endX); endX -= 7; if (endX > startX) - MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX, getHeight() - 6, Color.white, Color.gray); + MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX, + getHeight() - 6, Color.white, Color.gray); } g.setColor(savedColor); } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java index 6be573f4bac..abe6a2817e1 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java @@ -41,8 +41,10 @@ package javax.swing.plaf.metal; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.ActionMap; import javax.swing.JComponent; import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicInternalFrameUI; @@ -162,4 +164,20 @@ public class MetalInternalFrameUI frame.removePropertyChangeListener(IS_PALETTE, paletteListener); paletteListener = null; } + + /** + * Installs keyboard actions. This is overridden to remove the + * <code>showSystemMenu</code> Action that is installed by the + * <code>BasicInternalFrameUI</code>, since Metal JInternalFrames don't have + * a system menu. + */ + protected void installKeyboardActions() + { + super.installKeyboardActions(); + ActionMap am = SwingUtilities.getUIActionMap(frame); + if (am != null) + { + am.remove("showSystemMenu"); + } + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java index 7a973d46eef..09eafd40fe9 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -67,7 +67,7 @@ import javax.swing.plaf.basic.BasicLookAndFeel; * }</pre> */ public class MetalLookAndFeel extends BasicLookAndFeel -{ +{ private static final long serialVersionUID = 6680646159193457980L; /** The current theme. */ @@ -888,11 +888,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel "CheckBox.font", new FontUIResource("Dialog", Font.BOLD, 12), "CheckBox.foreground", getControlTextColor(), "CheckBox.icon", - new UIDefaults.ProxyLazyValue - ("javax.swing.plaf.metal.MetalCheckBoxIcon"), + new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalCheckBoxIcon"), "CheckBox.checkIcon", - new UIDefaults.ProxyLazyValue - ("javax.swing.plaf.metal.MetalCheckBoxIcon"), + new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalCheckBoxIcon"), "Checkbox.select", getControlShadow(), "CheckBoxMenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10), @@ -964,7 +962,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "FileChooser.detailsViewIcon", MetalIconFactory.getFileChooserDetailViewIcon(), "FileChooser.fileNameLabelMnemonic", new Integer(78), - "FileChooser.filesOfTypeLabelMnemonic",new Integer(84), + "FileChooser.filesOfTypeLabelMnemonic", new Integer(84), "FileChooser.lookInLabelMnemonic", new Integer(73), "FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(), "FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(), @@ -1273,6 +1271,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel "ToolBar.light", getControlHighlight(), "ToolBar.shadow", getControlShadow(), "ToolBar.border", new MetalBorders.ToolBarBorder(), + "ToolBar.rolloverBorder", MetalBorders.getToolbarButtonBorder(), + "ToolBar.nonrolloverBorder", MetalBorders.getToolbarButtonBorder(), "ToolTip.background", getPrimaryControl(), "ToolTip.backgroundInactive", getControl(), diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java index 44a2d3bcd6a..7c580f90f39 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java @@ -51,7 +51,7 @@ public class MetalPopupMenuSeparatorUI // FIXME: maybe replace by a Map of instances when this becomes stateful /** The shared UI instance for MetalPopupMenuSeparatorUIs */ - private static MetalPopupMenuSeparatorUI instance = null; + private static MetalPopupMenuSeparatorUI instance; /** * Constructs a new instance of <code>MetalPopupMenuSeparatorUI</code>. diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java index 9fb960f68b9..046e4942ee1 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -1,5 +1,5 @@ /* MetalRadioButtonUI.java - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -95,9 +95,10 @@ public class MetalRadioButtonUI public void installDefaults(AbstractButton b) { super.installDefaults(b); - disabledTextColor = UIManager.getColor("RadioButton.disabledText"); - focusColor = UIManager.getColor("RadioButton.focus"); - selectColor = UIManager.getColor("RadioButton.select"); + String prefix = getPropertyPrefix(); + disabledTextColor = UIManager.getColor(prefix + "disabledText"); + focusColor = UIManager.getColor(prefix + "focus"); + selectColor = UIManager.getColor(prefix + "select"); } /** diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalRootPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalRootPaneUI.java index 6cabc7e8691..eaee5bf929e 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalRootPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalRootPaneUI.java @@ -958,7 +958,7 @@ public class MetalRootPaneUI /** * The shared UI instance for MetalRootPaneUIs. */ - private static MetalRootPaneUI instance = null; + private static MetalRootPaneUI instance; /** * Constructs a shared instance of <code>MetalRootPaneUI</code>. diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalScrollBarUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalScrollBarUI.java index c7dfd11e48c..75f2750ae9c 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalScrollBarUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalScrollBarUI.java @@ -90,14 +90,14 @@ public class MetalScrollBarUI extends BasicScrollBarUI if (e.getPropertyName().equals(FREE_STANDING_PROP)) { Boolean prop = (Boolean) e.getNewValue(); - isFreeStanding = (prop == null ? true : prop.booleanValue()); - if (increaseButton != null) - increaseButton.setFreeStanding(isFreeStanding); - if (decreaseButton != null) - decreaseButton.setFreeStanding(isFreeStanding); + isFreeStanding = prop == null ? true : prop.booleanValue(); + if (increaseButton != null) + increaseButton.setFreeStanding(isFreeStanding); + if (decreaseButton != null) + decreaseButton.setFreeStanding(isFreeStanding); } else - super.propertyChange(e); + super.propertyChange(e); } } @@ -167,7 +167,7 @@ public class MetalScrollBarUI extends BasicScrollBarUI // createDecreaseButton() are called (unless there is somewhere earlier // that we can do this). Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP); - isFreeStanding = (prop == null ? true : prop.booleanValue()); + isFreeStanding = prop == null ? true : prop.booleanValue(); scrollBarShadowColor = UIManager.getColor("ScrollBar.shadow"); super.installDefaults(); } @@ -401,7 +401,7 @@ public class MetalScrollBarUI extends BasicScrollBarUI { g.drawLine(x, y, x + w - 1, y); g.drawLine(x, y, x, y + h - 1); - g.drawLine(x + w - 1, y, x + w - 1, y + h -1); + g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); } // then the highlight diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSeparatorUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalSeparatorUI.java index 1d48e9be2b0..6d7818f8b22 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalSeparatorUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalSeparatorUI.java @@ -58,7 +58,7 @@ public class MetalSeparatorUI // FIXME: maybe replace by a Map of instances when this becomes stateful /** The shared UI instance for MetalSeparatorUIs */ - private static MetalSeparatorUI instance = null; + private static MetalSeparatorUI instance; /** * Constructs a new instance of <code>MetalSeparatorUI</code>. diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java index f97717f31e0..0f824418c5d 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalSliderUI.java @@ -192,10 +192,13 @@ public class MetalSliderUI extends BasicSliderUI */ public void paintThumb(Graphics g) { + Color save = g.getColor(); + g.setColor(thumbColor); if (slider.getOrientation() == JSlider.HORIZONTAL) horizThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y); else vertThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y); + g.setColor(save); } /** @@ -229,9 +232,9 @@ public class MetalSliderUI extends BasicSliderUI if (slider.isEnabled()) { int xPos = xPositionForValue(slider.getValue()); - int x = (slider.getInverted() ? xPos : trackRect.x); - int w = (slider.getInverted() ? trackX + trackW - xPos - : xPos - trackRect.x); + int x = slider.getInverted() ? xPos : trackRect.x; + int w = slider.getInverted() ? trackX + trackW - xPos + : xPos - trackRect.x; g.setColor(MetalLookAndFeel.getWhite()); g.drawLine(x + 1, trackY + 1, x + w - 3, trackY + 1); g.setColor(UIManager.getColor("Slider.altTrackColor")); @@ -245,9 +248,9 @@ public class MetalSliderUI extends BasicSliderUI else if (filledSlider) { int xPos = xPositionForValue(slider.getValue()); - int x = (slider.getInverted() ? xPos : trackRect.x); - int w = (slider.getInverted() ? trackX + trackW - xPos - : xPos - trackRect.x); + int x = slider.getInverted() ? xPos : trackRect.x; + int w = slider.getInverted() ? trackX + trackW - xPos + : xPos - trackRect.x; g.setColor(MetalLookAndFeel.getControlShadow()); g.fillRect(x + 1, trackY + 1, w - 3, getTrackWidth() - 3); if (slider.isEnabled()) @@ -280,9 +283,9 @@ public class MetalSliderUI extends BasicSliderUI if (slider.isEnabled()) { int yPos = yPositionForValue(slider.getValue()); - int y = (slider.getInverted() ? trackY : yPos); - int h = (slider.getInverted() ? yPos - trackY - : trackY + trackH - yPos); + int y = slider.getInverted() ? trackY : yPos; + int h = slider.getInverted() ? yPos - trackY + : trackY + trackH - yPos; g.setColor(MetalLookAndFeel.getWhite()); g.drawLine(trackX + 1, y + 1, trackX + 1, y + h - 3); @@ -297,9 +300,9 @@ public class MetalSliderUI extends BasicSliderUI else if (filledSlider) { int yPos = yPositionForValue(slider.getValue()); - int y = (slider.getInverted() ? trackY : yPos); - int h = (slider.getInverted() ? yPos - trackY - : trackY + trackH - yPos); + int y = slider.getInverted() ? trackY : yPos; + int h = slider.getInverted() ? yPos - trackY + : trackY + trackH - yPos; g.setColor(MetalLookAndFeel.getControlShadow()); g.fillRect(trackX + 1, y + 1, getTrackWidth() - 3, h - 3); if (slider.isEnabled()) @@ -323,7 +326,8 @@ public class MetalSliderUI extends BasicSliderUI */ public void paintFocus(Graphics g) { - // do nothing as focus is shown by different color on thumb control + thumbColor = getFocusColor(); + paintThumb(g); } /** @@ -368,8 +372,8 @@ public class MetalSliderUI extends BasicSliderUI */ protected int getTrackLength() { - return (slider.getOrientation() == JSlider.HORIZONTAL - ? tickRect.width : tickRect.height); + return slider.getOrientation() == JSlider.HORIZONTAL + ? tickRect.width : tickRect.height; } /** diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java index 9c592bd5116..6081c355c37 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java @@ -1,5 +1,5 @@ /* MetalSplitPaneDivider.java -Copyright (C) 2005 Free Software Foundation, Inc. +Copyright (C) 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,21 +42,20 @@ 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 javax.swing.JSplitPane; import javax.swing.SwingConstants; +import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicSplitPaneDivider; /** - * The divider that is used by the MetalSplitPaneUI. + * The divider that is used by the {@link MetalSplitPaneUI}. * * @author Roman Kennke (roman@kennke.org) - * */ class MetalSplitPaneDivider extends BasicSplitPaneDivider { @@ -73,7 +72,7 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider int orientation; /** - * Creates a new instance of MetalSplitPaneDivider. + * Creates a new instance of <code>MetalSplitPaneDivider</code>. * * @param ui the <code>MetalSplitPaneUI</code> that uses this divider */ @@ -96,6 +95,12 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider { Dimension s = getSize(); + if (splitPane.hasFocus()) + { + g.setColor(UIManager.getColor("SplitPane.dividerFocusColor")); + g.fillRect(0, 0, s.width, s.height); + } + // Paint border if one exists. Border border = getBorder(); if (border != null) @@ -159,8 +164,8 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider if ((c1 instanceof BasicArrowButton) && (c2 instanceof BasicArrowButton)) { - lb = ((BasicArrowButton) c1); - rb = ((BasicArrowButton) c2); + lb = (BasicArrowButton) c1; + rb = (BasicArrowButton) c2; } } if (rb != null && lb != null) diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java index 39dec3d663f..c49abe832e4 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java @@ -607,11 +607,11 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI } else { - if (isOcean && tabIndex == tabPane.getSelectedIndex()+ 1) + if (isOcean && tabIndex == tabPane.getSelectedIndex() + 1) { g.setColor(oceanSelectedBorder); } - if (tabIndex != tabRuns[runCount- 1]) + if (tabIndex != tabRuns[runCount - 1]) { g.drawLine(0, 0, 0, bottom); } @@ -856,7 +856,7 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI // run directly above the content or the selected tab is not visible, // then we draw an unbroken line. if (tabPlacement != TOP || selectedIndex < 0 - || rect.y + rect.height + 1 < y || rect.x < x ||rect.x > x + w) + || rect.y + rect.height + 1 < y || rect.x < x || rect.x > x + w) { g.drawLine(x, y, x + w - 2, y); if (isOcean && tabPlacement == TOP) diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalToolTipUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalToolTipUI.java index f183ed5a149..d1040347fc6 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalToolTipUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalToolTipUI.java @@ -75,7 +75,7 @@ public class MetalToolTipUI public static final int padSpaceBetweenStrings = 12; /** The shared UI instance. */ - private static MetalToolTipUI instance = null; + private static MetalToolTipUI instance; /** A flag controlling the visibility of the accelerator (if there is one). */ private boolean isAcceleratorHidden; @@ -256,8 +256,8 @@ public class MetalToolTipUI g.setColor(acceleratorForeground); fm = t.getFontMetrics(acceleratorFont); int width = fm.stringWidth(acceleratorString); - g.drawString(acceleratorString, vr.x + vr.width - width - padSpaceBetweenStrings/2, - vr.y + vr.height - fm.getDescent()); + g.drawString(acceleratorString, vr.x + vr.width - width + - padSpaceBetweenStrings / 2, vr.y + vr.height - fm.getDescent()); } g.setColor(saved); diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalUtils.java b/libjava/classpath/javax/swing/plaf/metal/MetalUtils.java index 03617aa4099..72cbb34a6dc 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalUtils.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalUtils.java @@ -104,7 +104,7 @@ class MetalUtils else g.setColor(dark); - for (int mX = x + (xOff); mX < (x + w); mX += 4) + for (int mX = x + xOff; mX < (x + w); mX += 4) { g.drawLine(mX, mY, mX, mY); } diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiComboBoxUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiComboBoxUI.java index 05279d7d654..33b432152bf 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiComboBoxUI.java @@ -357,7 +357,8 @@ public class MultiComboBoxUI extends ComboBoxUI * @param c the component. * @param visible the visible state. */ - public void setPopupVisible(JComboBox c, boolean visible) { + public void setPopupVisible(JComboBox c, boolean visible) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { @@ -376,7 +377,8 @@ public class MultiComboBoxUI extends ComboBoxUI * * @return The result for the UI delegate from the primary look and feel. */ - public boolean isPopupVisible(JComboBox c) { + public boolean isPopupVisible(JComboBox c) + { boolean result = false; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -406,7 +408,8 @@ public class MultiComboBoxUI extends ComboBoxUI * UI delegate in the primary look and feel, and <code>false</code> * otherwise. */ - public boolean isFocusTraversable(JComboBox c) { + public boolean isFocusTraversable(JComboBox c) + { boolean result = false; Iterator iterator = uis.iterator(); // first UI delegate provides the return value diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiFileChooserUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiFileChooserUI.java index 6f88260101c..719f0437497 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiFileChooserUI.java @@ -364,7 +364,8 @@ public class MultiFileChooserUI extends FileChooserUI * @return The filter returned by the UI delegate from the primary * look and feel. */ - public FileFilter getAcceptAllFileFilter(JFileChooser chooser) { + public FileFilter getAcceptAllFileFilter(JFileChooser chooser) + { FileFilter result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -393,7 +394,8 @@ public class MultiFileChooserUI extends FileChooserUI * @return The view returned by the UI delegate from the primary * look and feel. */ - public FileView getFileView(JFileChooser chooser) { + public FileView getFileView(JFileChooser chooser) + { FileView result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -422,7 +424,8 @@ public class MultiFileChooserUI extends FileChooserUI * @return The text returned by the UI delegate from the primary * look and feel. */ - public String getApproveButtonText(JFileChooser chooser) { + public String getApproveButtonText(JFileChooser chooser) + { String result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -451,7 +454,8 @@ public class MultiFileChooserUI extends FileChooserUI * @return The title returned by the UI delegate from the primary * look and feel. */ - public String getDialogTitle(JFileChooser chooser) { + public String getDialogTitle(JFileChooser chooser) + { String result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -476,7 +480,8 @@ public class MultiFileChooserUI extends FileChooserUI * * @param chooser the file chooser. */ - public void rescanCurrentDirectory(JFileChooser chooser) { + public void rescanCurrentDirectory(JFileChooser chooser) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { @@ -493,7 +498,8 @@ public class MultiFileChooserUI extends FileChooserUI * @param chooser the file chooser. * @param file the file. */ - public void ensureFileIsVisible(JFileChooser chooser, File file) { + public void ensureFileIsVisible(JFileChooser chooser, File file) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiListUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiListUI.java index 7350b454115..78c22419f34 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiListUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiListUI.java @@ -364,7 +364,8 @@ public class MultiListUI extends ListUI * @return The index returned by the UI delegate from the primary * look and feel. */ - public int locationToIndex(JList list, Point location) { + public int locationToIndex(JList list, Point location) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -394,7 +395,8 @@ public class MultiListUI extends ListUI * @return The location returned by the UI delegate from the primary * look and feel. */ - public Point indexToLocation(JList list, int index) { + public Point indexToLocation(JList list, int index) + { Point result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -425,7 +427,8 @@ public class MultiListUI extends ListUI * @return The bounds returned by the UI delegate from the primary * look and feel. */ - public Rectangle getCellBounds(JList list, int index1, int index2) { + public Rectangle getCellBounds(JList list, int index1, int index2) + { Rectangle result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiLookAndFeel.java b/libjava/classpath/javax/swing/plaf/multi/MultiLookAndFeel.java index 2bd358dd01e..12351655a04 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiLookAndFeel.java @@ -49,7 +49,8 @@ import javax.swing.plaf.ComponentUI; * A look and feel that provides the ability to use auxiliary look and feels * in addition to the primary look and feel. */ -public class MultiLookAndFeel extends LookAndFeel { +public class MultiLookAndFeel extends LookAndFeel +{ /** * Creates a new instance of the look and feel. diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java index c5cb913a068..8d6f3861cff 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java @@ -356,7 +356,8 @@ public class MultiOptionPaneUI extends OptionPaneUI * * @param pane the option pane. */ - public void selectInitialValue(JOptionPane pane) { + public void selectInitialValue(JOptionPane pane) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { @@ -375,7 +376,8 @@ public class MultiOptionPaneUI extends OptionPaneUI * * @return The result for the UI delegate from the primary look and feel. */ - public boolean containsCustomComponents(JOptionPane pane) { + public boolean containsCustomComponents(JOptionPane pane) + { boolean result = false; Iterator iterator = uis.iterator(); // first UI delegate provides the return value diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java index f481f8109d9..70ea4f13be1 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java @@ -356,7 +356,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * * @param pane the component. */ - public void resetToPreferredSizes(JSplitPane pane) { + public void resetToPreferredSizes(JSplitPane pane) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { @@ -372,7 +373,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * @param pane the component. * @param location the location. */ - public void setDividerLocation(JSplitPane pane, int location) { + public void setDividerLocation(JSplitPane pane, int location) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { @@ -392,7 +394,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * @return The location returned by the UI delegate from the primary * look and feel. */ - public int getDividerLocation(JSplitPane pane) { + public int getDividerLocation(JSplitPane pane) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -421,7 +424,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * @return The location returned by the UI delegate from the primary * look and feel. */ - public int getMinimumDividerLocation(JSplitPane pane) { + public int getMinimumDividerLocation(JSplitPane pane) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -450,7 +454,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * @return The location returned by the UI delegate from the primary * look and feel. */ - public int getMaximumDividerLocation(JSplitPane pane) { + public int getMaximumDividerLocation(JSplitPane pane) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -476,7 +481,8 @@ public class MultiSplitPaneUI extends SplitPaneUI * @param pane the component. * @param g the graphics device. */ - public void finishedPaintingChildren(JSplitPane pane, Graphics g) { + public void finishedPaintingChildren(JSplitPane pane, Graphics g) + { Iterator iterator = uis.iterator(); while (iterator.hasNext()) { diff --git a/libjava/classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java index 575de192a53..2a2599bde1b 100644 --- a/libjava/classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java @@ -364,7 +364,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI * @return The tab index returned by the UI delegate from the primary * look and feel. */ - public int tabForCoordinate(JTabbedPane pane, int x, int y) { + public int tabForCoordinate(JTabbedPane pane, int x, int y) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -394,7 +395,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI * @return The bounds returned by the UI delegate from the primary * look and feel. */ - public Rectangle getTabBounds(JTabbedPane pane, int index) { + public Rectangle getTabBounds(JTabbedPane pane, int index) + { Rectangle result = null; Iterator iterator = uis.iterator(); // first UI delegate provides the return value @@ -423,7 +425,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI * @return The count returned by the UI delegate from the primary * look and feel. */ - public int getTabRunCount(JTabbedPane pane) { + public int getTabRunCount(JTabbedPane pane) + { int result = 0; Iterator iterator = uis.iterator(); // first UI delegate provides the return value diff --git a/libjava/classpath/javax/swing/table/AbstractTableModel.java b/libjava/classpath/javax/swing/table/AbstractTableModel.java index 3e9f6e9b382..7914e0b3f46 100644 --- a/libjava/classpath/javax/swing/table/AbstractTableModel.java +++ b/libjava/classpath/javax/swing/table/AbstractTableModel.java @@ -1,5 +1,5 @@ /* AbstractTableModel.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -83,7 +83,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable StringBuffer buffer = new StringBuffer(); while (columnIndex >= 0) { - buffer.insert (0, (char) ('A' + columnIndex % 26)); + buffer.insert(0, (char) ('A' + columnIndex % 26)); columnIndex = columnIndex / 26 - 1; } return buffer.toString(); @@ -221,7 +221,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable * @param firstRow the index of the first row. * @param lastRow the index of the last row. */ - public void fireTableRowsInserted (int firstRow, int lastRow) + public void fireTableRowsInserted(int firstRow, int lastRow) { fireTableChanged(new TableModelEvent(this, firstRow, lastRow, TableModelEvent.ALL_COLUMNS, @@ -235,7 +235,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable * @param firstRow the index of the first row. * @param lastRow the index of the last row. */ - public void fireTableRowsUpdated (int firstRow, int lastRow) + public void fireTableRowsUpdated(int firstRow, int lastRow) { fireTableChanged(new TableModelEvent(this, firstRow, lastRow, TableModelEvent.ALL_COLUMNS, @@ -263,7 +263,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable * @param row the row index. * @param column the column index. */ - public void fireTableCellUpdated (int row, int column) + public void fireTableCellUpdated(int row, int column) { fireTableChanged(new TableModelEvent(this, row, row, column)); } @@ -282,7 +282,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable for (index = 0; index < list.length; index += 2) { listener = (TableModelListener) list [index + 1]; - listener.tableChanged (event); + listener.tableChanged(event); } } diff --git a/libjava/classpath/javax/swing/table/DefaultTableModel.java b/libjava/classpath/javax/swing/table/DefaultTableModel.java index 09be2f75239..79285903c00 100644 --- a/libjava/classpath/javax/swing/table/DefaultTableModel.java +++ b/libjava/classpath/javax/swing/table/DefaultTableModel.java @@ -1,5 +1,5 @@ /* DefaultTableModel.java -- - Copyright (C) 2002, 2004, 2005, Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -249,7 +249,7 @@ public class DefaultTableModel extends AbstractTableModel public void setColumnIdentifiers(Vector columnIdentifiers) { this.columnIdentifiers = columnIdentifiers; - setColumnCount((columnIdentifiers == null ? 0 : columnIdentifiers.size())); + setColumnCount(columnIdentifiers == null ? 0 : columnIdentifiers.size()); } /** @@ -289,13 +289,13 @@ public class DefaultTableModel extends AbstractTableModel if (rowCount < existingRowCount) { dataVector.setSize(rowCount); - fireTableRowsDeleted(rowCount,existingRowCount-1); + fireTableRowsDeleted(rowCount, existingRowCount - 1); } else { int rowsToAdd = rowCount - existingRowCount; addExtraRows(rowsToAdd, columnIdentifiers.size()); - fireTableRowsInserted(existingRowCount,rowCount-1); + fireTableRowsInserted(existingRowCount, rowCount - 1); } } @@ -353,7 +353,8 @@ public class DefaultTableModel extends AbstractTableModel * @param columnName the column name (<code>null</code> permitted). * @param columnData the column data. */ - public void addColumn(Object columnName, Object[] columnData) { + public void addColumn(Object columnName, Object[] columnData) + { if (columnData != null) { // check columnData array for cases where the number of items @@ -384,7 +385,8 @@ public class DefaultTableModel extends AbstractTableModel * * @param rowData the row data (<code>null</code> permitted). */ - public void addRow(Vector rowData) { + public void addRow(Vector rowData) + { int rowIndex = dataVector.size(); dataVector.add(rowData); newRowsAdded(new TableModelEvent( @@ -398,7 +400,8 @@ public class DefaultTableModel extends AbstractTableModel * * @param rowData the row data (<code>null</code> permitted). */ - public void addRow(Object[] rowData) { + public void addRow(Object[] rowData) + { addRow(convertToVector(rowData)); } @@ -408,9 +411,10 @@ public class DefaultTableModel extends AbstractTableModel * @param row the row index. * @param rowData the row data. */ - public void insertRow(int row, Vector rowData) { + public void insertRow(int row, Vector rowData) + { dataVector.add(row, rowData); - fireTableRowsInserted(row,row); + fireTableRowsInserted(row, row); } /** @@ -419,7 +423,8 @@ public class DefaultTableModel extends AbstractTableModel * @param row the row index. * @param rowData the row data. */ - public void insertRow(int row, Object[] rowData) { + public void insertRow(int row, Object[] rowData) + { insertRow(row, convertToVector(rowData)); } @@ -431,7 +436,8 @@ public class DefaultTableModel extends AbstractTableModel * @param endIndex the end row. * @param toIndex the row to move to. */ - public void moveRow(int startIndex, int endIndex, int toIndex) { + public void moveRow(int startIndex, int endIndex, int toIndex) + { Vector removed = new Vector(); for (int i = endIndex; i >= startIndex; i--) { @@ -452,9 +458,10 @@ public class DefaultTableModel extends AbstractTableModel * * @param row the row index. */ - public void removeRow(int row) { + public void removeRow(int row) + { dataVector.remove(row); - fireTableRowsDeleted(row,row); + fireTableRowsDeleted(row, row); } /** @@ -462,7 +469,8 @@ public class DefaultTableModel extends AbstractTableModel * * @return The row count. */ - public int getRowCount() { + public int getRowCount() + { return dataVector.size(); } @@ -471,8 +479,9 @@ public class DefaultTableModel extends AbstractTableModel * * @return The column count. */ - public int getColumnCount() { - return (columnIdentifiers == null ? 0 : columnIdentifiers.size()); + public int getColumnCount() + { + return columnIdentifiers == null ? 0 : columnIdentifiers.size(); } /** @@ -485,7 +494,8 @@ public class DefaultTableModel extends AbstractTableModel * * @return The column name. */ - public String getColumnName(int column) { + public String getColumnName(int column) + { String result = ""; if (columnIdentifiers == null) result = super.getColumnName(column); @@ -516,7 +526,8 @@ public class DefaultTableModel extends AbstractTableModel * * @return <code>true</code> in all cases. */ - public boolean isCellEditable(int row, int column) { + public boolean isCellEditable(int row, int column) + { return true; } @@ -529,7 +540,8 @@ public class DefaultTableModel extends AbstractTableModel * @return The value (<code>Object</code>, possibly <code>null</code>) at * the specified cell in the table. */ - public Object getValueAt(int row, int column) { + public Object getValueAt(int row, int column) + { return ((Vector) dataVector.get(row)).get(column); } @@ -541,9 +553,10 @@ public class DefaultTableModel extends AbstractTableModel * @param row the row index. * @param column the column index. */ - public void setValueAt(Object value, int row, int column) { + public void setValueAt(Object value, int row, int column) + { ((Vector) dataVector.get(row)).set(column, value); - fireTableCellUpdated(row,column); + fireTableCellUpdated(row, column); } /** @@ -554,7 +567,8 @@ public class DefaultTableModel extends AbstractTableModel * @return A vector (or <code>null</code> if the data array * is <code>null</code>). */ - protected static Vector convertToVector(Object[] data) { + protected static Vector convertToVector(Object[] data) + { if (data == null) return null; Vector vector = new Vector(data.length); @@ -571,7 +585,8 @@ public class DefaultTableModel extends AbstractTableModel * @return A vector (or <code>null</code> if the data array * is <code>null</code>. */ - protected static Vector convertToVector(Object[][] data) { + protected static Vector convertToVector(Object[][] data) + { if (data == null) return null; Vector vector = new Vector(data.length); diff --git a/libjava/classpath/javax/swing/table/JTableHeader.java b/libjava/classpath/javax/swing/table/JTableHeader.java index f7c1e1cd589..482317ff0ad 100644 --- a/libjava/classpath/javax/swing/table/JTableHeader.java +++ b/libjava/classpath/javax/swing/table/JTableHeader.java @@ -1,5 +1,5 @@ /* JTableHeader.java -- - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,9 +38,8 @@ exception statement from your version. */ package javax.swing.table; -import gnu.classpath.NotImplementedException; - import java.awt.Color; +import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; @@ -82,282 +81,516 @@ public class JTableHeader extends JComponent protected class AccessibleJTableHeaderEntry extends AccessibleContext implements Accessible, AccessibleComponent { + + private int columnIndex; + + private JTableHeader parent; + + private JTable table; + public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t) - throws NotImplementedException { - throw new Error("not implemented"); + columnIndex = c; + parent = p; + table = t; } + /** + * Returns the column header renderer. + * + * @return The column header renderer. + */ + Component getColumnHeaderRenderer() + { + TableColumn tc = parent.getColumnModel().getColumn(columnIndex); + TableCellRenderer r = tc.getHeaderRenderer(); + if (r == null) + r = parent.getDefaultRenderer(); + return r.getTableCellRendererComponent(table, tc.headerValue, + false, false, -1, columnIndex); + } + + /** + * Returns the accessible context for the column header renderer, or + * <code>null</code>. + * + * @return The accessible context. + */ + AccessibleContext getAccessibleColumnHeaderRenderer() + { + Component c = getColumnHeaderRenderer(); + if (c instanceof Accessible) + return c.getAccessibleContext(); + return null; + } + + /** + * @see #removeFocusListener(FocusListener) + */ public void addFocusListener(FocusListener l) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + c.addFocusListener(l); } + /** + * @see #removePropertyChangeListener(PropertyChangeListener) + */ public void addPropertyChangeListener(PropertyChangeListener l) - throws NotImplementedException { - throw new Error("not implemented"); + // add the listener to the accessible context for the header + // renderer... + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + ac.addPropertyChangeListener(l); } public boolean contains(Point p) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.contains(p); + else + return false; } public AccessibleAction getAccessibleAction() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac instanceof AccessibleAction) + return (AccessibleAction) ac; + else + return null; } public Accessible getAccessibleAt(Point p) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getAccessibleAt(p); + else + return null; } + /** + * Returns <code>null</code> as the header entry has no accessible + * children. + * + * @return <code>null</code>. + */ public Accessible getAccessibleChild(int i) - throws NotImplementedException { - throw new Error("not implemented"); + return null; } + /** + * Returns the number of accessible children, zero in this case. + * + * @return 0 + */ public int getAccessibleChildrenCount() - throws NotImplementedException { - throw new Error("not implemented"); + return 0; } + /** + * Returns the accessible component for this header entry. + * + * @return <code>this</code>. + */ public AccessibleComponent getAccessibleComponent() - throws NotImplementedException { - throw new Error("not implemented"); + return this; } + /** + * Returns the accessible context for this header entry. + * + * @return <code>this</code>. + */ public AccessibleContext getAccessibleContext() - throws NotImplementedException { - throw new Error("not implemented"); + return this; } + /** + * Returns the accessible description. + * + * @return The accessible description. + * + * @see #setAccessibleDescription(String) + */ public String getAccessibleDescription() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + return ac.getAccessibleDescription(); + return accessibleDescription; } + /** + * Returns the index of this header entry. + * + * @return The index of this header entry. + */ public int getAccessibleIndexInParent() - throws NotImplementedException { - throw new Error("not implemented"); + return columnIndex; } + /** + * Returns the accessible name. + * + * @return The accessible name. + * + * @see #setAccessibleName(String) + */ public String getAccessibleName() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + return ac.getAccessibleName(); + return accessibleName; } + /** + * Returns the accessible role for the header entry. + * + * @return The accessible role. + */ public AccessibleRole getAccessibleRole() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + return ac.getAccessibleRole(); + else + return null; } public AccessibleSelection getAccessibleSelection() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac instanceof AccessibleValue) + return (AccessibleSelection) ac; + else + return null; } public AccessibleStateSet getAccessibleStateSet() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + return ac.getAccessibleStateSet(); + else + return null; } public AccessibleText getAccessibleText() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + return ac.getAccessibleText(); + else + return null; } public AccessibleValue getAccessibleValue() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac instanceof AccessibleValue) + return (AccessibleValue) ac; + else + return null; } public Color getBackground() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getBackground(); + else + return null; } public Rectangle getBounds() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getBounds(); + else + return null; } public Cursor getCursor() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getCursor(); + else + return null; } public Font getFont() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getFont(); + else + return null; } public FontMetrics getFontMetrics(Font f) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getFontMetrics(f); + else + return null; } public Color getForeground() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getForeground(); + else + return null; } public Locale getLocale() - throws NotImplementedException { - throw new Error("not implemented"); + Component c = getColumnHeaderRenderer(); + if (c != null) + return c.getLocale(); + return null; } public Point getLocation() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getLocation(); + else + return null; } public Point getLocationOnScreen() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getLocationOnScreen(); + else + return null; } public Dimension getSize() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.getSize(); + else + return null; } public boolean isEnabled() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.isEnabled(); + else + return false; } public boolean isFocusTraversable() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.isFocusTraversable(); + else + return false; } public boolean isShowing() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.isShowing(); + else + return false; } public boolean isVisible() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + return c.isVisible(); + else + return false; } + /** + * @see #addFocusListener(FocusListener) + */ public void removeFocusListener(FocusListener l) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + c.removeFocusListener(l); } + /** + * @see #addPropertyChangeListener(PropertyChangeListener) + */ public void removePropertyChangeListener(PropertyChangeListener l) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + ac.removePropertyChangeListener(l); } + /** + * @see #addFocusListener(FocusListener) + */ public void requestFocus() - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent c = ac.getAccessibleComponent(); + if (c != null) + c.requestFocus(); } + /** + * @see #getAccessibleDescription() + */ public void setAccessibleDescription(String s) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + ac.setAccessibleDescription(s); + else + accessibleDescription = s; } + /** + * @see #getAccessibleName() + */ public void setAccessibleName(String s) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + if (ac != null) + ac.setAccessibleName(s); } public void setBackground(Color c) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setBackground(c); } public void setBounds(Rectangle r) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setBounds(r); } public void setCursor(Cursor c) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setCursor(c); } public void setEnabled(boolean b) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setEnabled(b); } public void setFont(Font f) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setFont(f); } public void setForeground(Color c) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setForeground(c); } public void setLocation(Point p) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setLocation(p); } public void setSize(Dimension d) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setSize(d); } public void setVisible(boolean b) - throws NotImplementedException { - throw new Error("not implemented"); + AccessibleContext ac = getAccessibleColumnHeaderRenderer(); + AccessibleComponent comp = ac.getAccessibleComponent(); + if (comp != null) + comp.setVisible(b); } }; + + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.PANEL; + } + + public int getAccessibleChildrenCount() + { + return table.getColumnCount(); + } + + public Accessible getAccessibleChild(int i) + { + return new AccessibleJTableHeaderEntry(i, JTableHeader.this, table); + } + + public Accessible getAccessibleAt(Point p) + { + return getAccessibleChild(columnAtPoint(p)); + } } /** diff --git a/libjava/classpath/javax/swing/table/TableCellEditor.java b/libjava/classpath/javax/swing/table/TableCellEditor.java index b355311dcb2..15070a7555f 100644 --- a/libjava/classpath/javax/swing/table/TableCellEditor.java +++ b/libjava/classpath/javax/swing/table/TableCellEditor.java @@ -47,19 +47,19 @@ import javax.swing.JTable; * TableCellEditor public interface * @author Andrew Selkirk */ -public interface TableCellEditor extends CellEditor { +public interface TableCellEditor extends CellEditor +{ - /** - * Get table cell editor component - * @param table JTable - * @param value Value of cell - * @param isSelected Cell selected - * @param row Row of cell - * @param column Column of cell - * @returns Component - */ - Component getTableCellEditorComponent(JTable table, - Object value, boolean isSelected, int row, int column); + /** + * Get table cell editor component + * @param table JTable + * @param value Value of cell + * @param isSelected Cell selected + * @param row Row of cell + * @param column Column of cell + * @return Component + */ + Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, int row, int column); - -} // TableCellEditor +} diff --git a/libjava/classpath/javax/swing/table/TableCellRenderer.java b/libjava/classpath/javax/swing/table/TableCellRenderer.java index 639b4b9ad73..6c1fecf560b 100644 --- a/libjava/classpath/javax/swing/table/TableCellRenderer.java +++ b/libjava/classpath/javax/swing/table/TableCellRenderer.java @@ -46,21 +46,21 @@ import javax.swing.JTable; * TableCellRenderer public interface * @author Andrew Selkirk */ -public interface TableCellRenderer { +public interface TableCellRenderer +{ - /** - * Get table cell renderer component - * @param table JTable - * @param value Value of cell - * @param isSelected Cell selected - * @param hasFocus Cell has focus - * @param row Row of cell - * @param column Column of cell - * @returns Component - */ - Component getTableCellRendererComponent(JTable table, - Object value, boolean isSelected, boolean hasFocus, - int row, int column); + /** + * Get table cell renderer component + * @param table JTable + * @param value Value of cell + * @param isSelected Cell selected + * @param hasFocus Cell has focus + * @param row Row of cell + * @param column Column of cell + * @return Component + */ + Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column); -} // TableCellRenderer +} diff --git a/libjava/classpath/javax/swing/text/AbstractWriter.java b/libjava/classpath/javax/swing/text/AbstractWriter.java index d5fc395e1ac..8d5a6075df4 100644 --- a/libjava/classpath/javax/swing/text/AbstractWriter.java +++ b/libjava/classpath/javax/swing/text/AbstractWriter.java @@ -183,7 +183,8 @@ public abstract class AbstractWriter if (! elt.isLeaf()) throw new BadLocationException("Element is not a leaf", elt.getStartOffset()); - return document.getText(elt.getStartOffset(), elt.getEndOffset()); + return document.getText(elt.getStartOffset(), + elt.getEndOffset() - elt.getStartOffset()); } /** diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java index c9369af2089..4ad204c00c9 100644 --- a/libjava/classpath/javax/swing/text/DefaultCaret.java +++ b/libjava/classpath/javax/swing/text/DefaultCaret.java @@ -216,13 +216,26 @@ public class DefaultCaret extends Rectangle */ public void propertyChange(PropertyChangeEvent e) { - if (e.getPropertyName().equals("document")) + String name = e.getPropertyName(); + + if (name.equals("document")) { Document oldDoc = (Document) e.getOldValue(); oldDoc.removeDocumentListener(documentListener); Document newDoc = (Document) e.getNewValue(); newDoc.addDocumentListener(documentListener); } + else if (name.equals("editable")) + { + active = (((Boolean) e.getNewValue()).booleanValue() + && textComponent.isEnabled()); + } + else if (name.equals("enabled")) + { + active = (((Boolean) e.getNewValue()).booleanValue() + && textComponent.isEditable()); + } + } } @@ -281,8 +294,10 @@ public class DefaultCaret extends Rectangle /** * The text component in which this caret is installed. + * + * (Package private to avoid synthetic accessor method.) */ - private JTextComponent textComponent; + JTextComponent textComponent; /** * Indicates if the selection should be visible or not. @@ -314,6 +329,12 @@ public class DefaultCaret extends Rectangle * package private to avoid an accessor method. */ boolean visible = false; + + /** Indicates whether the text component where the caret is installed is + * editable and enabled. If either of these properties is <code>false</code> + * the caret is not drawn. + */ + boolean active = true; /** * The current highlight entry. @@ -388,14 +409,23 @@ public class DefaultCaret extends Rectangle /** * Moves the caret position when the mouse is dragged over the text - * component, modifying the selection accordingly. + * component, modifying the selectiony. + * + * <p>When the text component where the caret is installed is disabled, + * the selection is not change but you can still scroll the text and + * update the caret's location.</p> * * @param event the <code>MouseEvent</code> describing the drag operation */ public void mouseDragged(MouseEvent event) { if (event.getButton() == MouseEvent.BUTTON1) - moveCaret(event); + { + if (textComponent.isEnabled()) + moveCaret(event); + else + positionCaret(event); + } } /** @@ -426,6 +456,10 @@ public class DefaultCaret extends Rectangle */ public void mouseClicked(MouseEvent event) { + // Do not modify selection if component is disabled. + if (!textComponent.isEnabled()) + return; + int count = event.getClickCount(); if (event.getButton() == MouseEvent.BUTTON1 && count >= 2) @@ -523,7 +557,7 @@ public class DefaultCaret extends Rectangle // implemented (in regard to text components): // - a left-click moves the caret // - a left-click when shift is held down expands the selection - // - a right-click or click with any additionaly mouse button + // - a right-click or click with any additional mouse button // on a text component is ignored // - a middle-click positions the caret and pastes the clipboard // contents. @@ -540,6 +574,7 @@ public class DefaultCaret extends Rectangle else { positionCaret(event); + textComponent.paste(); } else @@ -564,8 +599,11 @@ public class DefaultCaret extends Rectangle */ public void focusGained(FocusEvent event) { - setVisible(true); - updateTimerStatus(); + if (textComponent.isEditable()) + { + setVisible(true); + updateTimerStatus(); + } } /** @@ -575,9 +613,10 @@ public class DefaultCaret extends Rectangle */ public void focusLost(FocusEvent event) { - if (event.isTemporary() == false) + if (textComponent.isEditable() && event.isTemporary() == false) { setVisible(false); + // Stop the blinker, if running. if (blinkTimer != null && blinkTimer.isRunning()) blinkTimer.stop(); @@ -670,6 +709,7 @@ public class DefaultCaret extends Rectangle textComponent.addPropertyChangeListener(propertyChangeListener); documentListener = new DocumentHandler(); textComponent.getDocument().addDocumentListener(documentListener); + active = textComponent.isEditable() && textComponent.isEnabled(); repaint(); } @@ -872,7 +912,7 @@ public class DefaultCaret extends Rectangle } // Now draw the caret on the new position if visible. - if (visible) + if (visible && active) { g.setColor(textComponent.getCaretColor()); g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height - 1); @@ -1013,7 +1053,9 @@ public class DefaultCaret extends Rectangle this.dot = Math.max(this.dot, 0); handleHighlight(); + appear(); + adjustVisibility(this); } } @@ -1050,7 +1092,9 @@ public class DefaultCaret extends Rectangle this.mark = this.dot; clearHighlight(); + appear(); + adjustVisibility(this); } } @@ -1104,7 +1148,7 @@ public class DefaultCaret extends Rectangle */ public boolean isVisible() { - return visible; + return visible && active; } /** diff --git a/libjava/classpath/javax/swing/text/DefaultEditorKit.java b/libjava/classpath/javax/swing/text/DefaultEditorKit.java index 1b686182b6a..8602e69f8e7 100644 --- a/libjava/classpath/javax/swing/text/DefaultEditorKit.java +++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java @@ -52,6 +52,7 @@ import java.io.Reader; import java.io.Writer; import javax.swing.Action; +import javax.swing.SwingConstants; /** * The default implementation of {@link EditorKit}. This <code>EditorKit</code> @@ -60,6 +61,7 @@ import javax.swing.Action; * * @author original author unknown * @author Roman Kennke (roman@kennke.org) + * @author Robert Schuster (robertschuster@fsfe.org) */ public class DefaultEditorKit extends EditorKit { @@ -123,6 +125,122 @@ public class DefaultEditorKit extends EditorKit } } + static class SelectionBeginWordAction extends TextAction + { + SelectionBeginWordAction() + { + super(selectionBeginWordAction); + } + + public void actionPerformed(ActionEvent event) + { + try + { + JTextComponent t = getTextComponent(event); + + if (t != null) + { + int offs = Utilities.getWordStart(t, t.getCaretPosition()); + + Caret c = t.getCaret(); + c.moveDot(offs); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + + static class SelectionEndWordAction extends TextAction + { + SelectionEndWordAction() + { + super(selectionEndWordAction); + } + + public void actionPerformed(ActionEvent event) + { + try + { + JTextComponent t = getTextComponent(event); + + if (t != null) + { + int offs = Utilities.getWordEnd(t, t.getCaretPosition()); + + Caret c = t.getCaret(); + c.moveDot(offs); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + + static class BeginWordAction extends TextAction + { + BeginWordAction() + { + super(beginWordAction); + } + + public void actionPerformed(ActionEvent event) + { + try + { + JTextComponent t = getTextComponent(event); + + if (t != null) + { + int offs = Utilities.getWordStart(t, t.getCaretPosition()); + + Caret c = t.getCaret(); + c.setDot(offs); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + + static class EndWordAction extends TextAction + { + EndWordAction() + { + super(endWordAction); + } + + public void actionPerformed(ActionEvent event) + { + try + { + JTextComponent t = getTextComponent(event); + + if (t != null) + { + int offs = Utilities.getWordEnd(t, t.getCaretPosition()); + + Caret c = t.getCaret(); + c.setDot(offs); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + static class PreviousWordAction extends TextAction { @@ -258,336 +376,260 @@ public class DefaultEditorKit extends EditorKit } } } - - static class SelectionEndLineAction - extends TextAction + + static class SelectionBeginLineAction + extends TextAction { - SelectionEndLineAction() + + SelectionBeginLineAction() { - super(selectionEndLineAction); + super(selectionBeginLineAction); } public void actionPerformed(ActionEvent event) { JTextComponent t = getTextComponent(event); - try - { - Point p = t.modelToView(t.getCaret().getDot()).getLocation(); - int cur = t.getCaretPosition(); - int y = p.y; - int length = t.getDocument().getLength(); - while (y == p.y && cur < length) - y = t.modelToView(++cur).getLocation().y; - if (cur != length) - cur--; - - Caret c = t.getCaret(); - c.moveDot(cur); - c.setMagicCaretPosition(t.modelToView(cur).getLocation()); - } - catch (BadLocationException ble) - { - // Nothing to do here - } + Caret c = t.getCaret(); + try + { + int offs = Utilities.getRowStart(t, c.getDot()); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + catch(BadLocationException ble) + { + // Can't happen. + } + } } - static class SelectionBeginLineAction + static class SelectionEndLineAction extends TextAction { - SelectionBeginLineAction() + SelectionEndLineAction() { - super(selectionBeginLineAction); + super(selectionEndLineAction); } public void actionPerformed(ActionEvent event) { JTextComponent t = getTextComponent(event); - + Caret c = t.getCaret(); try - { - // TODO: There is a more efficent solution, but - // viewToModel doesn't work properly. - Point p = t.modelToView(t.getCaret().getDot()).getLocation(); - - int cur = t.getCaretPosition(); - int y = p.y; - - while (y == p.y && cur > 0) - y = t.modelToView(--cur).getLocation().y; - if (cur != 0) - cur++; - - Caret c = t.getCaret(); - c.moveDot(cur); - c.setMagicCaretPosition(t.modelToView(cur).getLocation()); - } - catch (BadLocationException ble) - { - // Do nothing here. - } + { + int offs = Utilities.getRowEnd(t, c.getDot()); + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + catch(BadLocationException ble) + { + // Can't happen. + } + } } - - static class SelectionDownAction - extends TextAction + + static class SelectLineAction extends TextAction { - SelectionDownAction() + SelectLineAction() { - super(selectionDownAction); + super(selectLineAction); } - + public void actionPerformed(ActionEvent event) { JTextComponent t = getTextComponent(event); + Caret c = t.getCaret(); try { - if (t != null) - { - Caret c = t.getCaret(); - // The magic caret position may be null when the caret - // has not moved yet. - Point mcp = c.getMagicCaretPosition(); - int x = (mcp != null) ? mcp.x : 0; - int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x); - - if (pos > -1) - t.moveCaretPosition(pos); - } + int offs1 = Utilities.getRowStart(t, c.getDot()); + int offs2 = Utilities.getRowEnd(t, c.getDot()); + + c.setDot(offs2); + c.moveDot(offs1); + + c.setMagicCaretPosition(t.modelToView(offs2).getLocation()); } - catch(BadLocationException ble) + catch(BadLocationException ble) { - // FIXME: Swallowing allowed? + // Can't happen. } } } - - static class SelectionUpAction - extends TextAction + + static class SelectWordAction extends TextAction { - SelectionUpAction() + SelectWordAction() { - super(selectionUpAction); + super(selectWordAction); } - + public void actionPerformed(ActionEvent event) { JTextComponent t = getTextComponent(event); + Caret c = t.getCaret(); + int dot = c.getDot(); + try { - if (t != null) + int wordStart = Utilities.getWordStart(t, dot); + + if (dot == wordStart) { - Caret c = t.getCaret(); - // The magic caret position may be null when the caret - // has not moved yet. - Point mcp = c.getMagicCaretPosition(); - int x = (mcp != null) ? mcp.x : 0; - int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x); + // Current cursor position is on the first character in a word. + c.setDot(wordStart); + c.moveDot(Utilities.getWordEnd(t, wordStart)); + } + else + { + // Current cursor position is not on the first character + // in a word. + int nextWord = Utilities.getNextWord(t, dot); + int previousWord = Utilities.getPreviousWord(t, dot); + int previousWordEnd = Utilities.getWordEnd(t, previousWord); - if (pos > -1) - t.moveCaretPosition(pos); + // Cursor position is in the space between two words. In such a + // situation just select the space. + if (dot >= previousWordEnd && dot <= nextWord) + { + c.setDot(previousWordEnd); + c.moveDot(nextWord); + } + else + { + // Cursor position is inside a word. Just select it then. + c.setDot(previousWord); + c.moveDot(previousWordEnd); + } } + + // If the position was updated change the magic caret position + // as well. + if (c.getDot() != dot) + c.setMagicCaretPosition(t.modelToView(c.getDot()).getLocation()); + } - catch(BadLocationException ble) + catch(BadLocationException ble) { - // FIXME: Swallowing allowed? + // Can't happen. } } } + static class SelectionDownAction + extends TextAction.VerticalMovementAction + { + SelectionDownAction() + { + super(selectionDownAction, SwingConstants.SOUTH); + } + + protected void actionPerformedImpl(Caret c, int offs) + { + c.moveDot(offs); + } + + } + + static class SelectionUpAction + extends TextAction.VerticalMovementAction + { + SelectionUpAction() + { + super(selectionUpAction, SwingConstants.NORTH); + } + + protected void actionPerformedImpl(Caret c, int offs) + { + c.moveDot(offs); + } + + } + static class SelectionForwardAction - extends TextAction + extends TextAction.HorizontalMovementAction { SelectionForwardAction() { - super(selectionForwardAction); + super(selectionForwardAction, SwingConstants.EAST); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - if (t != null) - { - int offs = t.getCaretPosition() + 1; - - if(offs <= t.getDocument().getLength()) - { - Caret c = t.getCaret(); - c.moveDot(offs); - try - { - c.setMagicCaretPosition(t.modelToView(offs).getLocation()); - } - catch(BadLocationException ble) - { - // Can't happen. - } - } - } + c.moveDot(offs); } } static class SelectionBackwardAction - extends TextAction + extends TextAction.HorizontalMovementAction { SelectionBackwardAction() { - super(selectionBackwardAction); + super(selectionBackwardAction, SwingConstants.WEST); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - if (t != null) - { - int offs = t.getCaretPosition() - 1; - - if(offs >= 0) - { - Caret c = t.getCaret(); - c.moveDot(offs); - try - { - c.setMagicCaretPosition(t.modelToView(offs).getLocation()); - } - catch(BadLocationException ble) - { - // Can't happen. - } - } - } + c.moveDot(offs); } } static class DownAction - extends TextAction + extends TextAction.VerticalMovementAction { DownAction() { - super(downAction); + super(downAction, SwingConstants.SOUTH); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - try - { - if (t != null) - { - Caret c = t.getCaret(); - // The magic caret position may be null when the caret - // has not moved yet. - Point mcp = c.getMagicCaretPosition(); - int x = (mcp != null) ? mcp.x : 0; - int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x); - - if (pos > -1) - t.setCaretPosition(pos); - } - } - catch(BadLocationException ble) - { - // FIXME: Swallowing allowed? - } + c.setDot(offs); } } static class UpAction - extends TextAction + extends TextAction.VerticalMovementAction { UpAction() { - super(upAction); + super(upAction, SwingConstants.NORTH); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - try - { - if (t != null) - { - Caret c = t.getCaret(); - // The magic caret position may be null when the caret - // has not moved yet. - Point mcp = c.getMagicCaretPosition(); - int x = (mcp != null) ? mcp.x : 0; - int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x); - - if (pos > -1) - t.setCaretPosition(pos); - } - } - catch(BadLocationException ble) - { - // FIXME: Swallowing allowed? - } + c.setDot(offs); } + } static class ForwardAction - extends TextAction + extends TextAction.HorizontalMovementAction { ForwardAction() { - super(forwardAction); + super(forwardAction, SwingConstants.EAST); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - if (t != null) - { - int offs = t.getCaretPosition() + 1; - if (offs <= t.getDocument().getLength()) - { - Caret c = t.getCaret(); - c.setDot(offs); - - try - { - c.setMagicCaretPosition(t.modelToView(offs).getLocation()); - } - catch (BadLocationException ble) - { - // Should not happen. - } - } - } - + c.setDot(offs); } + } static class BackwardAction - extends TextAction + extends TextAction.HorizontalMovementAction { BackwardAction() { - super(backwardAction); + super(backwardAction, SwingConstants.WEST); } - public void actionPerformed(ActionEvent event) + protected void actionPerformedImpl(Caret c, int offs) { - JTextComponent t = getTextComponent(event); - if (t != null) - { - int offs = t.getCaretPosition() - 1; - if (offs >= 0) - { - Caret c = t.getCaret(); - c.setDot(offs); - - try - { - c.setMagicCaretPosition(t.modelToView(offs).getLocation()); - } - catch (BadLocationException ble) - { - // Should not happen. - } - } - } + c.setDot(offs); } + } static class DeletePrevCharAction @@ -720,6 +762,55 @@ public class DefaultEditorKit extends EditorKit } } + static class BeginAction extends TextAction + { + + BeginAction() + { + super(beginAction); + } + + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + Caret c = t.getCaret(); + c.setDot(0); + try + { + c.setMagicCaretPosition(t.modelToView(0).getLocation()); + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + + static class EndAction extends TextAction + { + + EndAction() + { + super(endAction); + } + + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + int offs = t.getDocument().getLength(); + Caret c = t.getCaret(); + c.setDot(offs); + try + { + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + catch(BadLocationException ble) + { + // Can't happen. + } + } + } + /** * Creates a beep on the PC speaker. * @@ -867,8 +958,8 @@ public class DefaultEditorKit extends EditorKit // first we filter the following events: // - control characters // - key events with the ALT modifier (FIXME: filter that too!) - char c = event.getActionCommand().charAt(0); - if (Character.isISOControl(c)) + int cp = event.getActionCommand().codePointAt(0); + if (Character.isISOControl(cp)) return; JTextComponent t = getTextComponent(event); @@ -1345,8 +1436,6 @@ public class DefaultEditorKit extends EditorKit * The <code>Action</code>s that are supported by the * <code>DefaultEditorKit</code>. */ - // TODO: All these inner classes look ugly. Maybe work out a better way - // to handle this. private static Action[] defaultActions = new Action[] { // These classes are public because they are so in the RI. @@ -1387,9 +1476,21 @@ public class DefaultEditorKit extends EditorKit new PreviousWordAction(), new SelectionPreviousWordAction(), + new BeginAction(), new SelectionBeginAction(), + + new EndAction(), new SelectionEndAction(), + + new BeginWordAction(), + new SelectionBeginWordAction(), + + new EndWordAction(), + new SelectionEndWordAction(), + new SelectAllAction(), + new SelectLineAction(), + new SelectWordAction() }; /** diff --git a/libjava/classpath/javax/swing/text/FieldView.java b/libjava/classpath/javax/swing/text/FieldView.java index 0c2f0fef156..f41f9013092 100644 --- a/libjava/classpath/javax/swing/text/FieldView.java +++ b/libjava/classpath/javax/swing/text/FieldView.java @@ -50,6 +50,7 @@ import java.awt.event.ActionListener; import javax.swing.BoundedRangeModel; import javax.swing.JTextField; +import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; @@ -241,12 +242,29 @@ public class FieldView extends PlainView Shape newAlloc = adjustAllocation(s); - // Set a clip to prevent drawing outside of the allocation area. - // TODO: Is there a better way to achieve this? Shape clip = g.getClip(); - g.setClip(s); + if (clip != null) + { + // Reason for this: The allocation area is always determined by the + // size of the component (and its insets) regardless of whether + // parts of the component are invisible or not (e.g. when the + // component is part of a JScrollPane and partly moved out of + // the user-visible range). However the clip of the Graphics + // instance may be adjusted properly to that condition but + // does not handle insets. By calculating the intersection + // we get the correct clip to paint the text in all cases. + Rectangle r = s.getBounds(); + Rectangle cb = clip.getBounds(); + SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, cb); + + g.setClip(cb); + } + else + g.setClip(s); + super.paint(g, newAlloc); g.setClip(clip); + } public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf) diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java index 219accb4056..1780d7ddfad 100644 --- a/libjava/classpath/javax/swing/text/GapContent.java +++ b/libjava/classpath/javax/swing/text/GapContent.java @@ -39,13 +39,10 @@ exception statement from your version. */ package javax.swing.text; import java.io.Serializable; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; -import java.util.ListIterator; +import java.util.Set; import java.util.Vector; +import java.util.WeakHashMap; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; @@ -60,8 +57,6 @@ import javax.swing.undo.UndoableEdit; * minimal (simple array access). The array only has to be shifted around when * the insertion point moves (then the gap also moves and one array copy is * necessary) or when the gap is filled up and the buffer has to be enlarged. - * - * TODO: Implement UndoableEdit support stuff */ public class GapContent implements AbstractDocument.Content, Serializable @@ -71,11 +66,14 @@ public class GapContent * A {@link Position} implementation for <code>GapContent</code>. */ private class GapContentPosition - implements Position, Comparable + implements Position { - /** The index within the buffer array. */ - int mark; + /** + * The index to the positionMarks array entry, which in turn holds the + * mark into the buffer array. + */ + int index; /** * Creates a new GapContentPosition object. @@ -84,33 +82,20 @@ public class GapContent */ GapContentPosition(int mark) { - this.mark = mark; - } - - /** - * Comparable interface implementation. This is used to store all - * positions in an ordered fashion. - * - * @param o the object to be compared to this - * - * @return a negative integer if this is less than <code>o</code>, zero - * if both are equal or a positive integer if this is greater than - * <code>o</code> - * - * @throws ClassCastException if <code>o</code> is not a - * GapContentPosition or Integer object - */ - public int compareTo(Object o) - { - if (o instanceof Integer) + // Try to find the mark in the positionMarks array, and store the index + // to it. + synchronized (GapContent.this) { - int otherMark = ((Integer) o).intValue(); - return mark - otherMark; - } - else - { - GapContentPosition other = (GapContentPosition) o; - return mark - other.mark; + int i = binarySearch(positionMarks, mark, numMarks); + if (i >= 0) // mark found + { + index = i; + } + else + { + index = -i - 1; + insertMark(index, mark); + } } } @@ -121,14 +106,19 @@ public class GapContent */ public int getOffset() { - // Check precondition. - assert mark <= gapStart || mark >= gapEnd : "mark: " + mark - + ", gapStart: " + gapStart - + ", gapEnd: " + gapEnd; - if (mark <= gapStart) - return mark; - else - return mark - (gapEnd - gapStart); + synchronized (GapContent.this) + { + // Fetch the actual mark. + int mark = positionMarks[index]; + // Check precondition. + assert mark <= gapStart || mark >= gapEnd : "mark: " + mark + + ", gapStart: " + gapStart + + ", gapEnd: " + gapEnd; + int res = mark; + if (mark > gapStart) + res -= (gapEnd - gapStart); + return res; + } } } @@ -209,40 +199,6 @@ public class GapContent } - /** - * Compares WeakReference objects in a List by comparing the referenced - * objects instead. - * - * @author Roman Kennke (kennke@aicas.com) - */ - private class WeakPositionComparator - implements Comparator - { - - /** - * Compares two objects of type WeakReference. The objects are compared - * using the referenced objects compareTo() method. - */ - public int compare(Object o1, Object o2) - { - // Unwrap references. - if (o1 instanceof WeakReference) - o1 = ((WeakReference) o1).get(); - if (o2 instanceof WeakReference) - o2 = ((WeakReference) o2).get(); - - GapContentPosition p1 = (GapContentPosition) o1; - GapContentPosition p2 = (GapContentPosition) o2; - - int retVal; - if (p1 == null || p2 == null) - retVal = -1; - else - retVal = p1.compareTo(p2); - return retVal; - } - } - /** The serialization UID (compatible with JDK1.5). */ private static final long serialVersionUID = -6226052713477823730L; @@ -267,12 +223,26 @@ public class GapContent */ int gapEnd; + // FIXME: We might want to track GC'ed GapContentPositions and remove their + // corresponding marks, or alternativly, perform some regular cleanup of + // the positionMarks array. + + /** + * Holds the marks for positions. These marks are referenced by the + * GapContentPosition instances by an index into this array. + */ + int[] positionMarks; + /** - * The positions generated by this GapContent. They are kept in an ordered - * fashion, so they can be looked up easily. The value objects will be - * WeakReference objects that in turn hold GapContentPosition objects. + * The number of elements in the positionMarks array. The positionMarks array + * might be bigger than the actual number of elements. */ - private ArrayList positions; + int numMarks; + + /** + * (Weakly) Stores the GapContentPosition instances. + */ + WeakHashMap positions; /** * Creates a new GapContent object. @@ -294,7 +264,9 @@ public class GapContent gapStart = 1; gapEnd = size; buffer[0] = '\n'; - positions = new ArrayList(); + positions = new WeakHashMap(); + positionMarks = new int[10]; + numMarks = 0; } /** @@ -483,26 +455,30 @@ public class GapContent */ public Position createPosition(final int offset) throws BadLocationException { - if (offset < 0 || offset > length()) - throw new BadLocationException("The offset was out of the bounds of this" - + " buffer", offset); - - clearPositionReferences(); - - // We store the actual array index in the GapContentPosition. The real - // offset is then calculated in the GapContentPosition. - int mark = offset; - if (offset >= gapStart) - mark += gapEnd - gapStart; - GapContentPosition pos = new GapContentPosition(mark); - WeakReference r = new WeakReference(pos); - - // Add this into our list in a sorted fashion. - int index = Collections.binarySearch(positions, r, - new WeakPositionComparator()); - if (index < 0) - index = -(index + 1); - positions.add(index, r); + // We try to find a GapContentPosition at the specified offset and return + // that. Otherwise we must create a new one. + GapContentPosition pos = null; + Set positionSet = positions.keySet(); + for (Iterator i = positionSet.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + if (p.getOffset() == offset) + { + pos = p; + break; + } + } + + // If none was found, then create and return a new one. + if (pos == null) + { + int mark = offset; + if (mark >= gapStart) + mark += (gapEnd - gapStart); + pos = new GapContentPosition(mark); + positions.put(pos, null); + } + return pos; } @@ -542,7 +518,6 @@ public class GapContent { if (newGapStart == gapStart) return; - int newGapEnd = newGapStart + gapEnd - gapStart; if (newGapStart < gapStart) { @@ -583,7 +558,7 @@ public class GapContent assert newGapStart < gapStart : "The new gap start must be less than the " + "old gap start."; - setPositionsInRange(newGapStart, gapStart - newGapStart, gapStart); + setPositionsInRange(newGapStart, gapStart, false); gapStart = newGapStart; } @@ -602,7 +577,7 @@ public class GapContent assert newGapEnd > gapEnd : "The new gap end must be greater than the " + "old gap end."; - setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd); + setPositionsInRange(gapEnd, newGapEnd, false); gapEnd = newGapEnd; } @@ -688,85 +663,79 @@ public class GapContent else res.clear(); - int endOffset = offset + length; - - int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset), - new WeakPositionComparator()); - if (index1 < 0) - index1 = -(index1 + 1); - - // Search the first index with the specified offset. The binarySearch does - // not necessarily find the first one. - while (index1 > 0) - { - WeakReference r = (WeakReference) positions.get(index1 - 1); - GapContentPosition p = (GapContentPosition) r.get(); - if (p != null && p.mark == offset || p == null) - index1--; - else - break; - } + int endOffs = offset + length; - for (ListIterator i = positions.listIterator(index1); i.hasNext();) + Set positionSet = positions.keySet(); + for (Iterator i = positionSet.iterator(); i.hasNext();) { - WeakReference r = (WeakReference) i.next(); - GapContentPosition p = (GapContentPosition) r.get(); - if (p == null) - continue; - - if (p.mark > endOffset) - break; - if (p.mark >= offset && p.mark <= endOffset) + GapContentPosition p = (GapContentPosition) i.next(); + int offs = p.getOffset(); + if (offs >= offset && offs < endOffs) res.add(p); } + return res; } /** - * Sets the mark of all <code>Position</code>s that are in the range - * specified by <code>offset</code> and </code>length</code> within - * the buffer array to <code>value</code> + * Crunches all positions in the specified range to either the start or + * end of that interval. The interval boundaries are meant to be inclusive + * [start, end]. * - * @param offset the start offset of the range to search - * @param length the length of the range to search - * @param value the new value for each mark + * @param start the start offset of the range + * @param end the end offset of the range + * @param toStart a boolean indicating if the positions should be crunched + * to the start (true) or to the end (false) */ - private void setPositionsInRange(int offset, int length, int value) + private void setPositionsInRange(int start, int end, boolean toStart) { - int endOffset = offset + length; - - int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset), - new WeakPositionComparator()); - if (index1 < 0) - index1 = -(index1 + 1); - - // Search the first index with the specified offset. The binarySearch does - // not necessarily find the first one. - while (index1 > 0) + // We slump together all the GapContentPositions to point to + // one mark. So this is implemented as follows: + // 1. Remove all the marks in the specified range. + // 2. Insert one new mark at the correct location. + // 3. Adjust all affected GapContentPosition instances to point to + // this new mark. + + synchronized (this) { - WeakReference r = (WeakReference) positions.get(index1 - 1); - GapContentPosition p = (GapContentPosition) r.get(); - if (p != null && p.mark == offset || p == null) - index1--; + int startIndex = binarySearch(positionMarks, start, numMarks); + if (startIndex < 0) // Translate to insertion index, if not found. + startIndex = - startIndex - 1; + int endIndex = binarySearch(positionMarks, end, numMarks); + if (endIndex < 0) // Translate to insertion index - 1, if not found. + endIndex = - endIndex - 2; + + // Update the marks. + // We have inclusive interval bounds, but let one element over for + // filling in the new value. + int removed = endIndex - startIndex; + if (removed <= 0) + return; + System.arraycopy(positionMarks, endIndex + 1, positionMarks, + startIndex + 1, positionMarks.length - endIndex - 1); + numMarks -= removed; + if (toStart) + { + positionMarks[startIndex] = start; + } else - break; - } - - for (ListIterator i = positions.listIterator(index1); i.hasNext();) - { - WeakReference r = (WeakReference) i.next(); - GapContentPosition p = (GapContentPosition) r.get(); - if (p == null) - continue; - - if (p.mark > endOffset) - break; - - if (p.mark >= offset && p.mark <= endOffset) - p.mark = value; - } + { + positionMarks[startIndex] = end; + } + + // Update all affected GapContentPositions to point to the new index + // and all GapContentPositions that come after the interval to + // have their index moved by -removed. + Set positionSet = positions.keySet(); + for (Iterator i = positionSet.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + if (p.index > startIndex || p.index <= endIndex) + p.index = startIndex; + else if (p.index > endIndex) + p.index -= removed; + } + } } /** @@ -780,39 +749,44 @@ public class GapContent */ private void adjustPositionsInRange(int offset, int length, int incr) { - int endOffset = offset + length; + int endMark = offset + length; - int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset), - new WeakPositionComparator()); - if (index1 < 0) - index1 = -(index1 + 1); - - // Search the first index with the specified offset. The binarySearch does - // not necessarily find the first one. - while (index1 > 0) + synchronized (this) { - WeakReference r = (WeakReference) positions.get(index1 - 1); - GapContentPosition p = (GapContentPosition) r.get(); - if (p != null && p.mark == offset || p == null) - index1--; - else - break; + // Find the start and end indices in the positionMarks array. + int startIndex = binarySearch(positionMarks, offset, numMarks); + if (startIndex < 0) // Translate to insertion index, if not found. + startIndex = - startIndex - 1; + int endIndex = binarySearch(positionMarks, endMark, numMarks); + if (endIndex < 0) // Translate to insertion index - 1, if not found. + endIndex = - endIndex - 2; + + // We must not change the order of the marks, this would have + // unpredictable results while binary-searching the marks. + assert (startIndex <= 0 + || positionMarks[startIndex - 1] + <= positionMarks [startIndex] + incr) + && (endIndex >= numMarks - 1 + || positionMarks[endIndex + 1] + >= positionMarks[endIndex] + incr) + : "Adjusting the marks must not change their order"; + + // Some debug helper output to determine if the start or end of the + // should ever be coalesced together with adjecent marks. + if (startIndex > 0 && positionMarks[startIndex - 1] + == positionMarks[startIndex] + incr) + System.err.println("DEBUG: We could coalesce the start of the region" + + " in GapContent.adjustPositionsInRange()"); + if (endIndex < numMarks - 1 && positionMarks[endIndex + 1] + == positionMarks[endIndex] + incr) + System.err.println("DEBUG: We could coalesce the end of the region" + + " in GapContent.adjustPositionsInRange()"); + + // Actually adjust the marks. + for (int i = startIndex; i <= endIndex; i++) + positionMarks[i] += incr; } - for (ListIterator i = positions.listIterator(index1); i.hasNext();) - { - WeakReference r = (WeakReference) i.next(); - GapContentPosition p = (GapContentPosition) r.get(); - if (p == null) - continue; - - if (p.mark > endOffset) - break; - - if (p.mark >= offset && p.mark <= endOffset) - p.mark += incr; - } } /** @@ -826,7 +800,7 @@ public class GapContent if (gapStart != 0) return; - setPositionsInRange(gapEnd, 0, 0); + positionMarks[0] = 0; } /** @@ -866,27 +840,94 @@ public class GapContent System.err.println(); } - private void dumpPositions() + /** + * Prints out the position marks. + */ + private void dumpMarks() + { + System.err.print("positionMarks: "); + for (int i = 0; i < numMarks; i++) + System.err.print(positionMarks[i] + ", "); + System.err.println(); + } + + /** + * Inserts a mark into the positionMarks array. This must update all the + * GapContentPosition instances in positions that come after insertionPoint. + * + * This is package private to avoid synthetic accessor methods. + * + * @param insertionPoint the index at which to insert the mark + * @param mark the mark to insert + */ + void insertMark(int insertionPoint, int mark) { - for (Iterator i = positions.iterator(); i.hasNext();) + synchronized (this) { - WeakReference r = (WeakReference) i.next(); - GapContentPosition pos = (GapContentPosition) r.get(); - System.err.println("position at: " + pos.mark); + // Update the positions. + Set positionSet = positions.keySet(); + for (Iterator i = positionSet.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + if (p.index >= insertionPoint) + p.index++; + } + + // Update the position marks. + if (positionMarks.length <= numMarks) + { + int[] newMarks = new int[positionMarks.length + 10]; + System.arraycopy(positionMarks, 0, newMarks, 0, insertionPoint); + newMarks[insertionPoint] = mark; + System.arraycopy(positionMarks, insertionPoint, newMarks, + insertionPoint + 1, + numMarks - insertionPoint); + positionMarks = newMarks; + } + else + { + System.arraycopy(positionMarks, insertionPoint, positionMarks, + insertionPoint + 1, + numMarks - insertionPoint); + positionMarks[insertionPoint] = mark; + } + numMarks++; } } /** - * Clears all GC'ed references in the positions array. + * An adaption of {@link java.util.Arrays#binarySearch(int[], int)} to + * specify a maximum index up to which the array is searched. This allows + * us to have some trailing entries that we ignore. + * + * This is package private to avoid synthetic accessor methods. + * + * @param a the array + * @param key the key to search for + * @param maxIndex the maximum index up to which the search is performed + * + * @return the index of the found entry, or (-(index)-1) for the + * insertion point when not found + * + * @see java.util.Arrays#binarySearch(int[], int) */ - private void clearPositionReferences() + int binarySearch(int[] a, int key, int maxIndex) { - Iterator i = positions.iterator(); - while (i.hasNext()) + int low = 0; + int hi = maxIndex - 1; + int mid = 0; + while (low <= hi) { - WeakReference r = (WeakReference) i.next(); - if (r.get() == null) - i.remove(); + mid = (low + hi) >> 1; + final int d = a[mid]; + if (d == key) + return mid; + else if (d > key) + hi = mid - 1; + else + // This gets the insertion point right on the last loop. + low = ++mid; } + return -mid - 1; } } diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java index 1103de9b473..9de151dfbac 100644 --- a/libjava/classpath/javax/swing/text/JTextComponent.java +++ b/libjava/classpath/javax/swing/text/JTextComponent.java @@ -38,6 +38,8 @@ exception statement from your version. */ package javax.swing.text; +import gnu.classpath.NotImplementedException; + import java.awt.AWTEvent; import java.awt.Color; import java.awt.Dimension; @@ -176,6 +178,7 @@ public abstract class JTextComponent extends JComponent * @param e - caret event */ public void caretUpdate(CaretEvent e) + throws NotImplementedException { // TODO: fire appropriate event. dot = e.getDot(); @@ -187,6 +190,7 @@ public abstract class JTextComponent extends JComponent * @return the accessible state set of this component */ public AccessibleStateSet getAccessibleStateSet() + throws NotImplementedException { AccessibleStateSet state = super.getAccessibleStateSet(); // TODO: Figure out what state must be added here to the super's state. @@ -237,6 +241,7 @@ public abstract class JTextComponent extends JComponent * @param e - document event */ public void insertUpdate(DocumentEvent e) + throws NotImplementedException { // TODO } @@ -248,6 +253,7 @@ public abstract class JTextComponent extends JComponent * @param e - document event */ public void removeUpdate(DocumentEvent e) + throws NotImplementedException { // TODO } @@ -259,6 +265,7 @@ public abstract class JTextComponent extends JComponent * @param e - document event */ public void changedUpdate(DocumentEvent e) + throws NotImplementedException { // TODO } @@ -271,6 +278,7 @@ public abstract class JTextComponent extends JComponent * @return the character index, or -1 */ public int getIndexAtPoint(Point p) + throws NotImplementedException { return 0; // TODO } @@ -289,6 +297,7 @@ public abstract class JTextComponent extends JComponent * @return the bounding box, may be empty or null. */ public Rectangle getCharacterBounds(int index) + throws NotImplementedException { return null; // TODO } @@ -311,6 +320,7 @@ public abstract class JTextComponent extends JComponent * @return the character's attributes */ public AttributeSet getCharacterAttribute(int index) + throws NotImplementedException { return null; // TODO } @@ -324,6 +334,7 @@ public abstract class JTextComponent extends JComponent * @return the selection of text at that index, or null */ public String getAtIndex(int part, int index) + throws NotImplementedException { return null; // TODO } @@ -337,6 +348,7 @@ public abstract class JTextComponent extends JComponent * @return the selection of text after that index, or null */ public String getAfterIndex(int part, int index) + throws NotImplementedException { return null; // TODO } @@ -350,6 +362,7 @@ public abstract class JTextComponent extends JComponent * @return the selection of text before that index, or null */ public String getBeforeIndex(int part, int index) + throws NotImplementedException { return null; // TODO } @@ -361,6 +374,7 @@ public abstract class JTextComponent extends JComponent * @return the 0-based number of actions */ public int getAccessibleActionCount() + throws NotImplementedException { return 0; // TODO } @@ -369,11 +383,11 @@ public abstract class JTextComponent extends JComponent * Get a description for the specified action. Returns null if out of * bounds. * - * @param i - * the action to describe, 0-based + * @param i the action to describe, 0-based * @return description of the action */ public String getAccessibleActionDescription(int i) + throws NotImplementedException { // TODO: Not implemented fully return super.getAccessibleDescription(); @@ -386,6 +400,7 @@ public abstract class JTextComponent extends JComponent * @return true if the action was performed */ public boolean doAccessibleAction(int i) + throws NotImplementedException { return false; // TODO } @@ -396,6 +411,7 @@ public abstract class JTextComponent extends JComponent * @param s the new text */ public void setTextContents(String s) + throws NotImplementedException { // TODO } @@ -407,6 +423,7 @@ public abstract class JTextComponent extends JComponent * @param s the new text */ public void insertTextAtIndex(int index, String s) + throws NotImplementedException { replaceText(index, index, s); } @@ -495,6 +512,7 @@ public abstract class JTextComponent extends JComponent * @param s the new attribute set for the range */ public void setAttributes(int start, int end, AttributeSet s) + throws NotImplementedException { // TODO } @@ -1365,7 +1383,7 @@ public abstract class JTextComponent extends JComponent { if (editable == newValue) return; - + boolean oldValue = editable; editable = newValue; firePropertyChange("editable", oldValue, newValue); @@ -1725,17 +1743,20 @@ public abstract class JTextComponent extends JComponent public void copy() { + if (isEnabled()) doTransferAction("copy", TransferHandler.getCopyAction()); } public void cut() { - doTransferAction("cut", TransferHandler.getCutAction()); + if (editable && isEnabled()) + doTransferAction("cut", TransferHandler.getCutAction()); } public void paste() { - doTransferAction("paste", TransferHandler.getPasteAction()); + if (editable && isEnabled()) + doTransferAction("paste", TransferHandler.getPasteAction()); } private void doTransferAction(String name, Action action) diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java index 18818c0bad3..48fe37ce880 100644 --- a/libjava/classpath/javax/swing/text/PlainView.java +++ b/libjava/classpath/javax/swing/text/PlainView.java @@ -437,132 +437,92 @@ public class PlainView extends View implements TabExpander */ protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f) { - // Return early and do no updates if the allocation area is null - // (like the RI). - if (a == null) - return; - - float oldMaxLineLength = maxLineLength; - Rectangle alloc = a.getBounds(); - Element el = getElement(); - ElementChange ec = changes.getChange(el); - - // If ec is null then no lines were added or removed, just - // repaint the changed line - if (ec == null) - { - int line = el.getElementIndex(changes.getOffset()); - - // If characters have been removed from the current longest line - // we have to find out which one is the longest now otherwise - // the preferred x-axis span will not shrink. - if (changes.getType() == DocumentEvent.EventType.REMOVE - && el.getElement(line) == longestLine) - { - maxLineLength = -1; - if (determineMaxLineLength() != alloc.width) - preferenceChanged(this, true, false); - } - - damageLineRange(line, line, a, getContainer()); - return; - } - - Element[] removed = ec.getChildrenRemoved(); - Element[] newElements = ec.getChildrenAdded(); - - // If no Elements were added or removed, we just want to repaint - // the area containing the line that was modified - if (removed == null && newElements == null) + // This happens during initialization. + if (metrics == null) { - int line = getElement().getElementIndex(changes.getOffset()); - - damageLineRange(line, line, a, getContainer()); + updateMetrics(); + preferenceChanged(null, true, true); return; } - // Check to see if we removed the longest line, if so we have to - // search through all lines and find the longest one again. - if (removed != null) - { - for (int i = 0; i < removed.length; i++) - if (removed[i].equals(longestLine)) - { - // reset maxLineLength and search through all lines for longest one - maxLineLength = -1; - if (determineMaxLineLength() != alloc.width) - preferenceChanged(this, true, removed.length != newElements.length); - - ((JTextComponent)getContainer()).repaint(); - - return; - } - } - - // If we've reached here, that means we haven't removed the longest line - if (newElements == null) - { - // No lines were added, just repaint the container and exit - ((JTextComponent)getContainer()).repaint(); - - return; - } + Element element = getElement(); - // Make sure we have the metrics - updateMetrics(); - - // If we've reached here, that means we haven't removed the longest line - // and we have added at least one line, so we have to check if added lines - // are longer than the previous longest line - Segment seg = getLineBuffer(); - float longestNewLength = 0; - Element longestNewLine = null; + // Find longest line if it hasn't been initialized yet. + if (longestLine == null) + findLongestLine(0, element.getElementCount() - 1); - // Loop through the added lines to check their length - for (int i = 0; i < newElements.length; i++) + ElementChange change = changes.getChange(element); + if (changes.getType() == DocumentEvent.EventType.INSERT) { - Element child = newElements[i]; - int start = child.getStartOffset(); - int end = child.getEndOffset() - 1; - try - { - el.getDocument().getText(start, end - start, seg); - } - catch (BadLocationException ex) + // Handles character/line insertion. + + // Determine if lines have been added. In this case we repaint + // differently. + boolean linesAdded = true; + if (change == null) + linesAdded = false; + + // Determine the start line. + int start; + if (linesAdded) + start = change.getIndex(); + else + start = element.getElementIndex(changes.getOffset()); + + // Determine the length of the updated region. + int length = 0; + if (linesAdded) + length = change.getChildrenAdded().length - 1; + + // Update the longest line and length. + int oldMaxLength = (int) maxLineLength; + if (longestLine.getEndOffset() < changes.getOffset() + || longestLine.getStartOffset() > changes.getOffset() + + changes.getLength()) { - AssertionError ae = new AssertionError("Unexpected bad location"); - ae.initCause(ex); - throw ae; + findLongestLine(start, start + length); } - - if (seg == null || seg.array == null || seg.count == 0) - continue; - - int width = metrics.charsWidth(seg.array, seg.offset, seg.count); - if (width > longestNewLength) + else { - longestNewLine = child; - longestNewLength = width; + findLongestLine(0, element.getElementCount() - 1); } + + // Trigger a preference change so that the layout gets updated + // correctly. + preferenceChanged(null, maxLineLength != oldMaxLength, linesAdded); + + // Damage the updated line range. + int endLine = start; + if (linesAdded) + endLine = element.getElementCount() - 1; + damageLineRange(start, endLine, a, getContainer()); + } - - // Check if the longest of the new lines is longer than our previous - // longest line, and if so update our values - if (longestNewLength > maxLineLength) + else { - maxLineLength = longestNewLength; - longestLine = longestNewLine; + // Handles character/lines removals. + + // Update the longest line and length and trigger preference changed. + int oldMaxLength = (int) maxLineLength; + if (change != null) + { + // Line(s) have been removed. + findLongestLine(0, element.getElementCount() - 1); + preferenceChanged(null, maxLineLength != oldMaxLength, true); + } + else + { + // No line has been removed. + int lineNo = getElement().getElementIndex(changes.getOffset()); + Element line = getElement().getElement(lineNo); + if (longestLine == line) + { + findLongestLine(0, element.getElementCount() - 1); + preferenceChanged(null, maxLineLength != oldMaxLength, false); + } + damageLineRange(lineNo, lineNo, a, getContainer()); + } } - - // Report any changes to the preferred sizes of the view - // which may cause the underlying component to be revalidated. - boolean widthChanged = oldMaxLineLength != maxLineLength; - boolean heightChanged = removed.length != newElements.length; - if (widthChanged || heightChanged) - preferenceChanged(this, widthChanged, heightChanged); - - // Repaint the container - ((JTextComponent)getContainer()).repaint(); } /** @@ -648,5 +608,54 @@ public class PlainView extends View implements TabExpander lineBuffer = new Segment(); return lineBuffer; } + + /** + * Finds and updates the longest line in the view inside an interval of + * lines. + * + * @param start the start of the search interval + * @param end the end of the search interval + */ + private void findLongestLine(int start, int end) + { + for (int i = start; i <= end; i++) + { + int w = getLineLength(i); + if (w > maxLineLength) + { + maxLineLength = w; + longestLine = getElement().getElement(i); + } + } + } + + /** + * Determines the length of the specified line. + * + * @param line the number of the line + * + * @return the length of the line in pixels + */ + private int getLineLength(int line) + { + Element lineEl = getElement().getElement(line); + Segment buffer = getLineBuffer(); + try + { + Document doc = getDocument(); + doc.getText(lineEl.getStartOffset(), + lineEl.getEndOffset() - lineEl.getStartOffset() - 1, + buffer); + } + catch (BadLocationException ex) + { + AssertionError err = new AssertionError("Unexpected bad location"); + err.initCause(ex); + throw err; + } + + return Utilities.getTabbedTextWidth(buffer, metrics, 0, this, + lineEl.getStartOffset()); + } } diff --git a/libjava/classpath/javax/swing/text/StyleContext.java b/libjava/classpath/javax/swing/text/StyleContext.java index 8ef34400d29..63df3df6a91 100644 --- a/libjava/classpath/javax/swing/text/StyleContext.java +++ b/libjava/classpath/javax/swing/text/StyleContext.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.text; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; @@ -50,7 +48,6 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.EventListener; -import java.util.HashSet; import java.util.Hashtable; import javax.swing.event.ChangeEvent; @@ -413,7 +410,7 @@ public class StyleContext /** * These attribute keys are handled specially in serialization. */ - private static HashSet staticAttributeKeys = new HashSet(); + private static Hashtable staticAttributeKeys = new Hashtable(); EventListenerList listenerList; Hashtable styleTable; @@ -708,49 +705,125 @@ public class StyleContext } } - - // 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. - + /** + * Gets the object previously registered with registerStaticAttributeKey. + * + * @param key - the key that was registered. + * @return the object previously registered with registerStaticAttributeKey. + */ public static Object getStaticAttribute(Object key) - throws NotImplementedException { - throw new InternalError("not implemented"); + if (key == null) + return null; + return staticAttributeKeys.get(key); } + /** + * Returns the String that key will be registered with + * registerStaticAttributeKey. + * + * @param key - the key that will be registered. + * @return the string the key will be registered with. + */ public static Object getStaticAttributeKey(Object key) - throws NotImplementedException { - throw new InternalError("not implemented"); + return key.getClass().getName() + "." + key.toString(); } + /** + * Reads a set of attributes from the given object input stream. This will + * attempt to restore keys that were static objects by considering only the + * keys that have were registered with registerStaticAttributeKey. The + * attributes retrieved will be placed into the given set. + * + * @param in - the stream to read from + * @param a - the set of attributes + * @throws ClassNotFoundException - may be encountered when reading from + * stream + * @throws IOException - any I/O error + */ public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new InternalError("not implemented"); + if (in == null || a == null) + return; + + Object key = in.readObject(); + Object val = in.readObject(); + while (key != null && val != null) + { + Object staticKey = staticAttributeKeys.get(key); + Object staticVal = staticAttributeKeys.get(val); + + if (staticKey != null) + key = staticKey; + if (staticVal != null) + val = staticVal; + + a.addAttribute(key, val); + key = in.readObject(); + val = in.readObject(); + } } + /** + * Serialize an attribute set in a way that is compatible with it + * being read in again by {@link #readAttributeSet(ObjectInputStream, MutableAttributeSet)}. + * In particular registered static keys are transformed properly. + * + * @param out - stream to write to + * @param a - the attribute set + * @throws IOException - any I/O error + */ public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a) - throws IOException, NotImplementedException + throws IOException { - throw new InternalError("not implemented"); + Enumeration e = a.getAttributeNames(); + while (e.hasMoreElements()) + { + Object oldKey = e.nextElement(); + Object newKey = getStaticAttribute(oldKey); + Object key = (newKey == null) ? oldKey : newKey; + + out.writeObject(key); + out.writeObject(a.getAttribute(oldKey)); + } + out.writeObject(null); + out.writeObject(null); } + /** + * Handles reading in the attributes. + * @see #readAttributeSet(ObjectInputStream, MutableAttributeSet) + * + * @param in - the stream to read from + * @param a - the set of attributes + * @throws ClassNotFoundException - may be encountered when reading from stream + * @throws IOException - any I/O error + */ public void readAttributes(ObjectInputStream in, MutableAttributeSet a) - throws ClassNotFoundException, IOException, NotImplementedException + throws ClassNotFoundException, IOException { - throw new InternalError("not implemented"); + readAttributeSet(in, a); } + /** + * Handles writing of the given attributes. + * @see #writeAttributeSet(ObjectOutputStream, AttributeSet) + * + * @param out - stream to write to + * @param a - the attribute set + * @throws IOException - any I/O error + */ public void writeAttributes(ObjectOutputStream out, AttributeSet a) - throws IOException, NotImplementedException + throws IOException { - throw new InternalError("not implemented"); + writeAttributeSet(out, a); } /** * Registers an attribute key as a well-known keys. When an attribute with - * such a key is written to a stream,, a special syntax is used so that it + * such a key is written to a stream, a special syntax is used so that it * can be recognized when it is read back in. All attribute keys defined * in <code>StyleContext</code> are registered as static keys. If you define * additional attribute keys that you want to exist as nonreplicated objects, @@ -760,6 +833,8 @@ public class StyleContext */ public static void registerStaticAttributeKey(Object key) { - staticAttributeKeys.add(key); + if (key != null) + staticAttributeKeys.put(key.getClass().getName() + "." + key.toString(), + key); } } diff --git a/libjava/classpath/javax/swing/text/TextAction.java b/libjava/classpath/javax/swing/text/TextAction.java index 8588e3cd202..144166e9cdb 100644 --- a/libjava/classpath/javax/swing/text/TextAction.java +++ b/libjava/classpath/javax/swing/text/TextAction.java @@ -38,12 +38,14 @@ exception statement from your version. */ package javax.swing.text; +import java.awt.Point; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.HashSet; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.SwingConstants; /** * TextAction @@ -108,4 +110,106 @@ public abstract class TextAction extends AbstractAction { return null; // TODO } + + /** Abstract helper class which implements everything needed for an + * Action implementation in <code>DefaultEditorKit</code> which + * does horizontal movement (and selection). + */ + abstract static class HorizontalMovementAction extends TextAction + { + int dir; + + HorizontalMovementAction(String name, int direction) + { + super(name); + dir = direction; + } + + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + try + { + if (t != null) + { + int offs + = Utilities.getNextVisualPositionFrom(t, + t.getCaretPosition(), + dir); + + Caret c = t.getCaret(); + + actionPerformedImpl(c, offs); + + c.setMagicCaretPosition(t.modelToView(offs).getLocation()); + } + } + catch(BadLocationException ble) + { + throw + (InternalError) new InternalError("Illegal offset").initCause(ble); + } + + } + + protected abstract void actionPerformedImpl(Caret c, int offs) + throws BadLocationException; + } + + /** Abstract helper class which implements everything needed for an + * Action implementation in <code>DefaultEditorKit</code> which + * does vertical movement (and selection). + */ + abstract static class VerticalMovementAction extends TextAction + { + int dir; + + VerticalMovementAction(String name, int direction) + { + super(name); + dir = direction; + } + + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + try + { + if (t != null) + { + Caret c = t.getCaret(); + // The magic caret position may be null when the caret + // has not moved yet. + Point mcp = c.getMagicCaretPosition(); + + int pos; + if (mcp != null) + { + mcp.y = t.modelToView(c.getDot()).y; + pos = t.viewToModel(mcp); + } + else + pos = c.getDot(); + + pos = Utilities.getNextVisualPositionFrom(t, + t.getCaretPosition(), + dir); + + if (pos > -1) + actionPerformedImpl(c, pos); + } + } + catch(BadLocationException ble) + { + throw + (InternalError) new InternalError("Illegal offset").initCause(ble); + } + } + + protected abstract void actionPerformedImpl(Caret c, int offs) + throws BadLocationException; + + } + + } diff --git a/libjava/classpath/javax/swing/text/Utilities.java b/libjava/classpath/javax/swing/text/Utilities.java index f154e55aac0..36361f49796 100644 --- a/libjava/classpath/javax/swing/text/Utilities.java +++ b/libjava/classpath/javax/swing/text/Utilities.java @@ -43,6 +43,9 @@ import java.awt.Graphics; import java.awt.Point; import java.text.BreakIterator; +import javax.swing.SwingConstants; +import javax.swing.text.Position.Bias; + /** * A set of utilities to deal with text. This is used by several other classes * inside this package. @@ -337,7 +340,7 @@ public class Utilities // location or is not whitespace (meaning it is a number or // punctuation). The first case means that 'last' denotes the // beginning of a word while the second case means it is the start - // of some else. + // of something else. if (Character.isLetter(cp) || !Character.isWhitespace(cp)) return last; @@ -346,7 +349,7 @@ public class Utilities current = wb.next(); } - throw new BadLocationException("no more word", offs); + throw new BadLocationException("no more words", offs); } /** @@ -363,24 +366,36 @@ public class Utilities public static final int getPreviousWord(JTextComponent c, int offs) throws BadLocationException { - if (offs < 0 || offs > (c.getText().length() - 1)) - throw new BadLocationException("invalid offset specified", offs); String text = c.getText(); + + if (offs <= 0 || offs > text.length()) + throw new BadLocationException("invalid offset specified", offs); + BreakIterator wb = BreakIterator.getWordInstance(); wb.setText(text); int last = wb.preceding(offs); int current = wb.previous(); + int cp; while (current != BreakIterator.DONE) { for (int i = last; i < offs; i++) { - if (Character.isLetter(text.codePointAt(i))) + cp = text.codePointAt(i); + + // Return the last found bound if there is a letter at the current + // location or is not whitespace (meaning it is a number or + // punctuation). The first case means that 'last' denotes the + // beginning of a word while the second case means it is the start + // of some else. + if (Character.isLetter(cp) + || !Character.isWhitespace(cp)) return last; } last = current; current = wb.previous(); } + return 0; } @@ -394,14 +409,17 @@ public class Utilities public static final int getWordStart(JTextComponent c, int offs) throws BadLocationException { - if (offs < 0 || offs >= c.getText().length()) + String text = c.getText(); + + if (offs < 0 || offs > text.length()) throw new BadLocationException("invalid offset specified", offs); - String text = c.getText(); BreakIterator wb = BreakIterator.getWordInstance(); wb.setText(text); + if (wb.isBoundary(offs)) return offs; + return wb.preceding(offs); } @@ -674,4 +692,38 @@ public class Utilities else return offs+1; } + + /** This is an internal helper method which is used by the + * <code>javax.swing.text</code> package. It simply delegates the + * call to a method with the same name on the <code>NavigationFilter</code> + * of the provided <code>JTextComponent</code> (if it has one) or its UI. + * + * If the underlying method throws a <code>BadLocationException</code> it + * will be swallowed and the initial offset is returned. + */ + static int getNextVisualPositionFrom(JTextComponent t, int offset, int direction) + { + NavigationFilter nf = t.getNavigationFilter(); + + try + { + return (nf != null) + ? nf.getNextVisualPositionFrom(t, + offset, + Bias.Forward, + direction, + null) + : t.getUI().getNextVisualPositionFrom(t, + offset, + Bias.Forward, + direction, + null); + } + catch (BadLocationException ble) + { + return offset; + } + + } + } diff --git a/libjava/classpath/javax/swing/text/html/HTMLDocument.java b/libjava/classpath/javax/swing/text/html/HTMLDocument.java index fba6cad12e9..b7a706904a4 100644 --- a/libjava/classpath/javax/swing/text/html/HTMLDocument.java +++ b/libjava/classpath/javax/swing/text/html/HTMLDocument.java @@ -40,14 +40,12 @@ package javax.swing.text.html; import gnu.classpath.NotImplementedException; +import gnu.javax.swing.text.html.CharacterAttributeTranslator; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.Stack; import java.util.Vector; - -import javax.swing.event.DocumentEvent; -import javax.swing.event.UndoableEditEvent; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; @@ -131,21 +129,6 @@ public class HTMLDocument extends DefaultStyledDocument } /** - * Replaces the contents of the document with the given element - * specifications. This is called before insert if the loading is done - * in bursts. This is the only method called if loading the document - * entirely in one burst. - * - * @param data - the date that replaces the content of the document - */ - protected void create(DefaultStyledDocument.ElementSpec[] data) - { - // Once the super behaviour is properly implemented it should be sufficient - // to simply call super.create(data). - super.create(data); - } - - /** * This method creates a root element for the new document. * * @return the new default root @@ -216,41 +199,6 @@ public class HTMLDocument extends DefaultStyledDocument } /** - * Inserts new elements in bulk. This is how elements get created in the - * document. The parsing determines what structure is needed and creates the - * specification as a set of tokens that describe the edit while leaving the - * document free of a write-lock. This method can then be called in bursts by - * the reader to acquire a write-lock for a shorter duration (i.e. while the - * document is actually being altered). - * - * @param offset - the starting offset - * @param data - the element data - * @throws BadLocationException - if the given position does not - * represent a valid location in the associated document. - */ - protected void insert(int offset, DefaultStyledDocument.ElementSpec[] data) - throws BadLocationException - { - super.insert(offset, data); - } - - /** - * Updates document structure as a result of text insertion. This will happen - * within a write lock. This implementation simply parses the inserted content - * for line breaks and builds up a set of instructions for the element buffer. - * - * @param chng - a description of the document change - * @param attr - the attributes - */ - protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng, - AttributeSet attr) - { - // FIXME: Not implemented - System.out.println("insertUpdate not implemented"); - super.insertUpdate(chng, attr); - } - - /** * Returns the parser used by this HTMLDocument to insert HTML. * * @return the parser used by this HTMLDocument to insert HTML. @@ -414,6 +362,7 @@ public class HTMLDocument extends DefaultStyledDocument } public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event) + throws NotImplementedException { // TODO: Implement this properly. } @@ -646,12 +595,16 @@ public class HTMLDocument extends DefaultStyledDocument { // Put the old attribute set on the stack. pushCharacterStyle(); - - // And create the new one by adding the attributes in <code>a</code>. - if (a != null) - charAttr.addAttribute(t, a.copyAttributes()); + + // Translate tag.. return if succesful. + if(CharacterAttributeTranslator.translateTag(charAttr, t, a)) + return; + + // Just add the attributes in <code>a</code>. + if (a != null) + charAttr.addAttribute(t, a.copyAttributes()); } - + /** * Called when an end tag is seen for one of the types of tags associated * with this Action. @@ -724,17 +677,6 @@ public class HTMLDocument extends DefaultStyledDocument // FIXME: Implement. print ("IsindexAction.start not implemented"); } - - /** - * Called when an end tag is seen for one of the types of tags associated - * with this Action. - */ - public void end(HTML.Tag t) - throws NotImplementedException - { - // FIXME: Implement. - print ("IsindexAction.end not implemented"); - } } public class ParagraphAction extends BlockAction @@ -745,7 +687,6 @@ public class HTMLDocument extends DefaultStyledDocument */ public void start(HTML.Tag t, MutableAttributeSet a) { - // FIXME: What else must be done here? blockOpen(t, a); } @@ -755,7 +696,6 @@ public class HTMLDocument extends DefaultStyledDocument */ public void end(HTML.Tag t) { - // FIXME: What else must be done here? blockClose(t); } } @@ -771,6 +711,7 @@ public class HTMLDocument extends DefaultStyledDocument { // FIXME: Implement. print ("PreAction.start not implemented"); + super.start(t, a); } /** @@ -782,6 +723,7 @@ public class HTMLDocument extends DefaultStyledDocument { // FIXME: Implement. print ("PreAction.end not implemented"); + super.end(t); } } @@ -792,22 +734,9 @@ public class HTMLDocument extends DefaultStyledDocument * of tags associated with this Action. */ public void start(HTML.Tag t, MutableAttributeSet a) - throws NotImplementedException { - // FIXME: Implement. - print ("SpecialAction.start not implemented"); + addSpecialElement(t, a); } - - /** - * Called when an end tag is seen for one of the types of tags associated - * with this Action. - */ - public void end(HTML.Tag t) - throws NotImplementedException - { - // FIXME: Implement. - print ("SpecialAction.end not implemented"); - } } class AreaAction extends TagAction @@ -1131,7 +1060,7 @@ public class HTMLDocument extends DefaultStyledDocument */ protected void pushCharacterStyle() { - charAttrStack.push(charAttr); + charAttrStack.push(charAttr.copyAttributes()); } /** @@ -1565,8 +1494,8 @@ public class HTMLDocument extends DefaultStyledDocument */ public Element getElement(String attrId) { - Element root = getDefaultRootElement(); - return getElement(root, HTML.getAttributeKey(attrId) , attrId); + return getElement(getDefaultRootElement(), HTML.getAttributeKey(attrId), + attrId); } /** @@ -1690,53 +1619,4 @@ public class HTMLDocument extends DefaultStyledDocument // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? System.out.println("insertAfterStart not implemented"); } - - /** - * This method sets the attributes associated with the paragraph containing - * offset. If replace is false, s is merged with existing attributes. The - * length argument determines how many characters are affected by the new - * attributes. This is often the entire paragraph. - * - * @param offset - - * the offset into the paragraph (must be at least 0) - * @param length - - * the number of characters affected (must be at least 0) - * @param s - - * the attributes - * @param replace - - * whether to replace existing attributes, or merge them - */ - public void setParagraphAttributes(int offset, int length, AttributeSet s, - boolean replace) - throws NotImplementedException - { - // FIXME: Not implemented. - System.out.println("setParagraphAttributes not implemented"); - super.setParagraphAttributes(offset, length, s, replace); - } - - /** - * This method flags a change in the document. - * - * @param e - the Document event - */ - protected void fireChangedUpdate(DocumentEvent e) - throws NotImplementedException - { - // FIXME: Not implemented. - System.out.println("fireChangedUpdate not implemented"); - super.fireChangedUpdate(e); - } - - /** - * This method fires an event intended to be caught by Undo listeners. It - * simply calls the super version inherited from DefaultStyledDocument. With - * this method, an HTML editor could easily provide undo support. - * - * @param e - the UndoableEditEvent - */ - protected void fireUndoableEditUpdate(UndoableEditEvent e) - { - super.fireUndoableEditUpdate(e); - } } diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java index 92d9de938eb..adda4922d57 100644 --- a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java +++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java @@ -548,6 +548,8 @@ public class HTMLEditorKit || tag.equals(HTML.Tag.BLOCKQUOTE) || tag.equals(HTML.Tag.PRE)) view = new BlockView(element, View.Y_AXIS); + else if (tag.equals(HTML.Tag.IMG)) + view = new ImageView(element); // FIXME: Uncomment when the views have been implemented else if (tag.equals(HTML.Tag.CONTENT)) @@ -558,13 +560,12 @@ public class HTMLEditorKit view = new HTMLTableView(element); else if (tag.equals(HTML.Tag.TD)) view = new ParagraphView(element); + /* else if (tag.equals(HTML.Tag.MENU) || tag.equals(HTML.Tag.DIR) || tag.equals(HTML.Tag.UL) || tag.equals(HTML.Tag.OL)) view = new ListView(element); - else if (tag.equals(HTML.Tag.IMG)) - view = new ImageView(element); else if (tag.equals(HTML.Tag.HR)) view = new HRuleView(element); else if (tag.equals(HTML.Tag.BR)) diff --git a/libjava/classpath/javax/swing/text/html/ImageView.java b/libjava/classpath/javax/swing/text/html/ImageView.java new file mode 100644 index 00000000000..84b021070a9 --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/ImageView.java @@ -0,0 +1,441 @@ +package javax.swing.text.html; + +import gnu.javax.swing.text.html.CombinedAttributes; +import gnu.javax.swing.text.html.ImageViewIconFactory; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Rectangle; +import java.awt.Shape; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.Position.Bias; +import javax.swing.text.html.HTML.Attribute; + +/** + * A view, representing a single image, represented by the HTML IMG tag. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ImageView extends View +{ + /** + * True if the image loads synchronuosly (on demand). By default, the image + * loads asynchronuosly. + */ + boolean loadOnDemand; + + /** + * The image icon, wrapping the image, + */ + ImageIcon imageIcon; + + /** + * The image state. + */ + byte imageState = MediaTracker.LOADING; + + /** + * Creates the image view that represents the given element. + * + * @param element the element, represented by this image view. + */ + public ImageView(Element element) + { + super(element); + } + + /** + * Load or reload the image. This method initiates the image reloading. After + * the image is ready, the repaint event will be scheduled. The current image, + * if it already exists, will be discarded. + * + * @param itsTime + * also load if the "on demand" property is set + */ + void reloadImage(boolean itsTime) + { + URL url = getImageURL(); + if (url == null) + imageState = (byte) MediaTracker.ERRORED; + else if (!(loadOnDemand && !itsTime)) + imageIcon = new ImageIcon(url); + else + imageState = (byte) MediaTracker.LOADING; + } + + /** + * Get the image alignment. This method works handling standart alignment + * attributes in the HTML IMG tag (align = top bottom middle left right). + * Depending from the parameter, either horizontal or vertical alingment + * information is returned. + * + * @param axis - + * either X_AXIS or Y_AXIS + */ + public float getAlignment(int axis) + { + AttributeSet attrs = getAttributes(); + Object al = attrs.getAttribute(Attribute.ALIGN); + + // Default is top left aligned. + if (al == null) + return 0.0f; + + String align = al.toString(); + + if (axis == View.X_AXIS) + { + if (align.equals("middle")) + return 0.5f; + else if (align.equals("left")) + return 0.0f; + else if (align.equals("right")) + return 1.0f; + else + return 0.0f; + } + else if (axis == View.Y_AXIS) + { + if (align.equals("middle")) + return 0.5f; + else if (align.equals("top")) + return 0.0f; + else if (align.equals("bottom")) + return 1.0f; + else + return 0.0f; + } + else + throw new IllegalArgumentException("axis " + axis); + } + + /** + * Get the text that should be shown as the image replacement and also as the + * image tool tip text. The method returns the value of the attribute, having + * the name {@link Attribute#ALT}. If there is no such attribute, the image + * name from the url is returned. If the URL is not available, the empty + * string is returned. + */ + public String getAltText() + { + Object rt = getAttributes().getAttribute(Attribute.ALT); + if (rt != null) + return rt.toString(); + else + { + URL u = getImageURL(); + if (u == null) + return ""; + else + return u.getFile(); + } + } + + /** + * Returns the combination of the document and the style sheet attributes. + */ + public AttributeSet getAttributes() + { + StyleSheet styles = getStyleSheet(); + if (styles == null) + return super.getAttributes(); + else + return CombinedAttributes.combine(super.getAttributes(), + styles.getViewAttributes(this)); + } + + /** + * Get the image to render. May return null if the image is not yet loaded. + */ + public Image getImage() + { + if (imageIcon == null) + return null; + else + return imageIcon.getImage(); + } + + /** + * Get the URL location of the image to render. If this method returns null, + * the "no image" icon is rendered instead. By defaul, url must be present as + * the "src" property of the IMG tag. If it is missing, null is returned and + * the "no image" icon is rendered. + * + * @return the URL location of the image to render. + */ + public URL getImageURL() + { + Object url = getAttributes().getAttribute(Attribute.SRC); + if (url == null) + return null; + + try + { + return new URL(url.toString()); + } + catch (MalformedURLException e) + { + // The URL is malformed - no image. + return null; + } + } + + /** + * Get the icon that should be displayed while the image is loading and hence + * not yet available. + * + * @return an icon, showing a non broken sheet of paper with image. + */ + public Icon getLoadingImageIcon() + { + return ImageViewIconFactory.getLoadingImageIcon(); + } + + /** + * Get the image loading strategy. + * + * @return false (default) if the image is loaded when the view is + * constructed, true if the image is only loaded on demand when + * rendering. + */ + public boolean getLoadsSynchronously() + { + return loadOnDemand; + } + + /** + * Get the icon that should be displayed when the image is not available. + * + * @return an icon, showing a broken sheet of paper with image. + */ + public Icon getNoImageIcon() + { + return ImageViewIconFactory.getNoImageIcon(); + } + + /** + * Get the preferred span of the image along the axis. The image size is first + * requested to the attributes {@link Attribute#WIDTH} and + * {@link Attribute#HEIGHT}. If they are missing, and the image is already + * loaded, the image size is returned. If there are no attributes, and the + * image is not loaded, zero is returned. + * + * @param axis - + * either X_AXIS or Y_AXIS + * @return either width of height of the image, depending on the axis. + */ + public float getPreferredSpan(int axis) + { + AttributeSet attrs = getAttributes(); + + Image image = getImage(); + + if (axis == View.X_AXIS) + { + Object w = attrs.getAttribute(Attribute.WIDTH); + if (w != null) + return Integer.parseInt(w.toString()); + else if (image != null) + return image.getWidth(getContainer()); + else + return getNoImageIcon().getIconWidth(); + } + else if (axis == View.Y_AXIS) + { + Object w = attrs.getAttribute(Attribute.HEIGHT); + if (w != null) + return Integer.parseInt(w.toString()); + else if (image != null) + return image.getHeight(getContainer()); + else + return getNoImageIcon().getIconHeight(); + } + else + throw new IllegalArgumentException("axis " + axis); + } + + /** + * Get the associated style sheet from the document. + * + * @return the associated style sheet. + */ + protected StyleSheet getStyleSheet() + { + Document d = getElement().getDocument(); + if (d instanceof HTMLDocument) + return ((HTMLDocument) d).getStyleSheet(); + else + return null; + } + + /** + * Get the tool tip text. This is overridden to return the value of the + * {@link #getAltText()}. The parameters are ignored. + * + * @return that is returned by getAltText(). + */ + public String getToolTipText(float x, float y, Shape shape) + { + return getAltText(); + } + + /** + * Paints the image or one of the two image state icons. The image is resized + * to the shape bounds. If there is no image available, the alternative text + * is displayed besides the image state icon. + * + * @param g + * the Graphics, used for painting. + * @param bounds + * the bounds of the region where the image or replacing icon must be + * painted. + */ + public void paint(Graphics g, Shape bounds) + { + Rectangle r = bounds.getBounds(); + + if (imageIcon == null) + + { + // Loading image on demand, rendering the loading icon so far. + reloadImage(true); + + // The reloadImage sets the imageIcon, unless the URL is broken + // or malformed. + if (imageIcon != null) + { + if (imageIcon.getImageLoadStatus() != MediaTracker.COMPLETE) + { + // Render "not ready" icon, unless the image is ready + // immediately. + renderIcon(g, r, getLoadingImageIcon()); + // Add the listener to repaint when the icon will be ready. + imageIcon.setImageObserver(getContainer()); + return; + } + } + else + { + renderIcon(g, r, getNoImageIcon()); + return; + } + } + + imageState = (byte) imageIcon.getImageLoadStatus(); + + switch (imageState) + { + case MediaTracker.ABORTED: + case MediaTracker.ERRORED: + renderIcon(g, r, getNoImageIcon()); + break; + case MediaTracker.LOADING: + // If the image is not loaded completely, we still render it, as the + // partial image may be available. + case MediaTracker.COMPLETE: + { + // Paint the scaled image. + Image scaled = imageIcon.getImage().getScaledInstance( + r.width, + r.height, + Image.SCALE_DEFAULT); + ImageIcon painter = new ImageIcon(scaled); + painter.paintIcon(getContainer(), g, r.x, r.y); + } + break; + } + } + + /** + * Render "no image" icon and the alternative "no image" text. The text is + * rendered right from the icon and is aligned to the icon bottom. + */ + private void renderIcon(Graphics g, Rectangle bounds, Icon icon) + { + Shape current = g.getClip(); + try + { + g.setClip(bounds); + if (icon != null) + { + icon.paintIcon(getContainer(), g, bounds.x, bounds.y); + g.drawString(getAltText(), bounds.x + icon.getIconWidth(), + bounds.y + icon.getIconHeight()); + } + } + finally + { + g.setClip(current); + } + } + + /** + * Set if the image should be loaded only when needed (synchronuosly). By + * default, the image loads asynchronuosly. If the image is not yet ready, the + * icon, returned by the {@link #getLoadingImageIcon()}, is displayed. + */ + public void setLoadsSynchronously(boolean load_on_demand) + { + loadOnDemand = load_on_demand; + } + + /** + * Update all cached properties from the attribute set, returned by the + * {@link #getAttributes}. + */ + protected void setPropertiesFromAttributes() + { + // In the current implementation, nothing is cached yet, unless the image + // itself. + imageIcon = null; + } + + /** + * Maps the picture co-ordinates into the image position in the model. As the + * image is not divideable, this is currently implemented always to return the + * start offset. + */ + public int viewToModel(float x, float y, Shape shape, Bias[] bias) + { + return getStartOffset(); + } + + /** + * This is currently implemented always to return the area of the image view, + * as the image is not divideable by character positions. + * + * @param pos character position + * @param area of the image view + * @param bias bias + * + * @return the shape, where the given character position should be mapped. + */ + public Shape modelToView(int pos, Shape area, Bias bias) + throws BadLocationException + { + return area; + } + + /** + * Starts loading the image asynchronuosly. If the image must be loaded + * synchronuosly instead, the {@link #setLoadsSynchronously} must be + * called before calling this method. The passed parameters are not used. + */ + public void setSize(float width, float height) + { + if (imageIcon == null) + reloadImage(false); + } + + +} diff --git a/libjava/classpath/javax/swing/text/html/MinimalHTMLWriter.java b/libjava/classpath/javax/swing/text/html/MinimalHTMLWriter.java new file mode 100644 index 00000000000..d42951a05ec --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/MinimalHTMLWriter.java @@ -0,0 +1,452 @@ +/* MinimalHTMLWriter.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.text.html; + +import javax.swing.text.AttributeSet; +import javax.swing.text.AbstractWriter; +import javax.swing.text.BadLocationException; +import javax.swing.text.DefaultStyledDocument; +import javax.swing.text.Element; +import javax.swing.text.ElementIterator; +import javax.swing.text.StyleConstants; +import javax.swing.text.Style; +import javax.swing.text.StyledDocument; +import java.io.Writer; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Stack; +import java.awt.Color; + +/** + * MinimalHTMLWriter, + * A minimal AbstractWriter implementation for HTML. + * + * @author Sven de Marothy + */ +public class MinimalHTMLWriter extends AbstractWriter +{ + private StyledDocument doc; + private Stack tagStack; + private boolean inFontTag = false; + + /** + * Constructs a MinimalHTMLWriter. + * @param w - a Writer, for output. + * @param doc - the document + */ + public MinimalHTMLWriter(Writer w, StyledDocument doc) + { + super(w, doc); + this.doc = doc; + tagStack = new Stack(); + } + + /** + * Constructs a MinimalHTMLWriter. + * @param w - a Writer, for output. + * @param doc - the document + * @param pos - start position + * @param len - length + */ + public MinimalHTMLWriter(Writer w, StyledDocument doc, int pos, int len) + { + super(w, doc, pos, len); + this.doc = doc; + tagStack = new Stack(); + } + + /** + * Starts a span tag. + */ + protected void startFontTag(String style) throws IOException + { + if( inFontTag() ) + endOpenTags(); + writeStartTag("<span style=\""+style+"\">"); + inFontTag = true; + } + + /** + * Returns whether the writer is within two span tags. + */ + protected boolean inFontTag() + { + return inFontTag; + } + + /** + * Ends a span tag. + */ + protected void endFontTag() throws IOException + { + writeEndTag("</span>"); + inFontTag = false; + } + + /** + * Write the entire HTML document. + */ + public synchronized void write() throws IOException, BadLocationException + { + writeStartTag("<html>"); + writeHeader(); + writeBody(); + writeEndTag("</html>"); + } + + /** + * Write a start tag and increment the indent. + */ + protected void writeStartTag(String tag) throws IOException + { + indent(); + write(tag+NEWLINE); + incrIndent(); + } + + /** + * Write an ending tag and decrement the indent. + */ + protected void writeEndTag(String endTag) throws IOException + { + decrIndent(); + indent(); + write(endTag+NEWLINE); + } + + /** + * Write the HTML header. + */ + protected void writeHeader() throws IOException + { + writeStartTag("<head>"); + writeStartTag("<style>"); + writeStartTag("<!--"); + writeStyles(); + writeEndTag("-->"); + writeEndTag("</style>"); + writeEndTag("</head>"); + } + + /** + * Write a paragraph start tag. + */ + protected void writeStartParagraph(Element elem) throws IOException + { + indent(); + write("<p class=default>"+NEWLINE); // FIXME: Class value = ? + incrIndent(); + } + + /** + * Write a paragraph end tag, closes any other open tags. + */ + protected void writeEndParagraph() throws IOException + { + endOpenTags(); + writeEndTag("</p>"); + } + + /** + * Writes the body of the HTML document. + */ + protected void writeBody() throws IOException, BadLocationException + { + writeStartTag("<body>"); + + ElementIterator ei = getElementIterator(); + Element e = ei.first(); + boolean inParagraph = false; + do + { + if( e.isLeaf() ) + { + boolean hasNL = (getText(e).indexOf(NEWLINE) != -1); + if( !inParagraph && hasText( e ) ) + { + writeStartParagraph(e); + inParagraph = true; + } + + if( hasText( e ) ) + writeContent(e, true); + + if( hasNL && inParagraph ) + { + writeEndParagraph(); + inParagraph = false; + } + else + endOpenTags(); + } + } + while((e = ei.next()) != null); + + writeEndTag("</body>"); + } + + protected void text(Element elem) throws IOException, BadLocationException + { + write( getText(elem).trim() ); + } + + /** + * Write bold, indent and underline tags. + */ + protected void writeHTMLTags(AttributeSet attr) throws IOException + { + if(attr.getAttribute(StyleConstants.Bold) != null) + if(((Boolean)attr.getAttribute(StyleConstants.Bold)).booleanValue()) + { + write("<b>"); + tagStack.push("</b>"); + } + if(attr.getAttribute(StyleConstants.Italic) != null) + if(((Boolean)attr.getAttribute(StyleConstants.Italic)).booleanValue()) + { + write("<i>"); + tagStack.push("</i>"); + } + if(attr.getAttribute(StyleConstants.Underline) != null) + if(((Boolean)attr.getAttribute(StyleConstants.Underline)).booleanValue()) + { + write("<u>"); + tagStack.push("</u>"); + } + } + + /** + * Returns whether the element contains text or not. + */ + protected boolean isText(Element elem) + { + return (elem.getEndOffset() != elem.getStartOffset()); + } + + /** + * Writes the content of an element. + */ + protected void writeContent(Element elem, boolean needsIndenting) + throws IOException, BadLocationException + { + writeNonHTMLAttributes(elem.getAttributes()); + if(needsIndenting) + indent(); + writeHTMLTags(elem.getAttributes()); + if( isText(elem) ) + text(elem); + else + writeLeaf(elem); + + endOpenTags(); + } + + /** + * Writes a non-text leaf element. + */ + protected void writeLeaf(Element e) throws IOException + { + // NOTE: Haven't tested if this is correct. + if(e.getName().equals(StyleConstants.IconElementName)) + writeImage(e); + else + writeComponent(e); + } + + /** + * Write the HTML attributes which do not have tag equivalents, + * e.g. attributes other than bold/italic/underlined. + */ + protected void writeNonHTMLAttributes(AttributeSet attr) throws IOException + { + String style = ""; + + // Alignment? Background? + + if( StyleConstants.getForeground(attr) != null ) + style = style + "color: " + + getColor(StyleConstants.getForeground(attr)) + "; "; + + style = style + "font-size: "+StyleConstants.getFontSize(attr)+"pt; "; + style = style + "font-family: "+StyleConstants.getFontFamily(attr); + + startFontTag(style); + } + + /** + * Write the styles used. + */ + protected void writeStyles() throws IOException + { + if(doc instanceof DefaultStyledDocument) + { + Enumeration styles = ((DefaultStyledDocument)doc).getStyleNames(); + while(styles.hasMoreElements()) + writeStyle(doc.getStyle((String)styles.nextElement())); + } + else + { // What else to do here? + Style s = (Style)doc.getStyle("default"); + if(s != null) + writeStyle( s ); + } + } + + /** + * Write a set of attributes. + */ + protected void writeAttributes(AttributeSet attr) throws IOException + { + Enumeration attribs = attr.getAttributeNames(); + while(attribs.hasMoreElements()) + { + Object attribName = attribs.nextElement(); + String name = attribName.toString(); + String output = getAttribute(name, attr.getAttribute(attribName)); + if( output != null ) + { + indent(); + write( output + NEWLINE ); + } + } + } + + /** + * Deliberately unimplemented, handles component elements. + */ + protected void writeComponent(Element elem) throws IOException + { + } + + /** + * Deliberately unimplemented. + * Writes StyleConstants.IconElementName elements. + */ + protected void writeImage(Element elem) throws IOException + { + } + + // -------------------- Private methods. -------------------------------- + + /** + * Write a single style attribute + */ + private String getAttribute(String name, Object a) throws IOException + { + if(name.equals("foreground")) + return "foreground:"+getColor((Color)a)+";"; + if(name.equals("background")) + return "background:"+getColor((Color)a)+";"; + if(name.equals("italic")) + return "italic:"+(((Boolean)a).booleanValue() ? "italic;" : ";"); + if(name.equals("bold")) + return "bold:"+(((Boolean)a).booleanValue() ? "bold;" : "normal;"); + if(name.equals("family")) + return "family:" + a + ";"; + if(name.equals("size")) + { + int size = ((Integer)a).intValue(); + int htmlSize; + if( size > 24 ) + htmlSize = 7; + else if( size > 18 ) + htmlSize = 6; + else if( size > 14 ) + htmlSize = 5; + else if( size > 12 ) + htmlSize = 4; + else if( size > 10 ) + htmlSize = 3; + else if( size > 8 ) + htmlSize = 2; + else + htmlSize = 1; + + return "size:" + htmlSize + ";"; + } + + return null; + } + + /** + * Stupid that Color doesn't have a method for this. + */ + private String getColor(Color c) + { + String r = "00" + Integer.toHexString(c.getRed()); + r = r.substring(r.length() - 2); + String g = "00" + Integer.toHexString(c.getGreen()); + g = g.substring(g.length() - 2); + String b = "00" + Integer.toHexString(c.getBlue()); + b = b.substring(b.length() - 2); + return "#" + r + g + b; + } + + /** + * Empty the stack of open tags + */ + private void endOpenTags() throws IOException + { + while(!tagStack.empty()) + write((String)tagStack.pop()); + + if( inFontTag() ) + { + write(""+NEWLINE); + endFontTag(); + } + } + + /** + * Output a single style + */ + private void writeStyle(Style s) throws IOException + { + if( s == null ) + return; + + writeStartTag("p."+s.getName()+" {"); + writeAttributes(s); + writeEndTag("}"); + } + + private boolean hasText(Element e) throws BadLocationException + { + return (getText(e).trim().length() > 0); + } +} diff --git a/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java b/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java index 8dbdd2f5e58..155343f5bcc 100644 --- a/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java +++ b/libjava/classpath/javax/swing/tree/AbstractLayoutCache.java @@ -1,5 +1,5 @@ /* AbstractLayoutCache.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,13 +38,10 @@ exception statement from your version. */ package javax.swing.tree; -import gnu.classpath.NotImplementedException; - import java.awt.Rectangle; import java.util.Enumeration; import javax.swing.event.TreeModelEvent; -import javax.swing.tree.VariableHeightLayoutCache.NodeRecord; /** * class AbstractLayoutCache @@ -275,7 +272,7 @@ public abstract class AbstractLayoutCache for (int i = 0; i < n; i++) { TreePath path = getPathForRow(i); - r.setBounds(0,0,0,0); + r.setBounds(0, 0, 0, 0); r = getBounds(path, r); if (r.x + r.width > maximalWidth) maximalWidth = r.x + r.width; diff --git a/libjava/classpath/javax/swing/tree/DefaultMutableTreeNode.java b/libjava/classpath/javax/swing/tree/DefaultMutableTreeNode.java index be8317f975c..6951b960005 100644 --- a/libjava/classpath/javax/swing/tree/DefaultMutableTreeNode.java +++ b/libjava/classpath/javax/swing/tree/DefaultMutableTreeNode.java @@ -887,8 +887,7 @@ public class DefaultMutableTreeNode return false; if (node == this) return true; - return (node.getParent() == getParent() - && getParent() != null); + return node.getParent() == getParent() && getParent() != null; } /** @@ -1070,7 +1069,7 @@ public class DefaultMutableTreeNode public Object nextElement() { - if(queue.isEmpty()) + if (queue.isEmpty()) throw new NoSuchElementException("No more elements left."); TreeNode node = (TreeNode) queue.removeFirst(); @@ -1105,7 +1104,7 @@ public class DefaultMutableTreeNode public Object nextElement() { - if( next == null ) + if (next == null) throw new NoSuchElementException("No more elements left."); Object current = next; @@ -1121,7 +1120,7 @@ public class DefaultMutableTreeNode private TreeNode traverse(Enumeration children) { // If more children are available step down. - if( children.hasMoreElements() ) + if (children.hasMoreElements()) { TreeNode child = (TreeNode) children.nextElement(); childrenEnums.push(child.children()); @@ -1134,7 +1133,7 @@ public class DefaultMutableTreeNode // If there are no more levels left, there is no next // element to return. - if ( childrenEnums.isEmpty() ) + if (childrenEnums.isEmpty()) return null; else { @@ -1165,7 +1164,7 @@ public class DefaultMutableTreeNode public Object nextElement() { - if( nodes.isEmpty() ) + if (nodes.isEmpty()) throw new NoSuchElementException("No more elements left!"); Enumeration children = (Enumeration) childrenEnums.peek(); @@ -1175,7 +1174,7 @@ public class DefaultMutableTreeNode private Object traverse(Enumeration children) { - if ( children.hasMoreElements() ) + if (children.hasMoreElements()) { TreeNode node = (TreeNode) children.nextElement(); nodes.push(node); diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java b/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java index cc19501d2b6..b0a4d8db823 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeCellEditor.java @@ -382,7 +382,6 @@ public class DefaultTreeCellEditor editingContainer = createContainer(); setFont(UIManager.getFont("Tree.font")); setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor")); - editingIcon = renderer.getIcon(); } /** diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java b/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java index 5e93145ae5c..e120b71c167 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeCellRenderer.java @@ -1,5 +1,5 @@ /* DefaultTreeCellRenderer.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,16 +47,17 @@ import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; -import javax.swing.border.Border; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JTree; -import javax.swing.UIManager; +import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.Border; import javax.swing.plaf.UIResource; /** - * DefaultTreeCellRenderer + * A default implementation of the {@link TreeCellRenderer} interface. * * @author Andrew Selkirk */ @@ -64,71 +65,81 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer { - // ------------------------------------------------------------- - // Variables -------------------------------------------------- - // ------------------------------------------------------------- /** - * selected + * A flag indicating the current selection status. */ protected boolean selected; /** - * hasFocus + * A flag indicating the current focus status. */ protected boolean hasFocus; /** - * drawsFocusBorderAroundIcon + * drawsFocusBorderAroundIcon // FIXME: is this used? */ private boolean drawsFocusBorderAroundIcon; /** - * closedIcon + * The icon used to represent non-leaf nodes that are closed. + * + * @see #setClosedIcon(Icon) */ protected transient Icon closedIcon; /** - * leafIcon + * The icon used to represent leaf nodes. + * + * @see #setLeafIcon(Icon) */ protected transient Icon leafIcon; /** - * openIcon + * The icon used to represent non-leaf nodes that are open. + * + * @see #setOpenIcon(Icon) */ protected transient Icon openIcon; /** - * textSelectionColor + * The color used for text in selected cells. + * + * @see #setTextSelectionColor(Color) */ protected Color textSelectionColor; /** - * textNonSelectionColor + * The color used for text in non-selected cells. + * + * @see #setTextNonSelectionColor(Color) */ protected Color textNonSelectionColor; /** - * backgroundSelectionColor + * The background color for selected cells. + * + * @see #setBackgroundSelectionColor(Color) */ protected Color backgroundSelectionColor; /** - * backgroundNonSelectionColor + * The background color for non-selected cells. + * + * @see #setBackgroundNonSelectionColor(Color) */ protected Color backgroundNonSelectionColor; /** - * borderSelectionColor + * The border color for selected tree cells. + * + * @see #setBorderSelectionColor(Color) */ protected Color borderSelectionColor; - // ------------------------------------------------------------- - // Initialization --------------------------------------------- - // ------------------------------------------------------------- - /** - * Constructor DefaultTreeCellRenderer + * Creates a new tree cell renderer with defaults appropriate for the + * current {@link LookAndFeel}. */ public DefaultTreeCellRenderer() { @@ -138,19 +149,17 @@ public class DefaultTreeCellRenderer setTextNonSelectionColor(UIManager.getColor("Tree.textForeground")); setTextSelectionColor(UIManager.getColor("Tree.selectionForeground")); - setBackgroundNonSelectionColor(UIManager.getColor("Tree.nonSelectionBackground")); + setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground")); setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground")); setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor")); } - // ------------------------------------------------------------- - // Methods ---------------------------------------------------- - // ------------------------------------------------------------- - /** - * getDefaultOpenIcon + * Returns the default icon for non-leaf tree cells that are open (expanded). + * The icon is fetched from the defaults table for the current + * {@link LookAndFeel} using the key <code>Tree.openIcon</code>. * - * @returns Icon + * @return The default icon. */ public Icon getDefaultOpenIcon() { @@ -158,9 +167,11 @@ public class DefaultTreeCellRenderer } /** - * getDefaultClosedIcon + * Returns the default icon for non-leaf tree cells that are closed (not + * expanded). The icon is fetched from the defaults table for the current + * {@link LookAndFeel} using the key <code>Tree.closedIcon</code>. * - * @returns Icon + * @return The default icon. */ public Icon getDefaultClosedIcon() { @@ -168,9 +179,11 @@ public class DefaultTreeCellRenderer } /** - * getDefaultLeafIcon + * Returns the default icon for leaf tree cells. The icon is fetched from + * the defaults table for the current {@link LookAndFeel} using the key + * <code>Tree.leafIcon</code>. * - * @returns Icon + * @return The default icon. */ public Icon getDefaultLeafIcon() { @@ -178,20 +191,25 @@ public class DefaultTreeCellRenderer } /** - * setOpenIcon + * Sets the icon to be displayed for non-leaf nodes that are open (expanded). + * Set this to <code>null</code> if no icon is required. + * + * @param icon the icon (<code>null</code> permitted). * - * @param i - * the icon. + * @see #getOpenIcon() */ - public void setOpenIcon(Icon i) + public void setOpenIcon(Icon icon) { - openIcon = i; + openIcon = icon; } /** - * getOpenIcon + * Returns the icon displayed for non-leaf nodes that are open (expanded). + * The default value is initialised from the {@link LookAndFeel}. * - * @returns Icon + * @return The open icon (possibly <code>null</code>). + * + * @see #setOpenIcon(Icon) */ public Icon getOpenIcon() { @@ -199,20 +217,25 @@ public class DefaultTreeCellRenderer } /** - * setClosedIcon + * Sets the icon to be displayed for non-leaf nodes that are closed. Set + * this to <code>null</code> if no icon is required. + * + * @param icon the icon (<code>null</code> permitted). * - * @param i - * the icon. + * @see #getClosedIcon() */ - public void setClosedIcon(Icon i) + public void setClosedIcon(Icon icon) { - closedIcon = i; + closedIcon = icon; } /** - * getClosedIcon + * Returns the icon displayed for non-leaf nodes that are closed. The + * default value is initialised from the {@link LookAndFeel}. + * + * @return The closed icon (possibly <code>null</code>). * - * @returns Icon + * @see #setClosedIcon(Icon) */ public Icon getClosedIcon() { @@ -220,20 +243,25 @@ public class DefaultTreeCellRenderer } /** - * setLeafIcon + * Sets the icon to be displayed for leaf nodes. Set this to + * <code>null</code> if no icon is required. * - * @param i - * the icon. + * @param icon the icon (<code>null</code> permitted). + * + * @see #getLeafIcon() */ - public void setLeafIcon(Icon i) + public void setLeafIcon(Icon icon) { - leafIcon = i; + leafIcon = icon; } /** - * getLeafIcon + * Returns the icon displayed for leaf nodes. The default value is + * initialised from the {@link LookAndFeel}. + * + * @return The leaf icon (possibly <code>null</code>). * - * @returns Icon + * @see #setLeafIcon(Icon) */ public Icon getLeafIcon() { @@ -241,10 +269,11 @@ public class DefaultTreeCellRenderer } /** - * setTextSelectionColor + * Sets the text color for tree cells that are selected. * - * @param c - * the color. + * @param c the color (<code>null</code> permitted). + * + * @see #getTextSelectionColor() */ public void setTextSelectionColor(Color c) { @@ -252,9 +281,13 @@ public class DefaultTreeCellRenderer } /** - * getTextSelectionColor + * Returns the text color for tree cells that are selected. + * The default value is obtained from the {@link LookAndFeel} defaults + * table using the key <code>Tree.selectionForeground</code>. + * + * @return The text color for tree cells that are selected. * - * @returns Color + * @see #setTextSelectionColor(Color) */ public Color getTextSelectionColor() { @@ -262,10 +295,11 @@ public class DefaultTreeCellRenderer } /** - * setTextNonSelectionColor + * Sets the text color for tree cells that are not selected. + * + * @param c the color (<code>null</code> permitted). * - * @param c - * the color. + * @see #getTextNonSelectionColor() */ public void setTextNonSelectionColor(Color c) { @@ -273,9 +307,13 @@ public class DefaultTreeCellRenderer } /** - * getTextNonSelectionColor + * Returns the text color for tree cells that are not selected. + * The default value is obtained from the {@link LookAndFeel} defaults + * table using the key <code>Tree.selectionForeground</code>. * - * @returns Color + * @return The background color for tree cells that are not selected. + * + * @see #setTextgroundNonSelectionColor(Color) */ public Color getTextNonSelectionColor() { @@ -283,10 +321,11 @@ public class DefaultTreeCellRenderer } /** - * setBackgroundSelectionColor + * Sets the background color for tree cells that are selected. + * + * @param c the color (<code>null</code> permitted). * - * @param c - * the color. + * @see #getBackgroundSelectionColor() */ public void setBackgroundSelectionColor(Color c) { @@ -294,9 +333,13 @@ public class DefaultTreeCellRenderer } /** - * getBackgroundSelectionColor + * Returns the background color for tree cells that are selected. + * The default value is obtained from the {@link LookAndFeel} defaults + * table using the key <code>Tree.selectionBackground</code>. * - * @returns Color + * @return The background color for tree cells that are selected. + * + * @see #setBackgroundSelectionColor(Color) */ public Color getBackgroundSelectionColor() { @@ -304,10 +347,11 @@ public class DefaultTreeCellRenderer } /** - * setBackgroundNonSelectionColor + * Sets the background color for tree cells that are not selected. + * + * @param c the color (<code>null</code> permitted). * - * @param c - * the color. + * @see #getBackgroundNonSelectionColor() */ public void setBackgroundNonSelectionColor(Color c) { @@ -315,9 +359,13 @@ public class DefaultTreeCellRenderer } /** - * getBackgroundNonSelectionColor + * Returns the background color for tree cells that are not selected. + * The default value is obtained from the {@link LookAndFeel} defaults + * table using the key <code>Tree.textBackground</code>. + * + * @return The background color for tree cells that are not selected. * - * @returns Color + * @see #setBackgroundNonSelectionColor(Color) */ public Color getBackgroundNonSelectionColor() { @@ -325,10 +373,11 @@ public class DefaultTreeCellRenderer } /** - * setBorderSelectionColor + * Sets the border color for tree cells that are selected. * - * @param c - * the color. + * @param c the color (<code>null</code> permitted). + * + * @see #getBorderSelectionColor() */ public void setBorderSelectionColor(Color c) { @@ -336,9 +385,13 @@ public class DefaultTreeCellRenderer } /** - * getBorderSelectionColor + * Returns the border color for tree cells that are selected. + * The default value is obtained from the {@link LookAndFeel} defaults + * table using the key <code>Tree.selectionBorderColor</code>. + * + * @return The border color for tree cells that are selected. * - * @returns Color + * @see #setBorderSelectionColor(Color) */ public Color getBorderSelectionColor() { @@ -346,10 +399,11 @@ public class DefaultTreeCellRenderer } /** - * setFont + * Sets the font. * - * @param f - * the font. + * @param f the font. + * + * @see #getFont() */ public void setFont(Font f) { @@ -359,10 +413,9 @@ public class DefaultTreeCellRenderer } /** - * setBackground + * Sets the background color. * - * @param c - * the color. + * @param c the color. */ public void setBackground(Color c) { @@ -372,23 +425,18 @@ public class DefaultTreeCellRenderer } /** - * getTreeCellRendererComponent + * Returns a component (in fact <code>this</code>) that can be used to + * render a tree cell with the specified state. + * + * @param tree the tree that the cell belongs to. + * @param val the cell value. + * @param selected indicates whether or not the cell is selected. + * @param expanded indicates whether or not the cell is expanded. + * @param leaf indicates whether or not the cell is a leaf in the tree. + * @param row the row index. + * @param hasFocus indicates whether or not the cell has the focus. * - * @param tree - * TODO - * @param val - * TODO - * @param selected - * TODO - * @param expanded - * TODO - * @param leaf - * TODO - * @param row - * TODO - * @param hasFocus - * TODO - * @returns Component + * @return <code>this</code>. */ public Component getTreeCellRendererComponent(JTree tree, Object val, boolean selected, @@ -433,9 +481,11 @@ public class DefaultTreeCellRenderer } /** - * getFont + * Returns the current font. + * + * @return The current font. * - * @return the current Font + * @see #setFont(Font) */ public Font getFont() { @@ -460,7 +510,7 @@ public class DefaultTreeCellRenderer insets = border.getBorderInsets(this); FontMetrics fm = getToolkit().getFontMetrics(getFont()); - SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(), + SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(), getIcon(), getVerticalAlignment(), getHorizontalAlignment(), getVerticalTextPosition(), @@ -471,7 +521,7 @@ public class DefaultTreeCellRenderer Rectangle bounds = getBounds(ir); bounds.x = tr.x - insets.left; - bounds.width = tr.width + insets.left+insets.right; + bounds.width = tr.width + insets.left + insets.right; g.setColor(super.getBackground()); g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); @@ -491,9 +541,9 @@ public class DefaultTreeCellRenderer } /** - * returns the preferred size of the cell. + * Returns the preferred size of the cell. * - * @returns Dimension + * @return The preferred size of the cell. */ public Dimension getPreferredSize() { @@ -502,7 +552,7 @@ public class DefaultTreeCellRenderer Rectangle tr = new Rectangle(); FontMetrics fm = getToolkit().getFontMetrics(getFont()); - SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(), + SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(), getIcon(), getVerticalAlignment(), getHorizontalAlignment(), getVerticalTextPosition(), @@ -510,182 +560,156 @@ public class DefaultTreeCellRenderer getIconTextGap()); Rectangle cr = ir.union(tr); return new Dimension(cr.width, cr.height); - } // getPreferredSize() + } /** - * validate + * For performance reasons, this method is overridden to do nothing. */ public void validate() { // Overridden for performance reasons. - } // validate() + } /** - * revalidate + * For performance reasons, this method is overridden to do nothing. */ public void revalidate() { // Overridden for performance reasons. - } // revalidate() + } /** - * repaint + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO - * @param value3 - * TODO - * @param value4 - * TODO + * @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 value0, int value1, int value2, int value3, - int value4) + public void repaint(long tm, int x, int y, int width, int height) { // Overridden for performance reasons. - } // repaint() + } /** - * repaint + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO + * @param area the area to repaint. */ - public void repaint(Rectangle value0) + public void repaint(Rectangle area) { // Overridden for performance reasons. - } // repaint() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - protected void firePropertyChange(String value0, Object value1, Object value2) + protected void firePropertyChange(String name, Object oldValue, + Object newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, byte value1, byte value2) + public void firePropertyChange(String name, byte oldValue, byte newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, char value1, char value2) + public void firePropertyChange(String name, char oldValue, char newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, short value1, short value2) + public void firePropertyChange(String name, short oldValue, short newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, int value1, int value2) + public void firePropertyChange(String name, int oldValue, int newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, long value1, long value2) + public void firePropertyChange(String name, long oldValue, long newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 - * TODO - * @param value1 - * TODO - * @param value2 - * TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, float value1, float value2) + public void firePropertyChange(String name, float oldValue, float newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param value0 TODO - * @param value1 TODO - * @param value2 TODO + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String value0, double value1, double value2) + public void firePropertyChange(String name, double oldValue, double newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } /** - * firePropertyChange + * For performance reasons, this method is overridden to do nothing. * - * @param name the property name. - * @param v1 the old value. - * @param v2 the new value. + * @param name the property name. + * @param oldValue the old value. + * @param newValue the new value. */ - public void firePropertyChange(String name, boolean v1, boolean v2) + public void firePropertyChange(String name, boolean oldValue, + boolean newValue) { // Overridden for performance reasons. - } // firePropertyChange() + } -} // DefaultTreeCellRenderer +} diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java index c1ca679d006..5819d15b627 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java @@ -1,5 +1,5 @@ /* DefaultTreeModel.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,8 +37,6 @@ exception statement from your version. */ package javax.swing.tree; -import gnu.classpath.NotImplementedException; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -62,7 +60,7 @@ public class DefaultTreeModel /** * root */ - protected TreeNode root = null; + protected TreeNode root; /** * listenerList diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java index 0676f7ec8f4..0684ef76659 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java @@ -147,9 +147,9 @@ public class DefaultTreeSelectionModel // Clone the selection and the list selection model. cloned.selection = (TreePath[]) selection.clone(); - if (listSelectionModel!=null) - cloned.listSelectionModel = - (DefaultListSelectionModel) listSelectionModel.clone(); + if (listSelectionModel != null) + cloned.listSelectionModel + = (DefaultListSelectionModel) listSelectionModel.clone(); return cloned; } @@ -171,7 +171,7 @@ public class DefaultTreeSelectionModel b.append(getRow(selection[i])); b.append(' '); } - b.append(", lead "+getLeadSelectionRow()); + b.append(", lead " + getLeadSelectionRow()); return b.toString(); } } @@ -360,7 +360,7 @@ public class DefaultTreeSelectionModel } } - if (path!=leadPath) + if (path != leadPath) { TreePath oldLead = leadPath; leadPath = path; @@ -445,7 +445,7 @@ public class DefaultTreeSelectionModel // If the removed path was the lead path, set the lead path to null. TreePath oldLead = leadPath; - if (path!=null && leadPath!=null && path.equals(leadPath)) + if (path != null && leadPath != null && path.equals(leadPath)) leadPath = null; fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead, @@ -564,7 +564,7 @@ public class DefaultTreeSelectionModel */ public boolean isSelectionEmpty() { - return ((selection == null) || (selection.length == 0)); + return (selection == null) || (selection.length == 0); } /** @@ -841,7 +841,7 @@ public class DefaultTreeSelectionModel if (leadIndex > 0 && leadIndex < selection.length) setSelectionPath(selection[leadIndex]); else - setSelectionPath(selection[selection.length -1]); + setSelectionPath(selection[selection.length - 1]); } /** @@ -882,7 +882,7 @@ public class DefaultTreeSelectionModel for (int i = 1; i < rows.length; i++) { - if (rows[i-1] != rows[i] - 1) + if (rows[i - 1] != rows[i] - 1) return false; } return true; diff --git a/libjava/classpath/javax/swing/tree/ExpandVetoException.java b/libjava/classpath/javax/swing/tree/ExpandVetoException.java index 1c8827c8a6c..57531d54200 100644 --- a/libjava/classpath/javax/swing/tree/ExpandVetoException.java +++ b/libjava/classpath/javax/swing/tree/ExpandVetoException.java @@ -1,5 +1,5 @@ /* ExpandVetoException.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,47 +37,40 @@ exception statement from your version. */ package javax.swing.tree; -// Imports import javax.swing.event.TreeExpansionEvent; /** * ExpandVetoException * @author Andrew Selkirk */ -public class ExpandVetoException extends Exception { - - //------------------------------------------------------------- - // Variables -------------------------------------------------- - //------------------------------------------------------------- - - /** - * event - */ - protected TreeExpansionEvent event = null; - - - //------------------------------------------------------------- - // Initialization --------------------------------------------- - //------------------------------------------------------------- - - /** - * Constructor ExpandVetoException - * @param event Tree Expansion Event - */ - public ExpandVetoException(TreeExpansionEvent event) { - super(); - this.event = event; - } // ExpandVetoException() - - /** - * Constructor ExpandVetoException - * @param event Tree Expansion Event - * @param message Message - */ - public ExpandVetoException(TreeExpansionEvent event, String message) { - super(message); - this.event = event; - } // ExpandVetoException() - - -} // ExpandVetoException +public class ExpandVetoException extends Exception +{ + + /** + * event + */ + protected TreeExpansionEvent event; + + + /** + * Constructor ExpandVetoException + * @param event Tree Expansion Event + */ + public ExpandVetoException(TreeExpansionEvent event) + { + super(); + this.event = event; + } + + /** + * Constructor ExpandVetoException + * @param event Tree Expansion Event + * @param message Message + */ + public ExpandVetoException(TreeExpansionEvent event, String message) + { + super(message); + this.event = event; + } + +} diff --git a/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java b/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java index 96655ce75fd..a699a6c9f21 100644 --- a/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java +++ b/libjava/classpath/javax/swing/tree/FixedHeightLayoutCache.java @@ -163,7 +163,7 @@ public class FixedHeightLayoutCache { // This method may be called in the context when the tree rectangle is // not known. To work around this, it is assumed near infinitely large. - if (bounds==null) + if (bounds == null) bounds = getNodeDimensions(node, row, depth, isExpanded, new Rectangle()); return bounds; @@ -266,7 +266,7 @@ public class FixedHeightLayoutCache if (expanded.contains(node)) { int sc = treeModel.getChildCount(node); - int deeper = depth+1; + int deeper = depth + 1; for (int i = 0; i < sc; i++) { Object child = treeModel.getChild(node, i); @@ -283,7 +283,7 @@ public class FixedHeightLayoutCache public void invalidatePathBounds(TreePath path) { NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent()); - if (r!=null) + if (r != null) r.bounds = null; } diff --git a/libjava/classpath/javax/swing/tree/RowMapper.java b/libjava/classpath/javax/swing/tree/RowMapper.java index 690efb77e32..59eb1e3a9fa 100644 --- a/libjava/classpath/javax/swing/tree/RowMapper.java +++ b/libjava/classpath/javax/swing/tree/RowMapper.java @@ -1,5 +1,5 @@ /* RowMapper.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,14 +41,14 @@ package javax.swing.tree; * RowMapper public interface * @author Andrew Selkirk */ -public interface RowMapper { +public interface RowMapper +{ - /** - * getRowsForPaths - * @param path TreePath - * @return TODO - */ - int[] getRowsForPaths(TreePath[] path); + /** + * getRowsForPaths + * @param path TreePath + * @return TODO + */ + int[] getRowsForPaths(TreePath[] path); - -} // RowMapper +}
\ No newline at end of file diff --git a/libjava/classpath/javax/swing/tree/TreeNode.java b/libjava/classpath/javax/swing/tree/TreeNode.java index 94f2c69f895..ae7380c703b 100644 --- a/libjava/classpath/javax/swing/tree/TreeNode.java +++ b/libjava/classpath/javax/swing/tree/TreeNode.java @@ -45,7 +45,8 @@ import java.util.Enumeration; * * @author Andrew Selkirk */ -public interface TreeNode { +public interface TreeNode +{ /** * Returns the parent node for this tree node, or <code>null</code> if this diff --git a/libjava/classpath/javax/swing/tree/TreePath.java b/libjava/classpath/javax/swing/tree/TreePath.java index 4671c4be54b..93b59b07edf 100644 --- a/libjava/classpath/javax/swing/tree/TreePath.java +++ b/libjava/classpath/javax/swing/tree/TreePath.java @@ -262,14 +262,16 @@ public class TreePath implements Serializable if (path == null) return false; int count = getPathCount(); - if (path.getPathCount() < count) + int otherPathLength = path.getPathCount(); + if (otherPathLength < count) return false; - for (int i = 0; i < count; i++) - { - if (!this.path[i].equals(path.getPathComponent(i))) - return false; - } - return true; + while (otherPathLength > count) + { + otherPathLength--; + path = path.getParentPath(); + } + + return equals(path); } /** diff --git a/libjava/classpath/javax/swing/tree/TreeSelectionModel.java b/libjava/classpath/javax/swing/tree/TreeSelectionModel.java index 4072ccc64c5..9bdc99be350 100644 --- a/libjava/classpath/javax/swing/tree/TreeSelectionModel.java +++ b/libjava/classpath/javax/swing/tree/TreeSelectionModel.java @@ -1,5 +1,5 @@ /* TreeSelectionModel.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,39 +46,67 @@ import javax.swing.event.TreeSelectionListener; * TreeSelectionModel public interface * @author Andrew Selkirk */ -public interface TreeSelectionModel { - - int SINGLE_TREE_SELECTION = 1; - int CONTIGUOUS_TREE_SELECTION = 2; - int DISCONTIGUOUS_TREE_SELECTION = 4; - - void setSelectionMode(int mode); - int getSelectionMode(); - void setSelectionPath(TreePath path); - void setSelectionPaths(TreePath[] paths); - void addSelectionPath(TreePath path); - void addSelectionPaths(TreePath[] paths); - void removeSelectionPath(TreePath path); - void removeSelectionPaths(TreePath[] paths); - TreePath getSelectionPath(); - TreePath[] getSelectionPaths(); - int getSelectionCount(); - boolean isPathSelected(TreePath path); - boolean isSelectionEmpty(); - void clearSelection(); - void setRowMapper(RowMapper newMapper); - RowMapper getRowMapper(); - int[] getSelectionRows(); - int getMinSelectionRow(); - int getMaxSelectionRow(); - boolean isRowSelected(int row); - void resetRowSelection(); - int getLeadSelectionRow(); - TreePath getLeadSelectionPath(); - void addPropertyChangeListener(PropertyChangeListener listener); - void removePropertyChangeListener(PropertyChangeListener listener); - void addTreeSelectionListener(TreeSelectionListener x); - void removeTreeSelectionListener(TreeSelectionListener x); - - -} // TreeSelectionModel +public interface TreeSelectionModel +{ + + int SINGLE_TREE_SELECTION = 1; + + int CONTIGUOUS_TREE_SELECTION = 2; + + int DISCONTIGUOUS_TREE_SELECTION = 4; + + void setSelectionMode(int mode); + + int getSelectionMode(); + + void setSelectionPath(TreePath path); + + void setSelectionPaths(TreePath[] paths); + + void addSelectionPath(TreePath path); + + void addSelectionPaths(TreePath[] paths); + + void removeSelectionPath(TreePath path); + + void removeSelectionPaths(TreePath[] paths); + + TreePath getSelectionPath(); + + TreePath[] getSelectionPaths(); + + int getSelectionCount(); + + boolean isPathSelected(TreePath path); + + boolean isSelectionEmpty(); + + void clearSelection(); + + void setRowMapper(RowMapper newMapper); + + RowMapper getRowMapper(); + + int[] getSelectionRows(); + + int getMinSelectionRow(); + + int getMaxSelectionRow(); + + boolean isRowSelected(int row); + + void resetRowSelection(); + + int getLeadSelectionRow(); + + TreePath getLeadSelectionPath(); + + void addPropertyChangeListener(PropertyChangeListener listener); + + void removePropertyChangeListener(PropertyChangeListener listener); + + void addTreeSelectionListener(TreeSelectionListener x); + + void removeTreeSelectionListener(TreeSelectionListener x); + +} diff --git a/libjava/classpath/javax/swing/tree/VariableHeightLayoutCache.java b/libjava/classpath/javax/swing/tree/VariableHeightLayoutCache.java index a9ed552e635..0a787f7ca8c 100644 --- a/libjava/classpath/javax/swing/tree/VariableHeightLayoutCache.java +++ b/libjava/classpath/javax/swing/tree/VariableHeightLayoutCache.java @@ -162,7 +162,7 @@ public class VariableHeightLayoutCache { // This method may be called in the context when the tree rectangle is // not known. To work around this, it is assumed near infinitely large. - if (bounds==null) + if (bounds == null) bounds = getNodeDimensions(node, row, depth, isExpanded, new Rectangle()); return bounds; @@ -232,6 +232,9 @@ public class VariableHeightLayoutCache totalHeight = maximalWidth = 0; + if (treeModel == null) + return; + Object root = treeModel.getRoot(); if (rootVisible) @@ -265,7 +268,7 @@ public class VariableHeightLayoutCache if (expanded.contains(node)) { int sc = treeModel.getChildCount(node); - int deeper = depth+1; + int deeper = depth + 1; for (int i = 0; i < sc; i++) { Object child = treeModel.getChild(node, i); @@ -282,7 +285,7 @@ public class VariableHeightLayoutCache public void invalidatePathBounds(TreePath path) { NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent()); - if (r!=null) + if (r != null) r.bounds = null; } @@ -555,9 +558,16 @@ public class VariableHeightLayoutCache public void setModel(TreeModel newModel) { treeModel = newModel; - // The root node is expanded by default. - expanded.add(treeModel.getRoot()); - dirty = true; + // We need to clear the table and update the layout, + // so that we don't end up with wrong data in the tables. + expanded.clear(); + update(); + if (treeModel != null) + { + // The root node is expanded by default. + expanded.add(treeModel.getRoot()); + dirty = true; + } } /** |