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.MouseEvent;
021: import java.awt.event.MouseWheelEvent;
022: import javax.accessibility.Accessible;
023: import javax.accessibility.AccessibleContext;
024: import javax.accessibility.AccessibleRole;
025: import org.apache.harmony.awt.ScrollStateController;
026: import org.apache.harmony.awt.Scrollable;
027: import org.apache.harmony.awt.internal.nls.Messages;
028: import org.apache.harmony.awt.theme.DefaultButton;
029:
030: public class ScrollPane extends Container implements Accessible {
031: private static final long serialVersionUID = 7956609840827222915L;
032:
033: public static final int SCROLLBARS_AS_NEEDED = 0;
034:
035: public static final int SCROLLBARS_ALWAYS = 1;
036:
037: public static final int SCROLLBARS_NEVER = 2;
038:
039: final static int HSCROLLBAR_HEIGHT = 16;
040:
041: final static int VSCROLLBAR_WIDTH = 16;
042:
043: final static int BORDER_SIZE = 2;
044:
045: private final static Insets defInsets = new Insets(BORDER_SIZE,
046: BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
047:
048: private int scrollbarDisplayPolicy;
049:
050: private boolean wheelScrollingEnabled;
051:
052: private ScrollPaneAdjustable hAdjustable;
053:
054: private ScrollPaneAdjustable vAdjustable;
055:
056: private final ScrollStateController stateController;
057:
058: private final Scrollable scrollable;
059:
060: protected class AccessibleAWTScrollPane extends
061: AccessibleAWTContainer {
062: private static final long serialVersionUID = 6100703663886637L;
063:
064: protected AccessibleAWTScrollPane() {
065: }
066:
067: @Override
068: public AccessibleRole getAccessibleRole() {
069: return AccessibleRole.SCROLL_PANE;
070: }
071: }
072:
073: class SPScrollable implements Scrollable {
074: public Adjustable getVAdjustable() {
075: return vAdjustable;
076: }
077:
078: public Adjustable getHAdjustable() {
079: return hAdjustable;
080: }
081:
082: public Insets getInsets() {
083: return ScrollPane.defInsets;
084: }
085:
086: public Point getLocation() {
087: return getScrollPosition();
088: }
089:
090: @SuppressWarnings("deprecation")
091: public void setLocation(Point p) {
092: Component comp = ScrollPane.this .getComponent();
093: if (comp != null) {
094: comp.move(p.x, p.y);
095: }
096: }
097:
098: public Component getComponent() {
099: return ScrollPane.this ;
100: }
101:
102: public Dimension getSize() {
103: Dimension size = new Dimension();
104: Component comp = ScrollPane.this .getComponent();
105: if (comp != null) {
106: size.setSize(comp.getSize());
107: }
108: return size;
109: }
110:
111: public void doRepaint() {
112: ScrollPane.this .doRepaint();
113: }
114:
115: public int getAdjustableWidth() {
116: return getVScrollbarWidth();
117: }
118:
119: public int getAdjustableHeight() {
120: return getHScrollbarHeight();
121: }
122:
123: public void setAdjustableSizes(Adjustable adj, int vis,
124: int min, int max) {
125: ((ScrollPaneAdjustable) adj).setSizes(vis, min, max);
126: }
127:
128: public int getAdjustableMode(Adjustable adj) {
129: return getScrollbarDisplayPolicy();
130: }
131:
132: public void setAdjustableBounds(Adjustable adj, Rectangle r) {
133: ((ScrollPaneAdjustable) adj).setBounds(r);
134: }
135:
136: public int getWidth() {
137: return ScrollPane.this .getWidth();
138: }
139:
140: public int getHeight() {
141: return ScrollPane.this .getHeight();
142: }
143:
144: public void doRepaint(Rectangle r) {
145: ScrollPane.this .doRepaint(r);
146: }
147: }
148:
149: public ScrollPane() throws HeadlessException {
150: this (SCROLLBARS_AS_NEEDED);
151: toolkit.lockAWT();
152: try {
153: } finally {
154: toolkit.unlockAWT();
155: }
156: }
157:
158: public ScrollPane(int scrollbarDisplayPolicy)
159: throws HeadlessException {
160: toolkit.lockAWT();
161: try {
162: Toolkit.checkHeadless();
163: switch (scrollbarDisplayPolicy) {
164: case SCROLLBARS_ALWAYS:
165: case SCROLLBARS_AS_NEEDED:
166: case SCROLLBARS_NEVER:
167: break;
168: default:
169: // awt.146=illegal scrollbar display policy
170: throw new IllegalArgumentException(Messages
171: .getString("awt.146")); //$NON-NLS-1$
172: }
173: this .scrollbarDisplayPolicy = scrollbarDisplayPolicy;
174: setWheelScrollingEnabled(true);
175: hAdjustable = new ScrollPaneAdjustable(this ,
176: Adjustable.HORIZONTAL);
177: vAdjustable = new ScrollPaneAdjustable(this ,
178: Adjustable.VERTICAL);
179: scrollable = new SPScrollable();
180: stateController = new ScrollStateController(scrollable);
181: addAWTComponentListener(stateController);
182: hAdjustable.addAWTAdjustmentListener(stateController);
183: vAdjustable.addAWTAdjustmentListener(stateController);
184: // The initial size of this container is set to 100x100:
185: setSize(100, 100);
186: } finally {
187: toolkit.unlockAWT();
188: }
189: }
190:
191: @Override
192: public void addNotify() {
193: toolkit.lockAWT();
194: try {
195: super .addNotify();
196: } finally {
197: toolkit.unlockAWT();
198: }
199: }
200:
201: @Override
202: public AccessibleContext getAccessibleContext() {
203: toolkit.lockAWT();
204: try {
205: return super .getAccessibleContext();
206: } finally {
207: toolkit.unlockAWT();
208: }
209: }
210:
211: @Override
212: public String paramString() {
213: /* The format is based on 1.5 release behavior
214: * which can be revealed by the following code:
215: * System.out.println(new ScrollPane());
216: */
217: toolkit.lockAWT();
218: try {
219: Point scrollPos = new Point();
220: try {
221: scrollPos = getScrollPosition();
222: } catch (NullPointerException npe) {
223: }
224: Insets ins = getInsets();
225: String strPolicy = ""; //$NON-NLS-1$
226: switch (getScrollbarDisplayPolicy()) {
227: case SCROLLBARS_ALWAYS:
228: strPolicy = "always"; //$NON-NLS-1$
229: break;
230: case SCROLLBARS_AS_NEEDED:
231: strPolicy = "as-needed"; //$NON-NLS-1$
232: break;
233: case SCROLLBARS_NEVER:
234: strPolicy = "never"; //$NON-NLS-1$
235: break;
236: }
237: return (super .paramString()
238: + ",ScrollPosition=(" + scrollPos.x + "," + scrollPos.x //$NON-NLS-1$ //$NON-NLS-2$
239: + ")" + ",Insets=(" + ins.left + "," + ins.top + "," + ins.right + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
240: + ins.bottom
241: + ")" + ",ScrollbarDisplayPolicy=" + strPolicy //$NON-NLS-1$ //$NON-NLS-2$
242: + ",wheelScrollingEnabled=" + isWheelScrollingEnabled()); //$NON-NLS-1$
243: } finally {
244: toolkit.unlockAWT();
245: }
246: }
247:
248: @Override
249: public void doLayout() {
250: toolkit.lockAWT();
251: try {
252: layout();
253: } finally {
254: toolkit.unlockAWT();
255: }
256: }
257:
258: protected boolean eventTypeEnabled(int type) {
259: toolkit.lockAWT();
260: try {
261: return (isWheelScrollingEnabled() && (type == MouseEvent.MOUSE_WHEEL));
262: } finally {
263: toolkit.unlockAWT();
264: }
265: }
266:
267: @SuppressWarnings("deprecation")
268: @Deprecated
269: @Override
270: public void layout() {
271: toolkit.lockAWT();
272: try {
273: Component scrollComp = getComponent();
274: if (scrollComp != null) {
275: Rectangle clientRect = getClient();
276: Dimension prefSize = scrollComp.getPreferredSize();
277: Dimension viewSize = clientRect.getSize();
278: int newWidth = Math.max(viewSize.width, prefSize.width);
279: int newHeight = Math.max(viewSize.height,
280: prefSize.height);
281: scrollComp.setSize(newWidth, newHeight);
282: stateController.layoutScrollbars();
283: //set value if current value is invalid:
284: Point oldScrollPos = getScrollPosition();
285: setScrollPosition(oldScrollPos);
286: Point scrollPos = getScrollPosition();
287: // correct component's position even if
288: // value is the same as old
289: if (oldScrollPos.equals(scrollPos)) {
290: scrollComp.setLocation(scrollPos);
291: }
292: }
293: } finally {
294: toolkit.unlockAWT();
295: }
296: }
297:
298: @Override
299: protected void processMouseWheelEvent(MouseWheelEvent e) {
300: toolkit.lockAWT();
301: try {
302: stateController.mouseWheelMoved(e);
303: super .processMouseWheelEvent(e);
304: } finally {
305: toolkit.unlockAWT();
306: }
307: }
308:
309: @Override
310: protected final void addImpl(Component comp, Object constraints,
311: int index) {
312: toolkit.lockAWT();
313: try {
314: if (index > 0) {
315: // awt.147=position greater than 0
316: throw new IllegalArgumentException(Messages
317: .getString("awt.147")); //$NON-NLS-1$
318: }
319: if (getComponentCount() > 0) {
320: remove(0);
321: }
322: super .addImpl(comp, constraints, index);
323: } finally {
324: toolkit.unlockAWT();
325: }
326: }
327:
328: public Adjustable getHAdjustable() {
329: toolkit.lockAWT();
330: try {
331: return hAdjustable;
332: } finally {
333: toolkit.unlockAWT();
334: }
335: }
336:
337: public int getHScrollbarHeight() {
338: toolkit.lockAWT();
339: try {
340: return isDisplayable() ? HSCROLLBAR_HEIGHT : 0;
341: } finally {
342: toolkit.unlockAWT();
343: }
344: }
345:
346: public Point getScrollPosition() {
347: toolkit.lockAWT();
348: try {
349: Component comp = getComponent();
350: if (comp == null) {
351: // awt.148=child is null
352: throw new NullPointerException(Messages
353: .getString("awt.148")); //$NON-NLS-1$
354: }
355: return new Point(hAdjustable.getValue(), vAdjustable
356: .getValue());
357: } finally {
358: toolkit.unlockAWT();
359: }
360: }
361:
362: public int getScrollbarDisplayPolicy() {
363: toolkit.lockAWT();
364: try {
365: return scrollbarDisplayPolicy;
366: } finally {
367: toolkit.unlockAWT();
368: }
369: }
370:
371: public Adjustable getVAdjustable() {
372: toolkit.lockAWT();
373: try {
374: return vAdjustable;
375: } finally {
376: toolkit.unlockAWT();
377: }
378: }
379:
380: public int getVScrollbarWidth() {
381: toolkit.lockAWT();
382: try {
383: return isDisplayable() ? VSCROLLBAR_WIDTH : 0;
384: } finally {
385: toolkit.unlockAWT();
386: }
387: }
388:
389: public Dimension getViewportSize() {
390: toolkit.lockAWT();
391: try {
392: return getClient().getSize();
393: } finally {
394: toolkit.unlockAWT();
395: }
396: }
397:
398: public boolean isWheelScrollingEnabled() {
399: toolkit.lockAWT();
400: try {
401: return wheelScrollingEnabled;
402: } finally {
403: toolkit.unlockAWT();
404: }
405: }
406:
407: @Override
408: public void printComponents(Graphics g) {
409: toolkit.lockAWT();
410: try {
411: // just call super
412: // TODO: find out why override
413: super .printComponents(g);
414: } finally {
415: toolkit.unlockAWT();
416: }
417: }
418:
419: @Override
420: public final void setLayout(LayoutManager mgr) {
421: toolkit.lockAWT();
422: try {
423: //don't let user set layout: throw error
424: // awt.149=ScrollPane controls layout
425: throw new AWTError(Messages.getString("awt.149")); //$NON-NLS-1$
426: } finally {
427: toolkit.unlockAWT();
428: }
429: }
430:
431: public void setScrollPosition(Point p) {
432: toolkit.lockAWT();
433: try {
434: setScrollPosition(p.x, p.y);
435: } finally {
436: toolkit.unlockAWT();
437: }
438: }
439:
440: public void setScrollPosition(int x, int y) {
441: toolkit.lockAWT();
442: try {
443: Component child = getComponent();
444: Dimension vSize = getViewportSize();
445: int maxX = child.getWidth() - vSize.width;
446: int maxY = child.getHeight() - vSize.height;
447: int newX = Math.max(0, Math.min(x, maxX));
448: int newY = Math.max(0, Math.min(y, maxY));
449: int oldX = hAdjustable.getValue();
450: int oldY = vAdjustable.getValue();
451: if (newX != oldX) {
452: hAdjustable.setValue(newX);
453: }
454: if (newY != oldY) {
455: vAdjustable.setValue(newY);
456: }
457: } finally {
458: toolkit.unlockAWT();
459: }
460: }
461:
462: public void setWheelScrollingEnabled(boolean handleWheel) {
463: toolkit.lockAWT();
464: try {
465: wheelScrollingEnabled = handleWheel;
466: long mask = AWTEvent.MOUSE_WHEEL_EVENT_MASK;
467: if (wheelScrollingEnabled) {
468: enableEvents(mask);
469: } else {
470: disableEvents(mask);
471: }
472: } finally {
473: toolkit.unlockAWT();
474: }
475: }
476:
477: @Override
478: ComponentBehavior createBehavior() {
479: return new HWBehavior(this );
480: }
481:
482: @Override
483: boolean isPrepainter() {
484: return true;
485: }
486:
487: @Override
488: void prepaint(Graphics g) {
489: g.setColor(getBackground());
490: g.fillRect(0, 0, w, h);
491: // draw pressed button frame:
492: DefaultButton.drawButtonFrame(g, new Rectangle(new Point(),
493: getSize()), true);
494: vAdjustable.prepaint(g);
495: hAdjustable.prepaint(g);
496: }
497:
498: Component getComponent() {
499: if (getComponentCount() > 0) {
500: return getComponent(0);
501: }
502: return null;
503: }
504:
505: @Override
506: Insets getNativeInsets() {
507: if (!isDisplayable()) {
508: return super .getNativeInsets();
509: }
510: Insets insets = (Insets) defInsets.clone();
511: insets.bottom += hAdjustable.getBounds().height;
512: insets.right += vAdjustable.getBounds().width;
513: return insets;
514: }
515:
516: @Override
517: String autoName() {
518: return ("scrollpane" + toolkit.autoNumber.nextScrollPane++); //$NON-NLS-1$
519: }
520:
521: Dimension calculateMinimumSize() {
522: return getSize(); // FIXME: component should do this
523: }
524:
525: Dimension calculatePreferredSize() {
526: return getMinimumSize(); // FIXME: component should do this
527: }
528:
529: private void doRepaint(Rectangle r) {
530: if (isDisplayable()) {
531: invalidate();
532: if (isShowing() && (r != null)) {
533: repaint(r.x, r.y, r.width, r.height);
534: }
535: }
536: }
537:
538: private void doRepaint() {
539: stateController.layoutScrollbars();
540: doRepaint(new Rectangle(new Point(), getSize()));
541: }
542:
543: @Override
544: AccessibleContext createAccessibleContext() {
545: return new AccessibleAWTScrollPane();
546: }
547: }
|