001: /*
002: * Javu WingS - Lightweight Java Component Set
003: * Copyright (c) 2005-2007 Krzysztof A. Sadlocha
004: * e-mail: ksadlocha@programics.com
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package com.javujavu.javux.wings;
022:
023: import java.awt.BorderLayout;
024: import java.awt.Component;
025: import java.awt.Dimension;
026: import java.awt.Insets;
027: import java.awt.Point;
028: import java.awt.event.AdjustmentEvent;
029: import java.awt.event.AdjustmentListener;
030:
031: /**
032: * This class provides a scrollable view containing
033: * a single child component.
034: * A <code>WingScrollPane</code> manages a view and optional
035: * vertical and horizontal scroll bars.
036: * <br>
037: * <br>
038: * <b>This class is thread safe.</b>
039: **/
040: public class WingScrollPane extends WingComponent implements
041: AdjustmentListener {
042: protected/*final*/Component client;
043: protected/*final*/WingScrollView view;
044:
045: protected/*final*/WingScroll hScroll;
046: protected/*final*/WingScroll vScroll;
047:
048: protected int vPolicy;
049: protected int hPolicy;
050:
051: protected int hScrollHeight;
052: protected int vScrollWidth;
053: private boolean showBorder;
054:
055: public WingScrollPane(Component client) {
056: this (client, true);
057: }
058:
059: public WingScrollPane(Component client, boolean showBorder) {
060: this .showBorder = showBorder;
061:
062: this .view = new WingScrollView(this );
063: this .client = client;
064: view.add(client, BorderLayout.CENTER);
065: this .add(view);
066: vPolicy = SCROLLBAR_AS_NEEDED;
067: ;
068: hPolicy = SCROLLBAR_AS_NEEDED;
069: hScroll = new WingScroll(HORIZONTAL);
070: vScroll = new WingScroll(VERTICAL);
071: hScrollHeight = 16;
072: vScrollWidth = 16;
073: add(hScroll);
074: add(vScroll);
075: hScroll.addAdjustmentListener(this );
076: vScroll.addAdjustmentListener(this );
077:
078: WingToolkit.the().addWheelListener(this , this );
079: }
080:
081: public void loadSkin() {
082: String idt = showBorder ? "border.scrollpane"
083: : "noborder.scrollpane";
084: stNormal = WingSkin.getStyle(styleId, idt, NORMAL, null);
085: stDisabled = WingSkin
086: .getStyle(styleId, idt, DISABLED, stNormal);
087: }
088:
089: public void mouseWheelMoved(Object src, int rotation) {
090: if (vScroll.isVisible())
091: vScroll.mouseWheelMoved(src, rotation);
092: else if (hScroll.isVisible())
093: hScroll.mouseWheelMoved(src, rotation);
094: }
095:
096: public void setVerticalScrollBarPolicy(int policy) {
097: vPolicy = policy;
098: revalidateAndRepaint();
099: }
100:
101: public void setHorizontalScrollBarPolicy(int policy) {
102: hPolicy = policy;
103: revalidateAndRepaint();
104: }
105:
106: public int getHorizontalScrollBarPolicy() {
107: return hPolicy;
108: }
109:
110: /**
111: * <br><br><strong>This method acquire TreeLock</strong>
112: */
113: public void setScrollPosition(int x, int y) {
114: if (!hScroll.isVisible())
115: x = 0;
116: if (!vScroll.isVisible())
117: y = 0;
118: hScroll.setValue(x);
119: vScroll.setValue(y);
120: adjustmentValueChanged(null);
121: }
122:
123: /**
124: * <br><br><strong>This method acquire TreeLock</strong>
125: */
126: public void adjustmentValueChanged(AdjustmentEvent e) {
127: client.setLocation(-hScroll.getValue(), -vScroll.getValue());
128: }
129:
130: public Point getScrollPosition() {
131: return new Point(hScroll.getValue(), vScroll.getValue());
132: }
133:
134: /**
135: * <br><br><strong>This method acquire TreeLock</strong>
136: */
137: public void doLayout() {
138: Dimension mySize = getSize();
139: if (mySize.width <= 0 || mySize.height <= 0)
140: return;
141:
142: Dimension clientPrefSize = client.getPreferredSize();
143: hScrollHeight = hScroll.getPreferredSize().height;
144: vScrollWidth = vScroll.getPreferredSize().width;
145: Dimension viewSize = new Dimension();
146: Insets margin = stNormal.margin;
147: Dimension c2;
148:
149: boolean needV, needH, alwaysH, alwaysV;
150: needH = hScroll.isVisible() && (hPolicy == SCROLLBAR_AS_NEEDED);
151: needV = vScroll.isVisible() && (vPolicy == SCROLLBAR_AS_NEEDED);
152: alwaysH = (hPolicy == SCROLLBAR_ALWAYS);
153: alwaysV = (vPolicy == SCROLLBAR_ALWAYS);
154:
155: final int iterationCount = 8;
156: int i;
157: for (i = 0; i < iterationCount; i++) {
158: viewSize.width = mySize.width - margin.left - margin.right;
159: viewSize.height = mySize.height - margin.top
160: - margin.bottom;
161: if (needV || alwaysV)
162: viewSize.width -= vScrollWidth;
163: if (needH || alwaysH)
164: viewSize.height -= hScrollHeight;
165:
166: if (!needV && viewSize.height < clientPrefSize.height
167: && vPolicy == SCROLLBAR_AS_NEEDED) {
168: needV = true;
169: } else if (!needH && viewSize.width < clientPrefSize.width
170: && hPolicy == SCROLLBAR_AS_NEEDED) {
171: needH = true;
172: } else if (needV
173: && viewSize.height >= clientPrefSize.height
174: && vPolicy == SCROLLBAR_AS_NEEDED) {
175: needV = false;
176: } else if (needH && viewSize.width >= clientPrefSize.width
177: && hPolicy == SCROLLBAR_AS_NEEDED) {
178: needH = false;
179: } else {
180: if (viewSize.width < 1)
181: viewSize.width = 1;
182: if (viewSize.height < 1)
183: viewSize.height = 1;
184: view.setBounds(margin.left, margin.top, viewSize.width,
185: viewSize.height);
186:
187: c2 = client.getPreferredSize();
188:
189: if (c2.equals(clientPrefSize) || c2.equals(viewSize)) {
190: int clientWidth = viewSize.width, clientHeight = viewSize.height;
191: if (hPolicy != WingScrollPane.SCROLLBAR_NEVER
192: && clientPrefSize.width > clientWidth)
193: clientWidth = clientPrefSize.width;
194: if (vPolicy != WingScrollPane.SCROLLBAR_NEVER
195: && clientPrefSize.height > clientHeight)
196: clientHeight = clientPrefSize.height;
197:
198: client.setSize(clientWidth, clientHeight);
199: client.validate();
200:
201: c2 = client.getPreferredSize();
202:
203: if (c2.equals(clientPrefSize)
204: || c2.equals(viewSize)) {
205: break;
206: }
207: }
208: clientPrefSize = c2;
209: }
210: }
211: int h = hScroll.getValue(), v = vScroll.getValue();
212: if (v > clientPrefSize.height - viewSize.height)
213: v = clientPrefSize.height - viewSize.height;
214: if (v < 0)
215: v = 0;
216: if (h > clientPrefSize.width - viewSize.width)
217: h = clientPrefSize.width - viewSize.width;
218: if (h < 0)
219: h = 0;
220:
221: if (needH || alwaysH) {
222: hScroll.setVisible(true);
223: hScroll.setEnabled(viewSize.width < clientPrefSize.width);
224: hScroll.setBounds(margin.left,
225: margin.top + viewSize.height, viewSize.width,
226: hScrollHeight);
227: } else {
228: hScroll.setVisible(false);
229: h = 0;
230: }
231: hScroll.setValues(h, viewSize.width, 0, clientPrefSize.width);
232: if (needV || alwaysV) {
233: vScroll.setVisible(true);
234: vScroll.setEnabled(viewSize.height < clientPrefSize.height);
235: vScroll.setBounds(margin.left + viewSize.width, margin.top,
236: vScrollWidth, viewSize.height);
237: } else {
238: vScroll.setVisible(false);
239: v = 0;
240: }
241: vScroll.setValues(v, viewSize.height, 0, clientPrefSize.height);
242:
243: client.setLocation(-h, -v);
244:
245: if (client instanceof WingComponent) {
246: Point unit = new Point(1, 1);
247: Point block = new Point(10, 10);
248: ((WingComponent) client).getScrollIncrements(unit, block);
249:
250: hScroll.setUnitIncrement(unit.x);
251: vScroll.setUnitIncrement(unit.y);
252: hScroll.setBlockIncrement(block.x);
253: vScroll.setBlockIncrement(block.y);
254: }
255: }
256:
257: /**
258: * <br><br><strong>This method acquire TreeLock</strong>
259: */
260: public Dimension getPreferredSize() {
261: Dimension prefSize = wingPrefSize;
262: if (prefSize == null) {
263: prefSize = new Dimension(client.getPreferredSize());
264: prefSize.height += stNormal.margin.left
265: + stNormal.margin.right;
266: prefSize.width += stNormal.margin.top
267: + stNormal.margin.bottom;
268: if (hPolicy != SCROLLBAR_NEVER)
269: prefSize.height += hScroll.getPreferredSize().height;
270: if (vPolicy != SCROLLBAR_NEVER)
271: prefSize.width += vScroll.getPreferredSize().width;
272: wingPrefSize = prefSize;
273: }
274: return prefSize;
275: }
276: }
|