diff options
author | graydon <graydon@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-27 06:17:44 +0000 |
---|---|---|
committer | graydon <graydon@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-27 06:17:44 +0000 |
commit | 7be583b48b04633a592ab530473b7f995955b160 (patch) | |
tree | 2ffcb4d3889f27364cadf6d34acb5b88d5881e8a /libjava/javax/swing/plaf/basic | |
parent | 765f486dfed484416d8afd28184f4cddb742a7d9 (diff) | |
download | gcc-7be583b48b04633a592ab530473b7f995955b160.tar.gz |
2004-05-25 David Jee <djee@redhat.com>
* java/awt/Container.java
(remove): Set component's parent to null only after we removed the
component from its parent's layout manager.
2004-05-25 David Jee <djee@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(GtkComponentPeer): Set bounds regardless of whether awtComponent
is valid.
* gnu/java/awt/peer/gtk/GtkListPeer.java
(getSize): Change native method declaration.
(minimumSize): Pass visible row count into getSize().
(preferredSize): Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
(Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize): Use scroll window's
natural size. Use visible row count to determine the final height
value to return.
2004-05-21 Graydon Hoare <graydon@redhat.com>
* gnu/java/awt/peer/gtk/GdkGraphics2D.java
(setClip): Minor correction to order of operations.
* javax/swing/JScrollPane.java: Extend sketchy implementation.
* javax/swing/ScrollPaneLayout.java: Likewise.
* javax/swing/JViewPort.java: Likewise.
* javax/swing/ViewportLayout.java: Likewise.
* javax/swing/JComponent.java: Rewrite.
* javax/swing/RepaintManager.java: Likewise.
* javax/swing/JLayeredPane.java: Change validate() to revalidate().
* javax/swing/JList.java
(setSelectedIndices):
(getSelectedIndices):
(getSelectedValues): New functions.
(getPreferredScrollableViewportSize): Return preferred size.
(getScrollableUnitIncrement):
(getScrollableBlockIncrement): Initial implementations.
* javax/swing/JRootPane.java: Clean up slightly.
(getUI):
(setUI):
(updateUI):
(getUIClassID):
(isValidateRoot): Add overrides from JComponent.
* javax/swing/JScrollBar.java: Set default orientation to VERTICAL.
* javax/swing/UIManager.java (getDimension): Return the dimension.
* javax/swing/plaf/basic/BasicButtonUI.java: Set component opaque.
* javax/swing/plaf/basic/BasicLabelUI.java: Likewise.
* javax/swing/plaf/basic/BasicMenuItemUI.java: Likewise.
* javax/swing/plaf/basic/BasicProgressBarUI.java: Likewise.
* javax/swing/plaf/basic/BasicSeparatorUI.java: Likewise.
* javax/swing/plaf/basic/BasicSliderUI.java: Likewise.
* javax/swing/plaf/basic/BasicTabbedPaneUI.java: Likewise.
* javax/swing/plaf/basic/BasicRootPaneUI.java:
Likewise, and set background.
* javax/swing/plaf/basic/BasicListUI.java:
Likewise, and improve a bit.
* javax/swing/plaf/basic/BasicScrollBarUI.java:
Likewise, and adjust calculations.
* javax/swing/plaf/basic/BasicViewportUI.java:
Likewise, and improve a bit.
* javax/swing/plaf/basic/BasicLookAndFeel.java
(Button.margin): Shrink.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c:
Hack to set horizontal always, workaround pango.
* jni/gtk-peer/gtkcairopeer.h: Change to match pattern API.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:
Synchronize more often, check cairo status after ops,
handle changes to cairo pattern API, check for disposal.
2004-05-21 Olga Rodimina <rodimina@redhat.com>
* javax/swing/plaf/basic/BasicMenuItemUI.java:
(BasicMenuItemUI): Create propertyChangeListener.
(getPath):Implemented.
(installListeners): Add propertyChangeListener to menuItem.
(uninstallListeners): Remove propertyChangeListener from menuItem.
(update): Implemented.
* javax/swing/plaf/basic/BasicMenuUI.MouseInputHandler:
(mouseEntered): Take insets of popup menu into account when
calculating position of popup menu.
2004-05-18 Olga Rodimina <rodimina@redhat.com>
* Makefile.am: Added new file.
* Makefile.in: Regenerate.
* javax/swing/JMenuBar.java:
Started implementation.
* javax/swing/JPopupMenu.java:
(setVisible): Fixed location of lightweight/mediumweight
popup menu.
(show): Fixed location of PopupMenu.
* javax/swing/plaf/basic/BasicMenuBarUI.java:
New file. UI Delegate for JMenuBar.
* javax/swing/plaf/basic/BasicMenuUI.MouseInputHandler:
(mouseEntered): Corrected position of the submenu.
2004-05-18 Thomas Fitzsimmons <fitzsim@redhat.com>
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c: Remove calls
to _gtk_accel_group_attach.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c:
Likewise.
* gnu/java/awt/peer/gtk/GtkButtonPeer.java: Give gtkSetFont
package access. Don't override setFont.
* gnu/java/awt/peer/gtk/GtkCheckboxPeer.java: Likewise.
* gnu/java/awt/peer/gtk/GtkComponentPeer.java: Give
gtkWidgetRequestFocus package access.
* gnu/java/awt/peer/gtk/GtkLabelPeer.java: Don't override
setFont.
* gnu/java/awt/peer/gtk/GtkListPeer.java: Override gtkSetFont.
Give gtkWidgetRequestFocus package access.
* gnu/java/awt/peer/gtk/GtkTextAreaPeer.java: Give
gtkWidgetRequestFocus package access. Don't override setFont.
* gnu/java/awt/peer/gtk/GtkTextFieldPeer.java: Don't override
setFont.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
(gtkSetLabel): Move call to gtk_bin_get_child into GDK critical
region.
(gtkSetFont): Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c (gtkSetFont):
Implement.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
(gtkSetFont): Whitespace fix.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
(gtkWidgetSetUsize): Remove method.
2004-05-18 David Jee <djee@redhat.com>
* java/awt/image/MemoryImageSource.java
(newPixels(int,int,int,int,boolean)): Set only the specified
rectangle of pixels.
(newPixels(byte[],ColorModel,int,int)): Implement.
(newPixels(int[],ColorModel,int,int)): Implement.
2004-05-18 Olga Rodimina <rodimina@redhat.com>
* Makefile.am: Added new file.
* Makefile.in: Regenerate.
* javax/swing/JMenu.java: Started
implementation.
* javax/swing/JPopupMenu.java:
(insert): If specified index is -1, then
add component at the end.
(isPopupTrigger): Reimplemented.
(JPopupMenu.LightWeightPopup): setBounds
of the lightWeightPopup before adding it
to the layeredPane.
(javax/swing/plaf/basic/BasicIconFactory.java):
(getMenuArrowIcon): Implemented.
* javax/swing/plaf/basic/BasicMenuItemUI.java:
(getPreferredSize): Add size of the arrow icon
if this menu item is instance of JMenu.
(paintMenuItem): Paint arrow icon if this
menu item is a submenu.
* javax/swing/plaf/basic/BasicMenuUI.java:
New File. UI Delegate for JMenu.
2004-05-17 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java (postKeyEvent):
Post KEY_TYPED events.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
(generates_key_typed_event): Remove function.
2004-05-17 Olga Rodimina <rodimina@redhat.com>
* javax/swing/JRootPane.java
(JRootPane.RootLayout): Reimplemented to
set bounds of contentPane and menuBar.
(setJMenuBar): Add menu bar to the layered pane.
(createLayeredPane): Set layout of layeredPane
to null.
* javax/swing/JLayeredPane.java:
(addImpl): Calculate index of the component in the
layeredPane according to the specified position within
the layer.
2004-05-17 David Jee <djee@redhat.com>
* gnu/java/awt/peer/gtk/GtkImagePainter.java
(setPixels): Change color model to the default model after
converting pixels.
* java/awt/image/MemoryImageSource.java
(newPixels): Set only the specified rectangle of pixels.
2004-05-13 Thomas Fitzsimmons <fitzsim@redhat.com>
* libgcj.spec.in (lib): Add -l-java-awt -l-java-applet
-l-java-beans -l-javax-accessibility -l-javax-swing.
* java/awt/AWTEvent.java (toString): Print source's name rather
than the source itself.
2004-05-12 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkToolkit.java (loadSystemColors): Make
native.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
(gdk_color_to_java_color): New function.
* jni/gtk-peer/gtkpeer.h: Add SystemColor defines.
2004-05-12 David Jee <djee@redhat.com>
* java/awt/image/RGBImageFilter.java:
Initialize origmodel as null.
(makeColor): Fix pixel component order.
(filterRGBPixels): Fix pixel iteration.
(setPixels): Add extra checks for index color model. Convert pixels
to default color model if necessary.
(convertColorModelToDefault): New override method for byte pixels.
(convertColorModelToDefault): For int pixels, fix pixel iteration.
(makeColorbyDefaultCM): New override method for byte pixels.
(makeColorbyDefaultCM): For int pixel, add color model as argument.
(makeColor): Fix pixel component order.
2004-05-11 Kim Ho <kho@redhat.com>
* javax/swing/Box.java:
Comment out more parts of Box.Filler.
2004-05-11 Kim Ho <kho@redhat.com>
* javax/swing/Box.java:
Remove reference to AccessibleAWTComponent so
it compiles again.
2004-05-10 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkListPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c: Update
implementation of list peer to use GtkTreeView instead of
deprecated GtkCList.
2004-05-07 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(gtkWidgetDispatchKeyEvent): Remove keyChar parameter.
(handleEvent): Remove keyChar argument to
gtkWidgetDispatchKeyEvent calls.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c: Fix
compiler warnings.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c: Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c: Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c:
Likewise.
2004-05-06 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(gtkWidgetRequestFocus): Mark protected.
(GtkComponentPeer): Only set the peer's bounds if its component
is valid.
* java/awt/Component.java (static): Set the default keyboard
focus manager.
(requestFocus(), requestFocus(boolean), requestFocusInWindow(),
requestFocusInWindow(temporary)): Don't request focus if the
component is not showing. Get tree lock before traversing
component hierarchy.
* java/awt/DefaultKeyboardFocusManager.java (dispatchEvent):
Only set the global focus owner if it is not a Window.
(processKeyEvent): Consume keystrokes associated with the focus
traversal keystroke.
(focusPreviousComponent, focusNextComponent, upFocusCycle,
downFocusCycle): Call requestFocusInWindow instead of
requestFocus.
* java/awt/EventDispatchThread.java (run): Move setting of
default keyboard focus manager to Component.java.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
(awt_keycode_to_keysym): New function.
(gtkWidgetDispatchKeyEvent): Finish implementation.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
(pre_event_handler): Add FIXME comment.
* gnu/java/awt/peer/gtk/GtkTextAreaPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
(gtkWidgetRequestFocus): New method.
* java/awt/TextArea.java (TextArea): Set focus traversal keys to
disable Tab and Shift-Tab keystrokes.
(addNotify, appendText, insertText, replaceText): Simplify peer
retrieval code.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
(connectSignals): Remove connections to "commit" signals.
Remove C++-style comments.
* gnu/java/awt/peer/gtk/GtkButtonPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
(handleEvent): Activate GTK button when the space bar key is
pressed.
(gtkActivate): New method.
2004-05-06 David Jee <djee@redhat.com>
* java/awt/image/CropImageFilter.java
(setPixels): Implement for byte array pixels.
* java/awt/image/ReplicateScaleFilter.java
(setPixels): Implement for byte array pixels.
(replicatePixels): Overload for byte array pixels.
2004-05-06 Kim Ho <kho@redhat.com>
* javax/swing/Box.java:
(getAccessibleContext): Return an instance of the
correct class.
2004-05-05 David Jee <djee@redhat.com>
* gnu/java/awt/peer/gtk/GdkGraphics.java
(drawImage): When component is null, use SystemColor.window as
the default bgcolor.
* gnu/java/awt/peer/gtk/GtkImage.java
(setPixels): We can avoid iterating through the pixel rows only
when height is 1.
* java/awt/Image.java
(getScaledInstance): Partially implement.
* java/awt/image/CropImageFilter.java
(setProperties): Fix "filter" property.
(setPixels): Implement.
* java/awt/image/ReplicateScaleFilter.java
(setDimensions): Use scaled dimensions.
(setPixels): Implement.
(replicatePixels): New method.
2004-05-05 David Jee <djee@redhat.com>
* gnu/java/awt/peer/gtk/GtkImagePainter.java
(convertPixels): If either pixels or model is null, return null.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c
(Java_gnu_java_awt_peer_gtk_GtkImagePainter_drawPixels): If jpixels
is null, do nothing and return.
2004-05-03 Kim Ho <kho@redhat.com>
* gnu/java/awt/peer/gtk/GtkDialogPeer.java:
(getGraphics): Like GtkFramePeer, the Graphics
object needs to be translate to account for
window decorations.
(postMouseEvent): New method. Account for
translation.
(postExposeEvent): ditto.
* javax/swing/Box.java: Stubbed.
* javax/swing/JDialog.java: Ran through jalopy
to fix indentation.
(JDialog): Call SwingUtilities' getOwnerFrame
for null owners.
(setLayout): Check isRootPaneCheckingEnabled
* javax/swing/JOptionPane.java: Re-implemented.
* javax/swing/SwingUtilities.java:
(getOwnerFrame): Static method to grab a default
owner frame for Dialogs that don't specify owners.
* javax/swing/event/SwingPropertyChangeSupport.java:
(firePropertyChange): Fix early exit condition.
* javax/swing/plaf/basic/BasicLabelUI.java:
(paint): Avoid painting text if it is null
or empty.
* javax/swing/plaf/basic/BasicOptionPaneUI.java:
Implement.
2004-05-03 Olga Rodimina <rodimina@redhat.com>
* Makefile.am: Added new file.
* Makefile.in: Regenerate.
* javax/swing/JPopupMenu.java:
Started implementation.
* javax/swing/JWindow.java
(JWindow): call super() if parent for window
is not specified.
* javax/swing/plaf/basic/BasicPopupMenuUI.java:
New File. UI Delegate for JPopupMenu.
2004-04-30 Olga Rodimina <rodimina@redhat.com>
* javax/swing/JApplet.java: Indicated that JApplet
implements RootPaneContainer and made method of this
interface public.
* javax/swing/JFrame.java: Ditto.
* javax/swing/JWindow.java: Ditto.
2004-04-29 Thomas Fitzsimmons <fitzsim@redhat.com>
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
(nativeSetBounds): Call gdk_window_move in addition to
gtk_window_move.
* java/applet/Applet.java (preferredSize): Call parent's
preferredSize if the applet stub is null.
(minimumSize): Likewise for parent's minimumSize.
2004-04-27 Olga Rodimina <rodimina@redhat.com>
* javax/swing/JMenuItem.java
(createActionPropertyChangeListener): Implemented.
(processMouseEvent): Ditto.
(fireMenuDragMouseEntered): Ditto.
(fireMenuDragMouseExited): Ditto.
(fireMenuDragMouseDragged): Ditto.
(fireMenuDragMouseReleased): Ditto.
(menuSelectionChanged): Ditto.
(getSubElements): Ditto.
(getComponent): Ditto.
(addMenuDragMouseListener): Ditto.
(removeMenuDragMouseListener):Ditto.
(addMenuKeyListener): Ditto.
(removeMenuKeyListener): Ditto.
* javax/swing/plaf/basic/BasicMenuItemUI.java
(doClick): Imlemented.
* javax/swing/plaf/basic/BasicMenuItemUI.MouseInputHandler:
Don't handle mouse events here. Pass them to
MenuSelectionManager.
2004-04-26 Olga Rodimina <rodimina@redhat.com>
Used correct version of jalopy configuration
file to fix style in the files below.
2004-04-26 Olga Rodimina <rodimina@redhat.com>
* javax/swing/JCheckBoxMenuItem.java:
Fixed style and removed unnecessary comments.
* javax/swing/JMenuItem.java: Ditto.
* javax/swing/JRadioButtonMenuItem.java: Ditto.
* javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java: Ditto.
* javax/swing/plaf/basic/BasicMenuItemUI.java: Ditto.
* javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java: Ditto.
2004-04-23 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu_java_awt_peer_gtk_GtkWindowPeer.c: Change FIXME comment to
C-style.
* gnu_java_awt_peer_gtk_GtkWindowPeer.c: Add FIXME comment.
* java/awt/ContainerOrderFocusTraversalPolicy.java
(getComponentAfter): Start from current component and work up
the component hierarchy until an acceptable component is found.
Synchronize on tree lock.
(getComponentBefore): Likewise.
2004-04-22 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java: Remove
focus-related debugging messages.
* java/awt/DefaultKeyboardFocusManager.java: Likewise.
* java/awt/EventDispatchThread.java: Likewise.
* java/awt/KeyboardFocusManager.java: Likewise.
* java/awt/Window.java: Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c: Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c: Likewise.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c: Change
new C++-style comments to C-style comments.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c: Likewise.
* gnu/java/awt/peer/gtk/GtkComponentPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
(handleEvent): Dispatch key press and key release events to
backing widget.
(requestFocus): Post a FOCUS_GAINED event to the event queue.
(gtkWidgetRequestFocus): New method.
(gtkWidgetDispatchKeyEvent): Likewise.
* java/awt/Component.java (requestFocus, requestFocus(boolean),
requestFocusInWindow, requestFocusInWindow(boolean),
getFocusCycleRootAncestor, nextFocus, transferFocus,
transferFocusBackward, transferFocusUpCycle, hasFocus,
isFocusOwner): Implement and document focus-handling methods.
(setFocusTraversalKeys): Inherit focus traversal keys when
keystrokes argument is null. Fix focus-handling documentation
throughout class.
* java/awt/Container.java (setFocusTraversalKeys,
getFocusTraversalKeys, areFocusTraversalKeysSet,
isFocusCycleRoot, setFocusTraversalPolicy,
getFocusTraversalPolicy, isFocusTraversalPolicySet,
setFocusCycleRoot, isFocusCycleRoot, transferFocusDownCycle):
Implement and document focus-handling methods.
(transferFocusBackward): Remove method.
(readObject, writeObject): Implement and document serialization
methods.
* java/awt/ContainerOrderFocusTraversalPolicy.java: Implement
and document.
* java/awt/DefaultFocusTraversalPolicy.java: Implement and
document.
* java/awt/DefaultKeyboardFocusManager.java: Implement and
partially document.
* java/awt/EventDispatchThread.java (run): Set default keyboard
focus manager. Attempt to dispatch each event to the keyboard
focus manager before normal dispatch.
* java/awt/KeyboardFocusManager.java: Implement and partially
document.
* java/awt/Window.java (Window): Set focusCycleRoot to true.
(show): Focus initial component when window is shown for the
first time.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
(pre_event_handler): Replace complex key press and key release
logic with simple callbacks into GtkComponentPeer.
* jni/gtk-peer/gtkpeer.h: Fix FOCUS_GAINED/FOCUS_LOST reversal.
2004-04-21 Olga Rodimina <rodimina@redhat.com>
* javax/swing/MenuSelectionManager.java
(componentForPoint): Added new method.
(defaultManager): New Method. Implemented.
(getSelectedPath): Ditto.
(isComponentPartOfCurrentMenu): Ditto.
(processKeyEvent): Added new method.
(processMouseEvent): New Method. Implemented.
(setSelectedPath): Ditto.
(getPath): Ditto.
2004-04-19 Kim Ho <kho@redhat.com>
* java/awt/Container.java:
(remove): Set the component's parent to null.
(getComponentAt): Implement.
* javax/swing/JComponent.java:
(JComponent): Initialize defaultLocale
(getDefaultLocale): Implement.
(setDefaultLocale): ditto.
* javax/swing/JSlider.java:
(JSlider): Fix calculation of value.
* javax/swing/JSplitPane.java: Implement.
* javax/swing/plaf/basic/BasicLookAndFeel.java:
Change SplitPane's default divider size.
* javax/swing/plaf/basic/BasicScrollBarUI.java:
(paint): Remove unused code.
* javax/swing/plaf/basic/BasicSplitPaneDivider.java:
Added comments and ran through jalopy.
(setBasicSplitPaneUI): Get reference to hidden divider
and set up one touch buttons if necessary.
(setBorder): Fire propertyChangeEvent only if
borders are different.
(getPreferredSize): Defer to layout manager.
(propertyChange): Implement.
(oneTouchExpandableChanged): ditto.
(createLeftOneTouchButton): Use BasicArrowButton.
(createRightOneTouchButton): ditto.
(moveDividerTo): New method. Moves the divider
to a set location based on the last divider location.
(BasicSplitPaneDivider::MouseHandler): Implement.
(BasicSplitPaneDivider::OneTouchButton): Removed.
(BasicSplitPaneDivider::DragController): Implement.
(BasicSplitPaneDivider::VerticalDragController):
ditto.
(BasicSplitPaneDivider::DividerLayout): ditto.
* javax/swing/plaf/basic/BasicSplitPaneUI.java: Reimplement.
* javax/swing/plaf/basic/BasicTabbedPaneUI.java:
(calculateLayoutInfo): Don't show component if it's
null.
(paintTab): Fix title paint logic.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82314 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/javax/swing/plaf/basic')
21 files changed, 4641 insertions, 548 deletions
diff --git a/libjava/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/javax/swing/plaf/basic/BasicButtonUI.java index 663050ee685..5ebde8f57fb 100644 --- a/libjava/javax/swing/plaf/basic/BasicButtonUI.java +++ b/libjava/javax/swing/plaf/basic/BasicButtonUI.java @@ -92,6 +92,7 @@ public class BasicButtonUI extends ButtonUI b.setBackground(defaults.getColor("Button.background")); b.setMargin(defaults.getInsets("Button.margin")); b.setBorder(defaults.getBorder("Button.border")); + b.setOpaque(true); } protected void uninstallDefaults(AbstractButton b) diff --git a/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java index 84c8e392357..553cec3d5c0 100644 --- a/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java +++ b/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java @@ -38,7 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; import java.awt.event.MouseEvent; - import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.MenuElement; @@ -48,18 +47,39 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.3 $ + */ public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI { + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public static ComponentUI createUI(final JComponent c) { return new BasicCheckBoxMenuItemUI(); } + /** + * DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected String getPropertyPrefix() { return null; // TODO } + /** + * DOCUMENT ME! + */ protected void installDefaults() { super.installDefaults(); @@ -68,6 +88,14 @@ public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI checkIcon = defaults.getIcon("CheckBoxMenuItem.checkIcon"); } + /** + * DOCUMENT ME! + * + * @param item DOCUMENT ME! + * @param e DOCUMENT ME! + * @param path DOCUMENT ME! + * @param manager DOCUMENT ME! + */ void processMouseEvent(JMenuItem item, MouseEvent e, MenuElement[] path, MenuSelectionManager manager) { diff --git a/libjava/javax/swing/plaf/basic/BasicIconFactory.java b/libjava/javax/swing/plaf/basic/BasicIconFactory.java index ef071aa0b77..9f3a5ac5e86 100644 --- a/libjava/javax/swing/plaf/basic/BasicIconFactory.java +++ b/libjava/javax/swing/plaf/basic/BasicIconFactory.java @@ -82,7 +82,34 @@ public class BasicIconFactory implements Serializable } public static Icon getMenuArrowIcon() { - return new DummyIcon(); + return new Icon() + { + public int getIconHeight() + { + return 12; + } + + public int getIconWidth() + { + return 12; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + g.translate(x, y); + + Color saved = g.getColor(); + + g.setColor(Color.BLACK); + + g.fillPolygon(new Polygon(new int[] { 3, 9, 3 }, + new int[] { 2, 6, 10 }, + 3)); + + g.setColor(saved); + g.translate(-x, -y); + } + }; } public static Icon getCheckBoxIcon() diff --git a/libjava/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/javax/swing/plaf/basic/BasicLabelUI.java index 669c7063645..782c2f0e5fa 100644 --- a/libjava/javax/swing/plaf/basic/BasicLabelUI.java +++ b/libjava/javax/swing/plaf/basic/BasicLabelUI.java @@ -168,23 +168,20 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener vr.width = 0; if (vr.height < 0) vr.height = 0; - + Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon(); String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr); - if (b.isOpaque()) - { - g.setColor(b.getBackground()); - g.fillRect(vr.x, vr.y, vr.width, vr.height); - } - if (icon != null) icon.paintIcon(b, g, ir.x, ir.y); - if (b.isEnabled()) - paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent()); - else - paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent()); + if (text != null && ! text.equals("")) + { + if (b.isEnabled()) + paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent()); + else + paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent()); + } g.setFont(saved_font); } @@ -354,6 +351,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener c.setBackground(defaults.getColor("Label.background")); c.setFont(defaults.getFont("Label.font")); c.setBorder(defaults.getBorder("Label.border")); + c.setOpaque(true); //XXX: There are properties we don't use called disabledForeground //and disabledShadow. } diff --git a/libjava/javax/swing/plaf/basic/BasicListUI.java b/libjava/javax/swing/plaf/basic/BasicListUI.java index 4be87652735..b356bdf2a9a 100644 --- a/libjava/javax/swing/plaf/basic/BasicListUI.java +++ b/libjava/javax/swing/plaf/basic/BasicListUI.java @@ -502,6 +502,7 @@ public class BasicListUI extends ListUI list.setBackground(defaults.getColor("List.background")); list.setSelectionForeground(defaults.getColor("List.selectionForeground")); list.setSelectionBackground(defaults.getColor("List.selectionBackground")); + list.setOpaque(true); } /** @@ -620,7 +621,8 @@ public class BasicListUI extends ListUI maybeUpdateLayoutState(); if (list.getModel().getSize() == 0) return new Dimension(0, 0); - Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1); + int nrows = Math.min(list.getVisibleRowCount(), list.getModel().getSize()); + Rectangle bounds = getCellBounds(list, 0, nrows - 1); return bounds.getSize(); } @@ -696,11 +698,11 @@ public class BasicListUI extends ListUI public int locationToIndex(JList list, Point location) { - throw new Error("Not implemented"); + return convertYToRow(location.y); } public Point indexToLocation(JList list, int index) { - throw new Error("Not implemented"); + return new Point(0, convertRowToY(index)); } } diff --git a/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java index 7a60c8e9336..f4466ef5083 100644 --- a/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -249,7 +249,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Button.foreground", new ColorUIResource(Color.black), "Button.highlight", new ColorUIResource(Color.white), "Button.light", new ColorUIResource(Color.lightGray.brighter()), - "Button.margin", new InsetsUIResource(2, 14, 2, 14), + "Button.margin", new InsetsUIResource(2, 2, 2, 2), "Button.shadow", new ColorUIResource(Color.gray), "Button.textIconGap", new Integer(4), "Button.textShiftOffset", new Integer(0), @@ -694,7 +694,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel }), "SplitPane.background", new ColorUIResource(Color.lightGray), "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null), - "SplitPane.dividerSize", new Integer(7), + "SplitPane.dividerSize", new Integer(10), "SplitPane.highlight", new ColorUIResource(Color.white), "SplitPane.shadow", new ColorUIResource(Color.gray), "TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { diff --git a/libjava/javax/swing/plaf/basic/BasicMenuBarUI.java b/libjava/javax/swing/plaf/basic/BasicMenuBarUI.java new file mode 100644 index 00000000000..0fe57f1c497 --- /dev/null +++ b/libjava/javax/swing/plaf/basic/BasicMenuBarUI.java @@ -0,0 +1,277 @@ +/* BasicMenuUI.java + Copyright (C) 2002, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.plaf.basic; + +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.awt.Dimension; +import javax.swing.BoxLayout; +import javax.swing.ButtonModel; +import javax.swing.Icon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.MenuDragMouseEvent; +import javax.swing.event.MenuDragMouseListener; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuKeyEvent; +import javax.swing.event.MenuKeyListener; +import javax.swing.event.MenuListener; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.MenuBarUI; +import javax.swing.plaf.MenuItemUI; +import java.awt.Insets; +import java.awt.GridLayout; + + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.1 $ + */ +public class BasicMenuBarUI extends MenuBarUI +{ + protected ChangeListener changeListener; + protected ContainerListener containerListener; + protected PropertyChangeListener propertyChangeListener; + protected JMenuBar menuBar; + + /** + * Creates a new BasicMenuBarUI object. + */ + public BasicMenuBarUI() + { + changeListener = createChangeListener(); + containerListener = createContainerListener(); + propertyChangeListener = new PropertyChangeHandler(); + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected ChangeListener createChangeListener() + { + return new ChangeHandler(); + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected ContainerListener createContainerListener() + { + return new ContainerHandler(); + } + + /** + * DOCUMENT ME! + * + * @param x DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public static ComponentUI createUI(JComponent x) + { + return new BasicMenuBarUI(); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getMaximumSize(JComponent c) + { + // let layout manager calculate its size + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getMinimumSize(JComponent c) + { + // let layout manager calculate its size + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getPreferredSize(JComponent c) + { + // let layout manager calculate its size + return null; + } + + /** + * DOCUMENT ME! + */ + protected void installDefaults() + { + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + menuBar.setBackground(defaults.getColor("MenuBar.background")); + menuBar.setBorder(defaults.getBorder("MenuBar.border")); + menuBar.setFont(defaults.getFont("MenuBar.font")); + menuBar.setForeground(defaults.getColor("MenuBar.foreground")); + } + + /** + * DOCUMENT ME! + */ + protected void installKeyboardActions() + { + } + + /** + * DOCUMENT ME! + */ + protected void installListeners() + { + menuBar.addContainerListener(containerListener); + menuBar.addPropertyChangeListener(propertyChangeListener); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ + public void installUI(JComponent c) + { + super.installUI(c); + menuBar = (JMenuBar) c; + menuBar.setLayout(new BoxLayout(menuBar, BoxLayout.X_AXIS)); + installDefaults(); + installListeners(); + } + + /** + * DOCUMENT ME! + */ + protected void uninstallDefaults() + { + menuBar.setBackground(null); + menuBar.setBorder(null); + menuBar.setFont(null); + menuBar.setForeground(null); + } + + /** + * DOCUMENT ME! + */ + protected void uninstallKeyboardActions() + { + } + + /** + * DOCUMENT ME! + */ + protected void uninstallListeners() + { + menuBar.removeContainerListener(containerListener); + menuBar.removePropertyChangeListener(propertyChangeListener); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ + public void uninstallUI(JComponent c) + { + uninstallDefaults(); + uninstallListeners(); + menuBar= null; + } + + protected class ChangeHandler implements ChangeListener + { + public void stateChanged(ChangeEvent event) + { + } + } + + protected class ContainerHandler implements ContainerListener + { + public void componentAdded(ContainerEvent e) + { + } + + public void componentRemoved(ContainerEvent e) + { + } + } + + protected class PropertyChangeHandler implements PropertyChangeListener + { + public void propertyChange(PropertyChangeEvent e) + { + } + } +} diff --git a/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java index 886ca9dbce6..29da4ec3bf2 100644 --- a/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -38,6 +38,7 @@ exception statement from your version. */ package javax.swing.plaf.basic; import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; @@ -47,12 +48,17 @@ import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; - +import java.beans.PropertyChangeListener; +import java.util.Vector; import javax.swing.AbstractButton; import javax.swing.ButtonModel; import javax.swing.Icon; +import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; +import javax.swing.JMenu; import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; import javax.swing.KeyStroke; import javax.swing.MenuElement; import javax.swing.MenuSelectionManager; @@ -68,116 +74,219 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.MenuItemUI; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.10 $ + */ public class BasicMenuItemUI extends MenuItemUI { - /** Font to be used when displaying menu item's accelerator. */ + /** + * Font to be used when displaying menu item's accelerator. + */ protected Font acceleratorFont; - /** Color to be used when displaying menu item's accelerator. */ + /** + * Color to be used when displaying menu item's accelerator. + */ protected Color acceleratorForeground; - /** Color to be used when displaying menu item's accelerator - * when menu item is selected. - */ + /** + * Color to be used when displaying menu item's accelerator when menu item is + * selected. + */ protected Color acceleratorSelectionForeground; - + /** - * Icon that is displayed after the text to indicated that this menu - * contains submenu. + * Icon that is displayed after the text to indicated that this menu contains + * submenu. */ protected Icon arrowIcon; - + /** * Icon that is displayed before the text. This icon is only used in * JCheckBoxMenuItem or JRadioBoxMenuItem. */ protected Icon checkIcon; - /** Number of spaces between icon and text. */ + /** + * Number of spaces between icon and text. + */ protected int defaultTextIconGap = 4; - - /** Color of the text when menu item is disabled*/ + + /** + * Color of the text when menu item is disabled + */ protected Color disabledForeground; - - /** The menu Drag mouse listener listening to the menu item. */ + + /** + * The menu Drag mouse listener listening to the menu item. + */ protected MenuDragMouseListener menuDragMouseListener; - - /** The menu item itself*/ + + /** + * The menu item itself + */ protected JMenuItem menuItem; - - /** Menu Key listener listening to the menu item. */ + + /** + * Menu Key listener listening to the menu item. + */ protected MenuKeyListener menuKeyListener; - - /** mouse input listener listening to menu item. */ + + /** + * mouse input listener listening to menu item. + */ protected MouseInputListener mouseInputListener; - - /** Indicates if border should be painted */ + + /** + * Indicates if border should be painted + */ protected boolean oldBorderPainted; - /** Color of text that is used when menu item is selected */ + /** + * Color of text that is used when menu item is selected + */ protected Color selectionBackground; - - /** Color of the background that is used when menu item is selected.*/ + + /** + * Color of the background that is used when menu item is selected. + */ protected Color selectionForeground; - /** String that separates description of the modifiers and the key*/ + /** + * String that separates description of the modifiers and the key + */ private String acceleratorDelimiter; - - /** Number of spaces between accelerator and menu item's label. */ + private PropertyChangeListener propertyChangeListener; + + /** + * Number of spaces between accelerator and menu item's label. + */ private int defaultAcceleratorLabelGap = 4; - // Constructor Summary - BasicMenuItemUI() + public BasicMenuItemUI() { mouseInputListener = createMouseInputListener(menuItem); menuDragMouseListener = createMenuDragMouseListener(menuItem); menuKeyListener = createMenuKeyListener(menuItem); + propertyChangeListener = new PropertyChangeHandler(); } - // Method Summary protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) { return new MenuDragMouseHandler(); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected MenuKeyListener createMenuKeyListener(JComponent c) { return new MenuKeyHandler(); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected MouseInputListener createMouseInputListener(JComponent c) { return new MouseInputHandler(); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public static ComponentUI createUI(JComponent c) { return new BasicMenuItemUI(); } + /** + * DOCUMENT ME! + * + * @param msm DOCUMENT ME! + */ protected void doClick(MenuSelectionManager msm) { - // TODO + menuItem.doClick(); + msm.clearSelectedPath(); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public Dimension getMaximumSize(JComponent c) { - // TODO return null; } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public Dimension getMinimumSize(JComponent c) { - // TODO return null; } + /** + * DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public MenuElement[] getPath() { - // TODO - return null; + Vector path = new Vector(); + Component c = menuItem; + while (c instanceof MenuElement) + { + path.add(c); + + if (c instanceof JPopupMenu) + c = ((JPopupMenu) c).getInvoker(); + else + c = c.getParent(); + } + + // convert from vector to array + MenuElement[] pathArray = new MenuElement[path.size()]; + for (int i = 0; i < path.size(); i++) + pathArray[i] = (MenuElement) path.get(path.size() - i - 1); + + return pathArray; } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * @param checkIcon DOCUMENT ME! + * @param arrowIcon DOCUMENT ME! + * @param defaultTextIconGap DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) @@ -186,51 +295,80 @@ public class BasicMenuItemUI extends MenuItemUI return null; } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public Dimension getPreferredSize(JComponent c) { AbstractButton b = (AbstractButton) c; Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, defaultTextIconGap); - + // if menu item has accelerator then take accelerator's size into account // when calculating preferred size. - KeyStroke accelerator = ((JMenuItem) c).getAccelerator(); Rectangle rect; + if (accelerator != null) { - rect = getAcceleratorRect(accelerator, - b.getToolkit().getFontMetrics(acceleratorFont)); - - // add width of accelerator's text - d.width = d.width + rect.width + defaultAcceleratorLabelGap; - - // adjust the heigth of the preferred size if necessary - if (d.height < rect.height) - d.height = rect.height; + rect = getAcceleratorRect(accelerator, + b.getToolkit().getFontMetrics(acceleratorFont)); + + // add width of accelerator's text + d.width = d.width + rect.width + defaultAcceleratorLabelGap; + + // adjust the heigth of the preferred size if necessary + if (d.height < rect.height) + d.height = rect.height; } if (checkIcon != null) { - d.width = d.width + checkIcon.getIconWidth() + defaultTextIconGap; - if (checkIcon.getIconHeight() > d.height) - d.height = checkIcon.getIconHeight(); + d.width = d.width + checkIcon.getIconWidth() + defaultTextIconGap; + + if (checkIcon.getIconHeight() > d.height) + d.height = checkIcon.getIconHeight(); } - + + if (arrowIcon != null && (c instanceof JMenu)) + { + d.width = d.width + arrowIcon.getIconWidth() + defaultTextIconGap; + + if (arrowIcon.getIconHeight() > d.height) + d.height = arrowIcon.getIconHeight(); + } + return d; } + /** + * DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected String getPropertyPrefix() { // TODO return null; } + /** + * DOCUMENT ME! + * + * @param menuItem DOCUMENT ME! + */ protected void installComponents(JMenuItem menuItem) { // TODO } + /** + * DOCUMENT ME! + */ protected void installDefaults() { UIDefaults defaults = UIManager.getLookAndFeelDefaults(); @@ -240,27 +378,40 @@ public class BasicMenuItemUI extends MenuItemUI menuItem.setFont(defaults.getFont("MenuItem.font")); menuItem.setForeground(defaults.getColor("MenuItem.foreground")); menuItem.setMargin(defaults.getInsets("MenuItem.margin")); + menuItem.setOpaque(true); + acceleratorFont = defaults.getFont("MenuItem.acceleratorFont"); acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground"); acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground"); - arrowIcon = defaults.getIcon("MenuItem.arrowIcon"); selectionBackground = defaults.getColor("MenuItem.selectionBackground"); selectionForeground = defaults.getColor("MenuItem.selectionForeground"); acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter"); } + /** + * DOCUMENT ME! + */ protected void installKeyboardActions() { // TODO } + /** + * DOCUMENT ME! + */ protected void installListeners() { menuItem.addMouseListener(mouseInputListener); menuItem.addMenuDragMouseListener(menuDragMouseListener); menuItem.addMenuKeyListener(menuKeyListener); + menuItem.addPropertyChangeListener(propertyChangeListener); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ public void installUI(JComponent c) { super.installUI(c); @@ -269,12 +420,25 @@ public class BasicMenuItemUI extends MenuItemUI installListeners(); } + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param c DOCUMENT ME! + */ public void paint(Graphics g, JComponent c) { - paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(), + paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(), c.getForeground(), defaultTextIconGap); } + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param menuItem DOCUMENT ME! + * @param bgColor DOCUMENT ME! + */ protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { Dimension size = getPreferredSize(menuItem); @@ -284,6 +448,17 @@ public class BasicMenuItemUI extends MenuItemUI g.setColor(foreground); } + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param c DOCUMENT ME! + * @param checkIcon DOCUMENT ME! + * @param arrowIcon DOCUMENT ME! + * @param background DOCUMENT ME! + * @param foreground DOCUMENT ME! + * @param defaultTextIconGap DOCUMENT ME! + */ protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, int defaultTextIconGap) @@ -295,7 +470,7 @@ public class BasicMenuItemUI extends MenuItemUI Rectangle br = new Rectangle(); // border rectangle Rectangle ar = new Rectangle(); // accelerator rectangle Rectangle cr = new Rectangle(); // checkIcon rectangle - + int vertAlign = b.getVerticalAlignment(); int horAlign = b.getHorizontalAlignment(); int vertTextPos = b.getVerticalTextPosition(); @@ -303,64 +478,67 @@ public class BasicMenuItemUI extends MenuItemUI Font f = c.getFont(); g.setFont(f); - FontMetrics fm = g.getFontMetrics(f); + FontMetrics fm = g.getFontMetrics(f); SwingUtilities.calculateInnerArea(b, br); - SwingUtilities.calculateInsetArea(br, b.getMargin(), vr); + SwingUtilities.calculateInsetArea(br, b.getMargin(), vr); paintBackground(g, (JMenuItem) c, c.getBackground()); - + if ((b.getModel().isArmed() && b.getModel().isPressed())) { - if (((AbstractButton) b).isContentAreaFilled()) - { - g.setColor(b.getBackground().darker()); - g.fillRect(br.x, br.y, br.width, br.height); - } + if (((AbstractButton) b).isContentAreaFilled()) + { + g.setColor(b.getBackground().darker()); + g.fillRect(br.x, br.y, br.width, br.height); + } } else { - if (((AbstractButton) b).isContentAreaFilled()) - { - g.setColor(b.getBackground()); - g.fillRect(br.x, br.y, br.width, br.height); - } + if (((AbstractButton) b).isContentAreaFilled()) + { + g.setColor(b.getBackground()); + g.fillRect(br.x, br.y, br.width, br.height); + } } - - + if (checkIcon != null) { - SwingUtilities.layoutCompoundLabel(c, fm, null, checkIcon, vertAlign, - horAlign, vertTextPos, horTextPos, - vr, cr, tr, defaultTextIconGap); - checkIcon.paintIcon(c, g, cr.x, cr.y); + SwingUtilities.layoutCompoundLabel(c, fm, null, checkIcon, vertAlign, + horAlign, vertTextPos, horTextPos, + vr, cr, tr, defaultTextIconGap); + checkIcon.paintIcon(c, g, cr.x, cr.y); - // We need to calculate position of the menu text and position of - // user menu icon if there exists one relative to the check icon. + // We need to calculate position of the menu text and position of + // user menu icon if there exists one relative to the check icon. // So we need to adjust view rectangle s.t. its starting point is at // checkIcon.width + defaultTextIconGap. - - vr.x = cr.x + cr.width + defaultTextIconGap; + vr.x = cr.x + cr.width + defaultTextIconGap; } - if (arrowIcon != null) + if (arrowIcon != null && (c instanceof JMenu)) { - // FIXME: if this menu contains a submenu, we need to draw arrow icon - // here as well + if (! ((JMenu) c).isTopLevelMenu()) + { + int width = arrowIcon.getIconWidth(); + int height = arrowIcon.getIconHeight(); + + arrowIcon.paintIcon(c, g, vr.width - width + defaultTextIconGap, + vr.y + 2); + } } - // paint text and user menu icon if it exists SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b.getIcon(), vertAlign, horAlign, vertTextPos, horTextPos, vr, ir, tr, defaultTextIconGap); - paintText(g, (JMenuItem) c, tr, b.getText()); - + paintText(g, (JMenuItem) c, tr, b.getText()); + // paint icon // FIXME: should paint different icon at different button state's. // i.e disabled icon when button is disabled.. etc. - - /* + + /* Icon i = b.getIcon(); if (i != null) { @@ -369,28 +547,35 @@ public class BasicMenuItemUI extends MenuItemUI i.paintIcon(c, g, x, y); } */ - + // paint accelerator String acceleratorText = ""; + if (((JMenuItem) c).getAccelerator() != null) { - acceleratorText = getAcceleratorText(((JMenuItem) c).getAccelerator()); - fm = g.getFontMetrics(acceleratorFont); - ar.width = fm.stringWidth(acceleratorText); - ar.x = br.width - ar.width; - vr.x = br.width - ar.width; - - SwingUtilities.layoutCompoundLabel(c, fm, acceleratorText, null, - vertAlign, horAlign, vertTextPos, - horTextPos, vr, ir, ar, - defaultTextIconGap); - - paintAccelerator(g, (JMenuItem) c, ar, acceleratorText); - - } - + acceleratorText = getAcceleratorText(((JMenuItem) c).getAccelerator()); + fm = g.getFontMetrics(acceleratorFont); + ar.width = fm.stringWidth(acceleratorText); + ar.x = br.width - ar.width; + vr.x = br.width - ar.width; + + SwingUtilities.layoutCompoundLabel(c, fm, acceleratorText, null, + vertAlign, horAlign, vertTextPos, + horTextPos, vr, ir, ar, + defaultTextIconGap); + + paintAccelerator(g, (JMenuItem) c, ar, acceleratorText); + } } + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param menuItem DOCUMENT ME! + * @param textRect DOCUMENT ME! + * @param text DOCUMENT ME! + */ protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { @@ -400,14 +585,22 @@ public class BasicMenuItemUI extends MenuItemUI g.setColor(menuItem.getForeground()); BasicGraphicsUtils.drawString(g, text, 0, textRect.x, - textRect.y + fm.getAscent()); + textRect.y + fm.getAscent()); } + /** + * DOCUMENT ME! + * + * @param menuItem DOCUMENT ME! + */ protected void uninstallComponents(JMenuItem menuItem) { // TODO } + /** + * DOCUMENT ME! + */ protected void uninstallDefaults() { menuItem.setForeground(null); @@ -428,18 +621,30 @@ public class BasicMenuItemUI extends MenuItemUI acceleratorDelimiter = null; } + /** + * DOCUMENT ME! + */ protected void uninstallKeyboardActions() { // TODO } + /** + * DOCUMENT ME! + */ protected void uninstallListeners() { menuItem.removeMouseListener(mouseInputListener); menuItem.removeMenuDragMouseListener(menuDragMouseListener); menuItem.removeMenuKeyListener(menuKeyListener); + menuItem.removePropertyChangeListener(propertyChangeListener); } + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ public void uninstallUI(JComponent c) { uninstallListeners(); @@ -447,24 +652,35 @@ public class BasicMenuItemUI extends MenuItemUI menuItem = null; } + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param c DOCUMENT ME! + */ public void update(Graphics g, JComponent c) { - // TODO + paint(g, c); } + /** + * DOCUMENT ME! + * + * @param accelerator DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ private String getAcceleratorText(KeyStroke accelerator) { - // convert keystroke into string format - String modifiersText = ""; int modifiers = accelerator.getModifiers(); char keyChar = accelerator.getKeyChar(); int keyCode = accelerator.getKeyCode(); if (modifiers != 0) - modifiersText = KeyEvent.getKeyModifiersText(modifiers) + - acceleratorDelimiter; + modifiersText = KeyEvent.getKeyModifiersText(modifiers) + + acceleratorDelimiter; if (keyCode == KeyEvent.VK_UNDEFINED) return modifiersText + keyChar; @@ -472,161 +688,233 @@ public class BasicMenuItemUI extends MenuItemUI return modifiersText + KeyEvent.getKeyText(keyCode); } + /** + * DOCUMENT ME! + * + * @param accelerator DOCUMENT ME! + * @param fm DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm) - { + { int width = fm.stringWidth(getAcceleratorText(accelerator)); int height = fm.getHeight(); return new Rectangle(0, 0, width, height); } - private void paintAccelerator(Graphics g, JMenuItem menuItem, Rectangle acceleratorRect, - String acceleratorText) + /** + * DOCUMENT ME! + * + * @param g DOCUMENT ME! + * @param menuItem DOCUMENT ME! + * @param acceleratorRect DOCUMENT ME! + * @param acceleratorText DOCUMENT ME! + */ + private void paintAccelerator(Graphics g, JMenuItem menuItem, + Rectangle acceleratorRect, + String acceleratorText) { g.setFont(acceleratorFont); FontMetrics fm = g.getFontMetrics(acceleratorFont); g.setColor(acceleratorForeground); BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x, - acceleratorRect.y + fm.getAscent()); + acceleratorRect.y + fm.getAscent()); } + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.10 $ + */ protected class MouseInputHandler implements MouseInputListener { + /** + * Creates a new MouseInputHandler object. + */ protected MouseInputHandler() { } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseClicked(MouseEvent e) { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseDragged(MouseEvent e) { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseEntered(MouseEvent e) { - if (e.getSource() instanceof AbstractButton) - { - AbstractButton button = (AbstractButton) e.getSource(); - ButtonModel model = button.getModel(); - - if (button.isRolloverEnabled()) - { - model.setRollover(true); - } - - if (model.isPressed() && - ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)) - { - model.setArmed(true); - } - else - { - model.setArmed(false); - } - } + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseExited(MouseEvent e) { - if (e.getSource() instanceof AbstractButton) - { - AbstractButton button = (AbstractButton) e.getSource(); - ButtonModel model = button.getModel(); - - if (button.isRolloverEnabled()) - { - model.setRollover(false); - } - - model.setArmed(false); - } + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseMoved(MouseEvent e) { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mousePressed(MouseEvent e) { - if (e.getSource() instanceof AbstractButton) - { - AbstractButton button = (AbstractButton) e.getSource(); - ButtonModel model = button.getModel(); - - if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) - { - // It is important that these transitions happen in this order. - model.setArmed(true); - model.setPressed(true); - } - } + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void mouseReleased(MouseEvent e) { - - if (e.getSource() instanceof AbstractButton) - { - AbstractButton button = (AbstractButton) e.getSource(); - ButtonModel model = button.getModel(); - - if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) - { - // It is important that these transitions happen in this order. - model.setPressed(false); - model.setArmed(false); - } - } + // FIXME: Should check if the mouse released while mouse cursor + // was indeed over the menu item. If this wasn't the case we probably + // should sent this event to MenuSelectionManager. + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.clearSelectedPath(); + menuItem.doClick(0); } } + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.10 $ + */ protected class MenuDragMouseHandler implements MenuDragMouseListener { + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuDragMouseDragged(MenuDragMouseEvent e) { - // TODO } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuDragMouseEntered(MenuDragMouseEvent e) { - // TODO } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuDragMouseExited(MenuDragMouseEvent e) { - // TODO } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuDragMouseReleased(MenuDragMouseEvent e) { - // TODO } } + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.10 $ + */ protected class MenuKeyHandler implements MenuKeyListener { + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuKeyPressed(MenuKeyEvent e) { - // TODO } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuKeyReleased(MenuKeyEvent e) { - // TODO } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ public void menuKeyTyped(MenuKeyEvent e) { - // TODO } } - protected class PropertyChangeHandler + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.10 $ + */ + protected class PropertyChangeHandler implements PropertyChangeListener { + /** + * DOCUMENT ME! + * + * @param evt DOCUMENT ME! + */ public void propertyChange(PropertyChangeEvent evt) { - // TODO } } } diff --git a/libjava/javax/swing/plaf/basic/BasicMenuUI.java b/libjava/javax/swing/plaf/basic/BasicMenuUI.java new file mode 100644 index 00000000000..406934e3adc --- /dev/null +++ b/libjava/javax/swing/plaf/basic/BasicMenuUI.java @@ -0,0 +1,357 @@ +/* BasicMenuUI.java + Copyright (C) 2002, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.plaf.basic; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.MenuDragMouseEvent; +import javax.swing.event.MenuDragMouseListener; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuKeyEvent; +import javax.swing.event.MenuKeyListener; +import javax.swing.event.MenuListener; +import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.MenuItemUI; + + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.3 $ + */ +public class BasicMenuUI extends BasicMenuItemUI +{ + protected ChangeListener changeListener; + protected MenuListener menuListener; + protected PropertyChangeListener propertyChangeListener; + + /** + * Creates a new BasicMenuUI object. + */ + public BasicMenuUI() + { + mouseInputListener = createMouseInputListener(menuItem); + menuListener = createMenuListener(menuItem); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected ChangeListener createChangeListener(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected MenuKeyListener createMenuKeyListener(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected MenuListener createMenuListener(JComponent c) + { + return new MenuHandler(); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected MouseInputListener createMouseInputListener(JComponent c) + { + return new MouseInputHandler(); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected PropertyChangeListener createPropertyChangeListener(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param x DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public static ComponentUI createUI(JComponent x) + { + return new BasicMenuUI(); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getMaximumSize(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected String getPropertyPrefix() + { + return null; + } + + /** + * DOCUMENT ME! + */ + protected void installDefaults() + { + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + menuItem.setBackground(defaults.getColor("Menu.background")); + menuItem.setBorder(defaults.getBorder("Menu.border")); + menuItem.setFont(defaults.getFont("Menu.font")); + menuItem.setForeground(defaults.getColor("Menu.foreground")); + menuItem.setMargin(defaults.getInsets("Menu.margin")); + acceleratorFont = defaults.getFont("Menu.acceleratorFont"); + acceleratorForeground = defaults.getColor("Menu.acceleratorForeground"); + acceleratorSelectionForeground = defaults.getColor("Menu.acceleratorSelectionForeground"); + arrowIcon = defaults.getIcon("Menu.arrowIcon"); + oldBorderPainted = defaults.getBoolean("Menu.borderPainted"); + } + + /** + * DOCUMENT ME! + */ + protected void installKeyboardActions() + { + } + + /** + * DOCUMENT ME! + */ + protected void installListeners() + { + ((JMenu) menuItem).addMouseListener(mouseInputListener); + ((JMenu) menuItem).addMenuListener(menuListener); + } + + /** + * DOCUMENT ME! + * + * @param menu DOCUMENT ME! + */ + protected void setupPostTimer(JMenu menu) + { + } + + /** + * DOCUMENT ME! + */ + protected void uninstallDefaults() + { + menuItem.setBackground(null); + menuItem.setBorder(null); + menuItem.setFont(null); + menuItem.setForeground(null); + menuItem.setMargin(null); + acceleratorFont = null; + acceleratorForeground = null; + acceleratorSelectionForeground = null; + arrowIcon = null; + } + + /** + * DOCUMENT ME! + */ + protected void uninstallKeyboardActions() + { + } + + /** + * DOCUMENT ME! + */ + protected void uninstallListeners() + { + } + + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.3 $ + */ + protected class MouseInputHandler implements MouseInputListener + { + protected MouseInputHandler() + { + } + + public void mouseClicked(MouseEvent e) + { + } + + public void mouseDragged(MouseEvent e) + { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); + } + + public void mouseEntered(MouseEvent e) + { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.setSelectedPath(manager.getPath((Component) e.getSource())); + manager.processMouseEvent(e); + + JMenu subMenu = (JMenu) menuItem; + + int x = 0; + int y = 0; + + // location of the popup menu is relative to the invoker + if (subMenu.isTopLevelMenu()) + { + JMenuBar mb = (JMenuBar) subMenu.getParent(); + + // Subtract menuBar's insets.bottom and popupMenu's insets.top, + // s.t. the space between menu bar and its popup menu is equal to + // menuBar's margin. By default menuBar's margin is Insets(0,0,0,0). + y = subMenu.getHeight() - mb.getInsets().bottom + - subMenu.getPopupMenu().getInsets().top + mb.getMargin().bottom; + } + else + x = subMenu.getWidth(); + + subMenu.getPopupMenu().show(subMenu, x, y); + } + + public void mouseExited(MouseEvent e) + { + } + + public void mouseMoved(MouseEvent e) + { + } + + public void mousePressed(MouseEvent e) + { + } + + public void mouseReleased(MouseEvent e) + { + MenuSelectionManager manager = MenuSelectionManager.defaultManager(); + manager.processMouseEvent(e); + } + } + + protected class MenuHandler implements MenuListener + { + public void menuCanceled(MenuEvent e) + { + } + + public void menuDeselected(MenuEvent e) + { + } + + public void menuSelected(MenuEvent e) + { + } + } +} diff --git a/libjava/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/javax/swing/plaf/basic/BasicOptionPaneUI.java index 466f4a5c285..8d65ee0928d 100644 --- a/libjava/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/libjava/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -1,5 +1,5 @@ /* BasicOptionPaneUI.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -35,124 +35,1275 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ - package javax.swing.plaf.basic; +import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import java.awt.LayoutManager; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.Icon; import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.IconUIResource; import javax.swing.plaf.OptionPaneUI; + +/** + * This class is the UI delegate for JOptionPane in the Basic Look and Feel. + */ public class BasicOptionPaneUI extends OptionPaneUI { - JOptionPane pane; + /** + * This is a helper class that listens to the buttons located at the bottom + * of the JOptionPane. + */ + protected class ButtonActionListener implements ActionListener + { + /** The index of the option this button represents. */ + protected int buttonIndex; + + /** + * Creates a new ButtonActionListener object with the given buttonIndex. + * + * @param buttonIndex The index of the option this button represents. + */ + public ButtonActionListener(int buttonIndex) + { + this.buttonIndex = buttonIndex; + } + + /** + * This method is called when one of the option buttons are pressed. + * + * @param e The ActionEvent. + */ + public void actionPerformed(ActionEvent e) + { + Object value = new Integer(JOptionPane.CLOSED_OPTION); + Object[] options = optionPane.getOptions(); + if (options != null) + value = options[buttonIndex]; + else + { + String text = ((JButton) e.getSource()).getText(); + if (text.equals(OK_STRING)) + value = new Integer(JOptionPane.OK_OPTION); + if (text.equals(CANCEL_STRING)) + value = new Integer(JOptionPane.CANCEL_OPTION); + if (text.equals(YES_STRING)) + value = new Integer(JOptionPane.YES_OPTION); + if (text.equals(NO_STRING)) + value = new Integer(JOptionPane.NO_OPTION); + } + optionPane.setValue(value); + resetInputValue(); + + Window owner = SwingUtilities.windowForComponent(optionPane); + + if (owner instanceof JDialog) + ((JDialog) owner).dispose(); + } + } + + /** + * This helper layout manager is responsible for the layout of the button + * area. The button area is the panel that holds the buttons which + * represent the options. + */ + protected class ButtonAreaLayout implements LayoutManager + { + /** Whether this layout will center the buttons. */ + protected boolean centersChildren = true; + + /** The space between the buttons. */ + protected int padding; + + /** Whether the buttons will share the same widths. */ + protected boolean syncAllWidths; - BasicOptionPaneUI() + /** The width of the widest button. */ + private transient int widthOfWidestButton; + + /** The height of the tallest button. */ + private transient int tallestButton; + + /** + * Creates a new ButtonAreaLayout object with the given sync widths + * property and padding. + * + * @param syncAllWidths Whether the buttons will share the same widths. + * @param padding The padding between the buttons. + */ + public ButtonAreaLayout(boolean syncAllWidths, int padding) { + this.syncAllWidths = syncAllWidths; + this.padding = padding; } - public static ComponentUI createUI(JComponent x) + /** + * This method is called when a component is added to the container. + * + * @param string The constraints string. + * @param comp The component added. + */ + public void addLayoutComponent(String string, Component comp) { - return new BasicOptionPaneUI(); + // Do nothing. } - public void installUI(JComponent c) + /** + * This method returns whether the children will be centered. + * + * @return Whether the children will be centered. + */ + public boolean getCentersChildren() { - super.installUI(c); - pane = (JOptionPane)c; + return centersChildren; + } - System.out.println(" -------------: " + pane); + /** + * This method returns the amount of space between components. + * + * @return The amount of space between components. + */ + public int getPadding() + { + return padding; + } - JLabel message = null; - JButton ok_button = new JButton("Ok"); + /** + * This method returns whether all components will share widths (set to + * largest width). + * + * @return Whether all components will share widths. + */ + public boolean getSyncAllWidths() + { + return syncAllWidths; + } - ok_button.addActionListener(new ActionListener() + /** + * This method lays out the given container. + * + * @param container The container to lay out. + */ + public void layoutContainer(Container container) + { + Component[] buttonList = container.getComponents(); + int x = container.getInsets().left; + if (getCentersChildren()) + x += (int) ((double) (container.getSize().width) / 2 + - (double) (buttonRowLength(container)) / 2); + for (int i = 0; i < buttonList.length; i++) + { + Dimension dims = buttonList[i].getPreferredSize(); + if (getSizeButtonsToSameWidth()) { - public void actionPerformed(ActionEvent a) - { - System.out.println("ACTION ---> " + a); - // pane.dialog.dispose(); - - if (pane.dialog.isModal()) - { - System.out.println("modal dialog !!"); - pane.dialog.setModal(false); - } - pane.dialog.setVisible(false); - } - }); - - Object[] options = null; - if (options != null) + buttonList[i].setBounds(x, 0, widthOfWidestButton, dims.height); + x += widthOfWidestButton + getPadding(); + } + else { - for (int i=0; i<options.length; i++) - { - Object o = options[i]; - if (o != null) - { - if (o instanceof String) - { - String s = (String) o; - JLabel m = new JLabel(s); - pane.add(m); - } - else if (o instanceof Component) - { - Component com = (Component) o; - pane.add(com); - } - else - { - System.out.println("UNRECOGNIZED ARG: " + o); - } - } - } + buttonList[i].setBounds(x, 0, dims.width, dims.height); + x += dims.width + getPadding(); } + } + } + + /** + * This method returns the width of the given container taking into + * consideration the padding and syncAllWidths. + * + * @param c The container to calculate width for. + * + * @return The width of the given container. + */ + private int buttonRowLength(Container c) + { + Component[] buttonList = c.getComponents(); + + int buttonLength = 0; + int widest = 0; + int tallest = 0; + + for (int i = 0; i < buttonList.length; i++) + { + Dimension dims = buttonList[i].getPreferredSize(); + buttonLength += dims.width + getPadding(); + widest = Math.max(widest, dims.width); + tallest = Math.max(tallest, dims.height); + } + + widthOfWidestButton = widest; + tallestButton = tallest; + + int width; + if (getSyncAllWidths()) + width = widest * buttonList.length + + getPadding() * (buttonList.length - 1); + else + width = buttonLength; - pane.add(message); - pane.add(ok_button); + Insets insets = c.getInsets(); + width += insets.left + insets.right; + + return width; } - Dimension getMinimumOptionPaneSize() + /** + * This method returns the minimum layout size for the given container. + * + * @param c The container to measure. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container c) { - return new Dimension(300,100); + return preferredLayoutSize(c); } - public Dimension getPreferredSize(JComponent c) + /** + * This method returns the preferred size of the given container. + * + * @param c The container to measure. + * + * @return The preferred size. + */ + public Dimension preferredLayoutSize(Container c) { - if (c == null) - return getMinimumOptionPaneSize(); + int w = buttonRowLength(c); - if (c != pane) - return null; + return new Dimension(w, tallestButton); + } - LayoutManager l = c.getLayout(); - if (l == null) - return getMinimumOptionPaneSize(); + /** + * This method removes the given component from the layout manager's + * knowledge. + * + * @param c The component to remove. + */ + public void removeLayoutComponent(Component c) + { + // Do nothing. + } - Dimension d1 = l.preferredLayoutSize(c); - Dimension d2 = getMinimumOptionPaneSize(); - - d1.width = Math.max(d1.width, d2.width); - d1.height = Math.max(d1.height, d2.height); + /** + * This method sets whether the children will be centered. + * + * @param newValue Whether the children will be centered. + */ + public void setCentersChildren(boolean newValue) + { + centersChildren = newValue; + optionPane.invalidate(); + } - return d2; + /** + * This method sets the amount of space between each component. + * + * @param newPadding The padding between components. + */ + public void setPadding(int newPadding) + { + padding = newPadding; + optionPane.invalidate(); } - public void selectInitialValue(JOptionPane op) + /** + * This method sets whether the widths will be synced. + * + * @param newValue Whether the widths will be synced. + */ + public void setSyncAllWidths(boolean newValue) + { + syncAllWidths = newValue; + optionPane.invalidate(); + } + } + + /** + * This helper class handles property change events from the JOptionPane. + */ + public class PropertyChangeHandler implements PropertyChangeListener + { + /** + * This method is called when one of the properties of the JOptionPane + * changes. + * + * @param e The PropertyChangeEvent. + */ + public void propertyChange(PropertyChangeEvent e) + { + if (e.getPropertyName().equals(JOptionPane.ICON_PROPERTY) + || e.getPropertyName().equals(JOptionPane.MESSAGE_TYPE_PROPERTY)) + addIcon(messageAreaContainer); + else if (e.getPropertyName().equals(JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY)) + resetSelectedValue(); + else if (e.getPropertyName().equals(JOptionPane.INITIAL_VALUE_PROPERTY) + || e.getPropertyName().equals(JOptionPane.OPTIONS_PROPERTY) + || e.getPropertyName().equals(JOptionPane.OPTION_TYPE_PROPERTY)) + { + Container newButtons = createButtonArea(); + optionPane.remove(buttonContainer); + optionPane.add(newButtons); + buttonContainer = newButtons; + } + + else if (e.getPropertyName().equals(JOptionPane.MESSAGE_PROPERTY) + || e.getPropertyName().equals(JOptionPane.WANTS_INPUT_PROPERTY) + || e.getPropertyName().equals(JOptionPane.SELECTION_VALUES_PROPERTY)) + { + optionPane.removeAll(); + messageAreaContainer = createMessageArea(); + optionPane.add(messageAreaContainer); + optionPane.add(buttonContainer); + } + optionPane.invalidate(); + optionPane.repaint(); + } + } + + /** Whether the JOptionPane contains custom components. */ + protected boolean hasCustomComponents = false; + + // The initialFocusComponent seems to always be set to a button (even if + // I try to set initialSelectionValue). This is different from what the + // javadocs state (which should switch this reference to the input component + // if one is present since that is what's going to get focus). + + /** + * The button that will receive focus based on initialValue when no input + * component is present. If an input component is present, then the input + * component will receive focus instead. + */ + protected Component initialFocusComponent; + + /** The component that receives input when the JOptionPane needs it. */ + protected JComponent inputComponent; + + /** The minimum height of the JOptionPane. */ + public static int minimumHeight; + + /** The minimum width of the JOptionPane. */ + public static int minimumWidth; + + /** The minimum dimensions of the JOptionPane. */ + protected Dimension minimumSize; + + /** The propertyChangeListener for the JOptionPane. */ + protected PropertyChangeListener propertyChangeListener; + + /** The JOptionPane this UI delegate is used for. */ + protected JOptionPane optionPane; + + /** The size of the icons. */ + private static int iconSize = 36; + + /** The foreground color for the message area. */ + private transient Color messageForeground; + + /** The border around the message area. */ + private transient Border messageBorder; + + /** The border around the button area. */ + private transient Border buttonBorder; + + /** The string used to describe OK buttons. */ + private static String OK_STRING = "OK"; + + /** The string used to describe Yes buttons. */ + private static String YES_STRING = "Yes"; + + /** The string used to describe No buttons. */ + private static String NO_STRING = "No"; + + /** The string used to describe Cancel buttons. */ + private static String CANCEL_STRING = "Cancel"; + + /** The container for the message area. */ + private transient Container messageAreaContainer; + + /** The container for the buttons. */ + private transient Container buttonContainer; + + /** + * A helper class that implements Icon. This is used temporarily until + * ImageIcons are fixed. + */ + private static class messageIcon implements Icon + { + /** + * This method returns the width of the icon. + * + * @return The width of the icon. + */ + public int getIconWidth() + { + return iconSize; + } + + /** + * This method returns the height of the icon. + * + * @return The height of the icon. + */ + public int getIconHeight() + { + return iconSize; + } + + /** + * This method paints the icon as a part of the given component using the + * given graphics and the given x and y position. + * + * @param c The component that owns this icon. + * @param g The Graphics object to paint with. + * @param x The x coordinate. + * @param y The y coordinate. + */ + public void paintIcon(Component c, Graphics g, int x, int y) + { + } + } + + /** The icon displayed for ERROR_MESSAGE. */ + private static messageIcon errorIcon = new messageIcon() + { + public void paintIcon(Component c, Graphics g, int x, int y) + { + Polygon oct = new Polygon(new int[] { 0, 0, 9, 27, 36, 36, 27, 9 }, + new int[] { 9, 27, 36, 36, 27, 9, 0, 0 }, 8); + g.translate(x, y); + + Color saved = g.getColor(); + g.setColor(Color.RED); + + g.fillPolygon(oct); + + g.setColor(Color.BLACK); + g.drawRect(13, 16, 10, 4); + + g.setColor(saved); + g.translate(-x, -y); + } + }; + + /** The icon displayed for INFORMATION_MESSAGE. */ + private static messageIcon infoIcon = new messageIcon() + { + public void paintIcon(Component c, Graphics g, int x, int y) + { + g.translate(x, y); + Color saved = g.getColor(); + + // Should be purple. + g.setColor(Color.RED); + + g.fillOval(0, 0, iconSize, iconSize); + + g.setColor(Color.BLACK); + g.drawOval(16, 6, 4, 4); + + Polygon bottomI = new Polygon(new int[] { 15, 15, 13, 13, 23, 23, 21, 21 }, + new int[] { 12, 28, 28, 30, 30, 28, 28, 12 }, + 8); + g.drawPolygon(bottomI); + + g.setColor(saved); + g.translate(-x, -y); + } + }; + + /** The icon displayed for WARNING_MESSAGE. */ + private static messageIcon warningIcon = new messageIcon() + { + public void paintIcon(Component c, Graphics g, int x, int y) + { + g.translate(x, y); + Color saved = g.getColor(); + g.setColor(Color.YELLOW); + + Polygon triangle = new Polygon(new int[] { 0, 18, 36 }, + new int[] { 36, 0, 36 }, 3); + g.fillPolygon(triangle); + + g.setColor(Color.BLACK); + + Polygon excl = new Polygon(new int[] { 15, 16, 20, 21 }, + new int[] { 8, 26, 26, 8 }, 4); + g.drawPolygon(excl); + g.drawOval(16, 30, 4, 4); + + g.setColor(saved); + g.translate(-x, -y); + } + }; + + /** The icon displayed for MESSAGE_ICON. */ + private static messageIcon questionIcon = new messageIcon() + { + public void paintIcon(Component c, Graphics g, int x, int y) + { + g.translate(x, y); + Color saved = g.getColor(); + g.setColor(Color.GREEN); + + g.fillRect(0, 0, iconSize, iconSize); + + g.setColor(Color.BLACK); + + g.drawOval(11, 2, 16, 16); + g.drawOval(14, 5, 10, 10); + + g.setColor(Color.GREEN); + g.fillRect(0, 10, iconSize, iconSize - 10); + + g.setColor(Color.BLACK); + + g.drawLine(11, 10, 14, 10); + + g.drawLine(24, 10, 17, 22); + g.drawLine(27, 10, 20, 22); + g.drawLine(17, 22, 20, 22); + + g.drawOval(17, 25, 3, 3); + + g.setColor(saved); + g.translate(-x, -y); + } + }; + + // FIXME: Uncomment when the ImageIcons are fixed. + + /* IconUIResource warningIcon, questionIcon, infoIcon, errorIcon;*/ + + /** + * Creates a new BasicOptionPaneUI object. + */ + public BasicOptionPaneUI() + { + } + + /** + * This method is messaged to add the buttons to the given container. + * + * @param container The container to add components to. + * @param buttons The buttons to add. (If it is an instance of component, + * the Object is added directly. If it is an instance of Icon, it is + * packed into a label and added. For all other cases, the string + * representation of the Object is retreived and packed into a + * label.) + * @param initialIndex The index of the component that is the initialValue. + */ + protected void addButtonComponents(Container container, Object[] buttons, + int initialIndex) + { + if (buttons == null) + return; + for (int i = 0; i < buttons.length; i++) + { + if (buttons[i] != null) + { + Component toAdd; + if (buttons[i] instanceof Component) + toAdd = (Component) buttons[i]; + else + { + if (buttons[i] instanceof Icon) + toAdd = new JButton((Icon) buttons[i]); + else + toAdd = new JButton(buttons[i].toString()); + ((JButton) toAdd).addActionListener(createButtonActionListener(i)); + hasCustomComponents = true; + } + + if (i == initialIndex) + initialFocusComponent = toAdd; + container.add(toAdd); + } + } + selectInitialValue(optionPane); + } + + /** + * This method adds the appropriate icon the given container. + * + * @param top The container to add an icon to. + */ + protected void addIcon(Container top) + { + JLabel iconLabel = null; + Icon icon = getIcon(); + if (icon != null) + { + iconLabel = new JLabel(icon); + top.add(iconLabel, BorderLayout.WEST); + } + } + + /** + * A helper method that returns an instance of GridBagConstraints to be used + * for creating the message area. + * + * @return An instance of GridBagConstraints. + */ + private static GridBagConstraints createConstraints() + { + GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = GridBagConstraints.REMAINDER; + constraints.gridy = GridBagConstraints.REMAINDER; + constraints.gridwidth = 0; + constraints.anchor = GridBagConstraints.LINE_START; + constraints.fill = GridBagConstraints.NONE; + constraints.insets = new Insets(0, 0, 3, 0); + + return constraints; + } + + /** + * This method creates the proper object (if necessary) to represent msg. + * (If msg is an instance of Component, it will add it directly. If it is + * an icon, then it will pack it in a label and add it. Otherwise, it gets + * treated as a string. If the string is longer than maxll, a box is + * created and the burstStringInto is called with the box as the container. + * The box is then added to the given container. Otherwise, the string is + * packed in a label and placed in the given container.) This method is + * also used for adding the inputComponent to the container. + * + * @param container The container to add to. + * @param cons The constraints when adding. + * @param msg The message to add. + * @param maxll The max line length. + * @param internallyCreated Whether the msg is internally created. + */ + protected void addMessageComponents(Container container, + GridBagConstraints cons, Object msg, + int maxll, boolean internallyCreated) + { + if (msg == null) + return; + hasCustomComponents = internallyCreated; + if (msg instanceof Object[]) + { + Object[] arr = (Object[]) msg; + for (int i = 0; i < arr.length; i++) + addMessageComponents(container, cons, arr[i], maxll, + internallyCreated); + return; + } + else if (msg instanceof Component) + { + container.add((Component) msg, cons); + cons.gridy++; + } + else if (msg instanceof Icon) + { + container.add(new JLabel((Icon) msg), cons); + cons.gridy++; + } + else + { + // Undocumented behaviour. + // if msg.toString().length greater than maxll + // it will create a box and burst the string. + // otherwise, it will just create a label and re-call + // this method with the label o.O + if (msg.toString().length() > maxll) + { + Box tmp = new Box(BoxLayout.Y_AXIS); + burstStringInto(tmp, msg.toString(), maxll); + addMessageComponents(container, cons, tmp, maxll, true); + } + else + addMessageComponents(container, cons, new JLabel(msg.toString()), + maxll, true); + } + } + + /** + * This method creates instances of d (recursively if necessary based on + * maxll) and adds to c. + * + * @param c The container to add to. + * @param d The string to burst. + * @param maxll The max line length. + */ + protected void burstStringInto(Container c, String d, int maxll) { - throw new Error ("Not implemented"); + // FIXME: Verify that this is the correct behaviour. + // One interpretation of the spec is that this method + // should recursively call itself to create (and add) + // JLabels to the container if the length of the String d + // is greater than maxll. + // but in practice, even with a really long string, this is + // all that happens. + if (d == null || c == null) + return; + JLabel label = new JLabel(d); + c.add(label); } + /** + * This method returns true if the given JOptionPane contains custom + * components. + * + * @param op The JOptionPane to check. + * + * @return True if the JOptionPane contains custom components. + */ public boolean containsCustomComponents(JOptionPane op) { - throw new Error ("Not implemented"); + return hasCustomComponents; + } + + /** + * This method creates a button action listener for the given button index. + * + * @param buttonIndex The index of the button in components. + * + * @return A new ButtonActionListener. + */ + protected ActionListener createButtonActionListener(int buttonIndex) + { + return new ButtonActionListener(buttonIndex); + } + + /** + * This method creates the button area. + * + * @return A new Button Area. + */ + protected Container createButtonArea() + { + JPanel buttonPanel = new JPanel(); + + buttonPanel.setLayout(createLayoutManager()); + addButtonComponents(buttonPanel, getButtons(), getInitialValueIndex()); + + return buttonPanel; + } + + /** + * This method creates a new LayoutManager for the button area. + * + * @return A new LayoutManager for the button area. + */ + protected LayoutManager createLayoutManager() + { + return new ButtonAreaLayout(getSizeButtonsToSameWidth(), 6); + } + + /** + * This method creates the message area. + * + * @return A new message area. + */ + protected Container createMessageArea() + { + JPanel messageArea = new JPanel(); + messageArea.setLayout(new BorderLayout()); + addIcon(messageArea); + + JPanel rightSide = new JPanel() + { + public Dimension getPreferredSize() + { + int w = Math.max(optionPane.getSize().width, + minimumWidth); + Insets i = optionPane.getInsets(); + Dimension orig = super.getPreferredSize(); + Dimension value = new Dimension(w - i.left - i.right - iconSize, + orig.height); + return value; + } + }; + rightSide.setLayout(new GridBagLayout()); + GridBagConstraints con = createConstraints(); + + addMessageComponents(rightSide, con, getMessage(), + getMaxCharactersPerLineCount(), false); + + if (optionPane.getWantsInput()) + { + Object[] selection = optionPane.getSelectionValues(); + + if (selection == null) + inputComponent = new JTextField(); + else if (selection.length < 20) + inputComponent = new JComboBox(selection); + else + inputComponent = new JList(selection); + if (inputComponent != null) + { + addMessageComponents(rightSide, con, inputComponent, + getMaxCharactersPerLineCount(), true); + resetSelectedValue(); + selectInitialValue(optionPane); + } + } + + messageArea.add(rightSide, BorderLayout.EAST); + + return messageArea; + } + + /** + * This method creates a new PropertyChangeListener for listening to the + * JOptionPane. + * + * @return A new PropertyChangeListener. + */ + protected PropertyChangeListener createPropertyChangeListener() + { + return new PropertyChangeHandler(); + } + + /** + * This method creates a Container that will separate the message and button + * areas. + * + * @return A Container that will separate the message and button areas. + */ + protected Container createSeparator() + { + return null; + } + + /** + * This method creates a new BasicOptionPaneUI for the given component. + * + * @param x The component to create a UI for. + * + * @return A new BasicOptionPaneUI. + */ + public static ComponentUI createUI(JComponent x) + { + return new BasicOptionPaneUI(); + } + + /** + * This method returns the buttons for the JOptionPane. If no options are + * set, a set of options will be created based upon the optionType. + * + * @return The buttons that will be added. + */ + protected Object[] getButtons() + { + if (optionPane.getOptions() != null) + return optionPane.getOptions(); + switch (optionPane.getOptionType()) + { + case JOptionPane.YES_NO_OPTION: + return new Object[] { YES_STRING, NO_STRING }; + case JOptionPane.YES_NO_CANCEL_OPTION: + return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING }; + case JOptionPane.OK_CANCEL_OPTION: + case JOptionPane.DEFAULT_OPTION: + return new Object[] { OK_STRING, CANCEL_STRING }; + } + return null; + } + + /** + * This method will return the icon the user has set or the icon that will + * be used based on message type. + * + * @return The icon to use in the JOptionPane. + */ + protected Icon getIcon() + { + if (optionPane.getIcon() != null) + return optionPane.getIcon(); + else + return getIconForType(optionPane.getMessageType()); + } + + /** + * This method returns the icon for the given messageType. + * + * @param messageType The type of message. + * + * @return The icon for the given messageType. + */ + protected Icon getIconForType(int messageType) + { + Icon tmp = null; + switch (messageType) + { + case JOptionPane.ERROR_MESSAGE: + tmp = errorIcon; + break; + case JOptionPane.INFORMATION_MESSAGE: + tmp = infoIcon; + break; + case JOptionPane.WARNING_MESSAGE: + tmp = warningIcon; + break; + case JOptionPane.QUESTION_MESSAGE: + tmp = questionIcon; + break; + } + return new IconUIResource(tmp); + } + + /** + * This method returns the index of the initialValue in the options array. + * + * @return The index of the initalValue. + */ + protected int getInitialValueIndex() + { + Object[] buttons = getButtons(); + + if (buttons == null) + return -1; + + Object select = optionPane.getInitialValue(); + + for (int i = 0; i < buttons.length; i++) + { + if (select == buttons[i]) + return i; + } + return 0; + } + + /** + * This method returns the maximum number of characters that should be + * placed on a line. + * + * @return The maximum number of characteres that should be placed on a + * line. + */ + protected int getMaxCharactersPerLineCount() + { + return optionPane.getMaxCharactersPerLineCount(); + } + + /** + * This method returns the maximum size. + * + * @param c The JComponent to measure. + * + * @return The maximum size. + */ + public Dimension getMaximumSize(JComponent c) + { + return getPreferredSize(c); + } + + /** + * This method returns the message of the JOptionPane. + * + * @return The message. + */ + protected Object getMessage() + { + return optionPane.getMessage(); + } + + /** + * This method returns the minimum size of the JOptionPane. + * + * @return The minimum size. + */ + public Dimension getMinimumOptionPaneSize() + { + return minimumSize; + } + + /** + * This method returns the minimum size. + * + * @param c The JComponent to measure. + * + * @return The minimum size. + */ + public Dimension getMinimumSize(JComponent c) + { + return getPreferredSize(c); + } + + /** + * This method returns the preferred size of the JOptionPane. The preferred + * size is the maximum of the size desired by the layout and the minimum + * size. + * + * @param c The JComponent to measure. + * + * @return The preferred size. + */ + public Dimension getPreferredSize(JComponent c) + { + Dimension d = optionPane.getLayout().preferredLayoutSize(optionPane); + Dimension d2 = getMinimumOptionPaneSize(); + + int w = Math.max(d.width, d2.width); + int h = Math.max(d.height, d2.height); + return new Dimension(w, h); + } + + /** + * This method returns whether all buttons should have the same width. + * + * @return Whether all buttons should have the same width. + */ + protected boolean getSizeButtonsToSameWidth() + { + return true; + } + + /** + * This method installs components for the JOptionPane. + */ + protected void installComponents() + { + // reset it. + hasCustomComponents = false; + Container msg = createMessageArea(); + if (msg != null) + { + ((JComponent) msg).setBorder(messageBorder); + msg.setForeground(messageForeground); + messageAreaContainer = msg; + optionPane.add(msg); + } + + Container sep = createSeparator(); + if (sep != null) + optionPane.add(sep); + + Container button = createButtonArea(); + if (button != null) + { + ((JComponent) button).setBorder(buttonBorder); + buttonContainer = button; + optionPane.add(button); + } + + optionPane.invalidate(); + } + + /** + * This method installs defaults for the JOptionPane. + */ + protected void installDefaults() + { + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + optionPane.setFont(defaults.getFont("OptionPane.font")); + optionPane.setBackground(defaults.getColor("OptionPane.background")); + optionPane.setForeground(defaults.getColor("OptionPane.foreground")); + optionPane.setBorder(defaults.getBorder("OptionPane.border")); + + messageBorder = defaults.getBorder("OptionPane.messageAreaBorder"); + messageForeground = defaults.getColor("OptionPane.messageForeground"); + buttonBorder = defaults.getBorder("OptionPane.buttonAreaBorder"); + + minimumSize = defaults.getDimension("OptionPane.minimumSize"); + minimumWidth = minimumSize.width; + minimumHeight = minimumSize.height; + + // FIXME: Image icons don't seem to work properly right now. + // Once they do, replace the synthetic icons with these ones. + + /* + warningIcon = (IconUIResource) defaults.getIcon("OptionPane.warningIcon"); + infoIcon = (IconUIResource) defaults.getIcon("OptionPane.informationIcon"); + errorIcon = (IconUIResource) defaults.getIcon("OptionPane.errorIcon"); + questionIcon = (IconUIResource) defaults.getIcon("OptionPane.questionIcon"); + */ + } + + /** + * This method installs keyboard actions for the JOptionpane. + */ + protected void installKeyboardActions() + { + // FIXME: implement. + } + + /** + * This method installs listeners for the JOptionPane. + */ + protected void installListeners() + { + propertyChangeListener = createPropertyChangeListener(); + + optionPane.addPropertyChangeListener(propertyChangeListener); + } + + /** + * This method installs the UI for the JOptionPane. + * + * @param c The JComponent to install the UI for. + */ + public void installUI(JComponent c) + { + if (c instanceof JOptionPane) + { + optionPane = (JOptionPane) c; + + installDefaults(); + installComponents(); + installListeners(); + installKeyboardActions(); + } + } + + /** + * Changes the inputValue property in the JOptionPane based on the current + * value of the inputComponent. + */ + protected void resetInputValue() + { + if (optionPane.getWantsInput() && inputComponent != null) + { + Object output = null; + if (inputComponent instanceof JTextField) + output = ((JTextField) inputComponent).getText(); + else if (inputComponent instanceof JComboBox) + output = ((JComboBox) inputComponent).getSelectedItem(); + else if (inputComponent instanceof JList) + output = ((JList) inputComponent).getSelectedValue(); + + if (output != null) + optionPane.setInputValue(output); + } + } + + /** + * This method requests focus to the inputComponent (if one is present) and + * the initialFocusComponent otherwise. + * + * @param op The JOptionPane. + */ + public void selectInitialValue(JOptionPane op) + { + if (inputComponent != null) + { + inputComponent.requestFocus(); + return; + } + if (initialFocusComponent != null) + initialFocusComponent.requestFocus(); + } + + /** + * This method resets the value in the inputComponent to the + * initialSelectionValue property. + */ + private void resetSelectedValue() + { + if (inputComponent != null) + { + Object init = optionPane.getInitialSelectionValue(); + if (init == null) + return; + if (inputComponent instanceof JTextField) + ((JTextField) inputComponent).setText((String) init); + else if (inputComponent instanceof JComboBox) + ((JComboBox) inputComponent).setSelectedItem(init); + else if (inputComponent instanceof JList) + { + // ((JList) inputComponent).setSelectedValue(init, true); + } + } + } + + /** + * This method uninstalls all the components in the JOptionPane. + */ + protected void uninstallComponents() + { + optionPane.removeAll(); + buttonContainer = null; + messageAreaContainer = null; + } + + /** + * This method uninstalls the defaults for the JOptionPane. + */ + protected void uninstallDefaults() + { + optionPane.setFont(null); + optionPane.setForeground(null); + optionPane.setBackground(null); + + minimumSize = null; + + messageBorder = null; + buttonBorder = null; + messageForeground = null; + + // FIXME: ImageIcons don't seem to work properly + + /* + warningIcon = null; + errorIcon = null; + questionIcon = null; + infoIcon = null; + */ + } + + /** + * This method uninstalls keyboard actions for the JOptionPane. + */ + protected void uninstallKeyboardActions() + { + // FIXME: implement. + } + + /** + * This method uninstalls listeners for the JOptionPane. + */ + protected void uninstallListeners() + { + optionPane.removePropertyChangeListener(propertyChangeListener); + propertyChangeListener = null; + } + + /** + * This method uninstalls the UI for the given JComponent. + * + * @param c The JComponent to uninstall for. + */ + public void uninstallUI(JComponent c) + { + uninstallKeyboardActions(); + uninstallListeners(); + uninstallComponents(); + uninstallDefaults(); + + optionPane = null; } } diff --git a/libjava/javax/swing/plaf/basic/BasicPopupMenuUI.java b/libjava/javax/swing/plaf/basic/BasicPopupMenuUI.java new file mode 100644 index 00000000000..d7ced7654ae --- /dev/null +++ b/libjava/javax/swing/plaf/basic/BasicPopupMenuUI.java @@ -0,0 +1,362 @@ +/* BasicPopupMenuUI.java + Copyright (C) 2002, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.plaf.basic; + +import java.awt.AWTKeyStroke; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Stroke; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.EventListener; +import javax.swing.AbstractButton; +import javax.swing.ButtonModel; +import javax.swing.Icon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.MenuDragMouseEvent; +import javax.swing.event.MenuDragMouseListener; +import javax.swing.event.MenuKeyEvent; +import javax.swing.event.MenuKeyListener; +import javax.swing.event.MouseInputListener; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.MenuItemUI; +import javax.swing.plaf.PopupMenuUI; + + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.1 $ + */ +public class BasicPopupMenuUI extends PopupMenuUI +{ + protected JPopupMenu popupMenu; + private static transient MouseInputListener mouseInputListener; + private transient PopupMenuListener popupMenuListener; + + /** + * Creates a new BasicPopupMenuUI object. + */ + public BasicPopupMenuUI() + { + popupMenuListener = new PopupMenuHandler(); + mouseInputListener = new MouseInputHandler(); + } + + /** + * DOCUMENT ME! + * + * @param x DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public static ComponentUI createUI(JComponent x) + { + return new BasicPopupMenuUI(); + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ + public void installUI(JComponent c) + { + super.installUI(c); + popupMenu = (JPopupMenu) c; + popupMenu.setLayout(new GridBagLayout()); + popupMenu.setBorderPainted(true); + popupMenu.setDefaultLightWeightPopupEnabled(true); + + installDefaults(); + installListeners(); + } + + /** + * DOCUMENT ME! + */ + public void installDefaults() + { + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + popupMenu.setBackground(defaults.getColor("PopupMenu.background")); + popupMenu.setBorder(defaults.getBorder("PopupMenu.border")); + popupMenu.setFont(defaults.getFont("PopupMenu.font")); + popupMenu.setForeground(defaults.getColor("PopupMenu.foreground")); + } + + /** + * DOCUMENT ME! + */ + protected void installListeners() + { + popupMenu.addMouseListener(mouseInputListener); + popupMenu.addMouseMotionListener(mouseInputListener); + popupMenu.addPopupMenuListener(popupMenuListener); + } + + /** + * DOCUMENT ME! + */ + protected void installKeyboardActions() + { + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + */ + public void uninstallUI(JComponent c) + { + uninstallListeners(); + uninstallDefaults(); + popupMenu = null; + } + + /** + * DOCUMENT ME! + */ + protected void uninstallDefaults() + { + popupMenu.setBackground(null); + popupMenu.setBorder(null); + popupMenu.setFont(null); + popupMenu.setForeground(null); + } + + /** + * DOCUMENT ME! + */ + protected void uninstallListeners() + { + } + + /** + * DOCUMENT ME! + */ + protected void uninstallKeyboardActions() + { + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getMinimumSize(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getPreferredSize(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param c DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Dimension getMaximumSize(JComponent c) + { + return null; + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public boolean isPopupTrigger(MouseEvent e) + { + return false; + } + + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.1 $ + */ + protected class PopupMenuHandler implements PopupMenuListener + { + /** + * DOCUMENT ME! + * + * @param event DOCUMENT ME! + */ + public void popupMenuCanceled(PopupMenuEvent event) + { + } + + /** + * DOCUMENT ME! + * + * @param event DOCUMENT ME! + */ + public void popupMenuWillBecomeInvisible(PopupMenuEvent event) + { + } + + /** + * DOCUMENT ME! + * + * @param event DOCUMENT ME! + */ + public void popupMenuWillBecomeVisible(PopupMenuEvent event) + { + } + } + + /** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.1 $ + */ + protected class MouseInputHandler implements MouseInputListener + { + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseClicked(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseDragged(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseEntered(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseExited(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseMoved(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mousePressed(MouseEvent e) + { + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseReleased(MouseEvent e) + { + } + } +} diff --git a/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java b/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java index 673c502a547..4a74617726d 100644 --- a/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java +++ b/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java @@ -712,6 +712,7 @@ public class BasicProgressBarUI extends ProgressBarUI progressBar.setForeground(defaults.getColor("ProgressBar.foreground")); progressBar.setBackground(defaults.getColor("ProgressBar.background")); progressBar.setBorder(defaults.getBorder("ProgressBar.border")); + progressBar.setOpaque(true); selectionForeground = defaults.getColor("ProgressBar.selectionForeground"); selectionBackground = defaults.getColor("ProgressBar.selectionBackground"); diff --git a/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java index 9a9f2e89c66..c3c3c840ddb 100644 --- a/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java +++ b/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java @@ -48,27 +48,55 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision: 1.1.2.3 $ + */ public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI { - + /** + * Creates a new BasicRadioButtonMenuItemUI object. + */ public BasicRadioButtonMenuItemUI() - { + { super(); UIDefaults defaults = UIManager.getLookAndFeelDefaults(); checkIcon = defaults.getIcon("RadioButtonMenuItem.checkIcon"); } + /** + * DOCUMENT ME! + * + * @param b DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ public static ComponentUI createUI(JComponent b) { return new BasicRadioButtonMenuItemUI(); } + /** + * DOCUMENT ME! + * + * @return $returnType$ DOCUMENT ME! + */ protected String getPropertyPrefix() { return null; // TODO } + /** + * DOCUMENT ME! + * + * @param item DOCUMENT ME! + * @param e DOCUMENT ME! + * @param path DOCUMENT ME! + * @param manager DOCUMENT ME! + */ void processMouseEvent(JMenuItem item, MouseEvent e, MenuElement[] path, MenuSelectionManager manager) { diff --git a/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java b/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java index e6472160587..96f09a11980 100644 --- a/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java +++ b/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java @@ -52,6 +52,8 @@ public class BasicRootPaneUI extends RootPaneUI public void installUI(JComponent c) { + c.setOpaque(true); + c.setBackground(javax.swing.UIManager.getColor("control")); super.installUI(c); } } diff --git a/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java b/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java index d6b31a2bafa..c52ca00409c 100644 --- a/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -125,6 +125,9 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, */ public void stateChanged(ChangeEvent e) { + // System.err.println(this + ".stateChanged()"); + calculatePreferredSize(); + layoutContainer(scrollbar); getThumbBounds(); scrollbar.repaint(); } @@ -734,6 +737,8 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, */ private void calculatePreferredSize() { + // System.err.println(this + ".calculatePreferredSize()"); + int height; int width; height = width = 0; @@ -743,7 +748,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, width += incrButton.getPreferredSize().getWidth(); width += decrButton.getPreferredSize().getWidth(); - width += Math.max(200, scrollbar.getVisibleAmount()); + width += (scrollbar.getMaximum() - scrollbar.getMinimum()); height = Math.max(incrButton.getPreferredSize().height, decrButton.getPreferredSize().height); @@ -756,7 +761,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, height += incrButton.getPreferredSize().getHeight(); height += decrButton.getPreferredSize().getHeight(); - height += Math.max(200, scrollbar.getVisibleAmount()); + height += (scrollbar.getMaximum() - scrollbar.getMinimum()); width = Math.max(incrButton.getPreferredSize().width, decrButton.getPreferredSize().width); @@ -804,6 +809,8 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, int value = scrollbar.getValue(); int extent = scrollbar.getVisibleAmount(); + // System.err.println(this + ".getThumbBounds()"); + if (max == min) { thumbRect.x = trackRect.x; @@ -892,8 +899,8 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, scrollbar.setForeground(defaults.getColor("ScrollBar.foreground")); scrollbar.setBackground(defaults.getColor("ScrollBar.background")); - scrollbar.setBorder(defaults.getBorder("ScrollBar.border")); + scrollbar.setOpaque(true); maximumThumbSize = defaults.getDimension("ScrollBar.maximumThumbSize"); minimumThumbSize = defaults.getDimension("ScrollBar.minimumThumbSize"); @@ -1046,14 +1053,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager, public void paint(Graphics g, JComponent c) { layoutContainer(scrollbar); - -// Rectangle r = incrButton.getBounds(); -// SwingUtilities.paintComponent(g, incrButton, scrollbar, r.x, r.y, r.width, -// r.height); -// r = decrButton.getBounds(); -// SwingUtilities.paintComponent(g, decrButton, scrollbar, r.x, r.y, r.width, -// r.height); - paintTrack(g, c, getTrackBounds()); paintThumb(g, c, getThumbBounds()); diff --git a/libjava/javax/swing/plaf/basic/BasicSeparatorUI.java b/libjava/javax/swing/plaf/basic/BasicSeparatorUI.java index b7df0acb27d..8f4500fd58c 100644 --- a/libjava/javax/swing/plaf/basic/BasicSeparatorUI.java +++ b/libjava/javax/swing/plaf/basic/BasicSeparatorUI.java @@ -123,6 +123,7 @@ public class BasicSeparatorUI extends SeparatorUI shadow = defaults.getColor("Separator.shadow"); highlight = defaults.getColor("Separator.highlight"); + s.setOpaque(true); } /** diff --git a/libjava/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/javax/swing/plaf/basic/BasicSliderUI.java index 05e3bb334f2..7b5a52f832c 100644 --- a/libjava/javax/swing/plaf/basic/BasicSliderUI.java +++ b/libjava/javax/swing/plaf/basic/BasicSliderUI.java @@ -681,6 +681,7 @@ public class BasicSliderUI extends SliderUI highlightColor = defaults.getColor("Slider.highlight"); focusColor = defaults.getColor("Slider.focus"); slider.setBorder(defaults.getBorder("Slider.border")); + slider.setOpaque(true); thumbHeight = defaults.getInt("Slider.thumbHeight"); thumbWidth = defaults.getInt("Slider.thumbWidth"); diff --git a/libjava/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/libjava/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 39db7e76bfb..3a2db55a863 100644 --- a/libjava/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/libjava/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -1,5 +1,5 @@ /* BasicSplitPaneDivider.java - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -35,14 +35,15 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ - package javax.swing.plaf.basic; +import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; +import java.awt.LayoutManager; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; @@ -50,173 +51,173 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JSplitPane; +import javax.swing.SwingConstants; import javax.swing.border.Border; /** - * The divider that separates the two parts of a JSplitPane in the - * Basic look and feel. - * - * <p>Implementation status: We do not have a real implementation yet. - * Currently, it is mostly a stub to allow compiling other parts of - * the javax.swing.plaf.basic package, although some parts are already + * The divider that separates the two parts of a JSplitPane in the Basic look + * and feel. + * + * <p> + * Implementation status: We do not have a real implementation yet. Currently, + * it is mostly a stub to allow compiling other parts of the + * javax.swing.plaf.basic package, although some parts are already * functional. + * </p> * - * @author Sascha Brawer (brawer@dandelis.ch) + * @author Sascha Brawer (brawer_AT_dandelis.ch) */ -public class BasicSplitPaneDivider - extends Container +public class BasicSplitPaneDivider extends Container implements PropertyChangeListener { /** - * Determined using the <code>serialver</code> tool - * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. + * Determined using the <code>serialver</code> tool of Apple/Sun JDK 1.3.1 + * on MacOS X 10.1.5. */ static final long serialVersionUID = 1463404307042803342L; - /** - * The width and height of the little buttons for showing and - * hiding parts of a JSplitPane in a single mouse click. + * The width and height of the little buttons for showing and hiding parts + * of a JSplitPane in a single mouse click. */ protected static final int ONE_TOUCH_SIZE = 6; - - // FIXME: Javadoc. + /** The distance the one touch buttons will sit from the divider's edges. */ protected static final int ONE_TOUCH_OFFSET = 2; - /** * An object that performs the tasks associated with an ongoing drag - * operation, or <code>null</code> if the user is currently not - * dragging the divider. + * operation, or <code>null</code> if the user is currently not dragging + * the divider. */ protected DragController dragger; - /** * The delegate object that is responsible for the UI of the * <code>JSplitPane</code> that contains this divider. */ protected BasicSplitPaneUI splitPaneUI; - - /** - * The thickness of the divider in pixels. - */ + /** The thickness of the divider in pixels. */ protected int dividerSize; - - /** - * A divider that is used for layout purposes. - */ + /** A divider that is used for layout purposes. */ protected Component hiddenDivider; - - /** - * The JSplitPane containing this divider. - */ + /** The JSplitPane containing this divider. */ protected JSplitPane splitPane; - /** - * The listener for handling mouse events from both the divider - * and the containing <code>JSplitPane</code>. - * - * <p>The reason for also handling MouseEvents from the containing - * <code>JSplitPane</code> is that users should be able to start - * a drag gesture from inside the JSplitPane, but slightly outisde - * the divider. + * The listener for handling mouse events from both the divider and the + * containing <code>JSplitPane</code>. + * + * <p> + * The reason for also handling MouseEvents from the containing + * <code>JSplitPane</code> is that users should be able to start a drag + * gesture from inside the JSplitPane, but slightly outisde the divider. + * </p> */ protected MouseHandler mouseHandler = new MouseHandler(); - /** - * The current orientation of the containing <code>JSplitPane</code>, - * which is either {@link javax.swing.JSplitPane#HORIZONTAL_SPLIT} - * or {@link javax.swing.JSplitPane#VERTICAL_SPLIT}. + * The current orientation of the containing <code>JSplitPane</code>, which + * is either {@link javax.swing.JSplitPane#HORIZONTAL_SPLIT} or {@link + * javax.swing.JSplitPane#VERTICAL_SPLIT}. */ protected int orientation; - /** - * The button for showing and hiding the left (or top) component - * of the <code>JSplitPane</code>. + * The button for showing and hiding the left (or top) component of the + * <code>JSplitPane</code>. */ protected JButton leftButton; - /** - * The button for showing and hiding the right (or bottom) component - * of the <code>JSplitPane</code>. + * The button for showing and hiding the right (or bottom) component of the + * <code>JSplitPane</code>. */ protected JButton rightButton; - /** - * The border of this divider. Typically, this will be an instance of - * {@link javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}. + * The border of this divider. Typically, this will be an instance of {@link + * javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}. * * @see #getBorder() * @see #setBorder(javax.swing.border.Border) */ private Border border; + // This is not a pixel count. + // This int should be able to take 3 values. + // left (top), middle, right(bottom) + // 0 1 2 + + /** Keeps track of where the divider should be placed when using one touch expand + * buttons. */ + private transient int currentDividerLocation = 1; /** * Constructs a new divider. * - * @param ui the UI delegate of the enclosing - * <code>JSplitPane</code>. + * @param ui the UI delegate of the enclosing <code>JSplitPane</code>. */ public BasicSplitPaneDivider(BasicSplitPaneUI ui) { + setLayout(new DividerLayout()); setBasicSplitPaneUI(ui); + setDividerSize(splitPane.getDividerSize()); } - /** - * Sets the delegate object that is responsible for the UI of the - * {@link javax.swing.JSplitPane} containing this divider. + * Sets the delegate object that is responsible for the UI of the {@link + * javax.swing.JSplitPane} containing this divider. * - * @param newUI the UI delegate, or <code>null</code> to release - * the connection to the current delegate. + * @param newUI the UI delegate, or <code>null</code> to release the + * connection to the current delegate. */ public void setBasicSplitPaneUI(BasicSplitPaneUI newUI) { /* Remove the connection to the existing JSplitPane. */ if (splitPane != null) - { - splitPane.removePropertyChangeListener(this); - splitPane.removeMouseListener(mouseHandler); - splitPane.removeMouseMotionListener(mouseHandler); - splitPane = null; - } - + { + splitPane.removePropertyChangeListener(this); + splitPane.removeMouseListener(mouseHandler); + splitPane.removeMouseMotionListener(mouseHandler); + removeMouseListener(mouseHandler); + removeMouseMotionListener(mouseHandler); + splitPane = null; + hiddenDivider = null; + } + /* Establish the connection to the new JSplitPane. */ splitPaneUI = newUI; if (splitPaneUI != null) splitPane = newUI.getSplitPane(); if (splitPane != null) - { - splitPane.addPropertyChangeListener(this); - splitPane.addMouseListener(mouseHandler); - splitPane.addMouseMotionListener(mouseHandler); - orientation = splitPane.getOrientation(); - } + { + splitPane.addPropertyChangeListener(this); + splitPane.addMouseListener(mouseHandler); + splitPane.addMouseMotionListener(mouseHandler); + addMouseListener(mouseHandler); + addMouseMotionListener(mouseHandler); + hiddenDivider = splitPaneUI.getNonContinuousLayoutDivider(); + orientation = splitPane.getOrientation(); + oneTouchExpandableChanged(); + } } - /** - * Returns the delegate object that is responsible for the UI of the - * {@link javax.swing.JSplitPane} containing this divider. + * Returns the delegate object that is responsible for the UI of the {@link + * javax.swing.JSplitPane} containing this divider. + * + * @return The UI for the JSplitPane. */ public BasicSplitPaneUI getBasicSplitPaneUI() { return splitPaneUI; } - /** * Sets the thickness of the divider. * @@ -227,37 +228,40 @@ public class BasicSplitPaneDivider this.dividerSize = newSize; } - /** * Retrieves the thickness of the divider. + * + * @return The thickness of the divider. */ public int getDividerSize() { return dividerSize; } - - + /** * Sets the border of this divider. * * @param border the new border. Typically, this will be an instance of - * {@link javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}. + * {@link + * javax.swing.plaf.basic.BasicBorders.SplitPaneDividerBorder}. * * @since 1.3 */ public void setBorder(Border border) { - Border oldValue = this.border; - this.border = border; - firePropertyChange("border", oldValue, border); + if (border != this.border) + { + Border oldValue = this.border; + this.border = border; + firePropertyChange("border", oldValue, border); + } } - /** * Retrieves the border of this divider. * - * @return the current border, or <code>null</code> if no border - * has been set. + * @return the current border, or <code>null</code> if no border has been + * set. * * @since 1.3 */ @@ -265,13 +269,12 @@ public class BasicSplitPaneDivider { return border; } - /** - * Retrieves the insets of the divider. If a border has been - * installed on the divider, the result of calling its - * <code>getBorderInsets</code> method is returned. Otherwise, - * the inherited implementation will be invoked. + * Retrieves the insets of the divider. If a border has been installed on + * the divider, the result of calling its <code>getBorderInsets</code> + * method is returned. Otherwise, the inherited implementation will be + * invoked. * * @see javax.swing.border.Border#getBorderInsets(java.awt.Component) */ @@ -282,42 +285,56 @@ public class BasicSplitPaneDivider else return super.getInsets(); } - - + /** * Returns the preferred size of this divider, which is - * <code>dividerSize</code> by <code>dividerSize</code> - * pixels. + * <code>dividerSize</code> by <code>dividerSize</code> pixels. + * + * @return The preferred size of the divider. */ public Dimension getPreferredSize() { - return new Dimension(dividerSize, dividerSize); + return getLayout().preferredLayoutSize(this); } - /** * Returns the minimal size of this divider, which is - * <code>dividerSize</code> by <code>dividerSize</code> - * pixels. + * <code>dividerSize</code> by <code>dividerSize</code> pixels. + * + * @return The minimal size of the divider. */ public Dimension getMinimumSize() { return getPreferredSize(); } - - + /** - * Processes events from the <code>JSplitPane</code> that contains - * this divider. + * Processes events from the <code>JSplitPane</code> that contains this + * divider. + * + * @param e The PropertyChangeEvent. */ public void propertyChange(PropertyChangeEvent e) { - // FIXME: Not yet implemented. + if (e.getPropertyName().equals(JSplitPane.ONE_TOUCH_EXPANDABLE_PROPERTY)) + oneTouchExpandableChanged(); + else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY)) + { + orientation = splitPane.getOrientation(); + if (splitPane.isOneTouchExpandable()) + { + layout(); + repaint(); + } + } + else if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY)) + dividerSize = splitPane.getDividerSize(); } - /** * Paints the divider by painting its border. + * + * @param g The Graphics Object to paint with. */ public void paint(Graphics g) { @@ -325,50 +342,85 @@ public class BasicSplitPaneDivider super.paint(g); if (border != null) - { - dividerSize = getSize(); - border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height); - //System.out.println(dividerSize); - //g.setColor(java.awt.Color.white); - //g.drawRect(0, 0, 5, 5); - } + { + dividerSize = getSize(); + border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height); + } } - /** - * Reacts to changes of the <code>oneToughExpandable</code> - * property of the containing <code>JSplitPane</code>. + * Reacts to changes of the <code>oneToughExpandable</code> property of the + * containing <code>JSplitPane</code>. */ protected void oneTouchExpandableChanged() { - // FIXME: Not yet implemented. + if (splitPane.isOneTouchExpandable()) + { + leftButton = createLeftOneTouchButton(); + rightButton = createRightOneTouchButton(); + add(leftButton); + add(rightButton); + + leftButton.addMouseListener(mouseHandler); + rightButton.addMouseListener(mouseHandler); + + // Set it to 1. + currentDividerLocation = 1; + } + else + { + if (leftButton != null && rightButton != null) + { + leftButton.removeMouseListener(mouseHandler); + rightButton.removeMouseListener(mouseHandler); + + remove(leftButton); + remove(rightButton); + leftButton = null; + rightButton = null; + } + } + layout(); + repaint(); } - /** - * Creates a button for showing and hiding the left (or top) - * part of a <code>JSplitPane</code>. + * Creates a button for showing and hiding the left (or top) part of a + * <code>JSplitPane</code>. + * + * @return The left one touch button. */ protected JButton createLeftOneTouchButton() { - return new OneTouchButton(/* left */ true); - } + int dir = SwingConstants.WEST; + if (orientation == JSplitPane.VERTICAL_SPLIT) + dir = SwingConstants.NORTH; + JButton button = new BasicArrowButton(dir); + button.setBorderPainted(false); + return button; + } /** - * Creates a button for showing and hiding the right (or bottom) - * part of a <code>JSplitPane</code>. + * Creates a button for showing and hiding the right (or bottom) part of a + * <code>JSplitPane</code>. + * + * @return The right one touch button. */ protected JButton createRightOneTouchButton() { - return new OneTouchButton(/* left */ false); + int dir = SwingConstants.EAST; + if (orientation == JSplitPane.VERTICAL_SPLIT) + dir = SwingConstants.SOUTH; + JButton button = new BasicArrowButton(dir); + button.setBorderPainted(false); + return button; } - /** * Prepares the divider for dragging by calling the - * <code>startDragging</code> method of the UI delegate of the - * enclosing <code>JSplitPane</code>. + * <code>startDragging</code> method of the UI delegate of the enclosing + * <code>JSplitPane</code>. * * @see BasicSplitPaneUI#startDragging() */ @@ -378,15 +430,14 @@ public class BasicSplitPaneDivider splitPaneUI.startDragging(); } - /** * Drags the divider to a given location by calling the - * <code>dragDividerTo</code> method of the UI delegate of the - * enclosing <code>JSplitPane</code>. + * <code>dragDividerTo</code> method of the UI delegate of the enclosing + * <code>JSplitPane</code>. * * @param location the new location of the divider. * - * @see BasicSplitPaneUI#dragDividerTo(int location) + * @see BasicSplitPaneUI#dragDividerTo(int location) */ protected void dragDividerTo(int location) { @@ -394,11 +445,9 @@ public class BasicSplitPaneDivider splitPaneUI.dragDividerTo(location); } - /** - * Finishes a dragging gesture by calling the - * <code>finishDraggingTo</code> method of the UI delegate of the - * enclosing <code>JSplitPane</code>. + * Finishes a dragging gesture by calling the <code>finishDraggingTo</code> + * method of the UI delegate of the enclosing <code>JSplitPane</code>. * * @param location the new, final location of the divider. * @@ -410,125 +459,425 @@ public class BasicSplitPaneDivider splitPaneUI.finishDraggingTo(location); } - /** - * The listener for handling mouse events from both the divider - * and the containing <code>JSplitPane</code>. + * This helper method moves the divider to one of the + * three locations when using one touch expand buttons. + * Location 0 is the left (or top) most location. + * Location 1 is the middle. + * Location 2 is the right (or bottom) most location. * - * <p>The reason for also handling MouseEvents from the containing - * <code>JSplitPane</code> is that users should be able to start - * a drag gesture from inside the JSplitPane, but slightly outisde - * the divider. + * @param locationIndex The location to move to. + */ + private void moveDividerTo(int locationIndex) + { + Insets insets = splitPane.getInsets(); + switch (locationIndex) + { + case 1: + splitPane.setDividerLocation(splitPane.getLastDividerLocation()); + break; + case 0: + int top = (orientation == JSplitPane.HORIZONTAL_SPLIT) ? insets.left + : insets.top; + splitPane.setDividerLocation(top); + break; + case 2: + int bottom; + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + bottom = splitPane.getBounds().width - insets.right - dividerSize; + else + bottom = splitPane.getBounds().height - insets.bottom - dividerSize; + splitPane.setDividerLocation(bottom); + break; + } + } + + /** + * The listener for handling mouse events from both the divider and the + * containing <code>JSplitPane</code>. + * + * <p> + * The reason for also handling MouseEvents from the containing + * <code>JSplitPane</code> is that users should be able to start a drag + * gesture from inside the JSplitPane, but slightly outisde the divider. + * </p> * - * @author Sascha Brawer (brawer@dandelis.ch) + * @author Sascha Brawer (brawer_AT_dandelis.ch) */ - protected class MouseHandler - extends MouseAdapter + protected class MouseHandler extends MouseAdapter implements MouseMotionListener { - + /** Keeps track of whether a drag is occurring. */ + private transient boolean isDragging; + + /** + * This method is called when the mouse is pressed. + * + * @param e The MouseEvent. + */ public void mousePressed(MouseEvent e) { - // FIXME: Not yet implemented. + if (splitPane.isOneTouchExpandable()) + { + if (e.getSource() == leftButton) + { + currentDividerLocation--; + if (currentDividerLocation < 0) + currentDividerLocation = 0; + moveDividerTo(currentDividerLocation); + return; + } + else if (e.getSource() == rightButton) + { + currentDividerLocation++; + if (currentDividerLocation > 2) + currentDividerLocation = 2; + moveDividerTo(currentDividerLocation); + return; + } + } + isDragging = true; + currentDividerLocation = 1; + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + dragger = new DragController(e); + else + dragger = new VerticalDragController(e); + prepareForDragging(); } - + /** + * This method is called when the mouse is released. + * + * @param e The MouseEvent. + */ public void mouseReleased(MouseEvent e) { - // FIXME: Not yet implemented. + if (isDragging) + dragger.completeDrag(e); + isDragging = false; } - /** - * Repeatedly invoked when the user is dragging the mouse cursor - * while having pressed a mouse button. + * Repeatedly invoked when the user is dragging the mouse cursor while + * having pressed a mouse button. + * + * @param e The MouseEvent. */ public void mouseDragged(MouseEvent e) { - // FIXME: Not yet implemented. + if (dragger != null) + dragger.continueDrag(e); } - /** - * Repeatedly invoked when the user is dragging the mouse cursor - * without having pressed a mouse button. + * Repeatedly invoked when the user is dragging the mouse cursor without + * having pressed a mouse button. + * + * @param e The MouseEvent. */ public void mouseMoved(MouseEvent e) { - // FIXME: Not yet implemented. + // Do nothing. } } - /** - * A small button for showing and hiding parts of a - * <code>JSplitPane</code> with a single mouse click. + * Performs the tasks associated with an ongoing drag operation. * - * @author Sascha Brawer (brawer@dandelis.ch) + * @author Sascha Brawer (brawer_AT_dandelis.ch) */ - private static class OneTouchButton - extends JButton + protected class DragController { - OneTouchButton(boolean left) + /** The difference between where the mouse is clicked and the + * initial divider location. */ + transient int offset; + + /** + * Creates a new DragController object. + * + * @param e The MouseEvent to initialize with. + */ + protected DragController(MouseEvent e) { - // FIXME: Set various properties of the button. - // Make sure it looks identical to the small - // buttons of the Sun reference implementation. - // The size should also be the same. - if (left) - setText("<"); - else - setText(">"); + offset = e.getX(); + } - Dimension butSize = new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE); - setMinimumSize(butSize); - setMaximumSize(butSize); - setPreferredSize(butSize); + /** + * This method returns true if the divider can move. + * + * @return True if dragging is allowed. + */ + protected boolean isValid() + { + // Views can always be resized? + return true; + } - setBorderPainted(false); + /** + * Returns a position for the divider given the MouseEvent. + * + * @param e MouseEvent. + * + * @return The position for the divider to move to. + */ + protected int positionForMouseEvent(MouseEvent e) + { + return e.getX() + getX() - offset; + ; } - } + /** + * This method returns one of the two paramters + * for the orientation. In this case, it returns x. + * + * @param x The x coordinate. + * @param y The y coordinate. + * + * @return The x coordinate. + */ + protected int getNeededLocation(int x, int y) + { + return x; + } + + /** + * This method is called to pass on the drag information + * to the UI through dragDividerTo. + * + * @param newX The x coordinate of the MouseEvent. + * @param newY The y coordinate of the MouseEvent. + */ + protected void continueDrag(int newX, int newY) + { + if (isValid()) + dragDividerTo(adjust(x, y)); + } + + /** + * This method is called to pass on the drag information + * to the UI through dragDividerTo. + * + * @param e The MouseEvent. + */ + protected void continueDrag(MouseEvent e) + { + if (isValid()) + dragDividerTo(positionForMouseEvent(e)); + } + + /** + * This method is called to finish the drag session + * by calling finishDraggingTo. + * + * @param x The x coordinate of the MouseEvent. + * @param y The y coordinate of the MouseEvent. + */ + protected void completeDrag(int x, int y) + { + finishDraggingTo(adjust(x, y)); + } + + /** + * This method is called to finish the drag session + * by calling finishDraggingTo. + * + * @param e The MouseEvent. + */ + protected void completeDrag(MouseEvent e) + { + finishDraggingTo(positionForMouseEvent(e)); + } + + /** + * This is a helper method that includes the offset + * in the needed location. + * + * @param x The x coordinate of the MouseEvent. + * @param y The y coordinate of the MouseEvent. + * + * @return The needed location adjusted by the offsets. + */ + int adjust(int x, int y) + { + return getNeededLocation(x, y) + getX() - offset; + } + } /** - * Performs the tasks associated with an ongoing drag - * operation. - * - * @author Sascha Brawer (brawer@dandelis.ch) + * This is a helper class that controls dragging when + * the orientation is VERTICAL_SPLIT. */ - protected class DragController + protected class VerticalDragController extends DragController { - // FIXME: Not yet implemented. - protected DragController(MouseEvent e) + /** + * Creates a new VerticalDragController object. + * + * @param e The MouseEvent to initialize with. + */ + protected VerticalDragController(MouseEvent e) { + super(e); + offset = e.getY(); } - protected boolean isValid() + /** + * This method returns one of the two parameters given + * the orientation. In this case, it returns y. + * + * @param x The x coordinate of the MouseEvent. + * @param y The y coordinate of the MouseEvent. + * + * @return The y coordinate. + */ + protected int getNeededLocation(int x, int y) { - // FIXME: Not yet implemented. - return true; + return y; } + /** + * This method returns the new location of the divider + * given a MouseEvent. + * + * @param e The MouseEvent. + * + * @return The new location of the divider. + */ protected int positionForMouseEvent(MouseEvent e) { - return 0; + return e.getY() + getY() - offset; } - protected int getNeededLocation(int x, int y) + /** + * This is a helper method that includes the offset + * in the needed location. + * + * @param x The x coordinate of the MouseEvent. + * @param y The y coordinate of the MouseEvent. + * + * @return The needed location adjusted by the offsets. + */ + int adjust(int x, int y) + { + return getNeededLocation(x, y) + getY() - offset; + } + } + + /** + * This helper class acts as the Layout Manager for + * the divider. + */ + protected class DividerLayout implements LayoutManager + { + /** + * Creates a new DividerLayout object. + */ + protected DividerLayout() { - return 0; } - protected void continueDrag(int newX, int newY) + /** + * This method is called when a Component is added. + * + * @param string The constraints string. + * @param c The Component to add. + */ + public void addLayoutComponent(String string, Component c) { + // Do nothing. } - protected void completeDrag(int x, int y) + /** + * This method is called to lay out the container. + * + * @param c The container to lay out. + */ + public void layoutContainer(Container c) { + if (splitPane.isOneTouchExpandable()) + { + changeButtonOrientation(); + positionButtons(); + } } - protected void completeDrag(MouseEvent e) + /** + * This method returns the minimum layout size. + * + * @param c The container to calculate for. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container c) { + return preferredLayoutSize(c); + } + + /** + * This method returns the preferred layout size. + * + * @param c The container to calculate for. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container c) + { + return new Dimension(dividerSize, dividerSize); + } + + /** + * This method is called when a component is removed. + * + * @param c The component to remove. + */ + public void removeLayoutComponent(Component c) + { + // Do nothing. + } + + /** + * This method changes the button orientation when + * the orientation of the SplitPane changes. + */ + private void changeButtonOrientation() + { + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + { + ((BasicArrowButton) rightButton).setDirection(SwingConstants.EAST); + ((BasicArrowButton) leftButton).setDirection(SwingConstants.WEST); + } + else + { + ((BasicArrowButton) rightButton).setDirection(SwingConstants.SOUTH); + ((BasicArrowButton) leftButton).setDirection(SwingConstants.NORTH); + } + } + + /** + * This method sizes and positions the buttons. + */ + private void positionButtons() + { + int w = 0; + int h = 0; + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + { + rightButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET); + leftButton.setLocation(ONE_TOUCH_OFFSET, + ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE); + w = dividerSize - 2 * ONE_TOUCH_OFFSET; + h = 2 * ONE_TOUCH_SIZE; + } + else + { + leftButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET); + rightButton.setLocation(ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE, + ONE_TOUCH_OFFSET); + h = dividerSize - 2 * ONE_TOUCH_OFFSET; + w = 2 * ONE_TOUCH_SIZE; + } + Dimension dims = new Dimension(w, h); + leftButton.setSize(dims); + rightButton.setSize(dims); } } } diff --git a/libjava/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/javax/swing/plaf/basic/BasicSplitPaneUI.java index 5c1c7f25e4f..f1ccb133997 100644 --- a/libjava/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/libjava/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* BasicSplitPaneUI.java - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,273 +37,1484 @@ exception statement from your version. */ package javax.swing.plaf.basic; +import java.awt.Canvas; +import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; +import java.awt.LayoutManager2; +import java.awt.Point; +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JSplitPane; import javax.swing.KeyStroke; +import javax.swing.UIDefaults; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.SplitPaneUI; + /** - * FIXME: Stubbed to allow compiling other classes, - * no real implementation. + * This is the Basic Look and Feel implementation of the SplitPaneUI class. */ -public class BasicSplitPaneUI - extends SplitPaneUI +public class BasicSplitPaneUI extends SplitPaneUI { - protected static final String NON_CONTINUOUS_DIVIDER - = "nonContinuousDivider"; + /** + * This Layout Manager controls the position and size of the components when + * the JSplitPane's orientation is HORIZONTAL_SPLIT. + */ + protected class BasicHorizontalLayoutManager implements LayoutManager2 + { + // 3 components at a time. + // LEFT/TOP = 0 + // RIGHT/BOTTOM = 1 + // DIVIDER = 2 + + /** + * This array contains the components in the JSplitPane. The left/top + * component is at index 0, the right/bottom is at 1, and the divider is + * at 2. + */ + protected Component[] components = new Component[3]; + + // These are the _current_ widths of the associated component. + + /** + * This array contains the current width (for HORIZONTAL_SPLIT) or height + * (for VERTICAL_SPLIT) of the components. The indices are the same as + * for components. + */ + protected int[] sizes = new int[3]; + + /** + * This method adds the component given to the JSplitPane. The position of + * the component is given by the constraints object. + * + * @param comp The Component to add. + * @param constraints The constraints that bind the object. + */ + public void addLayoutComponent(Component comp, Object constraints) + { + addLayoutComponent((String) constraints, comp); + } + + /** + * This method is called to add a Component to the JSplitPane. The + * placement string determines where the Component will be placed. The + * string should be one of LEFT, RIGHT, TOP, BOTTOM or null (signals that + * the component is the divider). + * + * @param place The placement of the Component. + * @param component The Component to add. + * + * @throws IllegalArgumentException DOCUMENT ME! + */ + public void addLayoutComponent(String place, Component component) + { + int i = 0; + if (place == null) + i = 2; + else if (place.equals(JSplitPane.TOP) || place.equals(JSplitPane.LEFT)) + i = 0; + else if (place.equals(JSplitPane.BOTTOM) + || place.equals(JSplitPane.RIGHT)) + i = 1; + else + throw new IllegalArgumentException("Illegal placement in JSplitPane"); + components[i] = component; + resetSizeAt(i); + layoutContainer(splitPane); + splitPane.repaint(); + } + + /** + * This method returns the width of the JSplitPane minus the insets. + * + * @param containerSize The Dimensions of the JSplitPane. + * @param insets The Insets of the JSplitPane. + * + * @return The width of the JSplitPane minus the insets. + */ + protected int getAvailableSize(Dimension containerSize, Insets insets) + { + return containerSize.width - insets.left - insets.right; + } + + /** + * This method returns the given insets left value. If the given inset is + * null, then 0 is returned. + * + * @param insets The Insets to use with the JSplitPane. + * + * @return The inset's left value. + */ + protected int getInitialLocation(Insets insets) + { + if (insets != null) + return insets.left; + return 0; + } + + /** + * This specifies how a component is aligned with respect to other + * components in the x fdirection. + * + * @param target The container. + * + * @return The component's alignment. + */ + public float getLayoutAlignmentX(Container target) + { + return target.getAlignmentX(); + } + + /** + * This specifies how a component is aligned with respect to other + * components in the y direction. + * + * @param target The container. + * + * @return The component's alignment. + */ + public float getLayoutAlignmentY(Container target) + { + return target.getAlignmentY(); + } + + /** + * This method returns the preferred width of the component. + * + * @param c The component to measure. + * + * @return The preferred width of the component. + */ + protected int getPreferredSizeOfComponent(Component c) + { + Dimension dims = c.getPreferredSize(); + if (dims != null) + return dims.width; + return 0; + } + + /** + * This method returns the current width of the component. + * + * @param c The component to measure. + * + * @return The width of the component. + */ + protected int getSizeOfComponent(Component c) + { + return c.getWidth(); + } + + /** + * This method returns the sizes array. + * + * @return The sizes array. + */ + protected int[] getSizes() + { + return sizes; + } + + /** + * This method invalidates the layout. It does nothing. + * + * @param c The container to invalidate. + */ + public void invalidateLayout(Container c) + { + // DO NOTHING + } + + /** + * This method lays out the components in the container. + * + * @param container The container to lay out. + */ + public void layoutContainer(Container container) + { + if (container instanceof JSplitPane) + { + JSplitPane split = (JSplitPane) container; + distributeExtraSpace(); + Insets insets = split.getInsets(); + int width = getInitialLocation(insets); + Dimension dims = split.getSize(); + for (int i = 0; i < components.length; i += 2) + { + if (components[i] == null) + continue; + setComponentToSize(components[i], sizes[i], width, insets, dims); + width += sizes[i]; + } + if (components[1] != null) + { + setComponentToSize(components[1], sizes[1], width, insets, dims); + width += sizes[1]; + } + } + } + + /** + * This method returns the maximum size for the container given the + * components. It returns a new Dimension object that has width and + * height equal to Integer.MAX_VALUE. + * + * @param target The container to measure. + * + * @return The maximum size. + */ + public Dimension maximumLayoutSize(Container target) + { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * This method returns the container's minimum size. The minimum width is + * the sum of all the component's minimum widths. The minimum height is + * the maximum of all the components' minimum heights. + * + * @param target The container to measure. + * + * @return The minimum size. + */ + public Dimension minimumLayoutSize(Container target) + { + if (target instanceof JSplitPane) + { + JSplitPane split = (JSplitPane) target; + Insets insets = target.getInsets(); + + int height = 0; + int width = 0; + for (int i = 0; i < components.length; i++) + { + if (components[i] == null) + continue; + Dimension dims = components[i].getMinimumSize(); + if (dims != null) + { + width += dims.width; + height = Math.max(height, dims.height); + } + } + return new Dimension(width, height); + } + return null; + } + + /** + * This method returns the container's preferred size. The preferred width + * is the sum of all the component's preferred widths. The preferred + * height is the maximum of all the components' preferred heights. + * + * @param target The container to measure. + * + * @return The preferred size. + */ + public Dimension preferredLayoutSize(Container target) + { + if (target instanceof JSplitPane) + { + JSplitPane split = (JSplitPane) target; + Insets insets = target.getInsets(); + + int height = 0; + int width = 0; + for (int i = 0; i < components.length; i++) + { + if (components[i] == null) + continue; + Dimension dims = components[i].getPreferredSize(); + if (dims != null) + { + width += dims.width; + if (! (components[i] instanceof BasicSplitPaneDivider)) + height = Math.max(height, dims.height); + } + } + return new Dimension(500, 500); //width, height); + } + return null; + } + + /** + * This method removes the component from the layout. + * + * @param component The component to remove from the layout. + */ + public void removeLayoutComponent(Component component) + { + for (int i = 0; i < components.length; i++) + { + if (component == components[i]) + { + components[i] = null; + sizes[i] = 0; + } + } + } + + /** + * This method resets the size of Component to the preferred size. + * + * @param index The index of the component to reset. + */ + protected void resetSizeAt(int index) + { + if (components[index] != null) + sizes[index] = getPreferredSizeOfComponent(components[index]); + } + + /** + * This method resets the sizes of all the components. + */ + public void resetToPreferredSizes() + { + for (int i = 0; i < components.length; i++) + resetSizeAt(i); + } + + /** + * This methods sets the bounds of the given component. The width is the + * size. The height is the container size minus the top and bottom + * inset. The x coordinate is the location given. The y coordinate is + * the top inset. + * + * @param c The component to set. + * @param size The width of the component. + * @param location The x coordinate. + * @param insets The insets to use. + * @param containerSize The height of the container. + */ + protected void setComponentToSize(Component c, int size, int location, + Insets insets, Dimension containerSize) + { + int w = size; + int h = containerSize.height - insets.top - insets.bottom; + int x = location; + int y = insets.top; + c.setBounds(x, y, w, h); + } + + /** + * This method stores the given int array as the new sizes array. + * + * @param newSizes The array to use as sizes. + */ + protected void setSizes(int[] newSizes) + { + sizes = newSizes; + } + + /** + * This method determines the size of each component. It should be called + * when a new Layout Manager is created for an existing JSplitPane. + */ + protected void updateComponents() + { + Component left = splitPane.getLeftComponent(); + Component right = splitPane.getRightComponent(); + + if (left != null) + { + components[0] = left; + resetSizeAt(0); + } + if (right != null) + { + components[1] = right; + resetSizeAt(1); + } + components[2] = divider; + resetSizeAt(2); + } + + /** + * This method resizes the left and right components to fit inside the + * JSplitPane when there is extra space. + */ + void distributeExtraSpace() + { + int availSize = getAvailableSize(splitPane.getSize(), + splitPane.getInsets()); + int[] newSizes = new int[3]; + double weight = splitPane.getResizeWeight(); + + int oldLen = sizes[0] + sizes[1]; + + // dividers don't change size. + availSize -= sizes[2] + oldLen; + + int rightAlloc = (int) (availSize * (1 - weight)); + int leftAlloc = availSize - rightAlloc; + + sizes[0] += leftAlloc; + sizes[1] += rightAlloc; + } + + /** + * This method returns the minimum width of the component at the given + * index. + * + * @param index The index to check. + * + * @return The minimum width. + */ + int minimumSizeOfComponent(int index) + { + Dimension dims = components[index].getMinimumSize(); + if (dims != null) + return dims.width; + else + return 0; + } + } //end BasicHorizontalLayoutManager + + /** + * This class is the Layout Manager for the JSplitPane when the orientation + * is VERTICAL_SPLIT. + */ + protected class BasicVerticalLayoutManager + extends BasicHorizontalLayoutManager + { + /** + * This method returns the height of the container minus the top and + * bottom inset. + * + * @param containerSize The size of the container. + * @param insets The insets of the container. + * + * @return The height minus top and bottom inset. + */ + protected int getAvailableSize(Dimension containerSize, Insets insets) + { + return containerSize.height - insets.top - insets.bottom; + } + + /** + * This method returns the top inset. + * + * @param insets The Insets to use. + * + * @return The top inset. + */ + protected int getInitialLocation(Insets insets) + { + return insets.top; + } + + /** + * This method returns the preferred height of the component. + * + * @param c The component to measure. + * + * @return The preferred height of the component. + */ + protected int getPreferredSizeOfComponent(Component c) + { + Dimension dims = c.getPreferredSize(); + if (dims != null) + return dims.height; + return 0; + } + + /** + * This method returns the current height of the component. + * + * @param c The component to measure. + * + * @return The current height of the component. + */ + protected int getSizeOfComponent(Component c) + { + return c.getHeight(); + } + + /** + * This method returns the minimum layout size. The minimum height is the + * sum of all the components' minimum heights. The minimum width is the + * maximum of all the components' minimum widths. + * + * @param container The container to measure. + * + * @return The minimum size. + */ + public Dimension minimumLayoutSize(Container container) + { + if (container instanceof JSplitPane) + { + JSplitPane split = (JSplitPane) container; + Insets insets = container.getInsets(); + int height = 0; + int width = 0; + for (int i = 0; i < components.length; i++) + { + if (components[i] == null) + continue; + Dimension dims = components[i].getMinimumSize(); + if (dims != null) + { + height += dims.height; + width = Math.max(width, dims.width); + } + } + return new Dimension(width, height); + } + return null; + } + + /** + * This method returns the preferred layout size. The preferred height is + * the sum of all the components' preferred heights. The preferred width + * is the maximum of all the components' preferred widths. + * + * @param container The container to measure. + * + * @return The preferred size. + */ + public Dimension preferredLayoutSize(Container container) + { + if (container instanceof JSplitPane) + { + JSplitPane split = (JSplitPane) container; + Insets insets = container.getInsets(); + + int height = 0; + int width = 0; + for (int i = 0; i < components.length; i++) + { + if (components[i] == null) + continue; + Dimension dims = components[i].getPreferredSize(); + if (dims != null) + { + height += dims.height; + width = Math.max(width, dims.width); + } + } + return new Dimension(500, 500); //width, height); + } + return null; + } + + /** + * This method sets the bounds of the given component. The y coordinate is + * the location given. The x coordinate is the left inset. The height is + * the size given. The width is the container size minus the left and + * right inset. + * + * @param c The component to set bounds for. + * @param size The height. + * @param location The y coordinate. + * @param insets The insets to use. + * @param containerSize The container's size. + */ + protected void setComponentToSize(Component c, int size, int location, + Insets insets, Dimension containerSize) + { + int y = location; + int x = insets.left; + int h = size; + int w = containerSize.width - insets.left - insets.right; + + c.setBounds(x, y, w, h); + } + + /** + * This method returns the minimum height of the component at the given + * index. + * + * @param index The index of the component to check. + * + * @return The minimum height of the given component. + */ + int minimumSizeOfComponent(int index) + { + Dimension dims = components[index].getMinimumSize(); + if (dims != null) + return dims.height; + else + return 0; + } + } + + /** + * This class handles FocusEvents from the JComponent. + */ + protected class FocusHandler extends FocusAdapter + { + /** + * This method is called when the JSplitPane gains focus. + * + * @param ev The FocusEvent. + */ + public void focusGained(FocusEvent ev) + { + // FIXME: implement. + } + + /** + * This method is called when the JSplitPane loses focus. + * + * @param ev The FocusEvent. + */ + public void focusLost(FocusEvent ev) + { + // FIXME: implement. + } + } + + /** + * This is a deprecated class. It is supposed to be used for handling down + * and right key presses. + */ + protected class KeyboardDownRightHandler implements ActionListener + { + /** + * This method is called when the down or right keys are pressed. + * + * @param ev The ActionEvent + */ + public void actionPerformed(ActionEvent ev) + { + // FIXME: implement. + } + } + + /** + * This is a deprecated class. It is supposed to be used for handling end + * key presses. + */ + protected class KeyboardEndHandler implements ActionListener + { + /** + * This method is called when the end key is pressed. + * + * @param ev The ActionEvent. + */ + public void actionPerformed(ActionEvent ev) + { + // FIXME: implement. + } + } + + /** + * This is a deprecated class. It is supposed to be used for handling home + * key presses. + */ + protected class KeyboardHomeHandler implements ActionListener + { + /** + * This method is called when the home key is pressed. + * + * @param ev The ActionEvent. + */ + public void actionPerformed(ActionEvent ev) + { + // FIXME: implement. + } + } + + /** + * This is a deprecated class. It is supposed to be used for handling resize + * toggles. + */ + protected class KeyboardResizeToggleHandler implements ActionListener + { + /** + * This method is called when a resize is toggled. + * + * @param ev The ActionEvent. + */ + public void actionPerformed(ActionEvent ev) + { + // FIXME: implement. + } + } + + /** + * This is a deprecated class. It is supposed to be used for handler up and + * left key presses. + */ + protected class KeyboardUpLeftHandler implements ActionListener + { + /** + * This method is called when the left or up keys are pressed. + * + * @param ev The ActionEvent. + */ + public void actionPerformed(ActionEvent ev) + { + // FIXME: implement. + } + } + + /** + * This helper class handles PropertyChangeEvents from the JSplitPane. When + * a property changes, this will update the UI accordingly. + */ + protected class PropertyHandler implements PropertyChangeListener + { + /** + * This method is called whenever one of the JSplitPane's properties + * change. + * + * @param e DOCUMENT ME! + */ + public void propertyChange(PropertyChangeEvent e) + { + if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY)) + { + int newSize = splitPane.getDividerSize(); + int[] tmpSizes = layoutManager.getSizes(); + dividerSize = tmpSizes[2]; + Component left = splitPane.getLeftComponent(); + Component right = splitPane.getRightComponent(); + int newSpace = newSize - tmpSizes[2]; + + tmpSizes[2] = newSize; + + tmpSizes[0] += newSpace / 2; + tmpSizes[1] += newSpace / 2; + + layoutManager.setSizes(tmpSizes); + } + else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY)) + { + int max = layoutManager.getAvailableSize(splitPane.getSize(), + splitPane.getInsets()); + int dividerLoc = getDividerLocation(splitPane); + double prop = ((double) dividerLoc) / max; + + resetLayoutManager(); + if (prop <= 1 && prop >= 0) + splitPane.setDividerLocation(prop); + } + layoutManager.layoutContainer(splitPane); + splitPane.repaint(); + // Don't have to deal with continuous_layout - only + // necessary in dragging modes (and it's checked + // every time you drag there) + // Don't have to deal with resize_weight (as there + // will be no extra space associated with this + // event - the changes to the weighting will + // be taken into account the next time the + // sizes change.) + // Don't have to deal with divider_location + // The method in JSplitPane calls our setDividerLocation + // so we'll know about those anyway. + // Don't have to deal with last_divider_location + // Although I'm not sure why, it doesn't seem to + // have any effect on Sun's JSplitPane. + // one_touch_expandable changes are dealt with + // by our divider. + } + } + + /** The location of the divider when dragging began. */ + protected int beginDragDividerLocation; + + /** The size of the divider while dragging. */ + protected int dividerSize; + + /** The location where the last drag location ended. */ + transient int lastDragLocation = -1; + + /** The distance the divider is moved when moved by keyboard actions. */ protected static int KEYBOARD_DIVIDER_MOVE_OFFSET; - protected JSplitPane splitPane; + /** The divider that divides this JSplitPane. */ protected BasicSplitPaneDivider divider; + + /** The listener that listens for PropertyChangeEvents from the JSplitPane. */ protected PropertyChangeListener propertyChangeListener; + + /** The JSplitPane's focus handler. */ protected FocusListener focusListener; - protected int dividerSize; - protected Component nonContinuousLayoutDivider; - protected boolean draggingHW; - protected int beginDragDividerLocation; - protected KeyStroke upKey; - protected KeyStroke downKey; - protected KeyStroke leftKey; - protected KeyStroke rightKey; - protected KeyStroke homeKey; - protected KeyStroke endKey; - protected KeyStroke dividerResizeToggleKey; - protected ActionListener keyboardUpLeftListener; + + /** Deprecated. The handler for down and right key presses. */ protected ActionListener keyboardDownRightListener; - protected ActionListener keyboardHomeListener; + + /** Deprecated. The handler for end key presses. */ protected ActionListener keyboardEndListener; + + /** Deprecated. The handler for home key presses. */ + protected ActionListener keyboardHomeListener; + + /** Deprecated. The handler for toggling resizes. */ protected ActionListener keyboardResizeToggleListener; - public static ComponentUI createUI(JComponent c) - { - BasicSplitPaneUI newUI; + /** Deprecated. The handler for up and left key presses. */ + protected ActionListener keyboardUpLeftListener; - newUI = new BasicSplitPaneUI(); - newUI.installUI(c); - return newUI; - } + /** The JSplitPane's current layout manager. */ + protected BasicHorizontalLayoutManager layoutManager; + + /** Deprecated. The divider resize toggle key. */ + protected KeyStroke dividerResizeToggleKey; + + /** Deprecated. The down key. */ + protected KeyStroke downKey; + + /** Deprecated. The end key. */ + protected KeyStroke endKey; + + /** Deprecated. The home key. */ + protected KeyStroke homeKey; + + /** Deprecated. The left key. */ + protected KeyStroke leftKey; + + /** Deprecated. The right key. */ + protected KeyStroke rightKey; + + /** Deprecated. The up key. */ + protected KeyStroke upKey; + + /** Set to true when dragging heavy weight components. */ + protected boolean draggingHW; + + /** + * The constraints object used when adding the non-continuous divider to the + * JSplitPane. + */ + protected static String NON_CONTINUOUS_DIVIDER; + + /** The dark divider used when dragging in non-continuous layout mode. */ + protected Component nonContinuousLayoutDivider; + + /** The JSplitPane that this UI draws. */ + protected JSplitPane splitPane; + /** + * Creates a new BasicSplitPaneUI object. + */ public BasicSplitPaneUI() { - propertyChangeListener = createPropertyChangeListener(); - focusListener = createFocusListener(); } - public void installUI(JComponent c) + /** + * This method creates a new BasicSplitPaneUI for the given JComponent. + * + * @param x The JComponent to create a UI for. + * + * @return A new BasicSplitPaneUI. + */ + public static ComponentUI createUI(JComponent x) { + return new BasicSplitPaneUI(); } - protected void installDefaults() + /** + * This method installs the BasicSplitPaneUI for the given JComponent. + * + * @param c The JComponent to install the UI for. + */ + public void installUI(JComponent c) { + if (c instanceof JSplitPane) + { + splitPane = (JSplitPane) c; + installDefaults(); + installListeners(); + installKeyboardActions(); + } } - protected void installListeners() + /** + * This method uninstalls the BasicSplitPaneUI for the given JComponent. + * + * @param c The JComponent to uninstall the UI for. + */ + public void uninstallUI(JComponent c) { + uninstallKeyboardActions(); + uninstallListeners(); + uninstallDefaults(); + + splitPane = null; } - protected void installKeyboardListeners() + /** + * This method installs the defaults given by the Look and Feel. + */ + protected void installDefaults() { + resetLayoutManager(); + divider = createDefaultDivider(); + nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider(); + splitPane.add(divider, JSplitPane.DIVIDER); + + // There is no need to add the nonContinuousLayoutDivider + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + splitPane.setBackground(defaults.getColor("SplitPane.background")); + splitPane.setBorder(defaults.getBorder("SplitPane.border")); + splitPane.setDividerSize(defaults.getInt("SplitPane.dividerSize")); } - protected void installKeyboardActions() + /** + * This method uninstalls the defaults and nulls any objects created during + * install. + */ + protected void uninstallDefaults() { + layoutManager = null; + splitPane.remove(divider); + divider = null; + nonContinuousLayoutDivider = null; + + splitPane.setBackground(null); + splitPane.setBorder(null); } - public void uninstallUI(JComponent c) + /** + * This method installs the listeners needed for this UI to function. + */ + protected void installListeners() { + propertyChangeListener = createPropertyChangeListener(); + focusListener = createFocusListener(); + + splitPane.addPropertyChangeListener(propertyChangeListener); + splitPane.addFocusListener(focusListener); } - protected void uninstallDefaults() + /** + * This method uninstalls all listeners registered for the UI. + */ + protected void uninstallListeners() { + splitPane.removePropertyChangeListener(propertyChangeListener); + splitPane.removeFocusListener(focusListener); + + focusListener = null; + propertyChangeListener = null; } - protected void uninstallListeners() + /** + * This method installs the keyboard actions for the JSplitPane. + */ + protected void installKeyboardActions() { + // FIXME: implement. } + /** + * This method reverses the work done in installKeyboardActions. + */ protected void uninstallKeyboardActions() { + // FIXME: implement. } + /** + * This method creates a new PropertyChangeListener. + * + * @return A new PropertyChangeListener. + */ protected PropertyChangeListener createPropertyChangeListener() { - return null; + return new PropertyHandler(); } + /** + * This method creates a new FocusListener. + * + * @return A new FocusListener. + */ protected FocusListener createFocusListener() { - return null; + return new FocusHandler(); } + /** + * Deprecated. This method creates a new ActionListener for up and left key + * presses. + * + * @return A new ActionListener for up and left keys. + */ protected ActionListener createKeyboardUpLeftListener() { - return null; + return new KeyboardUpLeftHandler(); } + /** + * Deprecated. This method creates a new ActionListener for down and right + * key presses. + * + * @return A new ActionListener for down and right keys. + */ protected ActionListener createKeyboardDownRightListener() { - return null; + return new KeyboardDownRightHandler(); } + /** + * Deprecated. This method creates a new ActionListener for home key + * presses. + * + * @return A new ActionListener for home keys. + */ protected ActionListener createKeyboardHomeListener() { - return null; + return new KeyboardHomeHandler(); } + /** + * Deprecated. This method creates a new ActionListener for end key presses. + * + * @return A new ActionListener for end keys. + */ protected ActionListener createKeyboardEndListener() { - return null; + return new KeyboardEndHandler(); } + /** + * Depcreated. This method creates a new ActionListener for resize toggle + * key events. + * + * @return A new ActionListener for resize toggle keys. + */ protected ActionListener createKeyboardResizeToggleListener() { - return null; + return new KeyboardResizeToggleHandler(); } + /** + * This method returns the orientation of the JSplitPane. + * + * @return The orientation of the JSplitPane. + */ public int getOrientation() { return splitPane.getOrientation(); } + /** + * This method sets the orientation of the JSplitPane. + * + * @param orientation The new orientation of the JSplitPane. + */ public void setOrientation(int orientation) { + splitPane.setOrientation(orientation); } - + /** + * This method returns true if the JSplitPane is using continuous layout. + * + * @return True if the JSplitPane is using continuous layout. + */ public boolean isContinuousLayout() { - return false; + return splitPane.isContinuousLayout(); } + /** + * This method sets the continuous layout property of the JSplitPane. + * + * @param b True if the JsplitPane is to use continuous layout. + */ public void setContinuousLayout(boolean b) { + splitPane.setContinuousLayout(b); } + /** + * This method returns the last location the divider was dragged to. + * + * @return The last location the divider was dragged to. + */ public int getLastDragLocation() { - return 0; + return lastDragLocation; } + /** + * This method sets the last location the divider was dragged to. + * + * @param l The last location the divider was dragged to. + */ public void setLastDragLocation(int l) { + lastDragLocation = l; } - + /** + * This method returns the BasicSplitPaneDivider that divides this + * JSplitPane. + * + * @return The divider for the JSplitPane. + */ public BasicSplitPaneDivider getDivider() { return divider; } - + /** + * This method creates a nonContinuousLayoutDivider for use with the + * JSplitPane in nonContinousLayout mode. The default divider is a gray + * Canvas. + * + * @return The default nonContinousLayoutDivider. + */ protected Component createDefaultNonContinuousLayoutDivider() { - return null; + if (nonContinuousLayoutDivider == null) + { + nonContinuousLayoutDivider = new Canvas(); + nonContinuousLayoutDivider.setBackground(Color.DARK_GRAY); + } + return nonContinuousLayoutDivider; } + /** + * This method sets the component to use as the nonContinuousLayoutDivider. + * + * @param newDivider The component to use as the nonContinuousLayoutDivider. + */ protected void setNonContinuousLayoutDivider(Component newDivider) { - setNonContinuousLayoutDivider(newDivider, true /* false? */); + setNonContinuousLayoutDivider(newDivider, true); } + /** + * This method sets the component to use as the nonContinuousLayoutDivider. + * + * @param newDivider The component to use as the nonContinuousLayoutDivider. + * @param rememberSizes FIXME: document. + */ protected void setNonContinuousLayoutDivider(Component newDivider, boolean rememberSizes) { + // FIXME: use rememberSizes for something nonContinuousLayoutDivider = newDivider; } + /** + * This method returns the nonContinuousLayoutDivider. + * + * @return The nonContinuousLayoutDivider. + */ public Component getNonContinuousLayoutDivider() { return nonContinuousLayoutDivider; } + /** + * This method returns the JSplitPane that this BasicSplitPaneUI draws. + * + * @return The JSplitPane. + */ public JSplitPane getSplitPane() { return splitPane; } + /** + * This method creates the divider used normally with the JSplitPane. + * + * @return The default divider. + */ public BasicSplitPaneDivider createDefaultDivider() { - return null; + if (divider == null) + divider = new BasicSplitPaneDivider(this); + return divider; } + /** + * This method is called when JSplitPane's resetToPreferredSizes is called. + * It resets the sizes of all components in the JSplitPane. + * + * @param jc The JSplitPane to reset. + */ public void resetToPreferredSizes(JSplitPane jc) { + layoutManager.resetToPreferredSizes(); } + /** + * This method sets the location of the divider. + * + * @param jc The JSplitPane to set the divider location in. + * @param location The new location of the divider. + */ public void setDividerLocation(JSplitPane jc, int location) { + setLastDragLocation(getDividerLocation(splitPane)); + splitPane.setLastDividerLocation(getDividerLocation(splitPane)); + int[] tmpSizes = layoutManager.getSizes(); + tmpSizes[0] = location + - layoutManager.getInitialLocation(splitPane.getInsets()); + tmpSizes[1] = layoutManager.getAvailableSize(splitPane.getSize(), + splitPane.getInsets()) + - tmpSizes[0] - tmpSizes[1]; + Point p = divider.getLocation(); + +// if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) + // setLastDragLocation(p.x); +// else +// setLastDragLocation(p.y); + layoutManager.setSizes(tmpSizes); + layoutManager.layoutContainer(splitPane); + + splitPane.repaint(); } + /** + * This method returns the location of the divider. + * + * @param jc The JSplitPane to retrieve the location for. + * + * @return The location of the divider. + */ public int getDividerLocation(JSplitPane jc) { - return 0; + return layoutManager.sizes[0] + + layoutManager.getInitialLocation(splitPane.getInsets()); } + /** + * This method returns the smallest value possible for the location of the + * divider. + * + * @param jc The JSplitPane. + * + * @return The minimum divider location. + */ public int getMinimumDividerLocation(JSplitPane jc) { - return 0; + int value = layoutManager.getInitialLocation(jc.getInsets()); + if (layoutManager.components[0] != null) + value += layoutManager.minimumSizeOfComponent(0); + return value; } + /** + * This method returns the largest value possible for the location of the + * divider. + * + * @param jc The JSplitPane. + * + * @return The maximum divider location. + */ public int getMaximumDividerLocation(JSplitPane jc) { - return 0; + int value = layoutManager.getInitialLocation(jc.getInsets()) + + layoutManager.getAvailableSize(jc.getSize(), jc.getInsets()) + - splitPane.getDividerSize(); + if (layoutManager.components[1] != null) + value -= layoutManager.minimumSizeOfComponent(1); + return value; } + /** + * This method is called after the children of the JSplitPane are painted. + * + * @param jc The JSplitPane. + * @param g The Graphics object to paint with. + */ public void finishedPaintingChildren(JSplitPane jc, Graphics g) { + if (! splitPane.isContinuousLayout() && nonContinuousLayoutDivider != null + && nonContinuousLayoutDivider.isVisible()) + javax.swing.SwingUtilities.paintComponent(g, nonContinuousLayoutDivider, + null, + nonContinuousLayoutDivider + .getBounds()); } + /** + * This method is called to paint the JSplitPane. + * + * @param g The Graphics object to paint with. + * @param jc The JSplitPane to paint. + */ public void paint(Graphics g, JComponent jc) { + // Do nothing. All the painting is handled by children. } + /** + * This method returns the preferred size of the JSplitPane. + * + * @param jc The JSplitPane. + * + * @return The preferred size of the JSplitPane. + */ public Dimension getPreferredSize(JComponent jc) { - return null; + return layoutManager.preferredLayoutSize((Container) jc); } + /** + * This method returns the minimum size of the JSplitPane. + * + * @param jc The JSplitPane. + * + * @return The minimum size of the JSplitPane. + */ public Dimension getMinimumSize(JComponent jc) { - return null; + return layoutManager.minimumLayoutSize((Container) jc); } + /** + * This method returns the maximum size of the JSplitPane. + * + * @param jc The JSplitPane. + * + * @return The maximum size of the JSplitPane. + */ public Dimension getMaximumSize(JComponent jc) { - return null; + return layoutManager.maximumLayoutSize((Container) jc); } + /** + * This method returns the border insets of the current border. + * + * @param jc The JSplitPane. + * + * @return The current border insets. + */ public Insets getInsets(JComponent jc) { - return new Insets(0, 0, 0, 0); + return splitPane.getBorder().getBorderInsets(splitPane); } + /** + * This method resets the current layout manager. The type of layout manager + * is dependent on the current orientation. + */ protected void resetLayoutManager() { + if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) + layoutManager = new BasicHorizontalLayoutManager(); + else + layoutManager = new BasicVerticalLayoutManager(); + layoutManager.invalidateLayout(splitPane); + layoutManager.updateComponents(); + getSplitPane().setLayout(layoutManager); + + // invalidating by itself does not invalidate the layout. + getSplitPane().invalidate(); } + /** + * This method is called when dragging starts. It resets lastDragLocation + * and dividerSize. + */ protected void startDragging() { + dividerSize = divider.getDividerSize(); + setLastDragLocation(-1); + + if (! splitPane.getLeftComponent().isLightweight() + || ! splitPane.getRightComponent().isLightweight()) + draggingHW = true; + + if (splitPane.isContinuousLayout()) + nonContinuousLayoutDivider.setVisible(false); + else + { + nonContinuousLayoutDivider.setVisible(true); + nonContinuousLayoutDivider.setBounds(divider.getBounds()); + } + splitPane.invalidate(); + splitPane.repaint(); } + /** + * This method is called whenever the divider is dragged. If the JSplitPane + * is in continuousLayout mode, the divider needs to be moved and the + * JSplitPane needs to be laid out. + * + * @param location The new location of the divider. + */ protected void dragDividerTo(int location) { + location = validLocation(location); + if (beginDragDividerLocation == -1) + beginDragDividerLocation = location; + + if (splitPane.isContinuousLayout()) + splitPane.setDividerLocation(location); + else + { + Point p = nonContinuousLayoutDivider.getLocation(); + if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) + p.x = location; + else + p.y = location; + nonContinuousLayoutDivider.setLocation(p); + } + setLastDragLocation(location); + splitPane.repaint(); } + /** + * This method is called when the dragging is finished. + * + * @param location The location where the drag finished. + */ protected void finishDraggingTo(int location) { + if (nonContinuousLayoutDivider != null) + nonContinuousLayoutDivider.setVisible(false); + draggingHW = false; + location = validLocation(location); + dragDividerTo(location); + splitPane.setDividerLocation(location); + splitPane.setLastDividerLocation(beginDragDividerLocation); + beginDragDividerLocation = -1; + splitPane.repaint(); } + /** + * Deprecated. This method returns the width of one of the sides of the + * divider's border. + * + * @return The width of one side of the divider's border. + */ protected int getDividerBorderSize() { - return 0; + if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) + return divider.getBorder().getBorderInsets(divider).left; + else + return divider.getBorder().getBorderInsets(divider).top; + } + + /** + * This is a helper method that returns a valid location for the divider + * when dragging. + * + * @param location The location to check. + * + * @return A valid location. + */ + private int validLocation(int location) + { + if (location < getMinimumDividerLocation(splitPane)) + return getMinimumDividerLocation(splitPane); + if (location > getMaximumDividerLocation(splitPane)) + return getMaximumDividerLocation(splitPane); + return location; } } diff --git a/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 4dcec822537..a0100558be5 100644 --- a/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -223,10 +223,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { Component visible = getVisibleComponent(); Insets insets = getContentBorderInsets(tabPane.getTabPlacement()); - visible.setBounds(contentRect.x + insets.left, - contentRect.y + insets.top, - contentRect.width - insets.left - insets.right, - contentRect.height - insets.top - insets.bottom); + if (visible != null) + visible.setBounds(contentRect.x + insets.left, + contentRect.y + insets.top, + contentRect.width - insets.left - insets.right, + contentRect.height - insets.top - insets.bottom); } } @@ -1510,6 +1511,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants tabPane.setFont(defaults.getFont("TabbedPane.font")); tabPane.setForeground(defaults.getColor("TabbedPane.foreground")); tabPane.setBackground(defaults.getColor("TabbedPane.background")); + tabPane.setOpaque(true); highlight = defaults.getColor("TabbedPane.highlight"); lightHighlight = defaults.getColor("TabbedPane.lightHighlight"); @@ -1790,7 +1792,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants // FIXME: Paint little folding corner and jagged edge clipped tab. if (icon != null) paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected); - if (title == null || ! title.equals("")) + if (title != null && ! title.equals("")) paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title, textRect, isSelected); } diff --git a/libjava/javax/swing/plaf/basic/BasicViewportUI.java b/libjava/javax/swing/plaf/basic/BasicViewportUI.java index 463865c5be9..c1adad1853c 100644 --- a/libjava/javax/swing/plaf/basic/BasicViewportUI.java +++ b/libjava/javax/swing/plaf/basic/BasicViewportUI.java @@ -47,6 +47,7 @@ import java.awt.Rectangle; import java.awt.image.ImageObserver; import javax.swing.JComponent; import javax.swing.JViewport; +import javax.swing.ViewportLayout; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.ComponentUI; @@ -70,7 +71,8 @@ public class BasicViewportUI extends ViewportUI } void installDefaults(JComponent c) - { + { + c.setOpaque(true); } void uninstallDefaults(JComponent c) @@ -100,6 +102,7 @@ public class BasicViewportUI extends ViewportUI public void installUI(JComponent c) { super.installUI(c); + c.setLayout(new ViewportLayout()); installListeners(c); } @@ -111,9 +114,8 @@ public class BasicViewportUI extends ViewportUI public Dimension getPreferredSize(JComponent c) { - // FIXME: integrate with Scrollable - Dimension d = new Dimension(100,100); - return d; + // let the ViewportLayout decide + return null; } public void paint(Graphics g, JComponent c) @@ -129,6 +131,12 @@ public class BasicViewportUI extends ViewportUI Rectangle viewBounds = view.getBounds(); Rectangle portBounds = v.getBounds(); + if (viewBounds.width == 0 + || viewBounds.height == 0 + || portBounds.width == 0 + || portBounds.height == 0) + return; + if (backingStoreImage == null || backingStoreWidth != viewBounds.width || backingStoreHeight != viewBounds.height) |