001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.awt;
019:
020: import java.awt.event.ActionEvent;
021: import java.awt.event.ActionListener;
022: import java.io.IOException;
023: import java.io.ObjectInputStream;
024: import java.util.EventListener;
025: import javax.accessibility.Accessible;
026: import javax.accessibility.AccessibleAction;
027: import javax.accessibility.AccessibleContext;
028: import javax.accessibility.AccessibleRole;
029: import javax.accessibility.AccessibleValue;
030: import org.apache.harmony.awt.ButtonStateController;
031: import org.apache.harmony.awt.FieldsAccessor;
032: import org.apache.harmony.awt.state.ButtonState;
033:
034: public class Button extends Component implements Accessible {
035: private static final long serialVersionUID = -8774683716313001058L;
036:
037: protected class AccessibleAWTButton extends AccessibleAWTComponent
038: implements AccessibleAction, AccessibleValue {
039: private static final long serialVersionUID = -5932203980244017102L;
040:
041: protected AccessibleAWTButton() {
042: super ();
043: }
044:
045: public int getAccessibleActionCount() {
046: return 1;
047: }
048:
049: public String getAccessibleActionDescription(int i) {
050: if (i == 0) {
051: return "click"; //$NON-NLS-1$
052: }
053: return null;
054: }
055:
056: public boolean doAccessibleAction(int i) {
057: if (i != 0) {
058: return false;
059: }
060: generateEvent(0l, 0);
061: return true;
062: }
063:
064: public Number getCurrentAccessibleValue() {
065: return Integer.valueOf(0);
066: }
067:
068: public boolean setCurrentAccessibleValue(Number n) {
069: return false;
070: }
071:
072: public Number getMinimumAccessibleValue() {
073: return Integer.valueOf(0);
074: }
075:
076: public Number getMaximumAccessibleValue() {
077: return Integer.valueOf(0);
078: }
079:
080: @Override
081: public AccessibleAction getAccessibleAction() {
082: return this ;
083: }
084:
085: @Override
086: public String getAccessibleName() {
087: return getLabel();
088: }
089:
090: @Override
091: public AccessibleRole getAccessibleRole() {
092: return AccessibleRole.PUSH_BUTTON;
093: }
094:
095: @Override
096: public AccessibleValue getAccessibleValue() {
097: return this ;
098: }
099: }
100:
101: private class State extends Component.ComponentState implements
102: ButtonState {
103: State() {
104: super ();
105: }
106:
107: public String getText() {
108: return label;
109: }
110:
111: public Dimension getTextSize() {
112: return labelSize;
113: }
114:
115: public void setTextSize(Dimension size) {
116: labelSize.width = size.width;
117: labelSize.height = size.height;
118: }
119:
120: public boolean isPressed() {
121: return stateController.isPressed();
122: }
123:
124: @Override
125: public void calculate() {
126: toolkit.theme.calculateButton(state);
127: }
128: }
129:
130: private String actionCommand;
131:
132: private String label;
133:
134: private final Dimension labelSize;
135:
136: private final transient ButtonStateController stateController;
137:
138: private final AWTListenerList<ActionListener> actionListeners;
139:
140: private final transient State state = new State();
141:
142: public Button(String label) throws HeadlessException {
143: toolkit.lockAWT();
144: try {
145: this .label = label;
146: labelSize = new Dimension();
147: actionCommand = null;
148: actionListeners = new AWTListenerList<ActionListener>(this );
149: stateController = createStateController();
150: addAWTMouseListener(stateController);
151: addAWTKeyListener(stateController);
152: addAWTFocusListener(stateController);
153: } finally {
154: toolkit.unlockAWT();
155: }
156: }
157:
158: public Button() throws HeadlessException {
159: this (""); //$NON-NLS-1$
160: toolkit.lockAWT();
161: try {
162: } finally {
163: toolkit.unlockAWT();
164: }
165: }
166:
167: public void setLabel(String label) {
168: toolkit.lockAWT();
169: try {
170: if (!(this .label == label || (label != null && label
171: .equals(this .label)))) {
172: // set new label only if it differs from the old one
173: // to avoid dead loop in repaint()
174: this .label = label;
175: if (isDisplayable()) {
176: invalidate();
177: if (isShowing()) {
178: repaint();
179: }
180: }
181: }
182: } finally {
183: toolkit.unlockAWT();
184: }
185: }
186:
187: @Override
188: void setFontImpl(Font f) {
189: super .setFontImpl(f);
190: if (isDisplayable()) {
191: invalidate();
192: }
193: }
194:
195: public String getLabel() {
196: toolkit.lockAWT();
197: try {
198: return label;
199: } finally {
200: toolkit.unlockAWT();
201: }
202: }
203:
204: @Override
205: public void addNotify() {
206: toolkit.lockAWT();
207: try {
208: super .addNotify();
209: invalidate();
210: state.calculate();
211: } finally {
212: toolkit.unlockAWT();
213: }
214: }
215:
216: public void setActionCommand(String command) {
217: toolkit.lockAWT();
218: try {
219: actionCommand = command;
220: } finally {
221: toolkit.unlockAWT();
222: }
223: }
224:
225: public String getActionCommand() {
226: toolkit.lockAWT();
227: try {
228: return (actionCommand == null ? label : actionCommand);
229: } finally {
230: toolkit.unlockAWT();
231: }
232: }
233:
234: @SuppressWarnings("unchecked")
235: @Override
236: public <T extends EventListener> T[] getListeners(
237: Class<T> listenerType) {
238: if (ActionListener.class.isAssignableFrom(listenerType)) {
239: return (T[]) getActionListeners();
240: }
241: return super .getListeners(listenerType);
242: }
243:
244: public void addActionListener(ActionListener l) {
245: actionListeners.addUserListener(l);
246: }
247:
248: public void removeActionListener(ActionListener l) {
249: actionListeners.removeUserListener(l);
250: }
251:
252: public ActionListener[] getActionListeners() {
253: return actionListeners.getUserListeners(new ActionListener[0]);
254: }
255:
256: @Override
257: protected void processEvent(AWTEvent e) {
258: if (toolkit.eventTypeLookup.getEventMask(e) == AWTEvent.ACTION_EVENT_MASK) {
259: processActionEvent((ActionEvent) e);
260: } else {
261: super .processEvent(e);
262: }
263: }
264:
265: protected void processActionEvent(ActionEvent e) {
266: for (ActionListener listener : actionListeners
267: .getUserListeners()) {
268: switch (e.getID()) {
269: case ActionEvent.ACTION_PERFORMED:
270: listener.actionPerformed(e);
271: break;
272: }
273: }
274: }
275:
276: @Override
277: protected String paramString() {
278: toolkit.lockAWT();
279: try {
280: return (super .paramString() + ",label=" + label + "," + (stateController //$NON-NLS-1$ //$NON-NLS-2$
281: .isPressed() ? "pressed" : "unpressed")); //$NON-NLS-1$ //$NON-NLS-2$
282: } finally {
283: toolkit.unlockAWT();
284: }
285: }
286:
287: Dimension getLabelSize() {
288: return labelSize;
289: }
290:
291: @Override
292: void prepaint(Graphics g) {
293: toolkit.theme.drawButton(g, state);
294: }
295:
296: @Override
297: boolean isPrepainter() {
298: return true;
299: }
300:
301: boolean isPressed() {
302: return stateController.isPressed();
303: }
304:
305: @Override
306: void setEnabledImpl(boolean value) {
307: if (isEnabled() != value) { // to avoid dead loop in repaint()
308: super .setEnabledImpl(value);
309: repaint();
310: }
311: }
312:
313: void generateEvent(long timestamp, int modifiers) {
314: postEvent(new ActionEvent(this , ActionEvent.ACTION_PERFORMED,
315: getActionCommand(), timestamp, modifiers));
316: }
317:
318: @Override
319: String autoName() {
320: return ("button" + Integer.toString(toolkit.autoNumber.nextButton++)); //$NON-NLS-1$
321: }
322:
323: @Override
324: public AccessibleContext getAccessibleContext() {
325: toolkit.lockAWT();
326: try {
327: return super .getAccessibleContext();
328: } finally {
329: toolkit.unlockAWT();
330: }
331: }
332:
333: @Override
334: Dimension getDefaultMinimumSize() {
335: if (getFont() == null) {
336: return new Dimension(0, 0);
337: }
338: if (state.getDefaultMinimumSize() == null) {
339: toolkit.theme.calculateButton(state);
340: }
341: return state.getDefaultMinimumSize();
342: }
343:
344: @Override
345: void resetDefaultSize() {
346: state.reset();
347: }
348:
349: @Override
350: ComponentBehavior createBehavior() {
351: return new HWBehavior(this );
352: }
353:
354: ButtonStateController createStateController() {
355: return new ButtonStateController(this ) {
356: @Override
357: protected void fireEvent() {
358: generateEvent(getWhen(), getMod());
359: }
360: };
361: }
362:
363: private void readObject(ObjectInputStream stream)
364: throws IOException, ClassNotFoundException {
365: stream.defaultReadObject();
366: FieldsAccessor accessor = new FieldsAccessor(Button.class, this );
367: accessor.set("stateController", createStateController()); //$NON-NLS-1$
368: accessor.set("state", new State()); //$NON-NLS-1$
369: }
370:
371: @Override
372: AccessibleContext createAccessibleContext() {
373: return new AccessibleAWTButton();
374: }
375: }
|