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 * 26 * Copyright (c) 1994-1995, 2001 by Sun Microsystems, Inc. 27 * All rights reserved. 28 * 29 * Permission to use, copy, modify, and distribute this software 30 * and its documentation for NON-COMMERCIAL purposes and without 31 * fee is hereby granted provided that this copyright notice 32 * appears in all copies. Please refer to the file "copyright.html" 33 * for further important copyright and licensing information. 34 * 35 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF 36 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 37 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 38 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 39 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 40 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES 41 * 42 * 43 * Copyright (C) 1996 Active Software, Inc. 44 * All rights reserved. 45 * 46 * @(#) WinScrollbar.java 1.13 - last change made 05/02/97 47 */ 48 49 package sunsoft.jws.visual.rt.awt; 50 51 import sunsoft.jws.visual.rt.base.Global; 52 import sunsoft.jws.visual.rt.base.Util; 53 import java.awt.*; 54 55 56 public class WinScrollbar extends Canvas implements Runnable { 57 58 /** 59 * The horizontal Scrollbar variable. 60 */ 61 public static final int HORIZONTAL = Scrollbar.HORIZONTAL; 62 63 /** 64 * The vertical Scrollbar variable. 65 */ 66 public static final int VERTICAL = Scrollbar.VERTICAL; 67 68 /** 69 * The value of the Scrollbar. 70 */ 71 int value; 72 73 /** 74 * The maximum value of the Scrollbar. 75 */ 76 int maximum; // doesn't include the visible area 77 78 /** 79 * The minimum value of the Scrollbar. 80 */ 81 int minimum; 82 83 /** 84 * The size of the visible portion of the Scrollbar. 85 */ 86 int sVisible; 87 88 /** 89 * The Scrollbar's orientation--being either horizontal or vertical. 90 */ 91 int orientation; 92 93 /** 94 * The amount by which the scrollbar value will change when going 95 * up or down by a line. 96 */ 97 int lineIncrement = 1; 98 99 /** 100 * The amount by which the scrollbar value will change when going 101 * up or down by a page. 102 */ 103 int pageIncrement = 10; 104 105 /** 106 * Are we running on WindowsNT 107 */ 108 private boolean winNT; 109 110 private static WinScrollbar threadScrollbar; 111 private static Thread scrollThread; 112 private WinScrollbar currentScrollbar; 113 private int currentScrollAction; 114 private int currentScrollPosition; 115 116 private static final int SCROLL_DELAY = 250; 117 private static final int SCROLL_INTERVAL = 40; 118 119 /** 120 * Constructs a new vertical Scrollbar. 121 */ WinScrollbar()122 public WinScrollbar() { 123 this(VERTICAL); 124 } 125 126 127 /** 128 * Constructs a new Scrollbar with the specified orientation. 129 * @param orientation either Scrollbar.HORIZONTAL 130 * or Scrollbar.VERTICAL 131 * @exception IllegalArgumentException When an 132 * illegal scrollbar orientation is given. 133 */ WinScrollbar(int orientation)134 public WinScrollbar(int orientation) { 135 switch (orientation) { 136 case Scrollbar.HORIZONTAL: 137 case Scrollbar.VERTICAL: 138 this.orientation = orientation; 139 break; 140 141 default: 142 /* JSTYLED */ 143 throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.WinScrollbar.IllegalOrientation")); 144 } 145 146 winNT = Global.isWindowsNT(); 147 } 148 149 /** 150 * Constructs a new Scrollbar with the specified orientation, 151 * value, page size, and minumum and maximum values. 152 * @param orientation either Scrollbar.HORIZONTAL 153 * or Scrollbar.VERTICAL 154 * @param value the scrollbar's value 155 * @param visible the size of the visible portion of the 156 * scrollable area. The scrollbar will use this value when paging up 157 * or down by a page. 158 * @param minimum the minimum value of the scrollbar 159 * @param maximum the maximum value of the scrollbar 160 */ WinScrollbar(int orientation, int value, int visible, int minimum, int maximum)161 public WinScrollbar(int orientation, int value, int visible, 162 int minimum, int maximum) { 163 this(orientation); 164 setValues(value, visible, minimum, maximum); 165 } 166 167 /** 168 * Returns the orientation for this Scrollbar. 169 */ getOrientation()170 public int getOrientation() { 171 return orientation; 172 } 173 174 /** 175 * Returns the current value of this Scrollbar. 176 * @see #getMinimum 177 * @see #getMaximum 178 */ getValue()179 public int getValue() { 180 return value; 181 } 182 183 /** 184 * Sets the value of this Scrollbar to the specified value. 185 * @param value the new value of the Scrollbar. If this value is 186 * below the current minimum or above 187 * the current maximum, it becomes the 188 * new one of those values, respectively. 189 * @see #getValue 190 */ setValue(int value)191 public void setValue(int value) { 192 if (value < minimum) { 193 value = minimum; 194 } 195 if (value > (maximum - sVisible)) { 196 value = maximum - sVisible; 197 } 198 if (value != this.value) { 199 this.value = value; 200 if (getPeer() != null) 201 peerSetValue(value); 202 } 203 } 204 205 /** 206 * Returns the minimum value of this Scrollbar. 207 * @see #getMaximum 208 * @see #getValue 209 */ getMinimum()210 public int getMinimum() { 211 return minimum; 212 } 213 214 /** 215 * Returns the maximum value of this Scrollbar. 216 * @see #getMinimum 217 * @see #getValue 218 */ getMaximum()219 public int getMaximum() { 220 return maximum; 221 } 222 223 /** 224 * Returns the visible amount of the Scrollbar. 225 */ getVisible()226 public int getVisible() { 227 return sVisible; 228 } 229 230 /** 231 * Sets the line increment for this scrollbar. This is the value 232 * that will be added (subtracted) when the user hits the line down 233 * (up) gadgets. 234 */ setLineIncrement(int l)235 public void setLineIncrement(int l) { 236 lineIncrement = l; 237 if (getPeer() != null) 238 peerSetLineIncrement(l); 239 } 240 241 /** 242 * Gets the line increment for this scrollbar. 243 */ getLineIncrement()244 public int getLineIncrement() { 245 return lineIncrement; 246 } 247 248 /** 249 * Sets the page increment for this scrollbar. This is the value 250 * that will be added (subtracted) when the user hits the page down 251 * (up) gadgets. 252 */ setPageIncrement(int l)253 public void setPageIncrement(int l) { 254 pageIncrement = l; 255 if (getPeer() != null) 256 peerSetPageIncrement(l); 257 } 258 259 /** 260 * Gets the page increment for this scrollbar. 261 */ getPageIncrement()262 public int getPageIncrement() { 263 return pageIncrement; 264 } 265 266 /** 267 * Sets the values for this Scrollbar. 268 * @param value is the position in the current window. 269 * @param visible is the amount visible per page 270 * @param minimum is the minimum value of the scrollbar 271 * @param maximum is the maximum value of the scrollbar 272 */ setValues(int value, int visible, int minimum, int maximum)273 public void setValues(int value, int visible, int minimum, 274 int maximum) { 275 if (visible < 0) 276 visible = 0; 277 278 if (visible > maximum) 279 visible = maximum; 280 281 if (maximum < minimum) { 282 maximum = minimum; 283 } 284 if (value < minimum) { 285 value = minimum; 286 } 287 if (value > (maximum - visible)) { 288 value = (maximum - visible); 289 } 290 291 this.value = value; 292 this.sVisible = visible; 293 this.minimum = minimum; 294 this.maximum = maximum; 295 296 if (getPeer() != null) 297 peerSetValues(value, sVisible, minimum, maximum); 298 } 299 300 /** 301 * Returns the String parameters for this Scrollbar. 302 */ paramString()303 protected String paramString() { 304 return super.paramString() + 305 /* NOI18N */",val=" + value + 306 /* NOI18N */",vis=" + isVisible() + 307 /* NOI18N */",min=" + minimum + 308 /* NOI18N */",max=" + maximum + 309 ((orientation == VERTICAL) ? /* NOI18N */ 310 ",vert" : /* NOI18N */",horz"); 311 } 312 313 /** 314 * Returns the minimum size for the scrollbar 315 */ minimumSize()316 public Dimension minimumSize() { 317 if (orientation == VERTICAL) 318 return new Dimension(16, 50); 319 else 320 return new Dimension(50, 16); 321 } 322 323 /** 324 * Returns the preferred size for the scrollbar 325 */ preferredSize()326 public Dimension preferredSize() { 327 return minimumSize(); 328 } 329 330 331 // The rest of this code does the things 332 // that the peer would normally 333 // if the peer weren't so badly broken. 334 335 private Image buffer; 336 private int prevWidth = 0; 337 private int prevHeight = 0; 338 private int action = 0; 339 340 private int anchorPos; 341 private int anchorValue; 342 private int dragSpace; 343 344 private static final int UP = 10; 345 private static final int DOWN = 11; 346 private static final int LEFT = 12; 347 private static final int RIGHT = 13; 348 349 private static final int LINEUP = 20; 350 private static final int LINEDOWN = 21; 351 private static final int PAGEUP = 22; 352 private static final int PAGEDOWN = 23; 353 private static final int DRAG = 24; 354 peerSetValue(int value)355 private void peerSetValue(int value) { 356 repaint(); 357 } 358 peerSetLineIncrement(int l)359 private void peerSetLineIncrement(int l) { 360 } 361 peerSetPageIncrement(int l)362 private void peerSetPageIncrement(int l) { 363 } 364 peerSetValues(int value, int sVisible, int minimum, int maximum)365 private void peerSetValues(int value, int sVisible, 366 int minimum, int maximum) { 367 repaint(); 368 } 369 reshape(int x, int y, int width, int height)370 public void reshape(int x, int y, int width, int height) { 371 super.reshape(x, y, width, height); 372 373 if (prevWidth != width || prevHeight != height) { 374 if (width > 0 && height > 0) 375 buffer = createImage(width, height); 376 else 377 buffer = null; 378 379 prevWidth = width; 380 prevHeight = height; 381 } 382 } 383 update(Graphics g)384 public void update(Graphics g) { 385 if (Global.isWindows()) 386 g = getGraphics(); 387 draw(g); 388 } 389 paint(Graphics g)390 public void paint(Graphics g) { 391 if (Global.isWindows()) 392 g = getGraphics(); 393 draw(g); 394 } 395 draw(Graphics g)396 private void draw(Graphics g) { 397 if (buffer == null) 398 return; 399 400 drawScrollbar(); 401 g.drawImage(buffer, 0, 0, null); 402 } 403 drawScrollbar()404 private void drawScrollbar() { 405 Graphics g = buffer.getGraphics(); 406 Dimension size = size(); 407 int w = size.width; 408 int h = size.height; 409 410 // Erase the old version 411 g.setColor(getBackground()); 412 g.fillRect(0, 0, size.width, size.height); 413 414 drawOutline(g, w-1, h-1); 415 drawEndBoxes(g, w-1, h-1); 416 417 int info[] = getDragBoxInfo(); 418 fillPageBox(g, w, h, info); 419 drawDragBox(g, w-1, h-1, info); 420 } 421 drawOutline(Graphics g, int w, int h)422 private void drawOutline(Graphics g, int w, int h) { 423 g.setColor(Global.util.darker(getBackground())); 424 if (orientation == VERTICAL) { 425 g.drawRect(0, 0, w, w); 426 g.drawRect(0, w, w, h-2*w); 427 g.drawRect(0, h-w, w, w); 428 } else { 429 g.drawRect(0, 0, h, h); 430 g.drawRect(h, 0, w-2*h, h); 431 g.drawRect(w-h, 0, h, h); 432 } 433 } 434 drawEndBoxes(Graphics g, int w, int h)435 private void drawEndBoxes(Graphics g, int w, int h) { 436 if (orientation == VERTICAL) { 437 if (action != LINEUP) { 438 drawArrow(g, 0, 0, w, w, UP); 439 drawBox(g, 0, 0, w, w); 440 } else { 441 drawArrow(g, 1, 1, w, w, UP); 442 } 443 444 if (action != LINEDOWN) { 445 drawArrow(g, 0, h-w, w, w, DOWN); 446 drawBox(g, 0, h-w, w, w); 447 } else { 448 drawArrow(g, 1, h-w+1, w, w, DOWN); 449 } 450 } else { 451 if (action != LINEUP) { 452 drawArrow(g, 0, 0, h, h, LEFT); 453 drawBox(g, 0, 0, h, h); 454 } else { 455 drawArrow(g, 1, 1, h, h, LEFT); 456 } 457 458 if (action != LINEDOWN) { 459 drawArrow(g, w-h, 0, h, h, RIGHT); 460 drawBox(g, w-h, 0, h, h); 461 } else { 462 drawArrow(g, w-h+1, 1, h, h, RIGHT); 463 } 464 } 465 } 466 fillPageBox(Graphics g, int w, int h, int info[])467 private void fillPageBox(Graphics g, int w, int h, int info[]) { 468 g.setColor(pageDarker(getBackground())); 469 if (orientation == VERTICAL) { 470 if (action == PAGEUP) { 471 g.fillRect(1, w, w-2, info[0]-w); 472 } else if (action == PAGEDOWN) { 473 g.fillRect(1, info[0]+info[1]+1, w-2, 474 h-(w+info[0]+info[1])-1); 475 } 476 } else { 477 if (action == PAGEUP) { 478 g.fillRect(h, 1, info[0]-h, h-2); 479 } else if (action == PAGEDOWN) { 480 g.fillRect(info[0]+info[1]+1, 1, 481 w-(h+info[0]+info[1])-1, h-2); 482 } 483 } 484 } 485 drawDragBox(Graphics g, int w, int h, int info[])486 private void drawDragBox(Graphics g, int w, int h, int info[]) { 487 if (orientation == VERTICAL) { 488 drawBox(g, 0, info[0], w, info[1]); 489 } else { 490 drawBox(g, info[0], 0, info[1], h); 491 } 492 } 493 getDragBoxInfo()494 private int [] getDragBoxInfo() { 495 int info[] = new int[2]; 496 int minpix; 497 int deltapix; 498 Dimension size = size(); 499 500 if (orientation == VERTICAL) { 501 minpix = size.width; 502 deltapix = size.height - 2 * size.width; 503 } else { 504 minpix = size.height; 505 deltapix = size.width - 2 * size.height; 506 } 507 508 int deltaval = maximum - minimum; 509 double d = (double)deltapix/(double)deltaval; 510 double xory = minpix + (value-minimum) * d; 511 double worh = sVisible * d; 512 513 info[0] = (int)xory; 514 info[1] = (int)worh; 515 516 return info; 517 } 518 drawBox(Graphics g, int x, int y, int w, int h)519 private void drawBox(Graphics g, int x, int y, int w, int h) { 520 g.setColor(getBackground()); 521 Global.util.draw3DRect(g, x, y, w, h, 522 Util.WIN95_WINDOW_BORDER, 2); 523 524 if (true) 525 return; 526 else { 527 g.setColor(Global.util.brighter(getBackground())); 528 g.drawLine(x, y, x+w-1, y); 529 g.drawLine(x, y, x, y+h-1); 530 531 g.setColor(Color.white); 532 g.drawLine(x+1, y+1, x+w-2, y+1); 533 g.drawLine(x+1, y+1, x+1, y+h-2); 534 535 g.setColor(Color.black); 536 g.drawLine(x+w, y, x+w, y+h); 537 g.drawLine(x, y+h, x+w, y+h); 538 539 g.setColor(Global.util.darker(getBackground())); 540 g.drawLine(x+w-1, y+1, x+w-1, y+h-1); 541 g.drawLine(x+1, y+h-1, x+w-1, y+h-1); 542 } 543 } 544 drawArrow(Graphics g, int x, int y, int w, int h, int direction)545 private void drawArrow(Graphics g, int x, int y, int w, int h, 546 int direction) { 547 Polygon p = new Polygon(); 548 549 // xoff=4 and yoff=4 for the default case where w=15 and y=15 550 int xoff = (w-3)/3; 551 int yoff = (h-3)/3; 552 int bd = 2; 553 554 g.setColor(Color.black); 555 556 switch (direction) { 557 case LEFT: 558 if (winNT) { 559 x -= xoff/4; 560 g.fillRect(x+bd+2*xoff-1, y+bd+(5*yoff/4)-1, 561 xoff/2+1, yoff/2+1); 562 } 563 p.addPoint(x+bd+xoff-1, y+bd+(3*yoff/2)-1); 564 p.addPoint(x+bd+2*xoff-1, y+bd+yoff-3); 565 p.addPoint(x+bd+2*xoff-1, y+bd+2*yoff+1); 566 break; 567 568 case RIGHT: 569 if (winNT) { 570 x += xoff/4+1; 571 g.fillRect(x+bd+(xoff/2)-1, y+bd+(5*yoff/4)-1, 572 xoff/2+2, yoff/2+1); 573 } 574 p.addPoint(x+bd+xoff, y+bd+yoff-3); 575 p.addPoint(x+bd+xoff*2, y+bd+(3*yoff/2)-1); 576 p.addPoint(x+bd+xoff, y+bd+2*yoff+1); 577 break; 578 579 case UP: 580 if (winNT) { 581 y -= yoff/4+1; 582 g.fillRect(x+bd+(5*xoff/4)-1, y+bd+2*yoff, 583 xoff/2+1, yoff/2+1); 584 } 585 p.addPoint(x+bd+xoff-3, y+bd+2*yoff); 586 p.addPoint(x+bd+(3*xoff/2)-1, y+bd+yoff); 587 p.addPoint(x+bd+(3*xoff/2), y+bd+yoff); 588 p.addPoint(x+bd+2*xoff+2, y+bd+2*yoff); 589 break; 590 591 case DOWN: 592 if (winNT) { 593 y += yoff/4+1; 594 g.fillRect(x+bd+(5*xoff/4)-1, y+bd+(yoff/2)-1, 595 xoff/2+1, yoff/2+2); 596 } 597 p.addPoint(x+bd+xoff-2, y+bd+yoff); 598 p.addPoint(x+bd+2*xoff+1, y+bd+yoff); 599 p.addPoint(x+bd+(3*xoff/2)-1, y+bd+2*yoff); 600 p.addPoint(x+bd+(3*xoff/2)-1, y+bd+2*yoff-1); 601 break; 602 } 603 604 g.fillPolygon(p); 605 } 606 607 private static final double PAGE_DFACTOR = 0.8; 608 609 /** 610 * Returns a darker version of this color used for the paging 611 * highlight color. 612 */ pageDarker(Color c)613 private Color pageDarker(Color c) { 614 return new Color(Math.max((int)(c.getRed() *PAGE_DFACTOR), 0), 615 Math.max((int)(c.getGreen()*PAGE_DFACTOR), 0), 616 Math.max((int)(c.getBlue() *PAGE_DFACTOR), 0)); 617 } 618 mouseDown(Event evt, int x, int y)619 public boolean mouseDown(Event evt, int x, int y) { 620 Dimension size = size(); 621 int w = size.width; 622 int h = size.height; 623 624 if (orientation == VERTICAL) { 625 if (y < w) { 626 lineUp(y); 627 } else if (y >= (h-w)) { 628 lineDown(y); 629 } else { 630 int info[] = getDragBoxInfo(); 631 if (y >= (w+1) && y < info[0]) { 632 pageUp(y); 633 } else if (y >= info[0]+info[1] && y < (h-w)) { 634 pageDown(y); 635 } else if (y >= info[0] && y < info[0]+info[1]) { 636 dragStart(x, y); 637 } 638 } 639 640 } else { 641 if (x < h) { 642 lineUp(x); 643 } else if (x >= (w-h)) { 644 lineDown(x); 645 } else { 646 int info[] = getDragBoxInfo(); 647 if (x >= (h+1) && x < info[0]) { 648 pageUp(x); 649 } else if (x >= info[0]+info[1] && x < (w-h)) { 650 pageDown(x); 651 } else if (x >= info[0] && x < info[0]+info[1]) { 652 dragStart(x, y); 653 } 654 } 655 } 656 657 return false; 658 } 659 mouseDrag(Event evt, int x, int y)660 public boolean mouseDrag(Event evt, int x, int y) { 661 if (action == DRAG) { 662 drag(x, y); 663 return true; 664 } else if (threadScrollbar != null && 665 threadScrollbar.currentScrollbar == this) { 666 synchronized (threadScrollbar) { 667 if (orientation == VERTICAL) 668 threadScrollbar.currentScrollPosition = y; 669 else 670 threadScrollbar.currentScrollPosition = x; 671 } 672 } 673 674 return false; 675 } 676 mouseUp(Event evt, int x, int y)677 public boolean mouseUp(Event evt, int x, int y) { 678 cancelAutoScroll(); 679 680 if (action == DRAG) { 681 dragStop(x, y); 682 } 683 684 action = 0; 685 repaint(); 686 687 return false; 688 } 689 lineUp(int pos)690 private boolean lineUp(int pos) { 691 boolean status = false; 692 action = LINEUP; 693 initAutoScroll(action, pos); 694 695 int prevValue = value; 696 value = Math.max(minimum, value-lineIncrement); 697 if (value != prevValue) { 698 status = true; 699 postEvent(new Event(this, Event.SCROLL_LINE_UP, 700 new Integer(value))); 701 } 702 703 repaint(); 704 return status; 705 } 706 lineDown(int pos)707 private boolean lineDown(int pos) { 708 boolean status = false; 709 action = LINEDOWN; 710 initAutoScroll(action, pos); 711 712 int prevValue = value; 713 value = Math.min(maximum-sVisible, value+lineIncrement); 714 if (value != prevValue) { 715 postEvent(new Event(this, Event.SCROLL_LINE_DOWN, 716 new Integer(value))); 717 status = true; 718 } 719 720 repaint(); 721 return status; 722 } 723 pageUp(int pos)724 private boolean pageUp(int pos) { 725 boolean status = false; 726 action = PAGEUP; 727 initAutoScroll(action, pos); 728 729 int prevValue = value; 730 value = Math.max(minimum, value-pageIncrement); 731 if (value != prevValue) { 732 status = true; 733 postEvent(new Event(this, Event.SCROLL_PAGE_UP, 734 new Integer(value))); 735 } 736 737 repaint(); 738 return status; 739 } 740 pageDown(int pos)741 private boolean pageDown(int pos) { 742 boolean status = false; 743 action = PAGEDOWN; 744 initAutoScroll(action, pos); 745 746 int prevValue = value; 747 value = Math.min(maximum-sVisible, value+pageIncrement); 748 if (value != prevValue) { 749 status = true; 750 postEvent(new Event(this, Event.SCROLL_PAGE_DOWN, 751 new Integer(value))); 752 } 753 754 repaint(); 755 return status; 756 } 757 dragStart(int x, int y)758 private void dragStart(int x, int y) { 759 action = DRAG; 760 761 if (orientation == VERTICAL) 762 anchorPos = y; 763 else 764 anchorPos = x; 765 766 anchorValue = value; 767 768 Dimension size = size(); 769 int info[] = getDragBoxInfo(); 770 771 if (orientation == VERTICAL) 772 dragSpace = size.height - size.width*2 - info[1]; 773 else 774 dragSpace = size.width - size.height*2 - info[1]; 775 } 776 drag(int x, int y)777 private void drag(int x, int y) { 778 if (orientation == VERTICAL) 779 newDragValue(y); 780 else 781 newDragValue(x); 782 } 783 dragStop(int x, int y)784 private void dragStop(int x, int y) { 785 action = 0; 786 drag(x, y); 787 } 788 newDragValue(int pos)789 private void newDragValue(int pos) { 790 int pixelsDiff = pos - anchorPos; 791 int valDiff = (pixelsDiff * (maximum-minimum) / dragSpace); 792 int prevValue = value; 793 794 value = anchorValue + valDiff; 795 if (valDiff < 0) 796 value = Math.max(value, minimum); 797 else 798 value = Math.min(value, maximum-sVisible); 799 800 if (value != prevValue) 801 postEvent(new Event(this, Event.SCROLL_ABSOLUTE, 802 new Integer(value))); 803 804 repaint(); 805 } 806 initAutoScroll(int action, int pos)807 private void initAutoScroll(int action, int pos) { 808 if (Thread.currentThread() == scrollThread) 809 return; 810 811 if (threadScrollbar == null) { 812 threadScrollbar = this; 813 scrollThread = new Thread(threadScrollbar, /* NOI18N */ 814 "WindowsScrollbarThread"); 815 scrollThread.setDaemon(true); 816 scrollThread.start(); 817 } 818 819 synchronized (threadScrollbar) { 820 threadScrollbar.currentScrollbar = this; 821 threadScrollbar.currentScrollAction = action; 822 threadScrollbar.currentScrollPosition = pos; 823 threadScrollbar.notify(); 824 } 825 } 826 cancelAutoScroll()827 private void cancelAutoScroll() { 828 if (threadScrollbar != null) { 829 synchronized (threadScrollbar) { 830 threadScrollbar.currentScrollbar = null; 831 threadScrollbar.currentScrollAction = -1; 832 threadScrollbar.currentScrollPosition = -1; 833 threadScrollbar.notify(); 834 } 835 } 836 } 837 run()838 public synchronized void run() { 839 boolean scrolling = false; 840 long waitTime; 841 842 while (scrollThread == Thread.currentThread()) { 843 long startTime = System.currentTimeMillis(); 844 845 if (currentScrollbar == null) { 846 waitTime = 0; 847 scrolling = false; 848 } else { 849 if (scrolling) { 850 if (!doScroll(currentScrollbar, 851 currentScrollAction, 852 currentScrollPosition)) { 853 cancelAutoScroll(); 854 waitTime = 0; 855 } else { 856 waitTime = SCROLL_INTERVAL; 857 } 858 } else { 859 waitTime = SCROLL_DELAY; 860 scrolling = true; 861 } 862 } 863 864 // Wait for "waitTime" milliseconds. 865 // But if "waitTime" is zero, 866 // then just wait for a notify. If 867 // the currentScrollbar changes, 868 // then don't wait any longer. 869 if (waitTime == 0 || currentScrollbar == null) { 870 try { wait(0); } 871 catch (InterruptedException ex) {} 872 } else { 873 WinScrollbar initScrollbar = currentScrollbar; 874 long targetTime = startTime + waitTime; 875 long diff = targetTime - System.currentTimeMillis(); 876 877 while (currentScrollbar == initScrollbar && diff > 0) { 878 try { wait(diff); } 879 catch (InterruptedException ex) {} 880 diff = targetTime - System.currentTimeMillis(); 881 } 882 883 if (currentScrollbar != initScrollbar) 884 scrolling = false; 885 } 886 } 887 } 888 doScroll(WinScrollbar scrollbar, int action, int pos)889 private boolean doScroll(WinScrollbar scrollbar, 890 int action, int pos) { 891 boolean status = false; 892 893 switch (action) { 894 case LINEUP: 895 status = scrollbar.lineUp(pos); 896 break; 897 898 case LINEDOWN: 899 status = scrollbar.lineDown(pos); 900 break; 901 902 case PAGEUP: 903 if (continuePaging(scrollbar, action, pos)) { 904 status = scrollbar.pageUp(pos); 905 } else { 906 // Keep trying to scroll for the case 907 // where the user drags 908 // the mouse while paging. We want to 909 // track the drag position 910 // in the direction of the original paging action. 911 status = true; 912 } 913 break; 914 915 case PAGEDOWN: 916 if (continuePaging(scrollbar, action, pos)) { 917 status = scrollbar.pageDown(pos); 918 } else { 919 // Keep trying to scroll for the case 920 // where the user drags 921 // the mouse while paging. We want to 922 // track the drag position 923 // in the direction of the original paging action. 924 status = true; 925 } 926 break; 927 928 default: 929 break; 930 } 931 932 return status; 933 } 934 continuePaging(WinScrollbar scrollbar, int action, int pos)935 private boolean continuePaging(WinScrollbar scrollbar, int action, 936 int pos) { 937 boolean status = false; 938 int info[] = scrollbar.getDragBoxInfo(); 939 940 if (pos < info[0]) { 941 status = (action == PAGEUP); 942 } else if (pos >= info[0]+info[1]) { 943 status = (action == PAGEDOWN); 944 } 945 946 return status; 947 } 948 } 949