1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright (c) 2000 by Sun Microsystems, Inc. 26 * All rights reserved. 27 */ 28 29/* 30 * Copyright (C) 1996 Active Software, Inc. 31 * All rights reserved. 32 * 33 * @(#) ScrollPanel.java 1.41 - last change made 07/25/97 34 */ 35 36package sunsoft.jws.visual.rt.awt; 37 38import sunsoft.jws.visual.rt.awt.*; 39import sunsoft.jws.visual.rt.base.Global; 40import sunsoft.jws.visual.rt.base.Util; 41import java.awt.*; 42 43public class ScrollPanel extends VJPanel { 44 protected VJScrollbar vbar, hbar; 45 46 private Component comp; 47 private boolean vshow, hshow; 48 private GBLayout gridbag; 49 private boolean hasFocus; 50 51 private int scrollAreaWidth = 0; 52 private int scrollAreaHeight = 0; 53 private Insets scrollAreaInsets; 54 55 public ScrollPanel() { 56 super(Util.WIN95_FIELD_BORDER); 57 setBorderInsets(new Insets(0, 0, 0, 0)); 58 59 GBConstraints c = new GBConstraints(); 60 gridbag = new GBLayout(); 61 setLayout(gridbag); 62 63 hbar = new VJScrollbar(VJScrollbar.HORIZONTAL); 64 vbar = new VJScrollbar(VJScrollbar.VERTICAL); 65 66 c.gridx = 1; 67 c.gridy = 0; 68 c.shrinkx = false; 69 c.shrinky = true; 70 c.fill = GBConstraints.VERTICAL; 71 72 // #ifdef JDK1.1 73 super.addImpl(vbar, null, -1); 74 // #else 75 // super.add(vbar, -1); 76 // #endif 77 78 gridbag.setConstraints(vbar, c); 79 80 c.gridx = 0; 81 c.gridy = 1; 82 c.shrinkx = true; 83 c.shrinky = false; 84 c.fill = GBConstraints.HORIZONTAL; 85 86 // #ifdef JDK1.1 87 super.addImpl(hbar, null, -1); 88 // #else 89 // super.add(hbar, -1); 90 // #endif 91 92 gridbag.setConstraints(hbar, c); 93 94 // Have the initial minimumSize include the vertical scrollbar, 95 // but not the horizontal scrollbar. 96 vshow = true; 97 hbar.hide(); 98 } 99 100 // #ifdef JDK1.1 101 protected void addImpl(Component comp, Object constraints, 102 int index) { 103 super.addImpl(comp, constraints, index); 104 doAdd(comp); 105 } 106 // #else 107 // public Component add(Component comp, int pos) { 108 // super.add(comp, pos); 109 // doAdd(comp); 110 // return comp; 111 // } 112 // #endif 113 114 private void doAdd(Component comp) { 115 if (!(comp instanceof Scrollable)) 116 throw new Error(Global.getMsg( 117 "sunsoft.jws.visual.rt.awt.ScrollPanel.OnlyOneInstance")); 118 119 if (this.comp != null) 120 remove(this.comp); 121 122 this.comp = comp; 123 124 GBConstraints c = new GBConstraints(); 125 c.gridx = 0; 126 c.gridy = 0; 127 c.weightx = 1; 128 c.weighty = 1; 129 c.shrinkx = true; 130 c.shrinky = true; 131 c.fill = GBConstraints.BOTH; 132 c.insets = scrollAreaInsets; 133 134 gridbag.setConstraints(comp, c); 135 } 136 137 public int getScrollAreaWidth() { 138 return scrollAreaWidth; 139 } 140 141 public void setScrollAreaWidth(int scrollAreaWidth) { 142 this.scrollAreaWidth = scrollAreaWidth; 143 } 144 145 public int getScrollAreaHeight() { 146 return scrollAreaHeight; 147 } 148 149 public void setScrollAreaHeight(int scrollAreaHeight) { 150 this.scrollAreaHeight = scrollAreaHeight; 151 } 152 153 public Insets getScrollAreaInsets() { 154 return scrollAreaInsets; 155 } 156 157 public void setScrollAreaInsets(Insets insets) { 158 scrollAreaInsets = insets; 159 160 if (comp != null) { 161 GBConstraints c = gridbag.getConstraints(comp); 162 c.insets = insets; 163 gridbag.setConstraints(comp, c); 164 } 165 } 166 167 public int getVisibleIndex() { 168 if (!vshow) 169 return 0; 170 171 int lineHeight = ((Scrollable)comp).lineHeight(); 172 int scrolly = vbar.getValue(); 173 174 return (scrolly+lineHeight-1)/lineHeight; 175 } 176 177 public void makeVisible(int index) { 178 if (!vshow) 179 return; 180 181 if (index == -1) 182 return; 183 184 Scrollable scrollable = (Scrollable)comp; 185 Dimension viewSize = scrollable.viewSize(comp.size()); 186 int lineHeight = scrollable.lineHeight(); 187 int y = lineHeight*index; 188 int scrolly = vbar.getValue(); 189 190 if (y < scrolly) { 191 vbar.setValue(y); 192 scrollable.scrollY(y); 193 } else if ((y + lineHeight) > scrolly + viewSize.height) { 194 y -= (viewSize.height - lineHeight); 195 if (y < 0) 196 y = 0; 197 vbar.setValue(y); 198 scrollable.scrollY(y); 199 } 200 } 201 202 public boolean handleEvent(Event e) { 203 if (e.id == Event.GOT_FOCUS) { 204 hasFocus = true; 205 return super.handleEvent(e); 206 } else if (e.id == Event.LOST_FOCUS) { 207 hasFocus = false; 208 return super.handleEvent(e); 209 } else if (e.target == hbar) 210 ((Scrollable)comp).scrollX(hbar.getValue()); 211 else if (e.target == vbar) 212 ((Scrollable)comp).scrollY(vbar.getValue()); 213 else 214 return super.handleEvent(e); 215 216 return true; 217 } 218 219 private Dimension viewSize() { 220 Dimension size = size(); 221 size = new Dimension(size.width, size.height); 222 223 // take out our insets 224 Insets insets = insets(); 225 Insets scrollAreaInsets = getScrollAreaInsets(); 226 if (scrollAreaInsets == null) 227 scrollAreaInsets = new Insets(0, 0, 0, 0); 228 229 size.width -= (insets.left + insets.right + 230 scrollAreaInsets.left + scrollAreaInsets.right); 231 size.height -= (insets.top + insets.bottom + 232 scrollAreaInsets.top + scrollAreaInsets.bottom); 233 234 return ((Scrollable)comp).viewSize(size); 235 } 236 237 // Always leave space for the scrollbars 238 public Dimension minimumSize() { 239 Dimension compMin; 240 Dimension hbarMin = hbar.minimumSize(); 241 Dimension vbarMin = vbar.minimumSize(); 242 243 if (comp != null) { 244 compMin = comp.minimumSize(); 245 compMin = new Dimension(compMin.width, compMin.height); 246 } 247 else 248 compMin = new Dimension(0, 0); 249 250 return calcSize(compMin, hbarMin, vbarMin); 251 } 252 253 // Always leave space for the scrollbars 254 public Dimension preferredSize() { 255 Dimension compPref; 256 Dimension hbarPref = hbar.preferredSize(); 257 Dimension vbarPref = vbar.preferredSize(); 258 259 if (comp != null) { 260 compPref = comp.preferredSize(); 261 compPref = new Dimension(compPref.width, compPref.height); 262 } 263 else 264 compPref = new Dimension(0, 0); 265 266 return calcSize(compPref, hbarPref, vbarPref); 267 } 268 269 private Dimension calcSize(Dimension compMin, 270 Dimension hbarMin, Dimension vbarMin) { 271 Insets insets = insets(); 272 Insets scrollAreaInsets = getScrollAreaInsets(); 273 if (scrollAreaInsets == null) 274 scrollAreaInsets = new Insets(0, 0, 0, 0); 275 276 if (scrollAreaWidth != 0) 277 compMin.width = scrollAreaWidth; 278 if (scrollAreaHeight != 0) 279 compMin.height = scrollAreaHeight; 280 281 int insetsWidth = insets.left + insets.right + 282 scrollAreaInsets.left + scrollAreaInsets.right; 283 compMin.width += (vbarMin.width + insetsWidth); 284 compMin.width = Math.max(compMin.width, (hbarMin.width + 285 insetsWidth)); 286 287 int insetsHeight = insets.top + insets.bottom + 288 scrollAreaInsets.top + scrollAreaInsets.bottom; 289 compMin.height += (hbarMin.height + insetsHeight); 290 compMin.height = Math.max(compMin.height, (vbarMin.height + 291 insetsHeight)); 292 293 return compMin; 294 } 295 296 public void layout() { 297 boolean hadFocus = hasFocus; 298 299 Dimension viewSize = viewSize(); 300 if (viewSize.width <= 0 || viewSize.height <= 0) { 301 super.layout(); 302 return; 303 } 304 305 Dimension d; 306 Dimension scrollSize = ((Scrollable)comp).scrollSize(); 307 boolean needHShow = false, needVShow = false; 308 boolean revalidate = false; 309 310 if (viewSize.width < scrollSize.width) 311 needHShow = true; 312 if (viewSize.height < scrollSize.height) 313 needVShow = true; 314 315 if ((needHShow || needVShow) && !(needHShow && needVShow)) { 316 if (needVShow) { 317 d = vbar.minimumSize(); 318 if (viewSize.width < (scrollSize.width + d.width)) 319 needHShow = true; 320 } else if (needHShow) { 321 d = hbar.minimumSize(); 322 if (viewSize.height < (scrollSize.height + d.height)) 323 needVShow = true; 324 } 325 } 326 327 if (needHShow) { 328 if (!hshow) { 329 hbar.show(); 330 hshow = true; 331 revalidate = true; 332 } 333 } else { 334 if (hshow) { 335 hbar.hide(); 336 hshow = false; 337 revalidate = true; 338 if (hbar.getValue() != 0) 339 hbar.setValue(0); 340 ((Scrollable)comp).scrollX(0); 341 } 342 } 343 344 if (needVShow) { 345 if (!vshow) { 346 vbar.show(); 347 vshow = true; 348 revalidate = true; 349 } 350 } else { 351 if (vshow) { 352 vbar.hide(); 353 vshow = false; 354 revalidate = true; 355 if (vbar.getValue() != 0) 356 vbar.setValue(0); 357 ((Scrollable)comp).scrollY(0); 358 } 359 } 360 361 if (hshow) 362 updateHScrollbar(); 363 if (vshow) 364 updateVScrollbar(); 365 366 if (revalidate) { 367 validate(); 368 if (hadFocus && Global.isMotif()) 369 comp.requestFocus(); 370 } else { 371 super.layout(); 372 } 373 } 374 375 public void updateWindow() { 376 invalidate(); 377 validate(); 378 } 379 380 protected void updateHScrollbar() { 381 Dimension viewSize = viewSize(); 382 Dimension scrollSize = ((Scrollable)comp).scrollSize(); 383 384 if (vshow) { 385 Dimension d = vbar.minimumSize(); 386 viewSize.width -= d.width; 387 } 388 389 // (viewSize.width-d.width) can become negative 390 // during initialization 391 if (viewSize.width < 1) 392 return; 393 394 int maximum = scrollSize.width; 395 // #ifndef MAXIMUM_HACK 396 // maximum -= viewSize.width; 397 // #endif 398 399 hbar.setValues(hbar.getValue(), viewSize.width, 0, maximum); 400 401 Scrollable scrollable = (Scrollable)comp; 402 int lineWidth = Math.max(10, viewSize.width/6); 403 int pageSize = Math.max(lineWidth, viewSize.width - lineWidth); 404 pageSize = Math.min(scrollSize.width - viewSize.width, 405 pageSize); 406 407 hbar.setLineIncrement(lineWidth); 408 hbar.setPageIncrement(pageSize); 409 410 scrollable.scrollX(hbar.getValue()); 411 } 412 413 protected void updateVScrollbar() { 414 Dimension viewSize = viewSize(); 415 Dimension scrollSize = ((Scrollable)comp).scrollSize(); 416 417 if (hshow) { 418 Dimension d = hbar.minimumSize(); 419 viewSize.height -= d.height; 420 } 421 422 // (viewSize.height-d.height) can become 423 // negative during initialization 424 if (viewSize.height < 1) 425 return; 426 427 int maximum = scrollSize.height; 428 // #ifndef MAXIMUM_HACK 429 // maximum -= viewSize.height; 430 // #endif 431 vbar.setValues(vbar.getValue(), viewSize.height, 0, maximum); 432 433 Scrollable scrollable = (Scrollable)comp; 434 int lineHeight = scrollable.lineHeight(); 435 int pageSize = 436 Math.max(lineHeight, 437 (viewSize.height/lineHeight)*lineHeight - lineHeight); 438 pageSize = Math.min(scrollSize.height-viewSize.height, 439 pageSize); 440 441 vbar.setLineIncrement(lineHeight); 442 vbar.setPageIncrement(pageSize); 443 444 scrollable.scrollY(vbar.getValue()); 445 } 446} 447