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.AdjustmentEvent;
021: import java.awt.event.AdjustmentListener;
022: import java.util.EventListener;
023: import javax.accessibility.Accessible;
024: import javax.accessibility.AccessibleContext;
025: import javax.accessibility.AccessibleRole;
026: import javax.accessibility.AccessibleState;
027: import javax.accessibility.AccessibleStateSet;
028: import javax.accessibility.AccessibleValue;
029: import org.apache.harmony.awt.ScrollbarStateController;
030: import org.apache.harmony.awt.internal.nls.Messages;
031: import org.apache.harmony.awt.state.ScrollbarState;
032:
033: public class Scrollbar extends Component implements Adjustable,
034: Accessible {
035: private static final long serialVersionUID = 8451667562882310543L;
036:
037: protected class AccessibleAWTScrollBar extends
038: Component.AccessibleAWTComponent implements AccessibleValue {
039: private static final long serialVersionUID = -344337268523697807L;
040:
041: @Override
042: public AccessibleRole getAccessibleRole() {
043: return AccessibleRole.SCROLL_BAR;
044: }
045:
046: @Override
047: public AccessibleStateSet getAccessibleStateSet() {
048: toolkit.lockAWT();
049: try {
050: AccessibleStateSet aStateSet = super
051: .getAccessibleStateSet();
052: AccessibleState aState = null;
053: switch (getOrientation()) {
054: case VERTICAL:
055: aState = AccessibleState.VERTICAL;
056: break;
057: case HORIZONTAL:
058: aState = AccessibleState.HORIZONTAL;
059: break;
060: }
061: if (aState != null) {
062: aStateSet.add(aState);
063: }
064: return aStateSet;
065: } finally {
066: toolkit.unlockAWT();
067: }
068: }
069:
070: @Override
071: public AccessibleValue getAccessibleValue() {
072: return this ;
073: }
074:
075: public Number getCurrentAccessibleValue() {
076: return new Integer(getValue());
077: }
078:
079: public Number getMaximumAccessibleValue() {
080: return new Integer(getMaximum());
081: }
082:
083: public Number getMinimumAccessibleValue() {
084: return new Integer(getMinimum());
085: }
086:
087: public boolean setCurrentAccessibleValue(Number n) {
088: setValue(n.intValue());
089: return true;
090: }
091: }
092:
093: public static final int HORIZONTAL = 0;
094:
095: public static final int VERTICAL = 1;
096:
097: final static int MAX = Integer.MAX_VALUE;
098:
099: private final AWTListenerList<AdjustmentListener> adjustmentListeners = new AWTListenerList<AdjustmentListener>(
100: this );
101:
102: private int blockIncrement;
103:
104: private int unitIncrement;
105:
106: private int maximum;
107:
108: private int minimum;
109:
110: private int orientation;
111:
112: private int value;
113:
114: private transient boolean valueIsAdjusting;
115:
116: private int visibleAmount;
117:
118: final transient State state = new State();
119:
120: private final transient ScrollbarStateController stateController;
121:
122: public Scrollbar() throws HeadlessException {
123: this (VERTICAL);
124: toolkit.lockAWT();
125: try {
126: } finally {
127: toolkit.unlockAWT();
128: }
129: }
130:
131: public Scrollbar(int orientation) throws HeadlessException {
132: this (orientation, 0, 10, 0, 100);
133: toolkit.lockAWT();
134: try {
135: } finally {
136: toolkit.unlockAWT();
137: }
138: }
139:
140: public Scrollbar(int orientation, int value, int visible, int min,
141: int max) throws HeadlessException {
142: toolkit.lockAWT();
143: try {
144: setOrientation(orientation);
145: setValues(value, visible, min, max);
146: setUnitIncrement(1);
147: setBlockIncrement(10);
148: stateController = new ScrollbarStateController(state) {
149: @Override
150: protected void fireEvent() {
151: generateEvent();
152: }
153:
154: @Override
155: protected void repaint(Rectangle r) {
156: doRepaint(r);
157: }
158:
159: @Override
160: protected void repaint() {
161: doRepaint();
162: }
163:
164: @Override
165: protected void requestFocus() {
166: if (isFocusable()) {
167: Scrollbar.this .requestFocus(false);
168: }
169: }
170: };
171: addAWTMouseListener(stateController);
172: addAWTKeyListener(stateController);
173: addAWTFocusListener(stateController);
174: addAWTMouseMotionListener(stateController);
175: addAWTComponentListener(stateController);
176: } finally {
177: toolkit.unlockAWT();
178: }
179: }
180:
181: class State extends Component.ComponentState implements
182: ScrollbarState {
183: private final Rectangle decreaseRect = new Rectangle();
184:
185: private final Rectangle increaseRect = new Rectangle();
186:
187: private final Rectangle sliderRect = new Rectangle();
188:
189: private final Rectangle trackRect = new Rectangle();
190:
191: private final Rectangle upperTrackRect = new Rectangle();
192:
193: private final Rectangle lowerTrackRect = new Rectangle();
194:
195: private int trackSize;
196:
197: public boolean isDecreasePressed() {
198: return stateController.isDecreasePressed();
199: }
200:
201: public boolean isIncreasePressed() {
202: return stateController.isIncreasePressed();
203: }
204:
205: public boolean isSliderPressed() {
206: return stateController.isSliderDragged();
207: }
208:
209: public int getSliderPosition() {
210: return value - minimum;
211: }
212:
213: public boolean isVertical() {
214: return (orientation == VERTICAL);
215: }
216:
217: public int getSliderSize() {
218: return visibleAmount;
219: }
220:
221: public int getScrollSize() {
222: return maximum - minimum;
223: }
224:
225: public Rectangle getSliderRect() {
226: //don't let modify rect in any other way
227: //than calling setXXXRect()
228: return sliderRect;
229: }
230:
231: public Rectangle getIncreaseRect() {
232: return increaseRect;
233: }
234:
235: public Rectangle getDecreaseRect() {
236: return decreaseRect;
237: }
238:
239: public void setSliderRect(Rectangle r) {
240: sliderRect.setRect(r);
241: }
242:
243: public void setIncreaseRect(Rectangle r) {
244: increaseRect.setRect(r);
245: }
246:
247: public void setDecreaseRect(Rectangle r) {
248: decreaseRect.setRect(r);
249: }
250:
251: public int getTrackSize() {
252: return trackSize;
253: }
254:
255: public void setTrackSize(int size) {
256: trackSize = size;
257: }
258:
259: public Adjustable getAdjustable() {
260: return Scrollbar.this ;
261: }
262:
263: public int getHighlight() {
264: return stateController.getHighlight();
265: }
266:
267: public Rectangle getTrackBounds() {
268: return trackRect;
269: }
270:
271: public void setTrackBounds(Rectangle r) {
272: trackRect.setBounds(r);
273: }
274:
275: public ComponentOrientation getComponentOrientation() {
276: return Scrollbar.this .getComponentOrientation();
277: }
278:
279: public Rectangle getUpperTrackBounds() {
280: return upperTrackRect;
281: }
282:
283: public Rectangle getLowerTrackBounds() {
284: return lowerTrackRect;
285: }
286:
287: public void setUpperTrackBounds(Rectangle r) {
288: upperTrackRect.setBounds(r);
289: }
290:
291: public void setLowerTrackBounds(Rectangle r) {
292: lowerTrackRect.setBounds(r);
293: }
294:
295: public Point getLocation() {
296: return new Point(0, 0);
297: }
298:
299: public void setValue(int type, int value) {
300: if (type == AdjustmentEvent.TRACK) {
301: setValuesImpl(value, visibleAmount, minimum, maximum,
302: false);
303: return;
304: }
305: Adjustable adj = getAdjustable();
306: if (adj != null) {
307: adj.setValue(value);
308: }
309: }
310:
311: @Override
312: public void calculate() {
313: toolkit.theme.calculateScrollbar(state);
314: }
315: }
316:
317: public int getValue() {
318: toolkit.lockAWT();
319: try {
320: return value;
321: } finally {
322: toolkit.unlockAWT();
323: }
324: }
325:
326: public void setValue(int val) {
327: toolkit.lockAWT();
328: try {
329: setValues(val, visibleAmount, minimum, maximum);
330: } finally {
331: toolkit.unlockAWT();
332: }
333: }
334:
335: @Override
336: public void addNotify() {
337: toolkit.lockAWT();
338: try {
339: super .addNotify();
340: } finally {
341: toolkit.unlockAWT();
342: }
343: }
344:
345: @Override
346: public AccessibleContext getAccessibleContext() {
347: toolkit.lockAWT();
348: try {
349: return super .getAccessibleContext();
350: } finally {
351: toolkit.unlockAWT();
352: }
353: }
354:
355: public int getBlockIncrement() {
356: toolkit.lockAWT();
357: try {
358: return getPageIncrement();
359: } finally {
360: toolkit.unlockAWT();
361: }
362: }
363:
364: /**
365: * @deprecated
366: */
367: @Deprecated
368: public int getLineIncrement() {
369: toolkit.lockAWT();
370: try {
371: return unitIncrement;
372: } finally {
373: toolkit.unlockAWT();
374: }
375: }
376:
377: public int getMaximum() {
378: toolkit.lockAWT();
379: try {
380: return maximum;
381: } finally {
382: toolkit.unlockAWT();
383: }
384: }
385:
386: public int getMinimum() {
387: toolkit.lockAWT();
388: try {
389: return minimum;
390: } finally {
391: toolkit.unlockAWT();
392: }
393: }
394:
395: public int getOrientation() {
396: toolkit.lockAWT();
397: try {
398: return orientation;
399: } finally {
400: toolkit.unlockAWT();
401: }
402: }
403:
404: /**
405: * @deprecated
406: */
407: @Deprecated
408: public int getPageIncrement() {
409: toolkit.lockAWT();
410: try {
411: return blockIncrement;
412: } finally {
413: toolkit.unlockAWT();
414: }
415: }
416:
417: public int getUnitIncrement() {
418: toolkit.lockAWT();
419: try {
420: return getLineIncrement();
421: } finally {
422: toolkit.unlockAWT();
423: }
424: }
425:
426: public boolean getValueIsAdjusting() {
427: toolkit.lockAWT();
428: try {
429: return valueIsAdjusting;
430: } finally {
431: toolkit.unlockAWT();
432: }
433: }
434:
435: /**
436: * @deprecated
437: */
438: @Deprecated
439: public int getVisible() {
440: toolkit.lockAWT();
441: try {
442: return visibleAmount;
443: } finally {
444: toolkit.unlockAWT();
445: }
446: }
447:
448: public int getVisibleAmount() {
449: toolkit.lockAWT();
450: try {
451: return getVisible();
452: } finally {
453: toolkit.unlockAWT();
454: }
455: }
456:
457: @Override
458: protected String paramString() {
459: /* The format is based on 1.5 release behavior
460: * which can be revealed by the following code:
461: * System.out.println(new Scrollbar());
462: * System.out.println(new Scrollbar(Scrollbar.HORIZONTAL));
463: */
464: toolkit.lockAWT();
465: try {
466: return (super .paramString()
467: + ",val=" + getValue() + ",vis=" + getVisibleAmount() //$NON-NLS-1$ //$NON-NLS-2$
468: + ",min=" + getMinimum() + ",max=" + getMaximum() //$NON-NLS-1$ //$NON-NLS-2$
469: + (getOrientation() == HORIZONTAL ? ",horz" : ",vert") + ",isAdjusting=" + getValueIsAdjusting()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
470: } finally {
471: toolkit.unlockAWT();
472: }
473: }
474:
475: public void setBlockIncrement(int v) {
476: toolkit.lockAWT();
477: try {
478: blockIncrement = Math.max(1, v);
479: } finally {
480: toolkit.unlockAWT();
481: }
482: }
483:
484: /**
485: * @deprecated
486: */
487: @Deprecated
488: public void setLineIncrement(int v) {
489: toolkit.lockAWT();
490: try {
491: setUnitIncrement(v);
492: } finally {
493: toolkit.unlockAWT();
494: }
495: }
496:
497: public void setMaximum(int max) {
498: toolkit.lockAWT();
499: try {
500: int oldMin = minimum;
501: int oldMax = maximum;
502: maximum = Math.max(Integer.MIN_VALUE + 1, max);
503: minimum = Math.min(maximum - 1, minimum);
504: setValues(value, visibleAmount, minimum, maximum);
505: if ((maximum != oldMax) || (minimum != oldMin)) {
506: doRepaint();
507: }
508: } finally {
509: toolkit.unlockAWT();
510: }
511: }
512:
513: public void setMinimum(int min) {
514: toolkit.lockAWT();
515: try {
516: setValues(value, visibleAmount, min, maximum);
517: } finally {
518: toolkit.unlockAWT();
519: }
520: }
521:
522: public void setOrientation(int orientation) {
523: toolkit.lockAWT();
524: try {
525: if ((orientation != HORIZONTAL)
526: && (orientation != VERTICAL)) {
527: // awt.113=illegal scrollbar orientation
528: throw new IllegalArgumentException(Messages
529: .getString("awt.113")); //$NON-NLS-1$
530: }
531: this .orientation = orientation;
532: doRepaint();
533: } finally {
534: toolkit.unlockAWT();
535: }
536: }
537:
538: /**
539: * @deprecated
540: */
541: @Deprecated
542: public void setPageIncrement(int v) {
543: toolkit.lockAWT();
544: try {
545: setBlockIncrement(v);
546: } finally {
547: toolkit.unlockAWT();
548: }
549: }
550:
551: public void setUnitIncrement(int v) {
552: toolkit.lockAWT();
553: try {
554: unitIncrement = Math.max(1, v);
555: } finally {
556: toolkit.unlockAWT();
557: }
558: }
559:
560: public void setValueIsAdjusting(boolean b) {
561: toolkit.lockAWT();
562: try {
563: valueIsAdjusting = b;
564: } finally {
565: toolkit.unlockAWT();
566: }
567: }
568:
569: public void setValues(int value, int visible, int min, int max) {
570: toolkit.lockAWT();
571: try {
572: setValuesImpl(value, visible, min, max, true);
573: } finally {
574: toolkit.unlockAWT();
575: }
576: }
577:
578: public void setVisibleAmount(int newAmount) {
579: toolkit.lockAWT();
580: try {
581: setValues(value, newAmount, minimum, maximum);
582: } finally {
583: toolkit.unlockAWT();
584: }
585: }
586:
587: @SuppressWarnings("unchecked")
588: @Override
589: public <T extends EventListener> T[] getListeners(
590: Class<T> listenerType) {
591: if (AdjustmentListener.class.isAssignableFrom(listenerType)) {
592: return (T[]) getAdjustmentListeners();
593: }
594: return super .getListeners(listenerType);
595: }
596:
597: public void addAdjustmentListener(AdjustmentListener l) {
598: adjustmentListeners.addUserListener(l);
599: }
600:
601: public void removeAdjustmentListener(AdjustmentListener l) {
602: adjustmentListeners.removeUserListener(l);
603: }
604:
605: public AdjustmentListener[] getAdjustmentListeners() {
606: return adjustmentListeners
607: .getUserListeners(new AdjustmentListener[0]);
608: }
609:
610: @Override
611: protected void processEvent(AWTEvent e) {
612: if (toolkit.eventTypeLookup.getEventMask(e) == AWTEvent.ADJUSTMENT_EVENT_MASK) {
613: processAdjustmentEvent((AdjustmentEvent) e);
614: } else {
615: super .processEvent(e);
616: }
617: }
618:
619: protected void processAdjustmentEvent(AdjustmentEvent e) {
620: for (AdjustmentListener listener : adjustmentListeners
621: .getUserListeners()) {
622: switch (e.getID()) {
623: case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
624: listener.adjustmentValueChanged(e);
625: break;
626: }
627: }
628: }
629:
630: @Override
631: String autoName() {
632: return ("scrollbar" + toolkit.autoNumber.nextScrollbar++); //$NON-NLS-1$
633: }
634:
635: @Override
636: void prepaint(Graphics g) {
637: toolkit.theme.drawScrollbar(g, state);
638: }
639:
640: @Override
641: boolean isPrepainter() {
642: return true;
643: }
644:
645: private void doRepaint(Rectangle r) {
646: if (isDisplayable()) {
647: if (isShowing()) {
648: repaint(r.x, r.y, r.width, r.height);
649: }
650: }
651: }
652:
653: private void doRepaint() {
654: toolkit.theme.layoutScrollbar(state);
655: invalidate();
656: doRepaint(new Rectangle(new Point(), getSize()));
657: }
658:
659: @Override
660: void setEnabledImpl(boolean value) {
661: super .setEnabledImpl(value);
662: doRepaint();
663: }
664:
665: @Override
666: ComponentBehavior createBehavior() {
667: return new HWBehavior(this );
668: }
669:
670: @Override
671: void validateImpl() {
672: super .validateImpl();
673: toolkit.theme.calculateScrollbar(state);
674: }
675:
676: void generateEvent() {
677: int type = stateController.getType();
678: if (type < 0) {
679: return;
680: }
681: setValueIsAdjusting(stateController.isSliderDragged());
682: postEvent(new AdjustmentEvent(this ,
683: AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, type, value,
684: getValueIsAdjusting()));
685: }
686:
687: @Override
688: Dimension getDefaultMinimumSize() {
689: return state.getDefaultMinimumSize();
690: }
691:
692: @Override
693: void resetDefaultSize() {
694: state.reset();
695: }
696:
697: void setValuesImpl(int value, int visible, int min, int max,
698: boolean repaint) {
699: int oldValue = this .value;
700: int oldMin = minimum;
701: minimum = Math.min(min, MAX - 1);
702: maximum = Math.max(minimum + 1, max);
703: if (maximum - minimum < 0) {
704: maximum = minimum + MAX;
705: }
706: visibleAmount = Math.max(1, visible);
707: visibleAmount = Math.min(maximum - minimum, visibleAmount);
708: this .value = Math.max(minimum, value);
709: this .value = Math.min(this .value, maximum - visibleAmount);
710: repaint &= (oldValue != this .value) || (oldMin != minimum);
711: if (repaint) {
712: doRepaint();
713: }
714: }
715:
716: @Override
717: AccessibleContext createAccessibleContext() {
718: return new AccessibleAWTScrollBar();
719: }
720: }
|