aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@redhat.com>2004-01-22 09:54:19 +0000
committerGraydon Hoare <graydon@gcc.gnu.org>2004-01-22 09:54:19 +0000
commitca3bb0c283932ab6342cac597f2a9e04e2b0c1b2 (patch)
tree0f7e79b1c6afb9ecf4b3d15908999b740f7cd2ef /libjava
parent1fd05073984ebdf3e087613adce163587b33e1e5 (diff)
downloadgcc-ca3bb0c283932ab6342cac597f2a9e04e2b0c1b2.zip
gcc-ca3bb0c283932ab6342cac597f2a9e04e2b0c1b2.tar.gz
gcc-ca3bb0c283932ab6342cac597f2a9e04e2b0c1b2.tar.bz2
2004-01-22 Graydon Hoare <graydon@redhat.com>
* gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java: * gnu/java/awt/peer/gtk/GdkGlyphVector.java: Predicate static initialization on GtkToolkit.useGraphics2D(). * java/awt/Component.java (processPaintEvent): Consume event. * javax/swing/AbstractButton.java: Reimplement, document. * javax/swing/DefaultButtonModel.java: Reimplement, document. * javax/swing/JComponent.java (paint): Use double buffer. (listenerList): Enable member. * javax/swing/ToggleButtonModel.java: Remove incorrect constructor. * javax/swing/JToggleButton.java (JToggleButton): Modify model constructor. * javax/swing/SwingUtilities.java (layoutCompoundLabel): Adjust arithmetic. * javax/swing/plaf/basic/BasicButtonUI.java: Reimplement, document. * javax/swing/plaf/basic/BasicGraphicsUtils.java (getPreferredButtonSize): Include margins in calculation. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals): Receive up events from subordinate layout component. From-SVN: r76344
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog22
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java2
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java2
-rw-r--r--libjava/java/awt/Component.java1
-rw-r--r--libjava/javax/swing/AbstractButton.java1842
-rw-r--r--libjava/javax/swing/DefaultButtonModel.java459
-rw-r--r--libjava/javax/swing/JComponent.java37
-rw-r--r--libjava/javax/swing/JToggleButton.java2
-rw-r--r--libjava/javax/swing/SwingUtilities.java8
-rw-r--r--libjava/javax/swing/ToggleButtonModel.java5
-rw-r--r--libjava/javax/swing/plaf/basic/BasicButtonUI.java349
-rw-r--r--libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java10
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c13
13 files changed, 2150 insertions, 602 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 4b38db9..6f307f1 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,25 @@
+2004-01-22 Graydon Hoare <graydon@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java:
+ * gnu/java/awt/peer/gtk/GdkGlyphVector.java:
+ Predicate static initialization on GtkToolkit.useGraphics2D().
+ * java/awt/Component.java (processPaintEvent): Consume event.
+ * javax/swing/AbstractButton.java: Reimplement, document.
+ * javax/swing/DefaultButtonModel.java: Reimplement, document.
+ * javax/swing/JComponent.java (paint): Use double buffer.
+ (listenerList): Enable member.
+ * javax/swing/ToggleButtonModel.java: Remove incorrect constructor.
+ * javax/swing/JToggleButton.java
+ (JToggleButton): Modify model constructor.
+ * javax/swing/SwingUtilities.java
+ (layoutCompoundLabel): Adjust arithmetic.
+ * javax/swing/plaf/basic/BasicButtonUI.java: Reimplement, document.
+ * javax/swing/plaf/basic/BasicGraphicsUtils.java
+ (getPreferredButtonSize): Include margins in calculation.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+ (Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals):
+ Receive up events from subordinate layout component.
+
2004-01-21 Thomas Fitzsimmons <fitzsim@redhat.com>
* java/awt/Component.java (show): Set visible to true before
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
index ca26289..8f96e15 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
@@ -70,6 +70,8 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer
{
System.loadLibrary("gtkpeer");
}
+
+ if (GtkToolkit.useGraphics2D ())
initStaticState ();
}
native static void initStaticState ();
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java
index 0ba4539..076a90e 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java
@@ -60,6 +60,8 @@ public class GdkGlyphVector extends GlyphVector
{
System.loadLibrary("gtkpeer");
}
+
+ if (GtkToolkit.useGraphics2D ())
initStaticState ();
}
native static void initStaticState ();
diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java
index 94b74a6..b440c51 100644
--- a/libjava/java/awt/Component.java
+++ b/libjava/java/awt/Component.java
@@ -4252,6 +4252,7 @@ p * <li>the set of backward traversal keys
default:
throw new IllegalArgumentException("unknown paint event");
}
+ event.consume ();
}
finally
{
diff --git a/libjava/javax/swing/AbstractButton.java b/libjava/javax/swing/AbstractButton.java
index d44d977..e9751fa 100644
--- a/libjava/javax/swing/AbstractButton.java
+++ b/libjava/javax/swing/AbstractButton.java
@@ -1,5 +1,5 @@
/* AbstractButton.java -- Provides basic button functionality.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,9 +35,10 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package javax.swing;
+import java.awt.AWTEvent;
+import java.awt.AWTEventMulticaster;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
@@ -51,11 +52,15 @@ import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.io.Serializable;
+import java.util.Vector;
+import java.util.EventListener;
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleIcon;
-import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleRelationSet;
+import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
import javax.swing.event.ChangeEvent;
@@ -63,739 +68,1734 @@ import javax.swing.event.ChangeListener;
import javax.swing.plaf.ButtonUI;
import javax.swing.text.AttributeSet;
+
/**
- * Provides basic button functionality
+ * <p>The purpose of this class is to serve as a facade over a number of
+ * classes which collectively represent the semantics of a button: the
+ * button's model, its listeners, its action, and its look and feel. Some
+ * parts of a button's state are stored explicitly in this class, other
+ * parts are delegates to the model. Some methods related to buttons are
+ * implemented in this class, other methods pass through to the current
+ * model or look and feel.</p>
+ *
+ * <p>Furthermore this class is supposed to serve as a base class for
+ * several kinds of buttons with similar but non-identical semantics:
+ * toggle buttons (radio buttons and checkboxes), simple "push" buttons,
+ * menu items.</p>
+ *
+ * <p>Buttons have many properties, some of which are stored in this class
+ * while others are delegated to the button's model. The following properties
+ * are available:</p>
+ *
+ * <table>
+ * <tr><th>Property </th><th>Stored in</th><th>Bound?</th></tr>
+ *
+ * <tr><td>action </td><td>button</td> <td>no</td></tr>
+ * <tr><td>actionCommand </td><td>model</td> <td>no</td></tr>
+ * <tr><td>borderPainted </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>contentAreaFilled </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>disabledIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>disabledSelectedIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr>
+ * <tr><td>enabled </td><td>model</td> <td>no</td></tr>
+ * <tr><td>focusPainted </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>horizontalAlignment </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>icon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>iconTextGap </td><td>button</td> <td>no</td></tr>
+ * <tr><td>label (same as text) </td><td>model</td> <td>yes</td></tr>
+ * <tr><td>margin </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>multiClickThreshold </td><td>button</td> <td>no</td></tr>
+ * <tr><td>pressedIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverEnabled </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>rolloverSelectedIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>selected </td><td>model</td> <td>no</td></tr>
+ * <tr><td>selectedIcon </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>selectedObjects </td><td>button</td> <td>no</td></tr>
+ * <tr><td>text </td><td>model</td> <td>yes</td></tr>
+ * <tr><td>UI </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>verticalAlignment </td><td>button</td> <td>yes</td></tr>
+ * <tr><td>verticalTextPosition </td><td>button</td> <td>yes</td></tr>
+ *
+ * </table>
+ *
+ * <p>The various behavioral aspects of these properties follows:</p>
*
- * @author Ronald Veldema (rveldema@cs.vu.nl)
+ * <ul>
+ *
+ * <li>When non-bound properties stored in the button change, the button
+ * fires ChangeEvents to its ChangeListeners.</li>
+ *
+ * <li>When bound properties stored in the button change, the button fires
+ * PropertyChangeEvents to its PropertyChangeListeners</li>
+ *
+ * <li>If any of the model's properties change, it fires a ChangeEvent to
+ * its ChangeListeners, which include the button.</li>
+ *
+ * <li>If the button receives a ChangeEvent from its model, it will
+ * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's
+ * "source" property set to refer to the button, rather than the model. The
+ * the button will request a repaint, to paint its updated state.</li>
+ *
+ * <li>If the model's "selected" property changes, the model will fire an
+ * ItemEvent to its ItemListeners, which include the button, in addition to
+ * the ChangeEvent which models the property change. The button propagates
+ * ItemEvents directly to its ItemListeners.</li>
+ *
+ * <li>If the model's armed and pressed properties are simultaneously
+ * <code>true</code>, the model will fire an ActionEvent to its
+ * ActionListeners, which include the button. The button will propagate
+ * this ActionEvent to its ActionListeners, with the ActionEvent's "source"
+ * property set to refer to the button, rather than the model.</li>
+ *
+ * </ul>
+ *
+ * @author Ronald Veldema (rveldema&064;cs.vu.nl)
+ * @author Graydon Hoare (graydon&064;redhat.com)
*/
+
public abstract class AbstractButton extends JComponent
implements ItemSelectable, SwingConstants
{
- Icon default_icon, pressed_button, disabled_button,
- selected_button, disabled_selected_button, current_icon;
+ /** The icon displayed by default. */
+ Icon default_icon;
+
+ /** The icon displayed when the button is pressed. */
+ Icon pressed_icon;
+
+ /** The icon displayed when the button is disabled. */
+ Icon disabled_icon;
+
+ /** The icon displayed when the button is selected. */
+ Icon selected_icon;
+
+ /** The icon displayed when the button is selected but disabled. */
+ Icon disabled_selected_icon;
+
+ /** The icon displayed when the button is rolled over. */
+ Icon rollover_icon;
+
+ /** The icon displayed when the button is selected and rolled over. */
+ Icon rollover_selected_icon;
+
+ /** The icon currently displayed. */
+ Icon current_icon;
+
+ /** The text displayed in the button. */
String text;
+ /** The vertical alignment of the button's text and icon. */
int vert_align = CENTER;
+
+ /** The horizontal alignment of the button's text and icon. */
int hori_align = CENTER;
+
+ /** The horizontal position of the button's text relative to its icon. */
int hori_text_pos = CENTER;
+
+ /** The vertical position of the button's text relative to its icon. */
int vert_text_pos = CENTER;
- boolean paint_border = true, paint_focus;
- Action action_taken;
+ /** Whether or not the button paints its border. */
+ boolean paint_border = true;
+
+ /** Whether or not the button paints its focus state. */
+ boolean paint_focus;
+
+ /** Whether or not the button fills its content area. */
+ boolean content_area_filled;
+
+ /** The action taken when the button is clicked. */
+ Action action;
+
+ /** The button's current state. */
ButtonModel model;
+
+ /** The margin between the button's border and its label. */
Insets margin;
- public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted";
+ /** a hint to the look and feel class, suggesting which character in the
+ * button's label should be underlined when drawing the label. */
+ int mnemonicIndex;
- /**
- * AccessibleAbstractButton
- */
- protected abstract class AccessibleAbstractButton
- extends AccessibleJComponent
- implements AccessibleAction, AccessibleValue, AccessibleText {
+ /** Listener the button uses to receive ActionEvents from its model. */
+ ActionListener actionListener;
- /**
- * Constructor AccessibleAbstractButton
- * @param component TODO
- */
- protected AccessibleAbstractButton(AbstractButton component) {
- super(component);
- // TODO
- } // AccessibleAbstractButton()
+ /** Listener the button uses to receive ItemEvents from its model. */
+ ItemListener itemListener;
+
+ /** Listener the button uses to receive ChangeEvents from its model. */
+ ChangeListener changeListener;
+
+ /** Listener the button uses to receive PropertyChangeEvents from its
+ Action. */
+ PropertyChangeListener actionPropertyChangeListener;
+
+ /** Fired in a PropertyChangeEvent when the "borderPainted" property changes. */
+ public static String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
+
+ /** Fired in a PropertyChangeEvent when the "contentAreaFilled" property changes. */
+ public static String CONTENT_AREA_FILLED_CHANGED_PROPERTY = "contentAreaFilled";
+
+ /** Fired in a PropertyChangeEvent when the "disabledIcon" property changes. */
+ public static String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon";
+
+ /** Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property changes. */
+ public static String DISABLED_SELECTED_ICON_CHANGED_PROPERTY = "disabledSelectedIcon";
+
+ /** Fired in a PropertyChangeEvent when the "focusPainted" property changes. */
+ public static String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted";
+
+ /** Fired in a PropertyChangeEvent when the "horizontalAlignment" property changes. */
+ public static String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY = "horizontalAlignment";
+
+ /** Fired in a PropertyChangeEvent when the "horizontalTextPosition" property changes. */
+ public static String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY = "horizontalTextPosition";
+
+ /** Fired in a PropertyChangeEvent when the "icon" property changes. */
+ public static String ICON_CHANGED_PROPERTY = "icon";
+
+ /** Fired in a PropertyChangeEvent when the "margin" property changes. */
+ public static String MARGIN_CHANGED_PROPERTY = "margin";
+
+ /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */
+ public static String MNEMONIC_CHANGED_PROPERTY = "mnemonic";
+
+ /** Fired in a PropertyChangeEvent when the "model" property changes. */
+ public static String MODEL_CHANGED_PROPERTY = "model";
+
+ /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */
+ public static String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon";
+
+ /** Fired in a PropertyChangeEvent when the "rolloverEnabled" property changes. */
+ public static String ROLLOVER_ENABLED_CHANGED_PROPERTY = "rolloverEnabled";
+
+ /** Fired in a PropertyChangeEvent when the "rolloverIcon" property changes. */
+ public static String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon";
+
+ /** Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property changes. */
+ public static String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY = "rolloverSelectedIcon";
+
+ /** Fired in a PropertyChangeEvent when the "selectedIcon" property changes. */
+ public static String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon";
+
+ /** Fired in a PropertyChangeEvent when the "text" property changes. */
+ public static String TEXT_CHANGED_PROPERTY = "text";
+
+ /** Fired in a PropertyChangeEvent when the "verticalAlignment" property changes. */
+ public static String VERTICAL_ALIGNMENT_CHANGED_PROPERTY = "verticalAlignment";
+
+ /** Fired in a PropertyChangeEvent when the "verticalTextPosition" property changes. */
+ public static String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY = "verticalTextPosition";
/**
- * getAccessibleStateSet
- * @returns AccessibleStateSet
+ * A Java Accessibility extension of the AbstractButton.
*/
- public AccessibleStateSet getAccessibleStateSet() {
+ protected abstract class AccessibleAbstractButton
+ extends AccessibleJComponent implements AccessibleAction, AccessibleValue,
+ AccessibleText
+ {
+ protected AccessibleAbstractButton(JComponent c)
+ {
+ super(c);
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
return null; // TODO
- } // getAccessibleStateSet()
+ }
- /**
- * getAccessibleName
- * @returns String
- */
- public String getAccessibleName() {
+ public String getAccessibleName()
+ {
return null; // TODO
- } // getAccessibleName()
+ }
- /**
- * getAccessibleIcon
- * @returns AccessibleIcon[]
- */
- public AccessibleIcon[] getAccessibleIcon() {
+ public AccessibleIcon[] getAccessibleIcon()
+ {
return null; // TODO
- } // getAccessibleIcon()
+ }
- /**
- * getAccessibleRelationSet
- * @returns AccessibleRelationSet
- */
- public AccessibleRelationSet getAccessibleRelationSet() {
+ public AccessibleRelationSet getAccessibleRelationSet()
+ {
return null; // TODO
- } // getAccessibleRelationSet()
+ }
- /**
- * getAccessibleAction
- * @returns AccessibleAction
- */
- public AccessibleAction getAccessibleAction() {
+ public AccessibleAction getAccessibleAction()
+ {
return null; // TODO
- } // getAccessibleAction()
+ }
- /**
- * getAccessibleValue
- * @returns AccessibleValue
- */
- public AccessibleValue getAccessibleValue() {
+ public AccessibleValue getAccessibleValue()
+ {
return null; // TODO
- } // getAccessibleValue()
+ }
- /**
- * getAccessibleActionCount
- * @returns int
- */
- public int getAccessibleActionCount() {
+ public int getAccessibleActionCount()
+ {
return 0; // TODO
- } // getAccessibleActionCount()
+ }
- /**
- * getAccessibleActionDescription
- * @param value0 TODO
- * @returns String
- */
- public String getAccessibleActionDescription(int value0) {
+ public String getAccessibleActionDescription(int value0)
+ {
return null; // TODO
- } // getAccessibleActionDescription()
+ }
- /**
- * doAccessibleAction
- * @param value0 TODO
- * @returns boolean
- */
- public boolean doAccessibleAction(int value0) {
+ public boolean doAccessibleAction(int value0)
+ {
return false; // TODO
- } // doAccessibleAction()
+ }
- /**
- * getCurrentAccessibleValue
- * @returns Number
- */
- public Number getCurrentAccessibleValue() {
+ public Number getCurrentAccessibleValue()
+ {
return null; // TODO
- } // getCurrentAccessibleValue()
+ }
- /**
- * setCurrentAccessibleValue
- * @param value0 TODO
- * @returns boolean
- */
- public boolean setCurrentAccessibleValue(Number value0) {
+ public boolean setCurrentAccessibleValue(Number value0)
+ {
return false; // TODO
- } // setCurrentAccessibleValue()
+ }
- /**
- * getMinimumAccessibleValue
- * @returns Number
- */
- public Number getMinimumAccessibleValue() {
+ public Number getMinimumAccessibleValue()
+ {
return null; // TODO
- } // getMinimumAccessibleValue()
+ }
- /**
- * getMaximumAccessibleValue
- * @returns Number
- */
- public Number getMaximumAccessibleValue() {
+ public Number getMaximumAccessibleValue()
+ {
return null; // TODO
- } // getMaximumAccessibleValue()
+ }
- /**
- * getAccessibleText
- * @returns AccessibleText
- */
- public AccessibleText getAccessibleText() {
+ public AccessibleText getAccessibleText()
+ {
return null; // TODO
- } // getAccessibleText()
+ }
- /**
- * getIndexAtPoint
- * @param value0 TODO
- * @returns int
- */
- public int getIndexAtPoint(Point value0) {
+ public int getIndexAtPoint(Point value0)
+ {
return 0; // TODO
- } // getIndexAtPoint()
+ }
- /**
- * getCharacterBounds
- * @param value0 TODO
- * @returns Rectangle
- */
- public Rectangle getCharacterBounds(int value0) {
+ public Rectangle getCharacterBounds(int value0)
+ {
return null; // TODO
- } // getCharacterBounds()
+ }
- /**
- * getCharCount
- * @returns int
- */
- public int getCharCount() {
+ public int getCharCount()
+ {
return 0; // TODO
- } // getCharCount()
+ }
- /**
- * getCaretPosition
- * @returns int
- */
- public int getCaretPosition() {
+ public int getCaretPosition()
+ {
return 0; // TODO
- } // getCaretPosition()
+ }
- /**
- * getAtIndex
- * @param value0 TODO
- * @param value1 TODO
- * @returns String
- */
- public String getAtIndex(int value0, int value1) {
+ public String getAtIndex(int value0, int value1)
+ {
return null; // TODO
- } // getAtIndex()
+ }
- /**
- * getAfterIndex
- * @param value0 TODO
- * @param value1 TODO
- * @returns String
- */
- public String getAfterIndex(int value0, int value1) {
+ public String getAfterIndex(int value0, int value1)
+ {
return null; // TODO
- } // getAfterIndex()
+ }
- /**
- * getBeforeIndex
- * @param value0 TODO
- * @param value1 TODO
- * @returns String
- */
- public String getBeforeIndex(int value0, int value1) {
+ public String getBeforeIndex(int value0, int value1)
+ {
return null; // TODO
- } // getBeforeIndex()
+ }
- /**
- * getCharacterAttribute
- * @param value0 TODO
- * @returns AttributeSet
- */
- public AttributeSet getCharacterAttribute(int value0) {
+ public AttributeSet getCharacterAttribute(int value0)
+ {
return null; // TODO
- } // getCharacterAttribute()
+ }
- /**
- * getSelectionStart
- * @returns int
- */
- public int getSelectionStart() {
+ public int getSelectionStart()
+ {
return 0; // TODO
- } // getSelectionStart()
+ }
- /**
- * getSelectionEnd
- * @returns int
- */
- public int getSelectionEnd() {
+ public int getSelectionEnd()
+ {
return 0; // TODO
- } // getSelectionEnd()
-
- /**
- * getSelectedText
- * @returns String
- */
- public String getSelectedText() {
- return null; // TODO
- } // getSelectedText()
-
- /**
- * getTextRectangle
- * @returns Rectangle
- */
- private Rectangle getTextRectangle() {
- return null; // TODO
- } // getTextRectangle()
-
-
- } // AccessibleAbstractButton
-
+ }
- static private class JFocusListener implements FocusListener
+ public String getSelectedText()
{
- AbstractButton c;
+ return null; // TODO
+ }
- JFocusListener(AbstractButton c)
+ private Rectangle getTextRectangle()
{
- this.c = c;
+ return null; // TODO
+ }
}
- public void focusLost(FocusEvent event)
+ /**
+ * Helper class used to subscribe to FocusEvents received by the button.
+ */
+ private class ButtonFocusListener implements FocusListener
{
- c.getModel().setArmed(false);
-
- System.out.println("LOST FOCUS");
- if (c.isFocusPainted())
+ /**
+ * Possibly repaint the model in response to loss of focus.
+ *
+ * @param event The loss-of-focus event
+ */
+ public void focusLost(FocusEvent event)
{
- c.repaint();
- }
+ if (AbstractButton.this.isFocusPainted())
+ AbstractButton.this.repaint();
}
+
+ /**
+ * Possibly repaint the button in response to acquisition of focus.
+ *
+ * @param event The gained-focus event
+ */
public void focusGained(FocusEvent event)
{
- System.out.println("GAIN FOCUS");
+ if (AbstractButton.this.isFocusPainted())
+ AbstractButton.this.repaint();
}
}
+ /**
+ * Creates a new AbstractButton object.
+ */
AbstractButton()
{
this("",null);
}
- AbstractButton(String text,
- Icon icon)
+ /**
+ * Creates a new AbstractButton object.
+ *
+ * @param txt Value to use for the button's "text" property
+ * @param icon Value to use for the button's "defaultIcon" property
+ */
+ AbstractButton(String txt, Icon icon)
{
- this.text = text;
- setIcon(icon);
+ text = txt;
+ default_icon = icon;
+ model = new DefaultButtonModel();
+ actionListener = createActionListener();
+ changeListener = createChangeListener();
+ itemListener = createItemListener();
+
+ model.addActionListener(actionListener);
+ model.addChangeListener(changeListener);
+ model.addItemListener(itemListener);
setAlignmentX(LEFT_ALIGNMENT);
setAlignmentY(CENTER_ALIGNMENT);
-
- addFocusListener( new JFocusListener(this) );
-
- setModel(new DefaultButtonModel(this));
-
- updateUI(); // get a proper ui
+ addFocusListener(new ButtonFocusListener());
+ updateUI();
}
+ /**
+ * Get the model the button is currently using.
+ *
+ * @return The current model
+ */
public ButtonModel getModel()
- { return model; }
+ {
+ return model;
+ }
+ /**
+ * Set the model the button is currently using. This un-registers all
+ * listeners associated with the current model, and re-registers them
+ * with the new model.
+ *
+ * @param newModel The new model
+ */
public void setModel(ButtonModel newModel)
- { model = newModel; }
+ {
+ if (newModel == model)
+ return;
+ if (model != null)
+ {
+ model.removeActionListener(actionListener);
+ model.removeChangeListener(changeListener);
+ model.removeItemListener(itemListener);
+ }
+ ButtonModel old = model;
+ model = newModel;
+ if (model != null)
+ {
+ model.addActionListener(actionListener);
+ model.addChangeListener(changeListener);
+ model.addItemListener(itemListener);
+ }
+ firePropertyChange(MODEL_CHANGED_PROPERTY, old, model);
+ revalidate();
+ repaint();
+ }
+
+ /**
+ * Get the action command string for this button's model.
+ *
+ * @return The current action command string from the button's model
+ */
public String getActionCommand()
- { return getModel().getActionCommand(); }
+ {
+ return getModel().getActionCommand();
+ }
+ /**
+ * Set the action command string for this button's model.
+ *
+ * @param aCommand The new action command string to set in the button's
+ * model.
+ */
public void setActionCommand(String aCommand)
- { getModel().setActionCommand(aCommand); }
+ {
+ getModel().setActionCommand(aCommand);
+ }
+ /**
+ * Adds an ActionListener to the button's listener list. When the
+ * button's model is clicked it fires an ActionEvent, and these
+ * listeners will be called.
+ *
+ * @param l The new listener to add
+ */
public void addActionListener(ActionListener l)
- { getModel().addActionListener(l); }
+ {
+ listenerList.add(ActionListener.class, l);
+ }
+ /**
+ * Removes an ActionListener from the button's listener list.
+ *
+ * @param l The listener to remove
+ */
public void removeActionListener(ActionListener l)
- { getModel().removeActionListener(l); }
+ {
+ listenerList.remove(ActionListener.class, l);
+ }
+ /**
+ * Adds an ItemListener to the button's listener list. When the button's
+ * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER
+ * or SELECTED) it fires an ItemEvent, and these listeners will be
+ * called.
+ *
+ * @param l The new listener to add
+ */
+ public void addItemListener(ItemListener l)
+ {
+ listenerList.add(ItemListener.class, l);
+ }
+
+ /**
+ * Removes an ItemListener from the button's listener list.
+ *
+ * @param l The listener to remove
+ */
+ public void removeItemListener(ItemListener l)
+ {
+ listenerList.remove(ItemListener.class, l);
+ }
+
+ /**
+ * Adds a ChangeListener to the button's listener list. When the button's
+ * model changes any of its (non-bound) properties, these listeners will be
+ * called.
+ *
+ * @param l The new listener to add
+ */
public void addChangeListener(ChangeListener l)
- { getModel().addChangeListener(l); }
+ {
+ listenerList.add(ChangeListener.class, l);
+ }
+ /**
+ * Removes a ChangeListener from the button's listener list.
+ *
+ * @param l The listener to remove
+ */
public void removeChangeListener(ChangeListener l)
- { getModel().removeChangeListener(l); }
+ {
+ listenerList.remove(ChangeListener.class, l);
+ }
- public void addItemListener(ItemListener l)
- { getModel().addItemListener(l); }
+ /**
+ * Calls {@link ItemListener.itemStateChanged} on each ItemListener in
+ * the button's listener list.
+ *
+ * @param e The event signifying that the button's model changed state
+ */
+ public void fireItemStateChanged(ItemEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ItemListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ItemListener)ll[i]).itemStateChanged(e);
+ }
- public void removeItemListener(ItemListener l)
- { getModel().removeItemListener(l); }
+ /**
+ * Calls {@link ActionListener.actionPerformed} on each {@link
+ * ActionListener} in the button's listener list.
+ *
+ * @param e The event signifying that the button's model was clicked
+ */
+ public void fireActionPerformed(ActionEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ActionListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ActionListener)ll[i]).actionPerformed(e);
+ }
- public int getHorizontalAlignment()
- { return hori_align; }
+ /**
+ * Calls {@link ChangeEvent.stateChanged} on each {@link ChangeListener}
+ * in the button's listener list.
+ *
+ * @param e The event signifying a change in one of the (non-bound)
+ * properties of the button's model.
+ */
+ public void fireStateChanged(ChangeEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ChangeListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ChangeListener)ll[i]).stateChanged(e);
+ }
- public int getHorizontalTextPosition()
- { return hori_text_pos; }
+ /**
+ * Get the current keyboard mnemonic value. This value corresponds to a
+ * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+ * codes) and is used to activate the button when pressed in conjunction
+ * with the "mouseless modifier" of the button's look and feel class, and
+ * when focus is in one of the button's ancestors.
+ *
+ * @return The button's current keyboard mnemonic
+ */
+ public int getMnemonic()
+ {
+ return getModel().getMnemonic();
+ }
- public int getVerticalAlignment()
- { return vert_align; }
+ /**
+ * Set the current keyboard mnemonic value. This value corresponds to a
+ * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+ * codes) and is used to activate the button when pressed in conjunction
+ * with the "mouseless modifier" of the button's look and feel class, and
+ * when focus is in one of the button's ancestors.
+ *
+ * @param mne A new mnemonic to use for the button
+ */
+ public void setMnemonic(char mne)
+ {
+ int old = getModel().getMnemonic();
+ getModel().setMnemonic(mne);
+ if (old != getModel().getMnemonic())
+ {
+ firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, (int) mne);
+ revalidate();
+ repaint();
+ }
+ }
- public int getVerticalTextPosition()
- { return vert_text_pos; }
+ /**
+ * Set the current keyboard mnemonic value. This value corresponds to a
+ * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
+ * codes) and is used to activate the button when pressed in conjunction
+ * with the "mouseless modifier" of the button's look and feel class, and
+ * when focus is in one of the button's ancestors.
+ *
+ * @param mne A new mnemonic to use for the button
+ */
+ public void setMnemonic(int mne)
+ {
+ int old = mne;
+ getModel().setMnemonic(mne);
+ if (old != getModel().getMnemonic())
+ {
+ firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne);
+ revalidate();
+ repaint();
+ }
+ }
- protected void fireItemStateChanged(ItemEvent event)
+ /**
+ * Sets the button's mnemonic index. The mnemonic index is a hint to the
+ * look and feel class, suggesting which character in the button's label
+ * should be underlined when drawing the label. If the mnemonic index is
+ * -1, no mnemonic will be displayed.
+ *
+ * If no mnemonic index is set, the button will choose a mnemonic index
+ * by default, which will be the first occurrence of the mnemonic
+ * character in the button's text.
+ *
+ * @param index An offset into the "text" property of the button
+ * @throws IllegalArgumentException If <code>index</code> is not within the
+ * range of legal offsets for the "text" property of the button.
+ * @since 1.4
+ */
+
+ public void setDisplayedMnemonicIndex(int index)
{
+ if (index < -1 || index >= text.length())
+ throw new IllegalArgumentException();
+ else
+ mnemonicIndex = index;
}
- protected void fireStateChanged(ChangeEvent event)
+ /**
+ * Get the button's mnemonic index, which is an offset into the button's
+ * "text" property. The character specified by this offset should be
+ * underlined when the look and feel class draws this button.
+ *
+ * @return An index into the button's "text" property
+ */
+ public int getDisplayedMnemonicIndex(int index)
{
+ return mnemonicIndex;
}
- protected void fireActionPerformed(ActionEvent event)
+
+ /**
+ * Set the "rolloverEnabled" property. When rollover is enabled, and the
+ * look and feel supports it, the button will change its icon to
+ * rollover_icon, when the mouse passes over it.
+ *
+ * @param r Whether or not to enable rollover icon changes
+ */
+ public void setRolloverEnabled(boolean r)
+ {
+ boolean old = getModel().isRollover();
+ getModel().setRollover(r);
+ if (old != getModel().isRollover())
{
+ firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, old, r);
+ revalidate();
+ repaint();
+ }
}
- public void setVerticalAlignment(int alignment)
- { vert_align = alignment; }
+ /**
+ * Returns whether or not rollover icon changes are enabled on the
+ * button.
+ *
+ * @return The state of the "rolloverEnabled" property
+ */
+ public boolean isRolloverEnabled()
+ {
+ return getModel().isRollover();
+ }
- public void setHorizontalAlignment(int alignment)
- { hori_align = alignment; }
+ /**
+ * Set the value of the button's "selected" property. Selection is only
+ * meaningful for toggle-type buttons (check boxes, radio buttons).
+ *
+ * @param s New value for the property
+ */
+ public void setSelected(boolean s)
+ {
+ getModel().setSelected(s);
+ }
- public void setVerticalTextPosition(int textPosition)
- { vert_text_pos = textPosition; }
+ /**
+ * Get the value of the button's "selected" property. Selection is only
+ * meaningful for toggle-type buttons (check boxes, radio buttons).
+ *
+ * @return The value of the property
+ */
+ public boolean isSelected()
+ {
+ return getModel().isSelected();
+ }
- public void setHorizontalTextPosition(int textPosition)
- { hori_text_pos = textPosition; }
+ /**
+ * Enables or disables the button. A button will neither be selectable
+ * nor preform any actions unless it is enabled.
+ *
+ * @param b Whether or not to enable the button
+ */
+ public void setEnabled(boolean b)
+ {
+ super.setEnabled(b);
+ getModel().setEnabled(b);
+ }
- public int getMnemonic()
- { return getModel().getMnemonic(); }
+ /**
+ * Set the horizontal alignment of the button's text and icon. The
+ * alignment is a numeric constant from {@link SwingConstants}. It must
+ * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+ * <code>LEADING</code> or <code>TRAILING</code>. The default is
+ * <code>RIGHT</code>.
+ *
+ * @return The current horizontal alignment
+ */
+ public int getHorizontalAlignment()
+ {
+ return hori_align;
+ }
- public void setMnemonic(char mne)
- { getModel().setMnemonic(mne); }
+ /**
+ * Set the horizontal alignment of the button's text and icon. The
+ * alignment is a numeric constant from {@link SwingConstants}. It must
+ * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+ * <code>LEADING</code> or <code>TRAILING</code>. The default is
+ * <code>RIGHT</code>.
+ *
+ * @param a The new horizontal alignment
+ * @throws IllegalArgumentException If alignment is not one of the legal
+ * constants.
+ */
+ public void setHorizontalAlignment(int a)
+ {
+ int old = hori_align;
+ hori_align = a;
+ if (old != a)
+ {
+ firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
+ revalidate();
+ repaint();
+ }
+ }
- public void setMnemonic(int mne)
- { getModel().setMnemonic(mne); }
+ /**
+ * Get the horizontal position of the button's text relative to its
+ * icon. The position is a numeric constant from {@link
+ * SwingConstants}. It must be one of: <code>RIGHT</code>,
+ * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
+ * <code>TRAILING</code>. The default is <code>TRAILING</code>.
+ *
+ * @return The current horizontal text position
+ */
+ public int getHorizontalTextPosition()
+ {
+ return hori_text_pos;
+ }
- public void setRolloverEnabled(boolean b)
- { getModel().setRollover(b); }
+ /**
+ * Set the horizontal position of the button's text relative to its
+ * icon. The position is a numeric constant from {@link
+ * SwingConstants}. It must be one of: <code>RIGHT</code>,
+ * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
+ * <code>TRAILING</code>. The default is <code>TRAILING</code>.
+ *
+ * @param t The new horizontal text position
+ * @throws IllegalArgumentException If position is not one of the legal
+ * constants.
+ */
+ public void setHorizontalTextPosition(int t)
+ {
+ int old = hori_text_pos;
+ hori_text_pos = t;
+ if (old != t)
+ {
+ firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
+ revalidate();
+ repaint();
+ }
+ }
- public boolean isRolloverEnabled()
- { return getModel().isRollover(); }
+ /**
+ * Get the vertical alignment of the button's text and icon. The
+ * alignment is a numeric constant from {@link SwingConstants}. It must
+ * be one of: <code>CENTER</code>, <code>TOP</code>, or
+ * <code>BOTTOM</code>. The default is <code>CENTER</code>.
+ *
+ * @return The current vertical alignment
+ */
+ public int getVerticalAlignment()
+ {
+ return vert_align;
+ }
+
+ /**
+ * Set the vertical alignment of the button's text and icon. The
+ * alignment is a numeric constant from {@link SwingConstants}. It must
+ * be one of: <code>CENTER</code>, <code>TOP</code>, or
+ * <code>BOTTOM</code>. The default is <code>CENTER</code>.
+ *
+ * @param a The new vertical alignment
+ * @throws IllegalArgumentException If alignment is not one of the legal
+ * constants.
+ */
+ public void setVerticalAlignment(int a)
+ {
+ int old = vert_align;
+ vert_align = a;
+ if (old != a)
+ {
+ firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
+ revalidate();
+ repaint();
+ }
+ }
+
+ /**
+ * Get the vertical position of the button's text relative to its
+ * icon. The alignment is a numeric constant from {@link
+ * SwingConstants}. It must be one of: <code>CENTER</code>,
+ * <code>TOP</code>, or <code>BOTTOM</code>. The default is
+ * <code>CENTER</code>.
+ *
+ * @return The current vertical position
+ */
+ public int getVerticalTextPosition()
+ {
+ return vert_text_pos;
+ }
+
+ /**
+ * Set the vertical position of the button's text relative to its
+ * icon. The alignment is a numeric constant from {@link
+ * SwingConstants}. It must be one of: <code>CENTER</code>,
+ * <code>TOP</code>, or <code>BOTTOM</code>. The default is
+ * <code>CENTER</code>.
+ *
+ * @param t The new vertical position
+ * @throws IllegalArgumentException If position is not one of the legal
+ * constants.
+ */
+ public void setVerticalTextPosition(int t)
+ {
+ int old = vert_text_pos;
+ vert_text_pos = t;
+ if (old != t)
+ {
+ firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
+ revalidate();
+ repaint();
+ }
+ }
+ /**
+ * Set the value of the "borderPainted" property. If set to
+ * <code>false</code>, the button's look and feel class should not paint
+ * a border for the button. The default is <code>true</code>.
+ *
+ * @return The current value of the property.
+ */
public boolean isBorderPainted()
- { return paint_border; }
+ {
+ return paint_border;
+ }
+ /**
+ * Set the value of the "borderPainted" property. If set to
+ * <code>false</code>, the button's look and feel class should not paint
+ * a border for the button. The default is <code>true</code>.
+ *
+ * @param b The new value of the property.
+ */
public void setBorderPainted(boolean b)
{
- if (b != paint_border)
- {
+ boolean old = paint_border;
paint_border = b;
+ if (b != old)
+ {
+ firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
revalidate();
repaint();
}
}
+ /**
+ * Get the value of the "action" property.
+ *
+ * @return The current value of the "action" property
+ */
public Action getAction()
- { return action_taken; }
+ {
+ return action;
+ }
+ /**
+ * <p>Set the button's "action" property, subscribing the new action to the
+ * button, as an ActionListener, if it is not already subscribed. The old
+ * Action, if it exists, is unsubscribed, and the button is unsubscribed
+ * from the old Action if it was previously subscribed as a
+ * PropertyChangeListener.</p>
+ *
+ * <p>This method also configures several of the button's properties from
+ * the Action, by calling {@link configurePropertiesFromAction}, and
+ * subscribes the button to the Action as a PropertyChangeListener.
+ * Subsequent changes to the Action will thus reconfigure the button
+ * automatically.</p>
+ *
+ * @param a The new value of the "action" property
+ */
public void setAction(Action a)
{
- action_taken = a;
- revalidate();
- repaint();
+ if (action != null)
+ {
+ action.removePropertyChangeListener(actionPropertyChangeListener);
+ removeActionListener(action);
+ if (actionPropertyChangeListener != null)
+ {
+ action.removePropertyChangeListener(actionPropertyChangeListener);
+ actionPropertyChangeListener = null;
+ }
+ actionPropertyChangeListener = createActionPropertyChangeListener(a);
}
- public void setSelected(boolean b)
- { getModel().setSelected(b); }
+ Action old = action;
+ action = a;
+ configurePropertiesFromAction(action);
- public boolean isSelected()
- { return getModel().isSelected(); }
+ if (action != null)
+ {
+ action.addPropertyChangeListener(actionPropertyChangeListener);
+ addActionListener(action);
+ }
+ }
+ /**
+ * Return the button's default "icon" property.
+ *
+ * @return The current default icon
+ */
public Icon getIcon()
- { return default_icon; }
-
- public void setIcon(Icon defaultIcon)
{
- if (default_icon == defaultIcon)
- return;
+ return default_icon;
+ }
- default_icon = defaultIcon;
- if (default_icon != null)
+ /**
+ * Set the button's default "icon" property. This icon is used as a basis
+ * for the pressed and disabled icons, if none are explicitly set.
+ *
+ * @param i The new default icon
+ */
+ public void setIcon(Icon i)
{
- // XXX FIXME - icons do not know their parent
- // default_icon.setParent(this);
- }
+ Icon old = default_icon;
+ default_icon = i;
+ if (old != i)
+ {
+ firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
revalidate();
repaint();
}
+ }
+ /**
+ * Return the button's "text" property. This property is synonymous with
+ * the "label" property.
+ *
+ * @return The current "text" property
+ */
public String getText()
- { return text; }
+ {
+ return text;
+ }
+ /**
+ * Set the button's "label" property. This property is synonymous with the
+ * "text" property.
+ *
+ * @param label The new "label" property
+ */
public void setLabel(String label)
- { setText(label); }
+ {
+ setText(label);
+ }
+ /**
+ * Return the button's "label" property. This property is synonymous with
+ * the "text" property.
+ *
+ * @return The current "label" property
+ */
public String getLabel()
- { return getText(); }
+ {
+ return getText();
+ }
- public void setText(String text)
+ /**
+ * Set the button's "text" property. This property is synonymous with the
+ * "label" property.
+ *
+ * @param t The new "text" property
+ */
+ public void setText(String t)
{
- this.text = text;
+ String old = text;
+ text = t;
+ if (t != old)
+ {
+ firePropertyChange(TEXT_CHANGED_PROPERTY, old, t);
revalidate();
repaint();
}
+ }
+ /**
+ * Return the button's "margin" property, which is an {@link Insets} object
+ * describing the distance between the button's border and its text and
+ * icon.
+ *
+ * @return The current "margin" property
+ */
public Insets getMargin()
- { return margin; }
+ {
+ return margin;
+ }
+ /**
+ * Set the button's "margin" property, which is an {@link Insets} object
+ * describing the distance between the button's border and its text and
+ * icon.
+ *
+ * @param m The new "margin" property
+ */
public void setMargin(Insets m)
{
+ Insets old = margin;
margin = m;
- revalidate();
+ if (m != old)
+ {
+ firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m);
+ revalidate();
repaint();
}
-
- public void setEnabled(boolean b)
- {
- super.setEnabled(b);
- getModel().setEnabled(b);
- repaint();
}
+ /**
+ * Return the button's "pressedIcon" property. The look and feel class
+ * should paint this icon when the "pressed" property of the button's
+ * {@link ButtonModel} is <code>true</code>. This property may be
+ * <code>null</code>, in which case the default icon is used.
+ *
+ * @return The current "pressedIcon" property
+ */
public Icon getPressedIcon()
- { return pressed_button; }
+ {
+ return pressed_icon;
+ }
+ /**
+ * Set the button's "pressedIcon" property. The look and feel class
+ * should paint this icon when the "pressed" property of the button's
+ * {@link ButtonModel} is <code>true</code>. This property may be
+ * <code>null</code>, in which case the default icon is used.
+ *
+ * @param pressedIcon The new "pressedIcon" property
+ */
public void setPressedIcon(Icon pressedIcon)
{
- pressed_button = pressedIcon;
+ Icon old = pressed_icon;
+ pressed_icon = pressedIcon;
+ if (pressed_icon != old)
+ {
+ firePropertyChange(PRESSED_ICON_CHANGED_PROPERTY, old, pressed_icon);
revalidate();
repaint();
}
+ }
+ /**
+ * Return the button's "disabledIcon" property. The look and feel class
+ * should paint this icon when the "enabled" property of the button's
+ * {@link ButtonModel} is <code>false</code>. This property may be
+ * <code>null</code>, in which case an icon is constructed, based on the
+ * default icon.
+ *
+ * @return The current "disabledIcon" property
+ */
public Icon getDisabledIcon()
- { return disabled_button; }
+ {
+ return disabled_icon;
+ }
+ /**
+ * Set the button's "disabledIcon" property. The look and feel class should
+ * paint this icon when the "enabled" property of the button's {@link
+ * ButtonModel} is <code>false</code>. This property may be
+ * <code>null</code>, in which case an icon is constructed, based on the
+ * default icon.
+ *
+ * @param disabledIcon The new "disabledIcon" property
+ */
public void setDisabledIcon(Icon disabledIcon)
{
- disabled_button = disabledIcon;
+ disabled_icon = disabledIcon;
revalidate();
repaint();
}
+ /**
+ * Return the button's "paintFocus" property. This property controls
+ * whether or not the look and feel class will paint a special indicator
+ * of focus state for the button. If it is false, the button still paints
+ * when focused, but no special decoration is painted to indicate the
+ * presence of focus.
+ *
+ * @return The current "paintFocus" property
+ */
public boolean isFocusPainted()
- { return paint_focus; }
+ {
+ return paint_focus;
+ }
+ /**
+ * Set the button's "paintFocus" property. This property controls whether
+ * or not the look and feel class will paint a special indicator of focus
+ * state for the button. If it is false, the button still paints when
+ * focused, but no special decoration is painted to indicate the presence
+ * of focus.
+ *
+ * @param b The new "paintFocus" property
+ */
public void setFocusPainted(boolean b)
{
boolean old = paint_focus;
paint_focus = b;
- firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY,
- old,
- b);
- if (hasFocus())
+ if (old != b)
{
+ firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, b);
revalidate();
repaint();
}
}
+ /**
+ * Return the button's "focusTraversable" property. This property controls
+ * whether or not the button can receive focus when the user attempts to
+ * traverse the focus hierarchy.
+ *
+ * @return The current "focusTraversable" property
+ */
public boolean isFocusTraversable()
{
- //Identifies whether or not this component can receive the focus.
return true;
}
-
+ /**
+ * Verifies that a particular key is one of the valid constants used for
+ * describing horizontal alignment and positioning. The valid constants
+ * are the following members of {@link SwingConstants}:
+ * <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
+ * <code>LEADING</code> or <code>TRAILING</code>.
+ *
+ * @param key The key to check
+ * @param exception A message to include in an IllegalArgumentException
+ *
+ * @return the value of key
+ *
+ * @throws IllegalArgumentException If key is not one of the valid constants
+ *
+ * @see setHorizontalTextPosition()
+ * @see setHorizontalAlignment()
+ */
protected int checkHorizontalKey(int key, String exception)
{
- // Verify that key is a legal value for the horizontalAlignment properties.
- return 0;
+ switch (key)
+ {
+ case SwingConstants.RIGHT:
+ case SwingConstants.LEFT:
+ case SwingConstants.CENTER:
+ case SwingConstants.LEADING:
+ case SwingConstants.TRAILING:
+ break;
+ default:
+ throw new IllegalArgumentException(exception);
+ }
+ return key;
}
+ /**
+ * Verifies that a particular key is one of the valid constants used for
+ * describing vertical alignment and positioning. The valid constants are
+ * the following members of {@link SwingConstants}: <code>TOP</code>,
+ * <code>BOTTOM</code> or <code>CENTER</code>.
+ *
+ * @param key The key to check
+ * @param exception A message to include in an IllegalArgumentException
+ *
+ * @return the value of key
+ *
+ * @throws IllegalArgumentException If key is not one of the valid constants
+ *
+ * @see setVerticalTextPosition()
+ * @see setVerticalAlignment()
+ */
protected int checkVerticalKey(int key, String exception)
{
- // Ensures that the key is a valid.
- return 0;
+ switch (key)
+ {
+ case SwingConstants.TOP:
+ case SwingConstants.BOTTOM:
+ case SwingConstants.CENTER:
+ break;
+ default:
+ throw new IllegalArgumentException(exception);
+ }
+ return key;
}
+ /**
+ * Configure various properties of the button by reading properties
+ * of an {@link Action}. The mapping of properties is as follows:
+ *
+ * <table>
+ *
+ * <tr><th>Action keyed property</th> <th>AbstractButton property</th></tr>
+ *
+ * <tr><td>NAME </td> <td>text </td></tr>
+ * <tr><td>SMALL_ICON </td> <td>icon </td></tr>
+ * <tr><td>SHORT_DESCRIPTION </td> <td>toolTipText </td></tr>
+ * <tr><td>MNEMONIC_KEY </td> <td>mnemonic </td></tr>
+ * <tr><td>ACTION_COMMAND_KEY </td> <td>actionCommand </td></tr>
+ *
+ * </table>
+ *
+ * <p>In addition, this method always sets the button's "enabled" property to
+ * the value of the Action's "enabled" property.</p>
+ *
+ * <p>If the provided Action is <code>null</code>, the text, icon, and
+ * toolTipText properties of the button are set to <code>null</code>, and
+ * the "enabled" property is set to <code>true</code>; the mnemonic and
+ * actionCommand properties are unchanged.</p>
+ *
+ * @param a An Action to configure the button from
+ */
protected void configurePropertiesFromAction(Action a)
{
- //Factory method which sets the ActionEvent source's properties according to values from the Action instance.
+ if (a == null)
+ {
+ setText(null);
+ setIcon(null);
+ setEnabled(true);
+ setToolTipText(null);
+ }
+ else
+ {
+ setText((String)(a.getValue(Action.NAME)));
+ setIcon((Icon)(a.getValue(Action.SMALL_ICON)));
+ setEnabled(a.isEnabled());
+ setToolTipText((String)(a.getValue(Action.SHORT_DESCRIPTION)));
+ setMnemonic(((Integer)(a.getValue(Action.MNEMONIC_KEY))).intValue());
+ setActionCommand((String)(a.getValue(Action.ACTION_COMMAND_KEY)));
+ }
}
+ /**
+ * <p>A factory method which should return an {@link ActionListener} that
+ * propagates events from the button's {@link ButtonModel} to any of the
+ * button's ActionListeners. By default, this is an inner class which
+ * calls {@link AbstractButton.fireActionPerformed} with a modified copy
+ * of the incoming model {@link ActionEvent}.</p>
+ *
+ * <p>The button calls this method during construction, stores the
+ * resulting ActionListener in its <code>actionListener</code> member
+ * field, and subscribes it to the button's model. If the button's model
+ * is changed, this listener is unsubscribed from the old model and
+ * subscribed to the new one.</p>
+ *
+ * @return A new ActionListener
+ */
protected ActionListener createActionListener()
{
return new ActionListener()
{
- public void actionPerformed(ActionEvent e) { }
+ public void actionPerformed(ActionEvent e)
+ {
+ e.setSource(AbstractButton.this);
+ AbstractButton.this.fireActionPerformed(e);
+ }
};
}
+ /**
+ * <p>A factory method which should return a {@link PropertyChangeListener}
+ * that accepts changes to the specified {@link Action} and reconfigure
+ * the {@link AbstractButton}, by default using the {@link
+ * configurePropertiesFromAction} method.</p>
+ *
+ * <p>The button calls this method whenever a new Action is assigned to
+ * the button's "action" property, via {@link setAction}, and stores the
+ * resulting PropertyChangeListener in its
+ * <code>actionPropertyChangeListener</code> member field. The button
+ * then subscribes the listener to the button's new action. If the
+ * button's action is changed subsequently, the listener is unsubscribed
+ * from the old action and subscribed to the new one.</p>
+ *
+ * @param a The Action which will be listened to, and which should be
+ * the same as the source of any PropertyChangeEvents received by the
+ * new listener returned from this method.
+ *
+ * @return A new PropertyChangeListener
+ */
protected PropertyChangeListener createActionPropertyChangeListener(Action a)
{
- //Factory method which creates the PropertyChangeListener used to update the ActionEvent source as properties change on its Action instance.
- return null;
+ return new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ Action act = (Action)(e.getSource());
+ AbstractButton.this.configurePropertiesFromAction(act);
+ }
+ };
}
+ /**
+ * <p>Factory method which creates a {@link ChangeListener}, used to
+ * subscribe to ChangeEvents from the button's model. Subclasses of
+ * AbstractButton may wish to override the listener used to subscribe to
+ * such ChangeEvents. By default, the listener just propagates the
+ * {@link ChangeEvent} to the button's ChangeListeners, via the {@link
+ * AbstractButton.fireStateChanged} method.</p>
+ *
+ * <p>The button calls this method during construction, stores the
+ * resulting ChangeListener in its <code>changeListener</code> member
+ * field, and subscribes it to the button's model. If the button's model
+ * is changed, this listener is unsubscribed from the old model and
+ * subscribed to the new one.</p>
+ *
+ * @return The new ChangeListener
+ */
protected ChangeListener createChangeListener()
{
- // Subclasses that want to handle ChangeEvents differently can override this to return another ChangeListener implementation.
return new ChangeListener()
{
- public void stateChanged(ChangeEvent e) { }
+ public void stateChanged(ChangeEvent e)
+ {
+ AbstractButton.this.fireStateChanged(e);
+ AbstractButton.this.revalidate();
+ AbstractButton.this.repaint();
+ }
};
}
+ /**
+ * <p>Factory method which creates a {@link ItemListener}, used to
+ * subscribe to ItemEvents from the button's model. Subclasses of
+ * AbstractButton may wish to override the listener used to subscribe to
+ * such ItemEvents. By default, the listener just propagates the
+ * {@link ItemEvent} to the button's ItemListeners, via the {@link
+ * AbstractButton.fireItemStateChanged} method.</p>
+ *
+ * <p>The button calls this method during construction, stores the
+ * resulting ItemListener in its <code>changeListener</code> member
+ * field, and subscribes it to the button's model. If the button's model
+ * is changed, this listener is unsubscribed from the old model and
+ * subscribed to the new one.</p>
+ *
+ * <p>Note that ItemEvents are only generated from the button's model
+ * when the model's <em>selected</em> property changes. If you want to
+ * subscribe to other properties of the model, you must subscribe to
+ * ChangeEvents.
+ *
+ * @return The new ItemListener
+ */
protected ItemListener createItemListener()
{
return new ItemListener()
{
- public void itemStateChanged(ItemEvent e) { }
+ public void itemStateChanged(ItemEvent e)
+ {
+ AbstractButton.this.fireItemStateChanged(e);
+ }
};
}
+ /**
+ * Programmatically perform a "click" on the button: arming, pressing,
+ * waiting, un-pressing, and disarming the model.
+ */
public void doClick()
{
doClick(100);
}
+ /**
+ * Programmatically perform a "click" on the button: arming, pressing,
+ * waiting, un-pressing, and disarming the model.
+ *
+ * @param pressTime The number of milliseconds to wait in the pressed state
+ */
public void doClick(int pressTime)
{
- //Toolkit.tlkBeep ();
- //Programmatically perform a "click".
- }
-
- public Icon getDisabledSelectedIcon()
+ getModel().setArmed(true);
+ getModel().setPressed(true);
+ try
{
- //Returns the icon used by the button when it's disabled and selected.
- return disabled_selected_button;
+ java.lang.Thread.sleep(pressTime);
}
-
- public Icon getRolloverIcon()
+ catch (java.lang.InterruptedException e)
{
- // Returns the rollover icon for the button.
- return null;
+ // probably harmless
}
-
- Icon getRolloverSelectedIcon()
- {
- // Returns the rollover selection icon for the button.
- return null;
+ getModel().setPressed(false);
+ getModel().setArmed(false);
}
- Icon getSelectedIcon()
+ /**
+ * Return the button's disabled selected icon. The look and feel class
+ * should paint this icon when the "enabled" property of the button's model
+ * is <code>false</code> and its "selected" property is
+ * <code>true</code>. This icon can be <code>null</code>, in which case
+ * it is synthesized from the button's selected icon.
+ *
+ * @return The current disabled selected icon
+ */
+ public Icon getDisabledSelectedIcon()
{
- // Returns the selected icon for the button.
- return selected_button;
+ return disabled_selected_icon;
}
- public Object[] getSelectedObjects()
+ /**
+ * Set the button's disabled selected icon. The look and feel class
+ * should paint this icon when the "enabled" property of the button's model
+ * is <code>false</code> and its "selected" property is
+ * <code>true</code>. This icon can be <code>null</code>, in which case
+ * it is synthesized from the button's selected icon.
+ *
+ * @param disabledSelectedIcon The new disabled selected icon
+ */
+ public void setDisabledSelectedIcon(Icon disabledSelectedIcon)
{
- //Returns an array (length 1) containing the label or null if the button is not selected.
- return null;
- }
-
- public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
+ Icon old = disabled_selected_icon;
+ disabled_selected_icon = disabledSelectedIcon;
+ if (old != disabledSelectedIcon)
{
- //This is overridden to return false if the current Icon's Image is not equal to the passed in Image img.
- return current_icon == img;
+ firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old,
+ disabledSelectedIcon);
+ revalidate();
+ repaint();
}
-
- public boolean isContentAreaFilled()
- {
- // Checks whether the "content area" of the button should be filled.
- return false;
}
- protected void paintBorder(Graphics g)
- {
- // Paint the button's border if BorderPainted property is true.
- if (isBorderPainted())
- super.paintBorder(g);
- }
- protected String paramString()
+ /**
+ * Return the button's rollover icon. The look and feel class should
+ * paint this icon when the "rolloverEnabled" property of the button is
+ * <code>true</code> and the mouse rolls over the button.
+ *
+ * @return The current rollover icon
+ */
+ public Icon getRolloverIcon()
{
- // Returns a string representation of this AbstractButton.
- return "AbstractButton";
+ return rollover_icon;
}
- public void setContentAreaFilled(boolean b)
+ /**
+ * Set the button's rollover icon. The look and feel class should
+ * paint this icon when the "rolloverEnabled" property of the button is
+ * <code>true</code> and the mouse rolls over the button.
+ *
+ * @param rolloverIcon The new rollover icon
+ */
+ public void setRolloverIcon(Icon rolloverIcon)
{
- //Sets whether the button should paint the content area or leave it transparent.
- }
-
- public void setDisabledSelectedIcon(Icon disabledSelectedIcon)
+ Icon old = rollover_icon;
+ rollover_icon = rolloverIcon;
+ if (old != rolloverIcon)
{
- // Sets the disabled selection icon for the button.
+ firePropertyChange(ROLLOVER_ICON_CHANGED_PROPERTY, old,
+ rolloverIcon);
+ revalidate();
+ repaint();
+ }
}
- public void setRolloverIcon(Icon rolloverIcon)
+ /**
+ * Return the button's rollover selected icon. The look and feel class
+ * should paint this icon when the "rolloverEnabled" property of the button
+ * is <code>true</code>, the "selected" property of the button's model is
+ * <code>true</code>, and the mouse rolls over the button.
+ *
+ * @return The current rollover selected icon
+ */
+ Icon getRolloverSelectedIcon()
{
- // Sets the rollover icon for the button.
+ return rollover_selected_icon;
}
+
+ /**
+ * Set the button's rollover selected icon. The look and feel class
+ * should paint this icon when the "rolloverEnabled" property of the button
+ * is <code>true</code>, the "selected" property of the button's model is
+ * <code>true</code>, and the mouse rolls over the button.
+ *
+ * @param rolloverSelectedIcon The new rollover selected icon
+ */
public void setRolloverSelectedIcon(Icon rolloverSelectedIcon)
{
- // Sets the rollover selected icon for the button.
- }
-
- public void setSelectedIcon(Icon selectedIcon)
+ Icon old = rollover_selected_icon;
+ rollover_selected_icon = rolloverSelectedIcon;
+ if (old != rolloverSelectedIcon)
{
- // Sets the selected icon for the button.
+ firePropertyChange(ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY, old,
+ rolloverSelectedIcon);
+ revalidate();
+ repaint();
}
-
- public void setUI(ButtonUI ui)
- { // Sets the L&F object that renders this component.
- super.setUI(ui);
}
- public ButtonUI getUI()
+
+ /**
+ * Return the button's selected icon. The look and feel class should
+ * paint this icon when the "selected" property of the button's model is
+ * <code>true</code>, and either the "rolloverEnabled" property of the
+ * button is <code>false</code> or the mouse is not currently rolled
+ * over the button.
+ *
+ * @return The current selected icon
+ */
+ Icon getSelectedIcon()
{
- //Returns the L&F object that renders this component.
- return (ButtonUI) ui;
+ return selected_icon;
}
- public void updateUI()
+ /**
+ * Set the button's selected icon. The look and feel class should
+ * paint this icon when the "selected" property of the button's model is
+ * <code>true</code>, and either the "rolloverEnabled" property of the
+ * button is <code>false</code> or the mouse is not currently rolled
+ * over the button.
+ *
+ * @param selectedIcon The new selected icon
+ */
+ public void setSelectedIcon(Icon selectedIcon)
{
- /*
- // Notification from the UIFactory that the L&F has changed.
- if (getUI() == null)
+ Icon old = selected_icon;
+ selected_icon = selectedIcon;
+ if (old != selectedIcon)
{
- setUI(getUI());
+ firePropertyChange(SELECTED_ICON_CHANGED_PROPERTY, old,
+ selectedIcon);
+ revalidate();
+ repaint();
}
- */
}
- protected void processActionEvent(ActionEvent e)
+ /**
+ * Returns an single-element array containing the "text" property of the
+ * button if the "selected" property of the button's model is
+ * <code>true</code>, otherwise returns <code>null</code>.
+ *
+ * @return The button's "selected object" array
+ */
+ public Object[] getSelectedObjects()
{
- System.out.println("PROCESS-ACTION-EVENT: " + e);
+ if (isSelected())
+ {
+ Object[] objs = new Object[1];
+ objs[0] = getText();
+ return objs;
}
-
- protected void processMouseEvent(MouseEvent e)
+ else
{
- // System.out.println("PROCESS-MOUSE-EVENT: " + e + ", PRESSED-IN-MODEL="+getModel().isPressed());
+ return null;
+ }
+ }
- switch (e.getID())
- {
- case MouseEvent.MOUSE_MOVED:
+ /**
+ * Called when image data becomes available for one of the button's icons.
+ *
+ * @param img The image being updated
+ * @param infoflags One of the constant codes in {@link ImageObserver} used to describe
+ * updated portions of an image.
+ * @param x X coordinate of the region being updated
+ * @param y Y coordinate of the region being updated
+ * @param w Width of the region beign updated
+ * @param h Height of the region being updated
+ *
+ * @return <code>true</code> if img is equal to the button's current
+ * icon, otherwise <code>false</code>
+ */
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
+ int h)
{
- break;
+ return current_icon == img;
}
- case MouseEvent.MOUSE_PRESSED:
- {
- if (! isEnabled())
+
+ /**
+ * Returns the value of the button's "contentAreaFilled" property. This
+ * property indicates whether the area surrounding the text and icon of
+ * the button should be filled by the look and feel class. If this
+ * property is <code>false</code>, the look and feel class should leave
+ * the content area transparent.
+ *
+ * @return The current value of the "contentAreaFilled" property
+ */
+ public boolean isContentAreaFilled()
{
- System.out.println("button not enabled, ignoring press");
+ return content_area_filled;
}
- else
+
+ /**
+ * Sets the value of the button's "contentAreaFilled" property. This
+ * property indicates whether the area surrounding the text and icon of
+ * the button should be filled by the look and feel class. If this
+ * property is <code>false</code>, the look and feel class should leave
+ * the content area transparent.
+ *
+ * @param b The new value of the "contentAreaFilled" property
+ */
+ public void setContentAreaFilled(boolean b)
{
- System.out.println("telling model:press: " + getModel());
- getModel().setPressed(true);
+ boolean old = content_area_filled;
+ content_area_filled = b;
+ if (b != old)
+ {
+ firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b);
+ revalidate();
repaint();
}
- break;
}
- case MouseEvent.MOUSE_RELEASED:
- {
- if (! isEnabled())
+ /**
+ * Paints the button's border, if the button's "borderPainted" property is
+ * <code>true</code>, by out calling to the button's look and feel class.
+ *
+ * @param g The graphics context used to paint the border
+ */
+ protected void paintBorder(Graphics g)
{
- System.out.println("button not enabled, ignoring release");
+ if (isBorderPainted())
+ super.paintBorder(g);
}
- else
- {
- int flags = 0;
- System.out.println(" XXX--> " + getActionCommand());
+ /**
+ * Returns a string, used only for debugging, which identifies or somehow
+ * represents this button. The exact value is implementation-defined.
+ *
+ * @return A string representation of the button
+ */
+ protected String paramString()
+ {
+ return "AbstractButton";
+ }
- fireActionPerformed(new ActionEvent(this,
- ActionEvent.ACTION_PERFORMED,
- getActionCommand(),
- flags));
- //System.out.println("telling model:release");
- getModel().setPressed(false);
- repaint();
- }
- break;
- }
- case MouseEvent.MOUSE_CLICKED:
+ /**
+ * Set the "UI" property of the button, which is a look and feel class
+ * responsible for handling the button's input events and painting it.
+ *
+ * @param ui The new "UI" property
+ */
+ public void setUI(ButtonUI ui)
{
- break;
+ super.setUI(ui);
}
+
+ /**
+ * Set the "UI" property of the button, which is a look and feel class
+ * responsible for handling the button's input events and painting it.
+ *
+ * @return The current "UI" property
+ */
+ public ButtonUI getUI()
+ {
+ return (ButtonUI) ui;
}
+
+ /**
+ * Set the "UI" property to a class constructed, via the {@link
+ * UIManager}, from the current look and feel. This should be overridden
+ * for each subclass of AbstractButton, to retrieve a suitable {@link
+ * ButtonUI} look and feel class.
+ */
+ public void updateUI()
+ {
}
}
diff --git a/libjava/javax/swing/DefaultButtonModel.java b/libjava/javax/swing/DefaultButtonModel.java
index 52b78b3..1997e6a 100644
--- a/libjava/javax/swing/DefaultButtonModel.java
+++ b/libjava/javax/swing/DefaultButtonModel.java
@@ -1,5 +1,5 @@
/* DefaultButtonModel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,9 +35,10 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package javax.swing;
+import java.awt.AWTEvent;
+import java.awt.AWTEventMulticaster;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
@@ -49,130 +50,412 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
-public class DefaultButtonModel
- implements ButtonModel, Serializable
+/**
+ * The purpose of this class is to model the dynamic state of an abstract
+ * button. The concrete button type holding this state may be a a "toggle"
+ * button (checkbox, radio button) or a "push" button (menu button, button).
+ *
+ * Any change to the model's properties will trigger the firing of a
+ * ChangeEvent.
+ *
+ * Any change to the "pressed" property will trigger the firing of an
+ * ItemEvent in addition to ChangeEvent.
+ *
+ * Any change which causes the enabled, armed and pressed properties to
+ * simultaneously become <code>true</code> will trigger the firing of an
+ * ActionEvent in addition to the ChangeEvent.
+ *
+ * @author Graydon Hoare (graydon&064;redhat.com)
+ */
+public class DefaultButtonModel implements ButtonModel, Serializable
{
static final long serialVersionUID = -5342609566534980231L;
- Vector actions = new Vector();
+ /** Indicates that the button is <em>partially</em> committed to being
+ pressed, but not entirely. This usually happens when a user has pressed
+ but not yet released the mouse button. */
+ static int ARMED = 1;
- Vector items = new Vector();
- Vector changes = new Vector();
- ButtonGroup group;
- JComponent comp;
+ /** State constant indicating that the button is enabled. Buttons cannot
+ be pressed or selected unless they are enabled. */
+ static int ENABLED = 2;
-
- DefaultButtonModel(JComponent a)
- {
- comp = a;
- }
+ /** State constant indicating that the button has been fully
+ pressed. This usually happens when a user has released the mouse over a
+ previously "armed" button. */
+ static int PRESSED = 4;
+
+ /** State constant indicating that the mouse is currently positioned over
+ the button. */
+ static int ROLLOVER = 8;
+ /** State constant indicating that the button is selected. This constant
+ is only meaningful for toggle-type buttons (radio buttons,
+ checkboxes). */
+ static int SELECTED = 16;
+
+ /** Represents the "state properties" (armed, enabled, pressed, rollover
+ and selected) by a bitwise combination of integer constants. */
+ int stateMask;
+
+ /** List of ItemListeners, ChangeListeners, and ActionListeners
+ registered on this model. */
+ EventListenerList listenerList;
+
+ /** The single ChangeEvent this model (re)uses to call its
+ ChangeListeners. */
+ ChangeEvent changeEvent;
+
+ /** The group this model belongs to. Only one button in a group may be
+ selected at any given time. */
+ ButtonGroup group;
+ /** The key code (one of {@link java.awt.event.KeyEvent} VK_*) used to
+ press this button via a keyboard interface. */
+ int mnemonic;
+
+ /** The string used as the "command" property of any ActionEvent this
+ model sends. */
+ String actionCommand;
+
+ public DefaultButtonModel()
+ {
+ stateMask = 0;
+ listenerList = new EventListenerList();
+ changeEvent = new ChangeEvent(this);
+ }
+
+ /**
+ * Return <code>null</code>. Use {@link AbstractButton} if you wish to
+ * interface with a button via an {@link ItemSelectable} interface.
+ *
+ * @return <code>null</code>
+ */
public Object[] getSelectedObjects()
{
return null;
}
-
- public void fireItemStateChanged(ItemEvent event)
- {
- for (int i=0;i<items.size();i++)
+ /**
+ * Add an ActionListener to the model. Usually only called to subscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addActionListener(ActionListener l)
{
- ItemListener a = (ItemListener) items.get(i);
- a.itemStateChanged(event);
- }
+ listenerList.add(ActionListener.class, l);
}
- public void fireStateChanged(ChangeEvent event)
+
+ /**
+ * Remove an ActionListener to the model. Usually only called to
+ * unsubscribe an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeActionListener(ActionListener l)
+ {
+ listenerList.remove(ActionListener.class, l);
+ }
+
+ /**
+ * Add an ItemListener to the model. Usually only called to subscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addItemListener(ItemListener l)
+ {
+ listenerList.add(ItemListener.class, l);
+ }
+
+ /**
+ * Remove an ItemListener to the model. Usually only called to
+ * unsubscribe an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeItemListener(ItemListener l)
+ {
+ listenerList.remove(ItemListener.class, l);
+ }
+
+ /**
+ * Add a ChangeListener to the model. Usually only called to subscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addChangeListener(ChangeListener l)
+ {
+ listenerList.add(ChangeListener.class, l);
+ }
+
+ /**
+ * Remove a ChangeListener to the model. Usually only called to
+ * unsubscribe an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeChangeListener(ChangeListener l)
+ {
+ listenerList.remove(ChangeListener.class, l);
+ }
+
+ /**
+ * Inform each ItemListener in the {@link listenerList} that an ItemEvent
+ * has occurred. This happens in response to any change to the {@link
+ * stateMask} field.
+ *
+ * @param e The ItemEvent to fire
+ */
+ public void fireItemStateChanged(ItemEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ItemListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ItemListener)ll[i]).itemStateChanged(e);
+ }
+
+ /**
+ * Inform each ActionListener in the {@link listenerList} that an
+ * ActionEvent has occurred. This happens in response to the any change
+ * to the {@link stateMask} field which makes the enabled, armed and
+ * pressed properties all simultaneously <code>true</code>.
+ *
+ * @param e The ActionEvent to fire
+ */
+ public void fireActionPerformed(ActionEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ActionListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ActionListener)ll[i]).actionPerformed(e);
+ }
+
+ /**
+ * Inform each ChangeListener in the {@link listenerList} that a
+ * ChangeEvent has occurred. This happens in response to the any change
+ * to a property of the model.
+ *
+ * @param event The ChangeEvent to fire
+ */
+ public void fireStateChanged(ChangeEvent e)
+ {
+ EventListener[] ll = listenerList.getListeners(ChangeListener.class);
+ for (int i = 0; i < ll.length; i++)
+ ((ChangeListener)ll[i]).stateChanged(e);
+ }
+
+ /**
+ * Helper method to fire a ChangeEvent with the model as the event's
+ * source.
+ */
+ protected void changeState(int stateflag, boolean b)
{
- for (int i=0;i<changes.size();i++)
+ int oldstate = stateMask;
+ int newstate;
+
+ if (b)
+ newstate = oldstate | stateflag;
+ else
+ newstate = oldstate & ~stateflag;
+
+ if (oldstate == newstate)
+ return;
+
+ stateMask = newstate;
+
+ fireStateChanged(changeEvent);
+
+ if ((newstate & ENABLED) == 0)
+ return;
+
+ if ((oldstate & SELECTED) == 0
+ && (newstate & SELECTED) == SELECTED)
+ fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+ null, ItemEvent.SELECTED));
+
+ else if ((oldstate & SELECTED) == SELECTED
+ && (newstate & SELECTED) == 0)
+ fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+ null, ItemEvent.DESELECTED));
+
+ else if ((newstate & ARMED) == ARMED
+ && (newstate & PRESSED) == PRESSED)
{
- ChangeListener a = (ChangeListener) changes.get(i);
- a.stateChanged(event);
+ fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+ actionCommand));
+ stateMask = stateMask & ~(PRESSED | ARMED);
}
+
}
- public void fireActionPerformed(ActionEvent event)
- {
- for (int i=0;i<actions.size();i++)
+
+ /**
+ * Get the value of the model's "armed" property.
+ *
+ * @return The current "armed" property
+ */
+ public boolean isArmed()
{
- ActionListener a = (ActionListener) actions.get(i);
- a.actionPerformed(event);
- }
+ return (stateMask & ARMED) == ARMED;
}
- boolean arm;
- public boolean isArmed() { return arm; }
- public void setArmed(boolean b) { arm = b; }
-
- boolean enabled = true;
- public boolean isEnabled() { return enabled; }
- public void setEnabled(boolean b) { enabled = b; }
-
- boolean pressed;
- public void setPressed(boolean b)
+ /**
+ * Set the value of the model's "armed" property.
+ *
+ * @param a The new "armed" property
+ */
+ public void setArmed(boolean a)
+ {
+ changeState(ARMED, a);
+ }
+
+ /**
+ * Get the value of the model's "enabled" property.
+ *
+ * @return The current "enabled" property.
+ */
+ public boolean isEnabled()
{
- pressed = b;
+ return (stateMask & ENABLED) == ENABLED;
}
- public boolean isPressed() { return pressed; }
-
- public void removeActionListener(ActionListener l) { actions.removeElement(l); }
- public void addActionListener(ActionListener l)
+ /**
+ * Set the value of the model's "enabled" property.
+ *
+ * @param e The new "enabled" property
+ */
+ public void setEnabled(boolean e)
+ {
+ changeState(ENABLED, e);
+ }
+
+ /**
+ * Set the value of the model's "pressed" property.
+ *
+ * @param p The new "pressed" property
+ */
+ public void setPressed(boolean p)
{
- // comp.enableEvents( AWTEvent.ACTION_EVENT_MASK );
- actions.addElement(l);
+ changeState(PRESSED, p);
}
- public void addItemListener(ItemListener l) { items.addElement(l); }
- public void removeItemListener(ItemListener l) { items.removeElement(l); }
-
- public void addChangeListener(ChangeListener l) { changes.addElement(l); }
- public void removeChangeListener(ChangeListener l) { changes.removeElement(l); }
-
- boolean roll;
- public void setRollover(boolean b) { roll = b; }
- public boolean isRollover() { return roll; }
-
- int mne;
- public int getMnemonic() { return mne; }
- public void setMnemonic(int key) { mne = key; }
-
- String com;
- public void setActionCommand(String s) { com = s; }
- public String getActionCommand() { return com; }
-
- public void setGroup(ButtonGroup group)
+ /**
+ * Get the value of the model's "pressed" property.
+ *
+ * @return The current "pressed" property
+ */
+ public boolean isPressed()
+ {
+ return (stateMask & PRESSED) == PRESSED;
+ }
+
+ /**
+ * Set the value of the model's "rollover" property.
+ *
+ * @param r The new "rollover" property
+ */
+ public void setRollover(boolean r)
+ {
+ changeState(ROLLOVER, r);
+ }
+
+
+ /**
+ * Set the value of the model's "selected" property.
+ *
+ * @param s The new "selected" property
+ */
+ public void setSelected(boolean s)
+ {
+ changeState(SELECTED, s);
+ }
+
+ /**
+ * Get the value of the model's "selected" property.
+ *
+ * @return The current "selected" property
+ */
+ public boolean isSelected()
+ {
+ return (stateMask & SELECTED) == SELECTED;
+ }
+
+ /**
+ * Get the value of the model's "rollover" property.
+ *
+ * @return The current "rollover" property
+ */
+ public boolean isRollover()
{
- this.group = group;
+ return (stateMask & ROLLOVER) == ROLLOVER;
}
- boolean sel;
- public void setSelected(boolean b)
+ /**
+ * Get the value of the model's "mnemonic" property.
+ *
+ * @return The current "mnemonic" property
+ */
+ public int getMnemonic()
{
- if (group != null)
+ return mnemonic;
+ }
+
+ /**
+ * Set the value of the model's "mnemonic" property.
+ *
+ * @param key The new "mnemonic" property
+ */
+ public void setMnemonic(int key)
{
- if (b == true)
+ if (mnemonic != key)
{
- System.out.println("selected button in group:"+this);
- group.setSelected(this, b);
- sel = true;
+ mnemonic = key;
+ fireStateChanged(changeEvent);
}
- else
+ }
+
+ /**
+ * Set the value of the model's "actionCommand" property. This property
+ * is used as the "command" property of the {@link ActionEvent} fired
+ * from the model.
+ *
+ * @param s The new "actionCommand" property.
+ */
+ public void setActionCommand(String s)
{
- System.out.println("deselected button in group: " + this);
- sel = false;
+ if (actionCommand != s)
+ {
+ actionCommand = s;
+ fireStateChanged(changeEvent);
}
}
- else
+
+ /**
+ * Set the value of the model's "actionCommand" property. This property
+ * is used as the "command" property of the {@link ActionEvent} fired
+ * from the model.
+ *
+ * @return The current "actionCommand" property
+ */
+ public String getActionCommand()
{
- sel = b;
+ return actionCommand;
+ }
+
+ /**
+ * Set the value of the model's "group" property. The model is said to be
+ * a member of the {@link ButtonGroup} held in its "group" property, and
+ * only one models in a given group can have their "selected" property be
+ * <code>true</code> at a time.
+ *
+ * @param g The new "group" property
+ */
+ public void setGroup(ButtonGroup g)
+ {
+ if (group != g)
+ {
+ group = g;
+ fireStateChanged(changeEvent);
}
}
- public boolean isSelected() { return sel; }
}
-
-
-
-
-
-
-
diff --git a/libjava/javax/swing/JComponent.java b/libjava/javax/swing/JComponent.java
index a0409a4..b95b7e6 100644
--- a/libjava/javax/swing/JComponent.java
+++ b/libjava/javax/swing/JComponent.java
@@ -46,6 +46,7 @@ import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
+import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
@@ -56,6 +57,7 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
+import java.awt.image.ImageObserver;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
@@ -271,13 +273,16 @@ public abstract class JComponent extends Container implements Serializable
super();
super.setLayout(new FlowLayout());
+ listenerList = new EventListenerList();
+
//eventMask |= AWTEvent.COMP_KEY_EVENT_MASK;
- enableEvents( AWTEvent.KEY_EVENT_MASK );
+ // enableEvents( AWTEvent.KEY_EVENT_MASK );
//updateUI(); // get a proper ui
}
- // protected EventListenerList listenerList
+ protected EventListenerList listenerList;
+
public boolean contains(int x, int y)
{
//return dims.contains(x,y);
@@ -701,11 +706,29 @@ public abstract class JComponent extends Container implements Serializable
public void paint(Graphics g)
{
- // System.out.println("SWING_PAINT:" + this);
+ Graphics g2 = g;
+ Image im = null;
+ Rectangle r = getBounds ();
+ // System.err.println(this + ".paint(...), bounds = " + r);
+
+ if (use_double_buffer)
+ {
+ im = createImage (r.width, r.height);
+ g2 = im.getGraphics ();
+ g2.clearRect (0, 0, r.width, r.height);
+ }
+
+ paintBorder(g2);
+ paintComponent(g2);
+ paintChildren(g2);
- paintBorder(g);
- paintComponent(g);
- paintChildren(g);
+ if (use_double_buffer)
+ {
+ // always draw at 0,0, because regardless of your current bounds,
+ // the graphics object you were passed was positioned so the origin
+ // was at the upper left corner of your bounds.
+ g.drawImage (im, 0, 0, (ImageObserver)null);
+ }
}
protected void paintBorder(Graphics g)
@@ -729,7 +752,7 @@ public abstract class JComponent extends Container implements Serializable
protected void paintChildren(Graphics g)
{
// Paint this component's children.
- //super.paintChildren(g);
+ super.paint(g);
}
protected void paintComponent(Graphics g)
diff --git a/libjava/javax/swing/JToggleButton.java b/libjava/javax/swing/JToggleButton.java
index 63972c1..1b05f31 100644
--- a/libjava/javax/swing/JToggleButton.java
+++ b/libjava/javax/swing/JToggleButton.java
@@ -74,7 +74,7 @@ public class JToggleButton extends AbstractButton implements Accessible
super(text, icon);
// Create the model
- setModel(new ToggleButtonModel(this));
+ setModel(new ToggleButtonModel());
model.setSelected(selected);
}
diff --git a/libjava/javax/swing/SwingUtilities.java b/libjava/javax/swing/SwingUtilities.java
index a9113f0..1591132 100644
--- a/libjava/javax/swing/SwingUtilities.java
+++ b/libjava/javax/swing/SwingUtilities.java
@@ -97,8 +97,8 @@ public class SwingUtilities implements SwingConstants
// view rect 'vr' already ok,
// we need to compute ir (icon rect) and tr (text-rect)
- int next_x = 0;//vr.x;
- int next_y = 0;//vr.y;
+ int next_x = vr.x;
+ int next_y = vr.y;
ir.height = ir.width = ir.y = ir.x = 0;
@@ -115,10 +115,10 @@ public class SwingUtilities implements SwingConstants
}
tr.x = next_x;
- tr.y = vr.y + (vr.height/2);
+ tr.y = vr.y; // + (vr.height/2);
tr.width = fm.stringWidth(text);
- tr.height = fm.getHeight() + fm.getAscent()/2;
+ tr.height = fm.getHeight(); // + fm.getAscent()/2;
return text;
}
diff --git a/libjava/javax/swing/ToggleButtonModel.java b/libjava/javax/swing/ToggleButtonModel.java
index b268925..4954604 100644
--- a/libjava/javax/swing/ToggleButtonModel.java
+++ b/libjava/javax/swing/ToggleButtonModel.java
@@ -40,11 +40,6 @@ package javax.swing;
public class ToggleButtonModel extends DefaultButtonModel
{
- ToggleButtonModel(JComponent c)
- {
- super(c);
- }
-
public void setPressed(boolean b)
{
if (! isEnabled())
diff --git a/libjava/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/javax/swing/plaf/basic/BasicButtonUI.java
index 37ce9099..3bcff94 100644
--- a/libjava/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicButtonUI.java
@@ -35,16 +35,23 @@ 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.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.Stroke;
import java.awt.Insets;
import java.awt.Rectangle;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
@@ -53,20 +60,161 @@ import javax.swing.plaf.ComponentUI;
public class BasicButtonUI extends ButtonUI
{
+ /** A constant used to pad out elements in the button's layout and
+ preferred size calculations. */
int gap = 3;
- // int y_text_space = 2, x_text_space + 5;
- Color textColor, disabledTextColor;
- Color pressedBackgroundColor;
- Color normalBackgroundColor;
+ /** The color that text will be painted when the button is enabled */
+ Color textColor;
+ /** The color that text will be painted when the button is disabled */
+ Color disabledTextColor;
+
+ /** The color that the button's background will be painted when the
+ button is pressed. */
+ Color pressedBackgroundColor;
+ /** The color that the button's background will be painted when the
+ button is not pressed. */
+ Color normalBackgroundColor;
+
+ /**
+ * Factory method to create an instance of BasicButtonUI for a given
+ * {@link JComponent}, which should be an {@link AbstractButton}.
+ *
+ * @param c The component to create a UI got
+ *
+ * @return A new UI capable of drawing the component
+ */
public static ComponentUI createUI(final JComponent c)
{
return new BasicButtonUI();
}
+ /**
+ * Helper class which listens to a button's focus events and disarms the
+ * button's model when focus is lost.
+ */
+ private static class FocusUIListener extends FocusAdapter
+ {
+ /** Button to listen to focus events from */
+ AbstractButton button;
+
+ /**
+ * Creates a new FocusUIListener object.
+ *
+ * @param b The button to listen to
+ */
+ FocusUIListener(AbstractButton b)
+ {
+ button = b;
+ }
+ /**
+ * Called when the button loses focus.
+ *
+ * @param event The loss of focus event.
+ */
+ public void focusLost(FocusEvent event)
+ {
+ // System.err.println("ButtonUI :: lost focus -- disarming");
+ button.getModel().setArmed(false);
+ }
+ }
+
+ /**
+ * A helper class which interprets mouse events as
+ * state changes to the button's underlying model.
+ */
+ private static class ButtonUIListener extends MouseAdapter
+ {
+ /** The button to change the model of */
+ AbstractButton button;
+
+ /**
+ * Creates a new ButtonUIListener object.
+ *
+ * @param b The button to change the model of
+ */
+ public ButtonUIListener(AbstractButton b)
+ {
+ button = b;
+ }
+
+ /**
+ * Accept a mouse press event and arm the button's model.
+ *
+ * @param e The mouse press event to accept
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ // System.err.println("ButtonUI :: mouse pressed");
+ if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)
+ {
+ // System.err.println("ButtonUI :: arming");
+ button.getModel().setArmed(true);
+ }
+ }
+
+ /**
+ * Accept a mouse enter event and set the button's model's
+ * "rollover" property to <code>true</code>. If the button's
+ * model is currently armed and the mouse button is not held
+ * down, this enter event will also disarm the model.
+ *
+ * @param e The mouse enter event to accept
+ */
+ public void mouseEntered(MouseEvent e)
+ {
+ // System.err.println("ButtonUI :: mouse entered");
+ // System.err.println("ButtonUI :: rolling over");
+ button.getModel().setRollover(true);
+ if (button.getModel().isArmed()
+ && (e.getModifiers() & InputEvent.BUTTON1_MASK) == 0)
+ {
+ // System.err.println("ButtonUI :: no button pressed -- disarming");
+ button.getModel().setArmed(false);
+ }
+ }
+
+ /**
+ * Accept a mouse exit event and set the button's model's
+ * "rollover" property to <code>false</code>.
+ *
+ * @param e The mouse exit event to accept
+ */
+ public void mouseExited(MouseEvent e)
+ {
+ // System.err.println("ButtonUI :: mouse exited");
+ button.getModel().setRollover(false);
+ }
+
+ /**
+ * Accept a mouse release event and set the button's model's
+ * "pressed" property to <code>true</code>, if the model
+ * is armed. If the model is not armed, ignore the event.
+ *
+ * @param e The mouse release event to accept
+ */
+ public void mouseReleased(MouseEvent e)
+ {
+ // System.err.println("ButtonUI :: mouse released");
+ if (button.getModel().isArmed()
+ && (e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)
+ {
+ button.getModel().setPressed(true);
+ }
+ }
+ }
+
+ /**
+ * Install the BasicButtonUI as the UI for a particular component.
+ * This means registering all the UI's listeners with the component,
+ * and setting any properties of the button which are particular to
+ * this look and feel.
+ *
+ * @param c The component to install the UI into
+ */
public void installUI(final JComponent c)
{
super.installUI(c);
@@ -76,18 +224,37 @@ public class BasicButtonUI extends ButtonUI
pressedBackgroundColor = new Color(150,150,150);
pressedBackgroundColor = new Color(150,150,150);
normalBackgroundColor = new Color(192,192,192);
- }
-
+ // this tells the border (if we have one) how to paint.
+ c.setBackground(normalBackgroundColor);
+ ((AbstractButton)c).setMargin (new Insets(10,10,10,10));
+
+ c.addMouseListener(new ButtonUIListener((AbstractButton) c));
+ c.addFocusListener(new FocusUIListener((AbstractButton) c));
+ }
+
+ /**
+ * Calculate the preferred size of this component, by delegating to
+ * {@link BasicGraphicsUtils.getPreferredButtonSize}.
+ *
+ * @param c The component to measure
+ *
+ * @return The preferred dimensions of the component
+ */
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
- // System.out.println("^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.text);
return d;
}
-
+ /**
+ * Paint the component, which is an {@link AbstractButton}, according to
+ * its current state.
+ *
+ * @param g The graphics context to paint with
+ * @param c The component to paint the state of
+ */
public void paint(Graphics g, JComponent c)
{
AbstractButton b = (AbstractButton) c;
@@ -95,6 +262,7 @@ public class BasicButtonUI extends ButtonUI
Rectangle tr = new Rectangle();
Rectangle ir = new Rectangle();
Rectangle vr = new Rectangle();
+ Rectangle br = new Rectangle();
Font f = c.getFont();
@@ -102,115 +270,150 @@ public class BasicButtonUI extends ButtonUI
FontMetrics fm = g.getFontMetrics(f);
- Insets i = c.getInsets();
+ Insets border = b.getInsets();
+ Insets margin = b.getMargin();
- vr.x = i.left;
- vr.y = i.top;
- vr.width = b.getWidth() - (i.right + vr.x);
- vr.height = b.getHeight() - (i.bottom + vr.y);
-
- //System.out.println(" VIEW-RECT-BUTTON="+vr+", insets="+i+", FONTM="+fm);
-
- String text = SwingUtilities.layoutCompoundLabel(c,
- fm,
- b.getText(),
+ br.x = border.left;
+ br.y = border.top;
+ br.width = b.getWidth() - (border.right + border.left);
+ br.height = b.getHeight() - (border.top + border.bottom);
+
+ vr.x = br.x + margin.left;
+ vr.y = br.y + margin.top;
+ vr.width = br.width - (margin.right + margin.left);
+ vr.height = br.height - (margin.top + margin.bottom);
+
+ String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
b.getHorizontalAlignment(),
b.getVerticalTextPosition(),
b.getHorizontalTextPosition(),
- vr,
- ir,
- tr,
- gap);
+ vr, ir, tr, gap);
- if (b.getModel().isPressed() ||
- b.getModel().isSelected())
- {
- //System.out.println("paint pressed");
- paintButtonPressed(g, c);
- }
+ if ((b.getModel().isRollover() && b.getModel().isArmed())
+ || b.getModel().isSelected())
+ paintButtonPressed(g, br, c);
else
- {
- //System.out.println("paint normal");
- paintButtonNormal(g, c);
- }
+ paintButtonNormal(g, br, c);
paintIcon(g, c, ir);
paintText(g, c, tr, b.getText());
paintFocus(g, c, vr, tr, ir);
}
-
- protected void paintFocus(Graphics g,
- JComponent c,
- Rectangle vr,
- Rectangle tr,
- Rectangle ir)
+ /**
+ * Paint any focus decoration this {@link JComponent} might have. The
+ * component, which in this case will be an {@link AbstractButton},
+ * should only have focus decoration painted if it has the focus, and its
+ * "focusPainted" property is <code>true</code>.
+ *
+ * @param g Graphics context to paint with
+ * @param c Component to paint the focus of
+ * @param vr Visible rectangle, the area in which to paint
+ * @param tr Text rectangle, contained in visible rectangle
+ * @param ir Icon rectangle, contained in visible rectangle
+ *
+ * @see AbstractButton.isFocusPainted()
+ * @see JComponent.hasFocus()
+ */
+ protected void paintFocus(Graphics g, JComponent c, Rectangle vr,
+ Rectangle tr, Rectangle ir)
+ {
+ AbstractButton b = (AbstractButton) c;
+ if (b.hasFocus() && b.isFocusPainted())
{
+ Graphics2D g2 = (Graphics2D) g;
+ Stroke saved_stroke = g2.getStroke();
+ Color saved_color = g2.getColor();
+ float dashes[] = new float[] {1.0f, 1.0f};
+ BasicStroke s = new BasicStroke(1.0f,
+ BasicStroke.CAP_SQUARE,
+ BasicStroke.JOIN_MITER,
+ 10, dashes, 0.0f);
+ g2.setStroke(s);
+ g2.setColor(Color.BLACK);
+ g2.drawRect(vr.x + 2,
+ vr.y + 2,
+ vr.width - 4,
+ vr.height - 4);
+ g2.setStroke(saved_stroke);
+ g2.setColor(saved_color);
+ }
}
- protected void paintIcon(Graphics g,
- JComponent c,
- Rectangle iconRect)
+ /**
+ * Paint the icon for this component. Depending on the state of the
+ * component and the availability of the button's various icon
+ * properties, this might mean painting one of several different icons.
+ *
+ * @param g Graphics context to paint with
+ * @param c Component to paint the icon of
+ * @param iconRect Rectangle in which the icon should be painted
+ */
+ protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
{
AbstractButton b = (AbstractButton) c;
if (b.getIcon() != null)
{
int x = iconRect.x;
int y = iconRect.y;
-
- System.out.println("WE HAVE AN ICON: " + b.getIcon());
-
b.getIcon().paintIcon(c, g, x, y);
}
- else
- {
- //System.out.println("NO ICON FOR BUTTON:" + b.text);
- }
}
- protected void paintButtonPressed(Graphics g,
- JComponent b)
+ /**
+ * Paints the background area of an {@link AbstractButton} in the pressed
+ * state. This means filling the supplied area with the {@link
+ * pressedBackgroundColor}.
+ *
+ * @param g The graphics context to paint with
+ * @param area The area in which to paint
+ * @param b The component to paint the state of
+ */
+ protected void paintButtonPressed(Graphics g, Rectangle area, JComponent b)
{
Dimension size = b.getSize();
g.setColor(pressedBackgroundColor);
- g.fillRect(1,1,size.width-2, size.height-2);
-
+ g.fillRect(area.x, area.y, area.width, area.height);
}
- protected void paintButtonNormal(Graphics g,
- JComponent b)
+ /**
+ * Paints the background area of an {@link AbstractButton} in the normal,
+ * non-pressed state. This means filling the supplied area with the
+ * {@link normalBackgroundColor}.
+ *
+ * @param g The graphics context to paint with
+ * @param area The area in which to paint
+ * @param b The component to paint the state of
+ */
+ protected void paintButtonNormal(Graphics g, Rectangle area, JComponent b)
{
Dimension size = b.getSize();
-
g.setColor(normalBackgroundColor);
- g.fillRect(1,1,size.width-2, size.height-2);
-
+ g.fillRect(area.x, area.y, area.width, area.height);
}
- protected void paintText(Graphics g,
- JComponent c,
- Rectangle textRect,
+ /**
+ * Paints the "text" property of an {@link AbstractButton}, using the
+ * {@link textColor} color.
+ *
+ * @param g The graphics context to paint with
+ * @param c The component to paint the state of
+ * @param textRect The area in which to paint the text
+ * @param text The text to paint
+ */
+ protected void paintText(Graphics g, JComponent c, Rectangle textRect,
String text)
{
Font f = c.getFont();
-
g.setFont(f);
-
FontMetrics fm = g.getFontMetrics(f);
-
g.setColor(c.isEnabled() ? textColor : disabledTextColor);
-
- BasicGraphicsUtils.drawString(g,
- text,
+ BasicGraphicsUtils.drawString(g, text,
0,
textRect.x,
- textRect.y + fm.getAscent()/2);
+ textRect.y + fm.getAscent());
}
}
-
-
-
-
diff --git a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
index d7b53d5..f88bf92 100644
--- a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
+++ b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
@@ -595,6 +595,7 @@ public class BasicGraphicsUtils
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Insets insets = b.getInsets();
+ Insets margin = b.getMargin();
/* For determining the ideal size, do not assume a size restriction. */
viewRect = new Rectangle(0, 0,
@@ -620,7 +621,6 @@ public class BasicGraphicsUtils
viewRect, iconRect, textRect,
textIconGap);
-
/* +------------------------+ +------------------------+
* | | | |
* | ICON | | CONTENTCONTENTCONTENT |
@@ -630,7 +630,11 @@ public class BasicGraphicsUtils
*/
contentRect = textRect.union(iconRect);
- return new Dimension(insets.left + contentRect.width + insets.right,
- insets.top + contentRect.height + insets.bottom);
+ return new Dimension(insets.left + margin.left
+ + contentRect.width
+ + insets.right + margin.right,
+ insets.top + margin.top
+ + contentRect.height
+ + insets.bottom + margin.bottom);
}
}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
index 9a935b0..742550f 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
@@ -228,12 +228,25 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
{
void *ptr = NSA_GET_PTR (env, obj);
jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+ GtkWidget* vbox, *layout;
+ GList* children;
g_assert (gref);
gdk_threads_enter ();
gtk_widget_realize (ptr);
+ /* Receive events from the GtkLayout too */
+ children = gtk_container_get_children(GTK_CONTAINER(ptr));
+ vbox = children->data;
+ g_assert(GTK_IS_VBOX(vbox));
+ children = gtk_container_get_children(GTK_CONTAINER(vbox));
+ layout = children->data;
+ g_assert(GTK_IS_LAYOUT(layout));
+
+ g_signal_connect (GTK_OBJECT (layout), "event",
+ G_CALLBACK (pre_event_handler), *gref);
+
/* Connect signals for window event support. */
g_signal_connect (G_OBJECT (ptr), "delete-event",
G_CALLBACK (window_delete_cb), *gref);