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.awt.event.InvocationEvent;
023: import java.io.Serializable;
024: import java.util.Collection;
025: import org.apache.harmony.awt.ScrollbarStateController;
026: import org.apache.harmony.awt.internal.nls.Messages;
027: import org.apache.harmony.awt.state.ScrollbarState;
028: import org.apache.harmony.awt.wtk.NativeWindow;
029:
030: public class ScrollPaneAdjustable implements Adjustable, Serializable {
031: private static final long serialVersionUID = -3359745691033257079L;
032:
033: private final AWTListenerList<AdjustmentListener> adjustmentListeners = new AWTListenerList<AdjustmentListener>();
034:
035: private final int orientation;
036:
037: private final Component comp;
038:
039: private int value;
040:
041: private int visibleAmount;
042:
043: private int minimum;
044:
045: private int maximum;
046:
047: private int unitIncrement;
048:
049: private int blockIncrement;
050:
051: private boolean valueIsAdjusting;
052:
053: private final ScrollbarStateController stateController;
054:
055: private final Rectangle bounds = new Rectangle();
056:
057: private final transient State state = new State();
058:
059: private boolean callAWTListener;
060:
061: class State implements ScrollbarState {
062: private final Rectangle decreaseRect = new Rectangle();
063:
064: private final Rectangle increaseRect = new Rectangle();
065:
066: private final Rectangle sliderRect = new Rectangle();
067:
068: private final Rectangle trackRect = new Rectangle();
069:
070: private final Rectangle upperTrackRect = new Rectangle();
071:
072: private final Rectangle lowerTrackRect = new Rectangle();
073:
074: private int trackSize;
075:
076: public Adjustable getAdjustable() {
077: return ScrollPaneAdjustable.this ;
078: }
079:
080: public int getHighlight() {
081: return stateController.getHighlight();
082: }
083:
084: public ComponentOrientation getComponentOrientation() {
085: return comp.getComponentOrientation();
086: }
087:
088: public boolean isDecreasePressed() {
089: return stateController.isDecreasePressed();
090: }
091:
092: public boolean isIncreasePressed() {
093: return stateController.isIncreasePressed();
094: }
095:
096: public boolean isSliderPressed() {
097: return stateController.isSliderDragged();
098: }
099:
100: public int getSliderPosition() {
101: return getValue();
102: }
103:
104: public int getSliderSize() {
105: return getVisibleAmount();
106: }
107:
108: public int getScrollSize() {
109: return getMaximum() - getMinimum();
110: }
111:
112: public boolean isVertical() {
113: return (getOrientation() == Adjustable.VERTICAL);
114: }
115:
116: public Rectangle getTrackBounds() {
117: return trackRect;
118: }
119:
120: public void setTrackBounds(Rectangle r) {
121: trackRect.setBounds(r);
122: }
123:
124: public Rectangle getUpperTrackBounds() {
125: return upperTrackRect;
126: }
127:
128: public Rectangle getLowerTrackBounds() {
129: return lowerTrackRect;
130: }
131:
132: public void setUpperTrackBounds(Rectangle r) {
133: upperTrackRect.setBounds(r);
134: }
135:
136: public void setLowerTrackBounds(Rectangle r) {
137: lowerTrackRect.setBounds(r);
138: }
139:
140: public void setDecreaseRect(Rectangle r) {
141: decreaseRect.setRect(r);
142: }
143:
144: public void setSliderRect(Rectangle r) {
145: sliderRect.setRect(r);
146: }
147:
148: public void setIncreaseRect(Rectangle r) {
149: increaseRect.setRect(r);
150: }
151:
152: public void setTrackSize(int size) {
153: trackSize = size;
154: }
155:
156: public int getTrackSize() {
157: return trackSize;
158: }
159:
160: public Rectangle getSliderRect() {
161: //don't let modify rect in any other way
162: //than calling setXXXRect()
163: return sliderRect;
164: }
165:
166: public Rectangle getIncreaseRect() {
167: return increaseRect;
168: }
169:
170: public Rectangle getDecreaseRect() {
171: return decreaseRect;
172: }
173:
174: public boolean isEnabled() {
175: return comp.isEnabled();
176: }
177:
178: public boolean isVisible() {
179: return comp.isVisible();
180: }
181:
182: public boolean isFocused() {
183: return false;
184: }
185:
186: public Font getFont() {
187: return null;
188: }
189:
190: public boolean isFontSet() {
191: return false;
192: }
193:
194: public FontMetrics getFontMetrics() {
195: return null;
196: }
197:
198: public Color getBackground() {
199: return comp.getBackground();
200: }
201:
202: public boolean isBackgroundSet() {
203: return comp.isBackgroundSet();
204: }
205:
206: public Color getTextColor() {
207: return null;
208: }
209:
210: public Rectangle getBounds() {
211: if (bounds != null) {
212: return bounds.getBounds();
213: }
214: return null;
215: }
216:
217: public Dimension getSize() {
218: if (bounds != null) {
219: return bounds.getSize();
220: }
221: return null;
222: }
223:
224: public Dimension getDefaultMinimumSize() {
225: return null;
226: }
227:
228: public void setDefaultMinimumSize(Dimension size) {
229: }
230:
231: public long getWindowId() {
232: NativeWindow win = comp.getNativeWindow();
233: return (win != null) ? win.getId() : 0;
234: }
235:
236: public Point getLocation() {
237: return bounds.getLocation();
238: }
239:
240: public void setValue(int type, int value) {
241: ScrollPaneAdjustable.this .setValue(type, value);
242: }
243:
244: public boolean isTextColorSet() {
245: return false;
246: }
247: }
248:
249: ScrollPaneAdjustable(Component comp, int orientation) {
250: this .comp = comp;
251: this .orientation = orientation;
252: unitIncrement = 1;
253: blockIncrement = 1;
254: stateController = new ScrollbarStateController(state) {
255: @Override
256: protected void fireEvent() {
257: generateEvent();
258: }
259:
260: @Override
261: protected void repaint(Rectangle r) {
262: doRepaint(r);
263: }
264:
265: @Override
266: protected void repaint() {
267: doRepaint();
268: }
269:
270: @Override
271: protected void requestFocus() {
272: // just don't do it
273: }
274: };
275: comp.addAWTMouseListener(stateController);
276: comp.addAWTMouseMotionListener(stateController);
277: comp.addAWTComponentListener(stateController);
278: }
279:
280: @Override
281: public String toString() {
282: return (getClass().getName() + "[" + paramString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
283: }
284:
285: public int getValue() {
286: return value;
287: }
288:
289: public void setValue(int v) {
290: setValue(AdjustmentEvent.TRACK, v);
291: }
292:
293: public int getBlockIncrement() {
294: return blockIncrement;
295: }
296:
297: public int getMaximum() {
298: return maximum;
299: }
300:
301: public int getMinimum() {
302: return minimum;
303: }
304:
305: public int getOrientation() {
306: return orientation;
307: }
308:
309: public int getUnitIncrement() {
310: return unitIncrement;
311: }
312:
313: public boolean getValueIsAdjusting() {
314: return valueIsAdjusting;
315: }
316:
317: public int getVisibleAmount() {
318: return visibleAmount;
319: }
320:
321: public String paramString() {
322: /* The format is based on 1.5 release behavior
323: * which can be revealed by the following code:
324: *
325: * System.out.println(new ScrollPane().getVAdjustable());
326: * System.out.println(new ScrollPane().getHAdjustable());
327: */
328: String orientStr = ""; //$NON-NLS-1$
329: switch (orientation) {
330: case Adjustable.HORIZONTAL:
331: orientStr = "horizontal"; //$NON-NLS-1$
332: break;
333: case Adjustable.VERTICAL:
334: orientStr = "vertical"; //$NON-NLS-1$
335: break;
336: case Adjustable.NO_ORIENTATION:
337: orientStr = "no orientation"; //$NON-NLS-1$
338: break;
339: }
340: return (orientStr
341: + ",val=" + value + ",vis=" + visibleAmount + ",[" + minimum + ".." //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
342: + maximum
343: + "]" + ",unit=" + unitIncrement + ",block=" + blockIncrement //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
344: + ",isAdjusting=" + valueIsAdjusting); //$NON-NLS-1$
345: }
346:
347: public void setBlockIncrement(int b) {
348: blockIncrement = b;
349: }
350:
351: public void setMaximum(int max) {
352: // awt.144=Can be set by scrollpane only
353: throw new AWTError(Messages.getString("awt.144")); //$NON-NLS-1$
354: }
355:
356: public void setMinimum(int min) {
357: // awt.144=Can be set by scrollpane only
358: throw new AWTError(Messages.getString("awt.144")); //$NON-NLS-1$
359: }
360:
361: public void setUnitIncrement(int u) {
362: unitIncrement = u;
363: }
364:
365: public void setValueIsAdjusting(boolean b) {
366: valueIsAdjusting = b;
367: }
368:
369: public void setVisibleAmount(int vis) {
370: // awt.144=Can be set by scrollpane only
371: throw new AWTError(Messages.getString("awt.144")); //$NON-NLS-1$
372: }
373:
374: public void addAdjustmentListener(AdjustmentListener l) {
375: adjustmentListeners.addUserListener(l);
376: }
377:
378: public void removeAdjustmentListener(AdjustmentListener l) {
379: adjustmentListeners.removeUserListener(l);
380: }
381:
382: public AdjustmentListener[] getAdjustmentListeners() {
383: return adjustmentListeners
384: .getUserListeners(new AdjustmentListener[0]);
385: }
386:
387: final Rectangle getBounds() {
388: return bounds.getBounds();
389: }
390:
391: final void setBounds(Rectangle bounds) {
392: Rectangle oldBounds = this .bounds.getBounds();
393: this .bounds.setBounds(bounds);
394: if (!oldBounds.equals(bounds)) {
395: doRepaint();
396: }
397: }
398:
399: void doRepaint() {
400: doRepaint(new Rectangle(new Point(), bounds.getSize()));
401: }
402:
403: void doRepaint(Rectangle r) {
404: if (comp.isDisplayable()) {
405: comp.toolkit.theme.layoutScrollbar(state);
406: comp.invalidate();
407: Rectangle paintRect = new Rectangle(r);
408: paintRect.translate(bounds.x, bounds.y);
409: repaintComponent(paintRect);
410: }
411: }
412:
413: void repaintComponent(Rectangle r) {
414: if (comp.isShowing()) {
415: comp.repaint(r.x, r.y, r.width, r.height);
416: }
417: }
418:
419: void prepaint(Graphics g) {
420: if ((bounds == null) || bounds.isEmpty()) {
421: return;
422: }
423: g.translate(bounds.x, bounds.y);
424: comp.toolkit.theme.drawScrollbar(g, state);
425: g.translate(-bounds.x, -bounds.y);
426: }
427:
428: void generateEvent() {
429: setValueIsAdjusting(stateController.isSliderDragged());
430: }
431:
432: private void postAdjustmentEvent(final int type) {
433: // create and post invocation event here:
434: comp.postEvent(new InvocationEvent(ScrollPaneAdjustable.this ,
435: new Runnable() {
436: public void run() {
437: AdjustmentEvent event = new AdjustmentEvent(
438: ScrollPaneAdjustable.this ,
439: AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
440: type, value, getValueIsAdjusting());
441: if (callAWTListener) {
442: comp.toolkit.lockAWT();
443: try {
444: processAdjustmentEvent(event,
445: adjustmentListeners
446: .getSystemListeners());
447: } finally {
448: comp.toolkit.unlockAWT();
449: }
450: }
451: processAdjustmentEvent(event,
452: adjustmentListeners.getUserListeners());
453: }
454: }));
455: }
456:
457: /**
458: * Set parameters which cannot be set by public api methods
459: */
460: void setSizes(int vis, int min, int max) {
461: boolean repaint = false;
462: if (vis != visibleAmount) {
463: visibleAmount = vis;
464: repaint = true;
465: }
466: if (min != minimum) {
467: minimum = min;
468: repaint = true;
469: }
470: if (max != maximum) {
471: maximum = max;
472: repaint = true;
473: }
474: if (repaint) {
475: doRepaint();
476: }
477: }
478:
479: void processAdjustmentEvent(AdjustmentEvent e,
480: Collection<AdjustmentListener> c) {
481: for (AdjustmentListener listener : c) {
482: switch (e.getID()) {
483: case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
484: listener.adjustmentValueChanged(e);
485: break;
486: }
487: }
488: }
489:
490: void setValue(int type, int val) {
491: int oldVal = value;
492: value = Math.max(Math.min(val, maximum - visibleAmount),
493: minimum);
494: if (oldVal != value) {
495: Rectangle oldRect = new Rectangle(state.getSliderRect());
496: comp.toolkit.theme.layoutScrollbar(state); //TODO: FIXME
497: Rectangle paintRect = oldRect.union(state.getSliderRect());
498: paintRect.grow(0, 1);
499: postAdjustmentEvent(type);
500: doRepaint(paintRect);
501: }
502: }
503:
504: void addAWTAdjustmentListener(AdjustmentListener l) {
505: adjustmentListeners.addSystemListener(l);
506: callAWTListener = true;
507: }
508:
509: ScrollbarStateController getStateController() {
510: return stateController;
511: }
512: }
|