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.ItemEvent;
021: import java.awt.event.ItemListener;
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.AccessibleState;
030: import javax.accessibility.AccessibleStateSet;
031: import javax.accessibility.AccessibleValue;
032: import org.apache.harmony.awt.ButtonStateController;
033: import org.apache.harmony.awt.FieldsAccessor;
034: import org.apache.harmony.awt.state.CheckboxState;
035:
036: public class Checkbox extends Component implements ItemSelectable,
037: Accessible {
038: private static final long serialVersionUID = 7270714317450821763L;
039:
040: protected class AccessibleAWTCheckbox extends
041: Component.AccessibleAWTComponent implements ItemListener,
042: AccessibleAction, AccessibleValue {
043: private static final long serialVersionUID = 7881579233144754107L;
044:
045: public AccessibleAWTCheckbox() {
046: super ();
047: // define default constructor explicitly just to make it public
048: // add listener to be able to fire property changes:
049: addItemListener(this );
050: }
051:
052: @Override
053: public AccessibleRole getAccessibleRole() {
054: return AccessibleRole.CHECK_BOX;
055: }
056:
057: @Override
058: public AccessibleStateSet getAccessibleStateSet() {
059: AccessibleStateSet aStateSet = super
060: .getAccessibleStateSet();
061: if (getState()) {
062: aStateSet.add(AccessibleState.CHECKED);
063: }
064: return aStateSet;
065: }
066:
067: @Override
068: public AccessibleAction getAccessibleAction() {
069: return this ;
070: }
071:
072: @Override
073: public AccessibleValue getAccessibleValue() {
074: return this ;
075: }
076:
077: public void itemStateChanged(ItemEvent e) {
078: // fire property change event
079: final AccessibleState checkedState = AccessibleState.CHECKED;
080: AccessibleState oldValue = null;
081: AccessibleState newValue = null;
082: switch (e.getStateChange()) {
083: case ItemEvent.SELECTED:
084: newValue = checkedState;
085: break;
086: case ItemEvent.DESELECTED:
087: oldValue = checkedState;
088: break;
089: }
090: firePropertyChange(
091: AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
092: oldValue, newValue);
093: }
094:
095: public int getAccessibleActionCount() {
096: return 0; // no actions
097: }
098:
099: public boolean doAccessibleAction(int i) {
100: return false;
101: }
102:
103: public String getAccessibleActionDescription(int i) {
104: return null;
105: }
106:
107: public Number getCurrentAccessibleValue() {
108: return null;
109: }
110:
111: public Number getMaximumAccessibleValue() {
112: return null;
113: }
114:
115: public Number getMinimumAccessibleValue() {
116: return null;
117: }
118:
119: public boolean setCurrentAccessibleValue(Number arg0) {
120: return false;
121: }
122: }
123:
124: private final class State extends Component.ComponentState
125: implements CheckboxState {
126: private final Dimension textSize = new Dimension();
127:
128: State() {
129: super ();
130: }
131:
132: public boolean isChecked() {
133: return checked;
134: }
135:
136: public String getText() {
137: return label;
138: }
139:
140: public Dimension getTextSize() {
141: return textSize;
142: }
143:
144: public void setTextSize(Dimension size) {
145: textSize.width = size.width;
146: textSize.height = size.height;
147: }
148:
149: public boolean isInGroup() {
150: return group != null;
151: }
152:
153: public boolean isPressed() {
154: return stateController.isPressed();
155: }
156:
157: @Override
158: public void calculate() {
159: toolkit.theme.calculateCheckbox(state);
160: }
161: }
162:
163: private final AWTListenerList<ItemListener> itemListeners = new AWTListenerList<ItemListener>(
164: this );
165:
166: private String label;
167:
168: private CheckboxGroup group;
169:
170: private boolean checked;
171:
172: private final transient State state = new State();
173:
174: private final transient ButtonStateController stateController;
175:
176: public Checkbox() throws HeadlessException {
177: this (new String(), null, false);
178: toolkit.lockAWT();
179: try {
180: } finally {
181: toolkit.unlockAWT();
182: }
183: }
184:
185: public Checkbox(String label, CheckboxGroup group, boolean state)
186: throws HeadlessException {
187: toolkit.lockAWT();
188: try {
189: this .label = label;
190: this .group = group;
191: setState(state);
192: stateController = createStateController();
193: addAWTMouseListener(stateController);
194: addAWTKeyListener(stateController);
195: addAWTFocusListener(stateController);
196: } finally {
197: toolkit.unlockAWT();
198: }
199: }
200:
201: private void generateEvent() {
202: setState(!getState());
203: int stateChange = (checked ? ItemEvent.SELECTED
204: : ItemEvent.DESELECTED);
205: postEvent(new ItemEvent(this , ItemEvent.ITEM_STATE_CHANGED,
206: this , stateChange));
207: }
208:
209: public Checkbox(String label) throws HeadlessException {
210: this (label, null, false);
211: toolkit.lockAWT();
212: try {
213: } finally {
214: toolkit.unlockAWT();
215: }
216: }
217:
218: public Checkbox(String label, boolean state)
219: throws HeadlessException {
220: this (label, null, state);
221: toolkit.lockAWT();
222: try {
223: } finally {
224: toolkit.unlockAWT();
225: }
226: }
227:
228: public Checkbox(String label, boolean state, CheckboxGroup group)
229: throws HeadlessException {
230: this (label, group, state);
231: toolkit.lockAWT();
232: try {
233: } finally {
234: toolkit.unlockAWT();
235: }
236: }
237:
238: public boolean getState() {
239: toolkit.lockAWT();
240: try {
241: return checked;
242: } finally {
243: toolkit.unlockAWT();
244: }
245: }
246:
247: @Override
248: public void addNotify() {
249: toolkit.lockAWT();
250: try {
251: super .addNotify();
252: } finally {
253: toolkit.unlockAWT();
254: }
255: }
256:
257: @Override
258: public AccessibleContext getAccessibleContext() {
259: toolkit.lockAWT();
260: try {
261: return super .getAccessibleContext();
262: } finally {
263: toolkit.unlockAWT();
264: }
265: }
266:
267: @Override
268: protected String paramString() {
269: /* The format is based on 1.5 release behavior
270: * which can be revealed by the following code:
271: * System.out.println(new Checkbox());
272: */
273: toolkit.lockAWT();
274: try {
275: return super .paramString()
276: + ",label=" + label + ",state=" + checked; //$NON-NLS-1$ //$NON-NLS-2$
277: } finally {
278: toolkit.unlockAWT();
279: }
280: }
281:
282: public CheckboxGroup getCheckboxGroup() {
283: toolkit.lockAWT();
284: try {
285: return group;
286: } finally {
287: toolkit.unlockAWT();
288: }
289: }
290:
291: public String getLabel() {
292: toolkit.lockAWT();
293: try {
294: return label;
295: } finally {
296: toolkit.unlockAWT();
297: }
298: }
299:
300: public Object[] getSelectedObjects() {
301: toolkit.lockAWT();
302: try {
303: if (checked) {
304: return new Object[] { label };
305: }
306: return null;
307: } finally {
308: toolkit.unlockAWT();
309: }
310: }
311:
312: public void setCheckboxGroup(CheckboxGroup group) {
313: toolkit.lockAWT();
314: try {
315: CheckboxGroup oldGroup = this .group;
316: this .group = group;
317: if (checked) {
318: if ((oldGroup != null)
319: && (oldGroup.getSelectedCheckbox() == this )) {
320: oldGroup.setSelectedCheckbox(null);
321: }
322: if (group != null) {
323: Checkbox selected = group.getSelectedCheckbox();
324: if (selected != null) {
325: checked = false;
326: } else {
327: group.setSelectedCheckbox(this );
328: }
329: }
330: }
331: } finally {
332: toolkit.unlockAWT();
333: }
334: }
335:
336: public void setLabel(String label) {
337: toolkit.lockAWT();
338: try {
339: this .label = label;
340: } finally {
341: toolkit.unlockAWT();
342: }
343: }
344:
345: public void setState(boolean state) {
346: toolkit.lockAWT();
347: try {
348: setChecked(state);
349: updateGroup();
350: } finally {
351: toolkit.unlockAWT();
352: }
353: }
354:
355: private void updateGroup() {
356: if (group != null) {
357: boolean wasSelected = (group.getSelectedCheckbox() == this );
358: if (checked) {
359: group.setSelectedCheckbox(this );
360: } else if (wasSelected) {
361: setChecked(true);
362: }
363: }
364: }
365:
366: void setChecked(boolean checked) {
367: if (checked != this .checked) { // avoid dead loop in repaint()
368: this .checked = checked;
369: repaint();
370: }
371: }
372:
373: @SuppressWarnings("unchecked")
374: @Override
375: public <T extends EventListener> T[] getListeners(
376: Class<T> listenerType) {
377: toolkit.lockAWT();
378: try {
379: if (ItemListener.class.isAssignableFrom(listenerType)) {
380: return (T[]) getItemListeners();
381: }
382: return super .getListeners(listenerType);
383: } finally {
384: toolkit.unlockAWT();
385: }
386: }
387:
388: public void addItemListener(ItemListener l) {
389: toolkit.lockAWT();
390: try {
391: itemListeners.addUserListener(l);
392: } finally {
393: toolkit.unlockAWT();
394: }
395: }
396:
397: public void removeItemListener(ItemListener l) {
398: toolkit.lockAWT();
399: try {
400: itemListeners.removeUserListener(l);
401: } finally {
402: toolkit.unlockAWT();
403: }
404: }
405:
406: public ItemListener[] getItemListeners() {
407: toolkit.lockAWT();
408: try {
409: return itemListeners.getUserListeners(new ItemListener[0]);
410: } finally {
411: toolkit.unlockAWT();
412: }
413: }
414:
415: @Override
416: protected void processEvent(AWTEvent e) {
417: toolkit.lockAWT();
418: try {
419: if (toolkit.eventTypeLookup.getEventMask(e) == AWTEvent.ITEM_EVENT_MASK) {
420: processItemEvent((ItemEvent) e);
421: } else {
422: super .processEvent(e);
423: }
424: } finally {
425: toolkit.unlockAWT();
426: }
427: }
428:
429: protected void processItemEvent(ItemEvent e) {
430: toolkit.lockAWT();
431: try {
432: for (ItemListener listener : itemListeners
433: .getUserListeners()) {
434: switch (e.getID()) {
435: case ItemEvent.ITEM_STATE_CHANGED:
436: listener.itemStateChanged(e);
437: break;
438: }
439: }
440: } finally {
441: toolkit.unlockAWT();
442: }
443: }
444:
445: @Override
446: boolean isPrepainter() {
447: return true;
448: }
449:
450: @Override
451: void prepaint(Graphics g) {
452: toolkit.theme.drawCheckbox(g, state);
453: }
454:
455: @Override
456: void setEnabledImpl(boolean value) {
457: if (value != isEnabled()) { // avoid dead loop in repaint()
458: super .setEnabledImpl(value);
459: repaint();
460: }
461: }
462:
463: @Override
464: String autoName() {
465: return ("checkbox" + toolkit.autoNumber.nextCheckBox++); //$NON-NLS-1$
466: }
467:
468: @Override
469: Dimension getDefaultMinimumSize() {
470: if (getFont() == null) {
471: return new Dimension(0, 0);
472: }
473: return state.getDefaultMinimumSize();
474: }
475:
476: @Override
477: void resetDefaultSize() {
478: state.reset();
479: }
480:
481: @Override
482: ComponentBehavior createBehavior() {
483: return new HWBehavior(this );
484: }
485:
486: ButtonStateController createStateController() {
487: return new ButtonStateController(this ) {
488: @Override
489: protected void fireEvent() {
490: generateEvent();
491: }
492: };
493: }
494:
495: private void readObject(ObjectInputStream stream)
496: throws IOException, ClassNotFoundException {
497: stream.defaultReadObject();
498: FieldsAccessor accessor = new FieldsAccessor(Button.class, this );
499: accessor.set("stateController", createStateController()); //$NON-NLS-1$
500: accessor.set("state", new State()); //$NON-NLS-1$
501: }
502:
503: @Override
504: AccessibleContext createAccessibleContext() {
505: return new AccessibleAWTCheckbox();
506: }
507: }
|