summaryrefslogtreecommitdiff
path: root/javax/swing/AbstractButton.java
diff options
context:
space:
mode:
Diffstat (limited to 'javax/swing/AbstractButton.java')
-rw-r--r--javax/swing/AbstractButton.java453
1 files changed, 398 insertions, 55 deletions
diff --git a/javax/swing/AbstractButton.java b/javax/swing/AbstractButton.java
index 49c74dd06..d4e35cfa3 100644
--- a/javax/swing/AbstractButton.java
+++ b/javax/swing/AbstractButton.java
@@ -45,6 +45,7 @@ import java.awt.Insets;
import java.awt.ItemSelectable;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
@@ -53,17 +54,26 @@ import java.awt.image.ImageObserver;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
+import java.util.Enumeration;
+import javax.accessibility.Accessible;
import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleIcon;
+import javax.accessibility.AccessibleRelation;
import javax.accessibility.AccessibleRelationSet;
+import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ButtonUI;
+import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Position;
+import javax.swing.text.View;
/**
@@ -277,6 +287,42 @@ public abstract class AbstractButton extends JComponent
protected ChangeEvent changeEvent = new ChangeEvent(this);
/**
+ * Indicates if the borderPainted property has been set by a client
+ * program or by the UI.
+ *
+ * @see #setUIProperty(String, Object)
+ * @see LookAndFeel#installProperty(JComponent, String, Object)
+ */
+ private boolean clientBorderPaintedSet = false;
+
+ /**
+ * Indicates if the rolloverEnabled property has been set by a client
+ * program or by the UI.
+ *
+ * @see #setUIProperty(String, Object)
+ * @see LookAndFeel#installProperty(JComponent, String, Object)
+ */
+ private boolean clientRolloverEnabledSet = false;
+
+ /**
+ * Indicates if the iconTextGap property has been set by a client
+ * program or by the UI.
+ *
+ * @see #setUIProperty(String, Object)
+ * @see LookAndFeel#installProperty(JComponent, String, Object)
+ */
+ private boolean clientIconTextGapSet = false;
+
+ /**
+ * Indicates if the contentAreaFilled property has been set by a client
+ * program or by the UI.
+ *
+ * @see #setUIProperty(String, Object)
+ * @see LookAndFeel#installProperty(JComponent, String, Object)
+ */
+ private boolean clientContentAreaFilledSet = false;
+
+ /**
* Fired in a PropertyChangeEvent when the "borderPainted" property changes.
*/
public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
@@ -390,10 +436,27 @@ public abstract class AbstractButton extends JComponent
// Nothing to do here yet.
}
+ /**
+ * Returns the accessible state set of this object. In addition to the
+ * superclass's states, the <code>AccessibleAbstractButton</code>
+ * supports the following states: {@link AccessibleState#ARMED},
+ * {@link AccessibleState#FOCUSED}, {@link AccessibleState#PRESSED} and
+ * {@link AccessibleState#CHECKED}.
+ *
+ * @return the curren state of this accessible object
+ */
public AccessibleStateSet getAccessibleStateSet()
- throws NotImplementedException
{
- return null; // TODO
+ AccessibleStateSet state = super.getAccessibleStateSet();
+
+ if (getModel().isArmed())
+ state.add(AccessibleState.ARMED);
+ if (getModel().isPressed())
+ state.add(AccessibleState.PRESSED);
+ if (isSelected())
+ state.add(AccessibleState.CHECKED);
+
+ return state;
}
/**
@@ -407,101 +470,300 @@ public abstract class AbstractButton extends JComponent
return result;
}
+ /**
+ * Returns the accessible icons of this object. If the AbstractButton's
+ * icon is an Accessible, and it's AccessibleContext is an AccessibleIcon,
+ * then this AccessibleIcon is returned, otherwise <code>null</code>.
+ *
+ * @return the accessible icons of this object, or <code>null</code> if
+ * there is no accessible icon
+ */
public AccessibleIcon[] getAccessibleIcon()
- throws NotImplementedException
{
- return null; // TODO
+ AccessibleIcon[] ret = null;
+ Icon icon = getIcon();
+ if (icon instanceof Accessible)
+ {
+ AccessibleContext ctx = ((Accessible) icon).getAccessibleContext();
+ if (ctx instanceof AccessibleIcon)
+ {
+ ret = new AccessibleIcon[]{ (AccessibleIcon) ctx };
+ }
+ }
+ return ret;
}
+ /**
+ * Returns the accessible relations of this AccessibleAbstractButton.
+ * If the AbstractButton is part of a ButtonGroup, then all the buttons
+ * in this button group are added as targets in a MEMBER_OF relation,
+ * otherwise an empty relation set is returned (from super).
+ *
+ * @return the accessible relations of this AccessibleAbstractButton
+ */
public AccessibleRelationSet getAccessibleRelationSet()
- throws NotImplementedException
{
- // TODO: What should be modified here?
- return super.getAccessibleRelationSet();
+ AccessibleRelationSet relations = super.getAccessibleRelationSet();
+ ButtonModel model = getModel();
+ if (model instanceof DefaultButtonModel)
+ {
+ ButtonGroup group = ((DefaultButtonModel) model).getGroup();
+ if (group != null)
+ {
+ Object[] target = new Object[group.getButtonCount()];
+ Enumeration els = group.getElements();
+
+ for (int index = 0; els.hasMoreElements(); ++index)
+ {
+ target[index] = els.nextElement();
+ }
+
+ AccessibleRelation rel =
+ new AccessibleRelation(AccessibleRelation.MEMBER_OF);
+ rel.setTarget(target);
+ relations.add(rel);
+ }
+ }
+ return relations;
}
+ /**
+ * Returns the accessible action associated with this object. For buttons,
+ * this will be <code>this</code>.
+ *
+ * @return <code>this</code>
+ */
public AccessibleAction getAccessibleAction()
- throws NotImplementedException
{
- return null; // TODO
+ return this;
}
+ /**
+ * Returns the accessible value of this AccessibleAbstractButton, which
+ * is always <code>this</code>.
+ *
+ * @return the accessible value of this AccessibleAbstractButton, which
+ * is always <code>this</code>
+ */
public AccessibleValue getAccessibleValue()
- throws NotImplementedException
{
- return null; // TODO
+ return this;
}
+ /**
+ * Returns the number of accessible actions that are supported by this
+ * object. Buttons support one action by default ('press button'), so this
+ * method always returns <code>1</code>.
+ *
+ * @return <code>1</code>, the number of supported accessible actions
+ */
public int getAccessibleActionCount()
- throws NotImplementedException
{
- return 0; // TODO
+ return 1;
}
- public String getAccessibleActionDescription(int value0)
- throws NotImplementedException
+ /**
+ * Returns a description for the action with the specified index or
+ * <code>null</code> if such action does not exist.
+ *
+ * @param actionIndex the zero based index to the actions
+ *
+ * @return a description for the action with the specified index or
+ * <code>null</code> if such action does not exist
+ */
+ public String getAccessibleActionDescription(int actionIndex)
{
- return null; // TODO
+ String descr = null;
+ if (actionIndex == 0)
+ {
+ // FIXME: Supply localized descriptions in the UIDefaults.
+ descr = UIManager.getString("AbstractButton.clickText");
+ }
+ return descr;
}
- public boolean doAccessibleAction(int value0)
- throws NotImplementedException
+ /**
+ * Performs the acccessible action with the specified index on this object.
+ * Since buttons have only one action by default (which is to press the
+ * button), this method performs a 'press button' when the specified index
+ * is <code>0</code> and nothing otherwise.
+ *
+ * @param actionIndex a zero based index into the actions of this button
+ *
+ * @return <code>true</code> if the specified action has been performed
+ * successfully, <code>false</code> otherwise
+ */
+ public boolean doAccessibleAction(int actionIndex)
{
- return false; // TODO
+ boolean retVal = false;
+ if (actionIndex == 0)
+ {
+ doClick();
+ retVal = true;
+ }
+ return retVal;
}
+ /**
+ * Returns the current value of this object as a number. This
+ * implementation returns an <code>Integer(1)</code> if the button is
+ * selected, <code>Integer(0)</code> if the button is not selected.
+ *
+ * @return the current value of this object as a number
+ */
public Number getCurrentAccessibleValue()
- throws NotImplementedException
{
- return null; // TODO
+ Integer retVal;
+ if (isSelected())
+ retVal = new Integer(1);
+ else
+ retVal = new Integer(0);
+ return retVal;
}
- public boolean setCurrentAccessibleValue(Number value0)
- throws NotImplementedException
+ /**
+ * Sets the current accessible value as object. If the specified number
+ * is 0 the button will be deselected, otherwise the button will
+ * be selected.
+ *
+ * @param value 0 for deselected button, other for selected button
+ *
+ * @return <code>true</code> if the value has been set, <code>false</code>
+ * otherwise
+ */
+ public boolean setCurrentAccessibleValue(Number value)
{
- return false; // TODO
+ boolean retVal = false;
+ if (value != null)
+ {
+ if (value.intValue() == 0)
+ setSelected(false);
+ else
+ setSelected(true);
+ retVal = true;
+ }
+ return retVal;
}
+ /**
+ * Returns the minimum accessible value for the AccessibleAbstractButton,
+ * which is <code>0</code>.
+ *
+ * @return the maxinimum accessible value for the AccessibleAbstractButton,
+ * which is <code>1</code>
+ */
public Number getMinimumAccessibleValue()
- throws NotImplementedException
{
- return null; // TODO
+ return new Integer(0);
}
+ /**
+ * Returns the maximum accessible value for the AccessibleAbstractButton,
+ * which is <code>1</code>.
+ *
+ * @return the maximum accessible value for the AccessibleAbstractButton,
+ * which is <code>1</code>
+ */
public Number getMaximumAccessibleValue()
- throws NotImplementedException
{
- return null; // TODO
+ return new Integer(1);
}
+ /**
+ * Returns the accessible text for this AccessibleAbstractButton. This
+ * will be <code>null</code> if the button has a non-HTML label, otherwise
+ * <code>this</code>.
+ *
+ * @return the accessible text for this AccessibleAbstractButton
+ */
public AccessibleText getAccessibleText()
- throws NotImplementedException
{
- return null; // TODO
+ AccessibleText accessibleText = null;
+ if (getClientProperty(BasicHTML.propertyKey) != null)
+ accessibleText = this;
+
+ return accessibleText;
}
- public int getIndexAtPoint(Point value0)
- throws NotImplementedException
+ /**
+ * Returns the index of the label's character at the specified point,
+ * relative to the local bounds of the button. This only works for
+ * HTML labels.
+ *
+ * @param p the point, relative to the buttons local bounds
+ *
+ * @return the index of the label's character at the specified point
+ */
+ public int getIndexAtPoint(Point p)
{
- return 0; // TODO
+ int index = -1;
+ View view = (View) getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ {
+ Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight());
+ index = view.viewToModel(p.x, p.y, shape, new Position.Bias[1]);
+ }
+ return index;
}
- public Rectangle getCharacterBounds(int value0)
- throws NotImplementedException
+ /**
+ * Returns the bounds of the character at the specified index of the
+ * button's label. This will only work for HTML labels.
+ *
+ * @param i the index of the character of the label
+ *
+ * @return the bounds of the character at the specified index of the
+ * button's label
+ */
+ public Rectangle getCharacterBounds(int i)
{
- return null; // TODO
+ Rectangle rect = null;
+ View view = (View) getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ {
+ Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight());
+ try
+ {
+ Shape s = view.modelToView(i, shape, Position.Bias.Forward);
+ rect = s.getBounds();
+ }
+ catch (BadLocationException ex)
+ {
+ rect = null;
+ }
+ }
+ return rect;
}
+ /**
+ * Returns the number of characters in the button's label.
+ *
+ * @return the bounds of the character at the specified index of the
+ * button's label
+ */
public int getCharCount()
- throws NotImplementedException
{
- return 0; // TODO
+ int charCount;
+ View view = (View) getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ {
+ charCount = view.getDocument().getLength();
+ }
+ else
+ {
+ charCount = getAccessibleName().length();
+ }
+ return charCount;
}
+ /**
+ * This always returns <code>-1</code> since there is no caret in a button.
+ *
+ * @return <code>-1</code> since there is no caret in a button
+ */
public int getCaretPosition()
- throws NotImplementedException
{
- return 0; // TODO
+ return -1;
}
public String getAtIndex(int value0, int value1)
@@ -522,34 +784,57 @@ public abstract class AbstractButton extends JComponent
return null; // TODO
}
- public AttributeSet getCharacterAttribute(int value0)
- throws NotImplementedException
+ /**
+ * Returns the text attribute for the character at the specified character
+ * index.
+ *
+ * @param i the character index
+ *
+ * @return the character attributes for the specified character or
+ * <code>null</code> if the character has no attributes
+ */
+ public AttributeSet getCharacterAttribute(int i)
{
- return null; // TODO
+ AttributeSet atts = null;
+ View view = (View) getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ {
+
+ }
+ return atts;
}
+ /**
+ * This always returns <code>-1</code> since
+ * button labels can't be selected.
+ *
+ * @return <code>-1</code>, button labels can't be selected
+ */
public int getSelectionStart()
- throws NotImplementedException
{
- return 0; // TODO
+ return -1;
}
+ /**
+ * This always returns <code>-1</code> since
+ * button labels can't be selected.
+ *
+ * @return <code>-1</code>, button labels can't be selected
+ */
public int getSelectionEnd()
- throws NotImplementedException
{
- return 0; // TODO
+ return -1;
}
+ /**
+ * Returns the selected text. This always returns <code>null</code> since
+ * button labels can't be selected.
+ *
+ * @return <code>null</code>, button labels can't be selected
+ */
public String getSelectedText()
- throws NotImplementedException
{
- return null; // TODO
- }
-
- private Rectangle getTextRectangle()
- throws NotImplementedException
- {
- return null; // TODO
+ return null;
}
}
@@ -939,6 +1224,7 @@ public abstract class AbstractButton extends JComponent
*/
public void setRolloverEnabled(boolean r)
{
+ clientRolloverEnabledSet = true;
if (rollOverEnabled != r)
{
rollOverEnabled = r;
@@ -1171,6 +1457,7 @@ public abstract class AbstractButton extends JComponent
*/
public void setBorderPainted(boolean b)
{
+ clientBorderPaintedSet = true;
if (borderPainted == b)
return;
boolean old = borderPainted;
@@ -1321,6 +1608,7 @@ public abstract class AbstractButton extends JComponent
*/
public void setIconTextGap(int i)
{
+ clientIconTextGapSet = true;
if (iconTextGap == i)
return;
@@ -1954,6 +2242,7 @@ public abstract class AbstractButton extends JComponent
*/
public void setContentAreaFilled(boolean b)
{
+ clientContentAreaFilledSet = true;
if (contentAreaFilled == b)
return;
@@ -2081,4 +2370,58 @@ public abstract class AbstractButton extends JComponent
multiClickThreshhold = threshhold;
}
+
+ /**
+ * Helper method for
+ * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
+ *
+ * @param propertyName the name of the property
+ * @param value the value of the property
+ *
+ * @throws IllegalArgumentException if the specified property cannot be set
+ * by this method
+ * @throws ClassCastException if the property value does not match the
+ * property type
+ * @throws NullPointerException if <code>c</code> or
+ * <code>propertyValue</code> is <code>null</code>
+ */
+ void setUIProperty(String propertyName, Object value)
+ {
+ if (propertyName.equals("borderPainted"))
+ {
+ if (! clientBorderPaintedSet)
+ {
+ setBorderPainted(((Boolean) value).booleanValue());
+ clientBorderPaintedSet = false;
+ }
+ }
+ else if (propertyName.equals("rolloverEnabled"))
+ {
+ if (! clientRolloverEnabledSet)
+ {
+ setRolloverEnabled(((Boolean) value).booleanValue());
+ clientRolloverEnabledSet = false;
+ }
+ }
+ else if (propertyName.equals("iconTextGap"))
+ {
+ if (! clientIconTextGapSet)
+ {
+ setIconTextGap(((Integer) value).intValue());
+ clientIconTextGapSet = false;
+ }
+ }
+ else if (propertyName.equals("contentAreaFilled"))
+ {
+ if (! clientContentAreaFilledSet)
+ {
+ setContentAreaFilled(((Boolean) value).booleanValue());
+ clientContentAreaFilledSet = false;
+ }
+ }
+ else
+ {
+ super.setUIProperty(propertyName, value);
+ }
+ }
}