Commit ca3bb0c2 by Graydon Hoare Committed by Graydon Hoare

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
parent 1fd05073
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> 2004-01-21 Thomas Fitzsimmons <fitzsim@redhat.com>
* java/awt/Component.java (show): Set visible to true before * java/awt/Component.java (show): Set visible to true before
......
...@@ -70,6 +70,8 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer ...@@ -70,6 +70,8 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer
{ {
System.loadLibrary("gtkpeer"); System.loadLibrary("gtkpeer");
} }
if (GtkToolkit.useGraphics2D ())
initStaticState (); initStaticState ();
} }
native static void initStaticState (); native static void initStaticState ();
......
...@@ -60,6 +60,8 @@ public class GdkGlyphVector extends GlyphVector ...@@ -60,6 +60,8 @@ public class GdkGlyphVector extends GlyphVector
{ {
System.loadLibrary("gtkpeer"); System.loadLibrary("gtkpeer");
} }
if (GtkToolkit.useGraphics2D ())
initStaticState (); initStaticState ();
} }
native static void initStaticState (); native static void initStaticState ();
......
...@@ -4252,6 +4252,7 @@ p * <li>the set of backward traversal keys ...@@ -4252,6 +4252,7 @@ p * <li>the set of backward traversal keys
default: default:
throw new IllegalArgumentException("unknown paint event"); throw new IllegalArgumentException("unknown paint event");
} }
event.consume ();
} }
finally finally
{ {
......
/* AbstractButton.java -- Provides basic button functionality. /* 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. This file is part of GNU Classpath.
...@@ -35,9 +35,10 @@ this exception to your version of the library, but you are not ...@@ -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 obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package javax.swing; package javax.swing;
import java.awt.AWTEvent;
import java.awt.AWTEventMulticaster;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Image; import java.awt.Image;
import java.awt.Insets; import java.awt.Insets;
...@@ -51,11 +52,15 @@ import java.awt.event.FocusListener; ...@@ -51,11 +52,15 @@ import java.awt.event.FocusListener;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.awt.event.ItemListener;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Vector;
import java.util.EventListener;
import javax.accessibility.AccessibleAction; import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleIcon; import javax.accessibility.AccessibleIcon;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleRelationSet; import javax.accessibility.AccessibleRelationSet;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText; import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue; import javax.accessibility.AccessibleValue;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
...@@ -63,739 +68,1734 @@ import javax.swing.event.ChangeListener; ...@@ -63,739 +68,1734 @@ import javax.swing.event.ChangeListener;
import javax.swing.plaf.ButtonUI; import javax.swing.plaf.ButtonUI;
import javax.swing.text.AttributeSet; import javax.swing.text.AttributeSet;
/** /**
* Provides basic button functionality * <p>The purpose of this class is to serve as a facade over a number of
* classes which collectively represent the semantics of a button: the
* button's model, its listeners, its action, and its look and feel. Some
* parts of a button's state are stored explicitly in this class, other
* parts are delegates to the model. Some methods related to buttons are
* implemented in this class, other methods pass through to the current
* model or look and feel.</p>
*
* <p>Furthermore this class is supposed to serve as a base class for
* several kinds of buttons with similar but non-identical semantics:
* toggle buttons (radio buttons and checkboxes), simple "push" buttons,
* menu items.</p>
*
* <p>Buttons have many properties, some of which are stored in this class
* while others are delegated to the button's model. The following properties
* are available:</p>
*
* <table>
* <tr><th>Property </th><th>Stored in</th><th>Bound?</th></tr>
*
* <tr><td>action </td><td>button</td> <td>no</td></tr>
* <tr><td>actionCommand </td><td>model</td> <td>no</td></tr>
* <tr><td>borderPainted </td><td>button</td> <td>yes</td></tr>
* <tr><td>contentAreaFilled </td><td>button</td> <td>yes</td></tr>
* <tr><td>disabledIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>disabledSelectedIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr>
* <tr><td>enabled </td><td>model</td> <td>no</td></tr>
* <tr><td>focusPainted </td><td>button</td> <td>yes</td></tr>
* <tr><td>horizontalAlignment </td><td>button</td> <td>yes</td></tr>
* <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr>
* <tr><td>icon </td><td>button</td> <td>yes</td></tr>
* <tr><td>iconTextGap </td><td>button</td> <td>no</td></tr>
* <tr><td>label (same as text) </td><td>model</td> <td>yes</td></tr>
* <tr><td>margin </td><td>button</td> <td>yes</td></tr>
* <tr><td>multiClickThreshold </td><td>button</td> <td>no</td></tr>
* <tr><td>pressedIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>rolloverEnabled </td><td>button</td> <td>yes</td></tr>
* <tr><td>rolloverIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>rolloverSelectedIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>selected </td><td>model</td> <td>no</td></tr>
* <tr><td>selectedIcon </td><td>button</td> <td>yes</td></tr>
* <tr><td>selectedObjects </td><td>button</td> <td>no</td></tr>
* <tr><td>text </td><td>model</td> <td>yes</td></tr>
* <tr><td>UI </td><td>button</td> <td>yes</td></tr>
* <tr><td>verticalAlignment </td><td>button</td> <td>yes</td></tr>
* <tr><td>verticalTextPosition </td><td>button</td> <td>yes</td></tr>
*
* </table>
*
* <p>The various behavioral aspects of these properties follows:</p>
*
* <ul>
*
* <li>When non-bound properties stored in the button change, the button
* fires ChangeEvents to its ChangeListeners.</li>
*
* <li>When bound properties stored in the button change, the button fires
* PropertyChangeEvents to its PropertyChangeListeners</li>
*
* <li>If any of the model's properties change, it fires a ChangeEvent to
* its ChangeListeners, which include the button.</li>
*
* <li>If the button receives a ChangeEvent from its model, it will
* propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's
* "source" property set to refer to the button, rather than the model. The
* the button will request a repaint, to paint its updated state.</li>
*
* <li>If the model's "selected" property changes, the model will fire an
* ItemEvent to its ItemListeners, which include the button, in addition to
* the ChangeEvent which models the property change. The button propagates
* ItemEvents directly to its ItemListeners.</li>
* *
* @author Ronald Veldema (rveldema@cs.vu.nl) * <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 public abstract class AbstractButton extends JComponent
implements ItemSelectable, SwingConstants implements ItemSelectable, SwingConstants
{ {
Icon default_icon, pressed_button, disabled_button, /** The icon displayed by default. */
selected_button, disabled_selected_button, current_icon; 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; String text;
/** The vertical alignment of the button's text and icon. */
int vert_align = CENTER; int vert_align = CENTER;
/** The horizontal alignment of the button's text and icon. */
int hori_align = CENTER; int hori_align = CENTER;
/** The horizontal position of the button's text relative to its icon. */
int hori_text_pos = CENTER; int hori_text_pos = CENTER;
/** The vertical position of the button's text relative to its icon. */
int vert_text_pos = CENTER; int vert_text_pos = CENTER;
boolean paint_border = true, paint_focus; /** Whether or not the button paints its border. */
Action action_taken; 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; ButtonModel model;
/** The margin between the button's border and its label. */
Insets margin; 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;
/** /** Listener the button uses to receive ActionEvents from its model. */
* AccessibleAbstractButton ActionListener actionListener;
*/
protected abstract class AccessibleAbstractButton
extends AccessibleJComponent
implements AccessibleAction, AccessibleValue, AccessibleText {
/** /** Listener the button uses to receive ItemEvents from its model. */
* Constructor AccessibleAbstractButton ItemListener itemListener;
* @param component TODO
*/ /** Listener the button uses to receive ChangeEvents from its model. */
protected AccessibleAbstractButton(AbstractButton component) { ChangeListener changeListener;
super(component);
// TODO /** Listener the button uses to receive PropertyChangeEvents from its
} // AccessibleAbstractButton() 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 * A Java Accessibility extension of the AbstractButton.
* @returns AccessibleStateSet
*/ */
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 return null; // TODO
} // getAccessibleStateSet() }
/** public String getAccessibleName()
* getAccessibleName {
* @returns String
*/
public String getAccessibleName() {
return null; // TODO return null; // TODO
} // getAccessibleName() }
/** public AccessibleIcon[] getAccessibleIcon()
* getAccessibleIcon {
* @returns AccessibleIcon[]
*/
public AccessibleIcon[] getAccessibleIcon() {
return null; // TODO return null; // TODO
} // getAccessibleIcon() }
/** public AccessibleRelationSet getAccessibleRelationSet()
* getAccessibleRelationSet {
* @returns AccessibleRelationSet
*/
public AccessibleRelationSet getAccessibleRelationSet() {
return null; // TODO return null; // TODO
} // getAccessibleRelationSet() }
/** public AccessibleAction getAccessibleAction()
* getAccessibleAction {
* @returns AccessibleAction
*/
public AccessibleAction getAccessibleAction() {
return null; // TODO return null; // TODO
} // getAccessibleAction() }
/** public AccessibleValue getAccessibleValue()
* getAccessibleValue {
* @returns AccessibleValue
*/
public AccessibleValue getAccessibleValue() {
return null; // TODO return null; // TODO
} // getAccessibleValue() }
/** public int getAccessibleActionCount()
* getAccessibleActionCount {
* @returns int
*/
public int getAccessibleActionCount() {
return 0; // TODO return 0; // TODO
} // getAccessibleActionCount() }
/** public String getAccessibleActionDescription(int value0)
* getAccessibleActionDescription {
* @param value0 TODO
* @returns String
*/
public String getAccessibleActionDescription(int value0) {
return null; // TODO return null; // TODO
} // getAccessibleActionDescription() }
/** public boolean doAccessibleAction(int value0)
* doAccessibleAction {
* @param value0 TODO
* @returns boolean
*/
public boolean doAccessibleAction(int value0) {
return false; // TODO return false; // TODO
} // doAccessibleAction() }
/** public Number getCurrentAccessibleValue()
* getCurrentAccessibleValue {
* @returns Number
*/
public Number getCurrentAccessibleValue() {
return null; // TODO return null; // TODO
} // getCurrentAccessibleValue() }
/** public boolean setCurrentAccessibleValue(Number value0)
* setCurrentAccessibleValue {
* @param value0 TODO
* @returns boolean
*/
public boolean setCurrentAccessibleValue(Number value0) {
return false; // TODO return false; // TODO
} // setCurrentAccessibleValue() }
/** public Number getMinimumAccessibleValue()
* getMinimumAccessibleValue {
* @returns Number
*/
public Number getMinimumAccessibleValue() {
return null; // TODO return null; // TODO
} // getMinimumAccessibleValue() }
/** public Number getMaximumAccessibleValue()
* getMaximumAccessibleValue {
* @returns Number
*/
public Number getMaximumAccessibleValue() {
return null; // TODO return null; // TODO
} // getMaximumAccessibleValue() }
/** public AccessibleText getAccessibleText()
* getAccessibleText {
* @returns AccessibleText
*/
public AccessibleText getAccessibleText() {
return null; // TODO return null; // TODO
} // getAccessibleText() }
/** public int getIndexAtPoint(Point value0)
* getIndexAtPoint {
* @param value0 TODO
* @returns int
*/
public int getIndexAtPoint(Point value0) {
return 0; // TODO return 0; // TODO
} // getIndexAtPoint() }
/** public Rectangle getCharacterBounds(int value0)
* getCharacterBounds {
* @param value0 TODO
* @returns Rectangle
*/
public Rectangle getCharacterBounds(int value0) {
return null; // TODO return null; // TODO
} // getCharacterBounds() }
/** public int getCharCount()
* getCharCount {
* @returns int
*/
public int getCharCount() {
return 0; // TODO return 0; // TODO
} // getCharCount() }
/** public int getCaretPosition()
* getCaretPosition {
* @returns int
*/
public int getCaretPosition() {
return 0; // TODO return 0; // TODO
} // getCaretPosition() }
/** public String getAtIndex(int value0, int value1)
* getAtIndex {
* @param value0 TODO
* @param value1 TODO
* @returns String
*/
public String getAtIndex(int value0, int value1) {
return null; // TODO return null; // TODO
} // getAtIndex() }
/** public String getAfterIndex(int value0, int value1)
* getAfterIndex {
* @param value0 TODO
* @param value1 TODO
* @returns String
*/
public String getAfterIndex(int value0, int value1) {
return null; // TODO return null; // TODO
} // getAfterIndex() }
/** public String getBeforeIndex(int value0, int value1)
* getBeforeIndex {
* @param value0 TODO
* @param value1 TODO
* @returns String
*/
public String getBeforeIndex(int value0, int value1) {
return null; // TODO return null; // TODO
} // getBeforeIndex() }
/** public AttributeSet getCharacterAttribute(int value0)
* getCharacterAttribute {
* @param value0 TODO
* @returns AttributeSet
*/
public AttributeSet getCharacterAttribute(int value0) {
return null; // TODO return null; // TODO
} // getCharacterAttribute() }
/** public int getSelectionStart()
* getSelectionStart {
* @returns int
*/
public int getSelectionStart() {
return 0; // TODO return 0; // TODO
} // getSelectionStart() }
/** public int getSelectionEnd()
* getSelectionEnd {
* @returns int
*/
public int getSelectionEnd() {
return 0; // TODO 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); /**
* Possibly repaint the model in response to loss of focus.
System.out.println("LOST FOCUS"); *
if (c.isFocusPainted()) * @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) public void focusGained(FocusEvent event)
{ {
System.out.println("GAIN FOCUS"); if (AbstractButton.this.isFocusPainted())
AbstractButton.this.repaint();
} }
} }
/**
* Creates a new AbstractButton object.
*/
AbstractButton() AbstractButton()
{ {
this("",null); 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; text = txt;
setIcon(icon); default_icon = icon;
model = new DefaultButtonModel();
actionListener = createActionListener();
changeListener = createChangeListener();
itemListener = createItemListener();
model.addActionListener(actionListener);
model.addChangeListener(changeListener);
model.addItemListener(itemListener);
setAlignmentX(LEFT_ALIGNMENT); setAlignmentX(LEFT_ALIGNMENT);
setAlignmentY(CENTER_ALIGNMENT); setAlignmentY(CENTER_ALIGNMENT);
addFocusListener(new ButtonFocusListener());
addFocusListener( new JFocusListener(this) ); updateUI();
setModel(new DefaultButtonModel(this));
updateUI(); // get a proper ui
} }
/**
* Get the model the button is currently using.
*
* @return The current model
*/
public ButtonModel getModel() 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) 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() 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) 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) 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) 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) 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) 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() 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) public void setBorderPainted(boolean b)
{ {
if (b != paint_border) boolean old = paint_border;
{
paint_border = b; paint_border = b;
if (b != old)
{
firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
revalidate(); revalidate();
repaint(); repaint();
} }
} }
/**
* Get the value of the "action" property.
*
* @return The current value of the "action" property
*/
public Action getAction() 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) public void setAction(Action a)
{ {
action_taken = a; if (action != null)
revalidate(); {
repaint(); action.removePropertyChangeListener(actionPropertyChangeListener);
removeActionListener(action);
if (actionPropertyChangeListener != null)
{
action.removePropertyChangeListener(actionPropertyChangeListener);
actionPropertyChangeListener = null;
}
actionPropertyChangeListener = createActionPropertyChangeListener(a);
} }
public void setSelected(boolean b) Action old = action;
{ getModel().setSelected(b); } action = a;
configurePropertiesFromAction(action);
public boolean isSelected() if (action != null)
{ return getModel().isSelected(); } {
action.addPropertyChangeListener(actionPropertyChangeListener);
addActionListener(action);
}
}
/**
* Return the button's default "icon" property.
*
* @return The current default icon
*/
public Icon getIcon() public Icon getIcon()
{ return default_icon; }
public void setIcon(Icon defaultIcon)
{ {
if (default_icon == defaultIcon) return default_icon;
return; }
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 Icon old = default_icon;
// default_icon.setParent(this); default_icon = i;
} if (old != i)
{
firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
revalidate(); revalidate();
repaint(); repaint();
} }
}
/**
* Return the button's "text" property. This property is synonymous with
* the "label" property.
*
* @return The current "text" property
*/
public String getText() 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) 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() 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(); revalidate();
repaint(); 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() public Insets getMargin()
{ return margin; }
public void setMargin(Insets m)
{ {
margin = m; return margin;
revalidate();
repaint();
} }
public void setEnabled(boolean b) /**
* 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)
{ {
super.setEnabled(b); Insets old = margin;
getModel().setEnabled(b); margin = m;
if (m != old)
{
firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m);
revalidate();
repaint(); 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() 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) 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(); revalidate();
repaint(); 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() 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) public void setDisabledIcon(Icon disabledIcon)
{ {
disabled_button = disabledIcon; disabled_icon = disabledIcon;
revalidate(); revalidate();
repaint(); 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() 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) public void setFocusPainted(boolean b)
{ {
boolean old = paint_focus; boolean old = paint_focus;
paint_focus = b; paint_focus = b;
firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, if (old != b)
old,
b);
if (hasFocus())
{ {
firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, b);
revalidate(); revalidate();
repaint(); 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() public boolean isFocusTraversable()
{ {
//Identifies whether or not this component can receive the focus.
return true; 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) protected int checkHorizontalKey(int key, String exception)
{ {
// Verify that key is a legal value for the horizontalAlignment properties. switch (key)
return 0; {
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) protected int checkVerticalKey(int key, String exception)
{ {
// Ensures that the key is a valid. switch (key)
return 0; {
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) 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() protected ActionListener createActionListener()
{ {
return new ActionListener() 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) 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 new PropertyChangeListener()
return null; {
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() protected ChangeListener createChangeListener()
{ {
// Subclasses that want to handle ChangeEvents differently can override this to return another ChangeListener implementation.
return new ChangeListener() 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() protected ItemListener createItemListener()
{ {
return new ItemListener() 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() public void doClick()
{ {
doClick(100); 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) public void doClick(int pressTime)
{ {
//Toolkit.tlkBeep (); getModel().setArmed(true);
//Programmatically perform a "click". getModel().setPressed(true);
} try
public Icon getDisabledSelectedIcon()
{ {
//Returns the icon used by the button when it's disabled and selected. java.lang.Thread.sleep(pressTime);
return disabled_selected_button;
} }
catch (java.lang.InterruptedException e)
public Icon getRolloverIcon()
{ {
// Returns the rollover icon for the button. // probably harmless
return null;
} }
getModel().setPressed(false);
Icon getRolloverSelectedIcon() getModel().setArmed(false);
{
// Returns the rollover selection icon for the button.
return null;
} }
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 disabled_selected_icon;
return selected_button;
} }
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. Icon old = disabled_selected_icon;
return null; disabled_selected_icon = disabledSelectedIcon;
} if (old != disabledSelectedIcon)
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
{ {
//This is overridden to return false if the current Icon's Image is not equal to the passed in Image img. firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old,
return current_icon == img; 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 rollover_icon;
return "AbstractButton";
} }
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. Icon old = rollover_icon;
} rollover_icon = rolloverIcon;
if (old != rolloverIcon)
public void setDisabledSelectedIcon(Icon disabledSelectedIcon)
{ {
// 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) public void setRolloverSelectedIcon(Icon rolloverSelectedIcon)
{ {
// Sets the rollover selected icon for the button. Icon old = rollover_selected_icon;
} rollover_selected_icon = rolloverSelectedIcon;
if (old != rolloverSelectedIcon)
public void setSelectedIcon(Icon selectedIcon)
{ {
// 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 selected_icon;
return (ButtonUI) ui;
} }
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)
{ {
/* Icon old = selected_icon;
// Notification from the UIFactory that the L&F has changed. selected_icon = selectedIcon;
if (getUI() == null) 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;
} }
else
protected void processMouseEvent(MouseEvent e)
{ {
// System.out.println("PROCESS-MOUSE-EVENT: " + e + ", PRESSED-IN-MODEL="+getModel().isPressed()); return null;
}
}
switch (e.getID()) /**
{ * Called when image data becomes available for one of the button's icons.
case MouseEvent.MOUSE_MOVED: *
* @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()); boolean old = content_area_filled;
getModel().setPressed(true); content_area_filled = b;
if (b != old)
{
firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b);
revalidate();
repaint(); repaint();
} }
break;
} }
case MouseEvent.MOUSE_RELEASED: /**
{ * Paints the button's border, if the button's "borderPainted" property is
if (! isEnabled()) * <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); * Set the "UI" property of the button, which is a look and feel class
repaint(); * responsible for handling the button's input events and painting it.
} *
break; * @param ui The new "UI" property
} */
case MouseEvent.MOUSE_CLICKED: 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()
{
} }
} }
/* DefaultButtonModel.java -- /* DefaultButtonModel.java --
Copyright (C) 2002 Free Software Foundation, Inc. Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -35,9 +35,10 @@ this exception to your version of the library, but you are not ...@@ -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 obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package javax.swing; package javax.swing;
import java.awt.AWTEvent;
import java.awt.AWTEventMulticaster;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
...@@ -49,130 +50,412 @@ import javax.swing.event.ChangeEvent; ...@@ -49,130 +50,412 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList; 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; 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;
/** State constant indicating that the button is enabled. Buttons cannot
be pressed or selected unless they are enabled. */
static int ENABLED = 2;
/** 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;
Vector items = new Vector(); /** Represents the "state properties" (armed, enabled, pressed, rollover
Vector changes = new Vector(); 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; ButtonGroup group;
JComponent comp;
/** 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;
DefaultButtonModel(JComponent a) public DefaultButtonModel()
{ {
comp = a; 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() public Object[] getSelectedObjects()
{ {
return null; return null;
} }
/**
public void fireItemStateChanged(ItemEvent event) * 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)
{ {
for (int i=0;i<items.size();i++) listenerList.add(ActionListener.class, l);
}
/**
* Remove an ActionListener to the model. Usually only called to
* unsubscribe an AbstractButton's listener to the model.
*
* @param l The listener to remove
*/
public void removeActionListener(ActionListener l)
{ {
ItemListener a = (ItemListener) items.get(i); listenerList.remove(ActionListener.class, l);
a.itemStateChanged(event);
} }
/**
* 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);
} }
public void fireStateChanged(ChangeEvent event)
/**
* 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)
{ {
for (int i=0;i<changes.size();i++) 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)
{ {
ChangeListener a = (ChangeListener) changes.get(i); listenerList.add(ChangeListener.class, l);
a.stateChanged(event);
} }
/**
* 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);
} }
public void fireActionPerformed(ActionEvent event)
/**
* 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)
{ {
for (int i=0;i<actions.size();i++) 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)
{ {
ActionListener a = (ActionListener) actions.get(i); EventListener[] ll = listenerList.getListeners(ActionListener.class);
a.actionPerformed(event); 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);
} }
boolean arm; /**
public boolean isArmed() { return arm; } * Helper method to fire a ChangeEvent with the model as the event's
public void setArmed(boolean b) { arm = b; } * source.
*/
protected void changeState(int stateflag, boolean b)
{
int oldstate = stateMask;
int newstate;
boolean enabled = true; if (b)
public boolean isEnabled() { return enabled; } newstate = oldstate | stateflag;
public void setEnabled(boolean b) { enabled = b; } else
newstate = oldstate & ~stateflag;
boolean pressed; if (oldstate == newstate)
public void setPressed(boolean b) return;
{
pressed = b;
}
public boolean isPressed() { return pressed; }
stateMask = newstate;
public void removeActionListener(ActionListener l) { actions.removeElement(l); } fireStateChanged(changeEvent);
public void addActionListener(ActionListener l)
{
// comp.enableEvents( AWTEvent.ACTION_EVENT_MASK );
actions.addElement(l);
}
public void addItemListener(ItemListener l) { items.addElement(l); } if ((newstate & ENABLED) == 0)
public void removeItemListener(ItemListener l) { items.removeElement(l); } return;
public void addChangeListener(ChangeListener l) { changes.addElement(l); } if ((oldstate & SELECTED) == 0
public void removeChangeListener(ChangeListener l) { changes.removeElement(l); } && (newstate & SELECTED) == SELECTED)
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
null, ItemEvent.SELECTED));
boolean roll; else if ((oldstate & SELECTED) == SELECTED
public void setRollover(boolean b) { roll = b; } && (newstate & SELECTED) == 0)
public boolean isRollover() { return roll; } fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
null, ItemEvent.DESELECTED));
int mne; else if ((newstate & ARMED) == ARMED
public int getMnemonic() { return mne; } && (newstate & PRESSED) == PRESSED)
public void setMnemonic(int key) { mne = key; } {
fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
actionCommand));
stateMask = stateMask & ~(PRESSED | ARMED);
}
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 "armed" property.
*
* @return The current "armed" property
*/
public boolean isArmed()
{ {
this.group = group; return (stateMask & ARMED) == ARMED;
} }
boolean sel; /**
public void setSelected(boolean b) * Set the value of the model's "armed" property.
*
* @param a The new "armed" property
*/
public void setArmed(boolean a)
{ {
if (group != null) changeState(ARMED, a);
}
/**
* Get the value of the model's "enabled" property.
*
* @return The current "enabled" property.
*/
public boolean isEnabled()
{ {
if (b == true) return (stateMask & ENABLED) == ENABLED;
}
/**
* Set the value of the model's "enabled" property.
*
* @param e The new "enabled" property
*/
public void setEnabled(boolean e)
{ {
System.out.println("selected button in group:"+this); changeState(ENABLED, e);
group.setSelected(this, b);
sel = true;
} }
else
/**
* Set the value of the model's "pressed" property.
*
* @param p The new "pressed" property
*/
public void setPressed(boolean p)
{ {
System.out.println("deselected button in group: " + this); changeState(PRESSED, p);
sel = false;
} }
/**
* Get the value of the model's "pressed" property.
*
* @return The current "pressed" property
*/
public boolean isPressed()
{
return (stateMask & PRESSED) == PRESSED;
} }
else
/**
* Set the value of the model's "rollover" property.
*
* @param r The new "rollover" property
*/
public void setRollover(boolean r)
{ {
sel = b; 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);
} }
public boolean isSelected() { return sel; }
}
/**
* Get the value of the model's "selected" property.
*
* @return The current "selected" property
*/
public boolean isSelected()
{
return (stateMask & SELECTED) == SELECTED;
}
/**
* Get the value of the model's "rollover" property.
*
* @return The current "rollover" property
*/
public boolean isRollover()
{
return (stateMask & ROLLOVER) == ROLLOVER;
}
/**
* Get the value of the model's "mnemonic" property.
*
* @return The current "mnemonic" property
*/
public int getMnemonic()
{
return mnemonic;
}
/**
* Set the value of the model's "mnemonic" property.
*
* @param key The new "mnemonic" property
*/
public void setMnemonic(int key)
{
if (mnemonic != key)
{
mnemonic = key;
fireStateChanged(changeEvent);
}
}
/**
* Set the value of the model's "actionCommand" property. This property
* is used as the "command" property of the {@link ActionEvent} fired
* from the model.
*
* @param s The new "actionCommand" property.
*/
public void setActionCommand(String s)
{
if (actionCommand != s)
{
actionCommand = s;
fireStateChanged(changeEvent);
}
}
/**
* 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()
{
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);
}
}
}
...@@ -46,6 +46,7 @@ import java.awt.Dimension; ...@@ -46,6 +46,7 @@ import java.awt.Dimension;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
...@@ -56,6 +57,7 @@ import java.awt.event.FocusEvent; ...@@ -56,6 +57,7 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.awt.peer.LightweightPeer; import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
...@@ -271,13 +273,16 @@ public abstract class JComponent extends Container implements Serializable ...@@ -271,13 +273,16 @@ public abstract class JComponent extends Container implements Serializable
super(); super();
super.setLayout(new FlowLayout()); super.setLayout(new FlowLayout());
listenerList = new EventListenerList();
//eventMask |= AWTEvent.COMP_KEY_EVENT_MASK; //eventMask |= AWTEvent.COMP_KEY_EVENT_MASK;
enableEvents( AWTEvent.KEY_EVENT_MASK ); // enableEvents( AWTEvent.KEY_EVENT_MASK );
//updateUI(); // get a proper ui //updateUI(); // get a proper ui
} }
// protected EventListenerList listenerList protected EventListenerList listenerList;
public boolean contains(int x, int y) public boolean contains(int x, int y)
{ {
//return dims.contains(x,y); //return dims.contains(x,y);
...@@ -701,11 +706,29 @@ public abstract class JComponent extends Container implements Serializable ...@@ -701,11 +706,29 @@ public abstract class JComponent extends Container implements Serializable
public void paint(Graphics g) 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); if (use_double_buffer)
paintComponent(g); {
paintChildren(g); // 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) protected void paintBorder(Graphics g)
...@@ -729,7 +752,7 @@ public abstract class JComponent extends Container implements Serializable ...@@ -729,7 +752,7 @@ public abstract class JComponent extends Container implements Serializable
protected void paintChildren(Graphics g) protected void paintChildren(Graphics g)
{ {
// Paint this component's children. // Paint this component's children.
//super.paintChildren(g); super.paint(g);
} }
protected void paintComponent(Graphics g) protected void paintComponent(Graphics g)
......
...@@ -74,7 +74,7 @@ public class JToggleButton extends AbstractButton implements Accessible ...@@ -74,7 +74,7 @@ public class JToggleButton extends AbstractButton implements Accessible
super(text, icon); super(text, icon);
// Create the model // Create the model
setModel(new ToggleButtonModel(this)); setModel(new ToggleButtonModel());
model.setSelected(selected); model.setSelected(selected);
} }
......
...@@ -97,8 +97,8 @@ public class SwingUtilities implements SwingConstants ...@@ -97,8 +97,8 @@ public class SwingUtilities implements SwingConstants
// view rect 'vr' already ok, // view rect 'vr' already ok,
// we need to compute ir (icon rect) and tr (text-rect) // we need to compute ir (icon rect) and tr (text-rect)
int next_x = 0;//vr.x; int next_x = vr.x;
int next_y = 0;//vr.y; int next_y = vr.y;
ir.height = ir.width = ir.y = ir.x = 0; ir.height = ir.width = ir.y = ir.x = 0;
...@@ -115,10 +115,10 @@ public class SwingUtilities implements SwingConstants ...@@ -115,10 +115,10 @@ public class SwingUtilities implements SwingConstants
} }
tr.x = next_x; tr.x = next_x;
tr.y = vr.y + (vr.height/2); tr.y = vr.y; // + (vr.height/2);
tr.width = fm.stringWidth(text); tr.width = fm.stringWidth(text);
tr.height = fm.getHeight() + fm.getAscent()/2; tr.height = fm.getHeight(); // + fm.getAscent()/2;
return text; return text;
} }
......
...@@ -40,11 +40,6 @@ package javax.swing; ...@@ -40,11 +40,6 @@ package javax.swing;
public class ToggleButtonModel extends DefaultButtonModel public class ToggleButtonModel extends DefaultButtonModel
{ {
ToggleButtonModel(JComponent c)
{
super(c);
}
public void setPressed(boolean b) public void setPressed(boolean b)
{ {
if (! isEnabled()) if (! isEnabled())
......
...@@ -35,16 +35,23 @@ this exception to your version of the library, but you are not ...@@ -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 obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */ exception statement from your version. */
package javax.swing.plaf.basic; package javax.swing.plaf.basic;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle; 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.AbstractButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
...@@ -53,20 +60,161 @@ import javax.swing.plaf.ComponentUI; ...@@ -53,20 +60,161 @@ import javax.swing.plaf.ComponentUI;
public class BasicButtonUI extends ButtonUI 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 gap = 3;
// int y_text_space = 2, x_text_space + 5;
Color textColor, disabledTextColor; /** 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; Color pressedBackgroundColor;
Color normalBackgroundColor;
/** 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) public static ComponentUI createUI(final JComponent c)
{ {
return new BasicButtonUI(); 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) public void installUI(final JComponent c)
{ {
super.installUI(c); super.installUI(c);
...@@ -76,18 +224,37 @@ public class BasicButtonUI extends ButtonUI ...@@ -76,18 +224,37 @@ public class BasicButtonUI extends ButtonUI
pressedBackgroundColor = new Color(150,150,150); pressedBackgroundColor = new Color(150,150,150);
pressedBackgroundColor = new Color(150,150,150); pressedBackgroundColor = new Color(150,150,150);
normalBackgroundColor = new Color(192,192,192); 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) public Dimension getPreferredSize(JComponent c)
{ {
AbstractButton b = (AbstractButton)c; AbstractButton b = (AbstractButton)c;
Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap); Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, gap);
// System.out.println("^^^^^^^^^^^^^^^^^^^^^^ BASIC-PREF="+d + ",T="+b.text);
return d; 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) public void paint(Graphics g, JComponent c)
{ {
AbstractButton b = (AbstractButton) c; AbstractButton b = (AbstractButton) c;
...@@ -95,6 +262,7 @@ public class BasicButtonUI extends ButtonUI ...@@ -95,6 +262,7 @@ public class BasicButtonUI extends ButtonUI
Rectangle tr = new Rectangle(); Rectangle tr = new Rectangle();
Rectangle ir = new Rectangle(); Rectangle ir = new Rectangle();
Rectangle vr = new Rectangle(); Rectangle vr = new Rectangle();
Rectangle br = new Rectangle();
Font f = c.getFont(); Font f = c.getFont();
...@@ -102,115 +270,150 @@ public class BasicButtonUI extends ButtonUI ...@@ -102,115 +270,150 @@ public class BasicButtonUI extends ButtonUI
FontMetrics fm = g.getFontMetrics(f); FontMetrics fm = g.getFontMetrics(f);
Insets i = c.getInsets(); Insets border = b.getInsets();
Insets margin = b.getMargin();
vr.x = i.left; br.x = border.left;
vr.y = i.top; br.y = border.top;
vr.width = b.getWidth() - (i.right + vr.x); br.width = b.getWidth() - (border.right + border.left);
vr.height = b.getHeight() - (i.bottom + vr.y); br.height = b.getHeight() - (border.top + border.bottom);
//System.out.println(" VIEW-RECT-BUTTON="+vr+", insets="+i+", FONTM="+fm); 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, String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(),
fm,
b.getText(),
b.getIcon(), b.getIcon(),
b.getVerticalAlignment(), b.getVerticalAlignment(),
b.getHorizontalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getVerticalTextPosition(),
b.getHorizontalTextPosition(), b.getHorizontalTextPosition(),
vr, vr, ir, tr, gap);
ir,
tr,
gap);
if (b.getModel().isPressed() || if ((b.getModel().isRollover() && b.getModel().isArmed())
b.getModel().isSelected()) || b.getModel().isSelected())
{ paintButtonPressed(g, br, c);
//System.out.println("paint pressed");
paintButtonPressed(g, c);
}
else else
{ paintButtonNormal(g, br, c);
//System.out.println("paint normal");
paintButtonNormal(g, c);
}
paintIcon(g, c, ir); paintIcon(g, c, ir);
paintText(g, c, tr, b.getText()); paintText(g, c, tr, b.getText());
paintFocus(g, c, vr, tr, ir); paintFocus(g, c, vr, tr, ir);
} }
/**
protected void paintFocus(Graphics g, * Paint any focus decoration this {@link JComponent} might have. The
JComponent c, * component, which in this case will be an {@link AbstractButton},
Rectangle vr, * should only have focus decoration painted if it has the focus, and its
Rectangle tr, * "focusPainted" property is <code>true</code>.
Rectangle ir) *
* @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, * Paint the icon for this component. Depending on the state of the
Rectangle iconRect) * 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; AbstractButton b = (AbstractButton) c;
if (b.getIcon() != null) if (b.getIcon() != null)
{ {
int x = iconRect.x; int x = iconRect.x;
int y = iconRect.y; int y = iconRect.y;
System.out.println("WE HAVE AN ICON: " + b.getIcon());
b.getIcon().paintIcon(c, g, x, y); 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(); Dimension size = b.getSize();
g.setColor(pressedBackgroundColor); 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(); Dimension size = b.getSize();
g.setColor(normalBackgroundColor); 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, * Paints the "text" property of an {@link AbstractButton}, using the
Rectangle textRect, * {@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) String text)
{ {
Font f = c.getFont(); Font f = c.getFont();
g.setFont(f); g.setFont(f);
FontMetrics fm = g.getFontMetrics(f); FontMetrics fm = g.getFontMetrics(f);
g.setColor(c.isEnabled() ? textColor : disabledTextColor); g.setColor(c.isEnabled() ? textColor : disabledTextColor);
BasicGraphicsUtils.drawString(g, text,
BasicGraphicsUtils.drawString(g,
text,
0, 0,
textRect.x, textRect.x,
textRect.y + fm.getAscent()/2); textRect.y + fm.getAscent());
} }
} }
...@@ -595,6 +595,7 @@ public class BasicGraphicsUtils ...@@ -595,6 +595,7 @@ public class BasicGraphicsUtils
Rectangle iconRect = new Rectangle(); Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle(); Rectangle textRect = new Rectangle();
Insets insets = b.getInsets(); Insets insets = b.getInsets();
Insets margin = b.getMargin();
/* For determining the ideal size, do not assume a size restriction. */ /* For determining the ideal size, do not assume a size restriction. */
viewRect = new Rectangle(0, 0, viewRect = new Rectangle(0, 0,
...@@ -620,7 +621,6 @@ public class BasicGraphicsUtils ...@@ -620,7 +621,6 @@ public class BasicGraphicsUtils
viewRect, iconRect, textRect, viewRect, iconRect, textRect,
textIconGap); textIconGap);
/* +------------------------+ +------------------------+ /* +------------------------+ +------------------------+
* | | | | * | | | |
* | ICON | | CONTENTCONTENTCONTENT | * | ICON | | CONTENTCONTENTCONTENT |
...@@ -630,7 +630,11 @@ public class BasicGraphicsUtils ...@@ -630,7 +630,11 @@ public class BasicGraphicsUtils
*/ */
contentRect = textRect.union(iconRect); contentRect = textRect.union(iconRect);
return new Dimension(insets.left + contentRect.width + insets.right, return new Dimension(insets.left + margin.left
insets.top + contentRect.height + insets.bottom); + contentRect.width
+ insets.right + margin.right,
insets.top + margin.top
+ contentRect.height
+ insets.bottom + margin.bottom);
} }
} }
...@@ -228,12 +228,25 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals ...@@ -228,12 +228,25 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
{ {
void *ptr = NSA_GET_PTR (env, obj); void *ptr = NSA_GET_PTR (env, obj);
jobject *gref = NSA_GET_GLOBAL_REF (env, obj); jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
GtkWidget* vbox, *layout;
GList* children;
g_assert (gref); g_assert (gref);
gdk_threads_enter (); gdk_threads_enter ();
gtk_widget_realize (ptr); 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. */ /* Connect signals for window event support. */
g_signal_connect (G_OBJECT (ptr), "delete-event", g_signal_connect (G_OBJECT (ptr), "delete-event",
G_CALLBACK (window_delete_cb), *gref); G_CALLBACK (window_delete_cb), *gref);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment