blob: 7325c8c97f21cf963b0add0ff2552624de83789d [file] [log] [blame]
wimba.come8e19102005-02-08 17:15:23 +00001
Constantin Kaplinskycf689b32008-04-30 12:50:34 +00002package com.tightvnc.rfbplayer;
wimba.come8e19102005-02-08 17:15:23 +00003
4import java.awt.*;
5import java.awt.event.*;
6
7class LWScrollPane extends Container implements AdjustmentListener {
8
9 /** position info */
10 private Point scrollPosition = new Point(0, 0);
11
12 /** panel to hold component to scroll */
13 private Panel innerPanel = new Panel() {
14
15 public void update(Graphics g) {
16 if (needClear) {
17 super.update(g);
18 needClear = false;
19 } else
20 this.paint(g);
21 }
22
23 };
24
25 /** component to display */
26 private Component containedComp;
27
28 /** layout info */
29 private GridBagLayout gb;
30 private GridBagConstraints gbc;
31
32 /** scroll bars */
33 private Scrollbar xScroller;
34 private Scrollbar yScroller;
35
36 /** flags indicating which scollbars are visible */
37 private boolean showingXScroll = false;
38 private boolean showingYScroll = false;
39
40 /** flag indicating when innerpanel needs to repaint background */
41 private boolean needClear = false;
42
43 /** dimensions for our preferred size */
44 private int width = 0;
45 private int height = 0;
46
47 /** c'tor for a new scroll pane */
48 public LWScrollPane() {
49 // create scroll bars
50 xScroller = new Scrollbar(Scrollbar.HORIZONTAL) {
51
52 public boolean isFocusable() {
53 return false;
54 }
55
56 };
57 yScroller = new Scrollbar(Scrollbar.VERTICAL) {
58
59 public boolean isFocusable() {
60 return false;
61 }
62
63 };
64 xScroller.addAdjustmentListener(this);
65 yScroller.addAdjustmentListener(this);
66
67 // layout info
68 gb = new GridBagLayout();
69 gbc = new GridBagConstraints();
70 setLayout(gb);
71 setBackground(Color.white);
72
73 // added inner panel
74 //innerPanel.setBackground(Color.blue);
75 gbc.fill = GridBagConstraints.BOTH;
76 gbc.gridx = 0;
77 gbc.gridy = 0;
78 gbc.weightx = 100;
79 gbc.weighty = 100;
80 gb.setConstraints(innerPanel, gbc);
81 add(innerPanel);
82 innerPanel.setLayout(null);
83 }
84 /*
85 public void update(Graphics g) {
86 paint(g);
87 }
88 */
89 /*
90 public void paint(Graphics g) {
91 super.paint(g);
92 }
93 */
94
95 /**
96 * Provided to allow the containing frame to resize.
97 * OS X JVM 1.3 would not allow a frame to be made
98 * smaller without overriding getMinimumSize.
99 */
100 public Dimension getMinimumSize() {
101 return new Dimension(0, 0);
102 }
103
104 public Dimension getPreferredSize() {
105 return new Dimension(width, height);
106 }
107
108 public void setSize(int width, int height) {
109 this.width = width;
110 this.height = height;
111 super.setSize(width, height);
112 }
113
114 public void setSize(Dimension d) {
115 setSize(d.width, d.height);
116 }
117
118 /**
119 * Force component to clear itself before repainting.
120 * Primarily useful if the contained component shrinks
121 * without the scroll pane reducing in size.
122 */
123 public void clearAndRepaint() {
124 needClear = true;
125 innerPanel.repaint();
126 }
127
128 /** Add the component to be scrolled by scroll pane */
129 void addComp(Component comp) {
130 containedComp = comp;
131 innerPanel.add(containedComp);
132 }
133
134 /**
135 * Set the point of the component to display in the
136 * upper left corner of the viewport.
137 */
138 void setScrollPosition(int x, int y) {
139 Dimension vps = getViewportSize();
140 Dimension ccs = containedComp.getPreferredSize();
141
142 // skip entirely if component smaller than viewer
143 if (ccs.width <= vps.width && ccs.height <= vps.height)
144 return;
145
146 // don't scroll too far left or up
147 if (x < 0)
148 x = 0;
149 if (y < 0)
150 y = 0;
151
152 // don't scroll too far right or down
153 if (ccs.width <= vps.width)
154 x = 0;
155 else if (x > (ccs.width - vps.width))
156 x = ccs.width - vps.width;
157 if (ccs.height <= vps.height)
158 y = 0;
159 else if (y > (ccs.height - vps.height))
160 y = ccs.height - vps.height;
161
162 scrollPosition = new Point(x, y);
163 containedComp.setLocation(-scrollPosition.x, -scrollPosition.y);
164 xScroller.setValue(scrollPosition.x);
165 yScroller.setValue(scrollPosition.y);
166 }
167
168 /** Returns the point at the upper left corner of viewport */
169 Point getScrollPosition() {
170 return new Point(scrollPosition);
171 }
172
173 /** Return the dimensions of the viewport */
174 public Dimension getViewportSize() {
175 int vpW, vpH;
176 Dimension size = getSize();
177 vpW = size.width;
178 vpH = size.height;
179 if (showingYScroll)
180 vpW -= yScroller.getSize().width;
181 if (showingXScroll)
182 vpH -= xScroller.getSize().height;
183
184 return new Dimension(vpW, vpH);
185 }
186
187 /**
188 * Ensure that the scroll pane is properly arranged after
189 * a component is added, the pane is resized, etc.
190 */
191 public void doLayout() {
192 /** Add scroll bars as necessary */
193 boolean needX = false, needY = false;
194 Dimension innerSize = containedComp.getPreferredSize();
195 Dimension scrollDimension = getSize();
196
197 if (innerSize.width > scrollDimension.width)
198 needX = true;
199 if (innerSize.height > scrollDimension.height)
200 needY = true;
201
202 showingXScroll = false;
203 showingYScroll = false;
204 remove(yScroller);
205 remove(xScroller);
206
207 if (needY) {
208 gbc.gridy = 0;
209 gbc.gridx = 1;
210 gbc.weightx = 0;
211 gb.setConstraints(yScroller, gbc);
212 add(yScroller);
213 showingYScroll = true;
214 }
215
216 if (needX) {
217 gbc.gridy = 1;
218 gbc.gridx = 0;
219 gbc.weightx = 100;
220 gbc.weighty = 0;
221 gb.setConstraints(xScroller, gbc);
222 add(xScroller);
223 showingXScroll = true;
224 }
225
226 /* set scroll bar values */
227 int vpW, vpH;
228 vpW = scrollDimension.width;
229 vpH = scrollDimension.height;
230 if (showingYScroll)
231 vpW -= yScroller.getSize().width;
232 if (showingXScroll)
233 vpH -= xScroller.getSize().height;
234 yScroller.setValues(0, vpH, 0, innerSize.height);
235 xScroller.setValues(0, vpW, 0, innerSize.width);
236
237 containedComp.setLocation(0, 0);
238 super.doLayout();
239 }
240
241 /**
242 * Adjustment listener method for receiving callbacks
243 * from scroll actions.
244 *
245 * @param e the AdjustmentEvent
246 * @return void
247 */
248 public void adjustmentValueChanged(AdjustmentEvent e) {
249 Point p = containedComp.getLocation();
250 if (e.getAdjustable() == xScroller) {
251 p.x = -e.getValue();
252 scrollPosition.x = e.getValue();
253 } else {
254 p.y = -e.getValue();
255 scrollPosition.y = e.getValue();
256 }
257 containedComp.setLocation(p);
258 }
259
260}