Source Code Cross Referenced for ScrollbarStateController.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:         * @author Dmitry A. Durnev
019:         * @version $Revision$
020:         */package org.apache.harmony.awt;
021:
022:        import java.awt.Adjustable;
023:        import java.awt.Dimension;
024:        import java.awt.EventQueue;
025:        import java.awt.Point;
026:        import java.awt.Rectangle;
027:        import java.awt.event.AdjustmentEvent;
028:        import java.awt.event.ComponentEvent;
029:        import java.awt.event.ComponentListener;
030:        import java.awt.event.FocusEvent;
031:        import java.awt.event.FocusListener;
032:        import java.awt.event.KeyEvent;
033:        import java.awt.event.KeyListener;
034:        import java.awt.event.MouseEvent;
035:        import java.awt.event.MouseListener;
036:        import java.awt.event.MouseMotionListener;
037:
038:        import org.apache.harmony.awt.internal.nls.Messages;
039:        import org.apache.harmony.awt.state.ScrollbarState;
040:
041:        /**
042:         * ScrollbarStateController.
043:         * Implements Scrollbar behavior. Responds to
044:         * input, focus, component events and updates
045:         * scrollbar state. Repaints scrollbar when necessary,
046:         * fires [adjustment] events.
047:         */
048:        public abstract class ScrollbarStateController implements 
049:                MouseListener, MouseMotionListener, FocusListener, KeyListener,
050:                ComponentListener {
051:
052:            private static final long DELAY = 100l; //animation delay in ms
053:            // delay between mouse press event and scroll start:
054:            private static final long START_DELAY = 250l;
055:
056:            private final ScrollbarState state;
057:            private final SimpleButton incr, decr;
058:            private final Slider slider;
059:            private boolean pressed;
060:            private boolean focused;
061:
062:            /**
063:             * store last scroll type(see AdjustmentEvent)  to be able
064:             * to get it when firing adjustment event 
065:             */
066:            private int type = -1;
067:
068:            /**
069:             * Which part of scrollbar track is highlighted
070:             * while block scrolling by mouse press on track
071:             * @see ScrollbarState
072:             */
073:            private int highlight = ScrollbarState.NO_HIGHLIGHT;
074:
075:            private ScrollTask unitTask;
076:            private BlockScrollTask blockTask;
077:            int curMouseX, curMouseY; //for dragging
078:            private Point dragPoint; //for dragging
079:
080:            public ScrollbarStateController(ScrollbarState state) {
081:                this .state = state;
082:                incr = new SimpleButton(state.getIncreaseRect());
083:                decr = new SimpleButton(state.getDecreaseRect());
084:                slider = new Slider(state.getSliderRect());
085:                unitTask = new ScrollTask(1);
086:                blockTask = new BlockScrollTask(1);
087:            }
088:
089:            /**
090:             * Scrollbar Arrow button behavior:
091:             * handles mouse events 
092:             */
093:            class SimpleButton {
094:                Rectangle rect;
095:                boolean pressed;
096:                boolean mouseInside;
097:
098:                SimpleButton(Rectangle r) {
099:                    rect = r;
100:                }
101:
102:                boolean mousePressed(Point pt) {
103:                    if (rect == null) {
104:                        return false;
105:                    }
106:
107:                    mouseInside = rect.contains(pt);
108:                    if (mouseInside) {
109:                        pressed = true;
110:                        repaint();
111:                    }
112:
113:                    return mouseInside;
114:                }
115:
116:                boolean mouseReleased(Point pt) {
117:                    if (rect == null) {
118:                        return false;
119:                    }
120:
121:                    // there's no mouse capture, so
122:                    // have to handle releases manually:
123:                    boolean wasPressed = pressed;
124:                    if (wasPressed) {
125:                        pressed = false;
126:                        repaint();
127:                    }
128:
129:                    mouseInside = rect.contains(pt);
130:                    return wasPressed && mouseInside;
131:                }
132:
133:                boolean mouseDragged(Point pt) {
134:
135:                    boolean oldInside = mouseInside;
136:                    mouseInside = rect.contains(pt);
137:                    if (pressed && (oldInside != mouseInside)) {
138:                        repaint();
139:                    }
140:                    return mouseInside;
141:                }
142:
143:                void repaint() {
144:                    ScrollbarStateController.this .repaint(rect);
145:                }
146:
147:                boolean isPressed() {
148:                    return (pressed && mouseInside);
149:                }
150:
151:            }
152:
153:            /**
154:             * Scrollbar Thumb[scroll box] behavior:
155:             * handles mouse drags
156:             */
157:            class Slider extends SimpleButton {
158:                boolean dragged;
159:
160:                Slider(Rectangle r) {
161:                    super (r);
162:                }
163:
164:                boolean isDragged() {
165:                    return dragged;
166:                }
167:
168:                @Override
169:                boolean mouseReleased(Point pt) {
170:                    boolean result = super .mouseReleased(pt);
171:
172:                    if (dragged) {
173:                        dragged = false;
174:                    }
175:                    return result;
176:                }
177:
178:                @Override
179:                boolean mouseDragged(Point pt) {
180:                    boolean result = super .mouseDragged(pt);
181:
182:                    if (pressed) {
183:                        dragged = true;
184:                        setValueOnDragging(pt);
185:                        curMouseX = pt.x;
186:                        curMouseY = pt.y;
187:                    }
188:                    return result;
189:                }
190:            }
191:
192:            /**
193:             * Timer task which scrolls by unit
194:             * on every tick.
195:             */
196:            class ScrollTask implements  Runnable {
197:
198:                /**
199:                 * scroll direction(up or down)
200:                 */
201:                int dir;
202:
203:                /**
204:                 * overall running time
205:                 */
206:                long runTime;
207:
208:                private PeriodicTimer timer;
209:
210:                /**
211:                 * Delay before scroll starts
212:                 */
213:                private long startDelay;
214:
215:                ScrollTask(int dir) {
216:                    setDir(dir);
217:                    timer = new PeriodicTimer(DELAY, this );
218:                }
219:
220:                public void run() {
221:                    runTime += timer.getPeriod();
222:                    if (runTime < startDelay) {
223:                        return;
224:                    }
225:                    EventQueue.invokeLater(new Runnable() {
226:                        public void run() {
227:                            scroll();
228:                        }
229:
230:                    });
231:                }
232:
233:                void setDir(int dir) {
234:                    this .dir = dir;
235:                }
236:
237:                void scroll() {
238:                    scrollByUnit(dir);
239:                }
240:
241:                PeriodicTimer getTimer() {
242:                    return timer;
243:                }
244:
245:                void start(int dir, long delay) {
246:                    setDir(dir);
247:                    startDelay = delay;
248:                    runTime = 0;
249:                    timer.start();
250:
251:                }
252:            }
253:
254:            /**
255:             * Timer task which scrolls by block
256:             * on every tick.
257:             */
258:            class BlockScrollTask extends ScrollTask {
259:
260:                BlockScrollTask(int dir) {
261:                    super (dir);
262:                }
263:
264:                @Override
265:                void scroll() {
266:                    int dir = getBlockDir(new Point(curMouseX, curMouseY));
267:                    if (this .dir != dir) {
268:                        getTimer().stop();
269:                        return;
270:                    }
271:                    scrollByBlock(dir);
272:                }
273:            }
274:
275:            public void mouseClicked(MouseEvent e) {
276:                // ignored
277:
278:            }
279:
280:            public void mouseEntered(MouseEvent e) {
281:                // ignored
282:
283:            }
284:
285:            public void mouseExited(MouseEvent e) {
286:                // ignored
287:
288:            }
289:
290:            public void mousePressed(MouseEvent me) {
291:                if (me.getButton() != MouseEvent.BUTTON1) {
292:                    return;
293:                }
294:                if (!focused) {
295:                    requestFocus();
296:                }
297:                Point pt = getPoint(me);
298:                curMouseX = pt.x;
299:                curMouseY = pt.y;
300:                boolean incrPressed = incr.mousePressed(pt);
301:                boolean decrPressed = decr.mousePressed(pt);
302:                slider.mousePressed(pt);
303:                if (incrPressed || decrPressed) {
304:                    int dir = (incrPressed ? 1 : -1);
305:                    scrollByUnit(dir);
306:                    // start timer
307:                    unitTask.start(dir, START_DELAY);
308:                } else {
309:                    pressed = true;
310:                    int dir = getBlockDir(pt);
311:                    if (dir != 0) {
312:                        scrollByBlock(dir);
313:                        blockTask.start(dir, START_DELAY);
314:                    } else {
315:                        Point thumbLoc = state.getSliderRect().getLocation();
316:                        dragPoint = new Point(pt.x - thumbLoc.x, pt.y
317:                                - thumbLoc.y);
318:                    }
319:                    repaint();
320:                }
321:
322:            }
323:
324:            /**
325:             * Gets direction of block scroll
326:             * started by mouse press on scrollbar
327:             * track
328:             * @param pt point where mouse was pressed
329:             * in scrollbar coordinates
330:             * @return 1 for scroll down/right, -1 for
331:             * up/left, 0 - no scroll
332:             */
333:            private int getBlockDir(Point pt) {
334:                Rectangle sliderRect = state.getSliderRect();
335:                if ((sliderRect == null) || sliderRect.isEmpty()) {
336:                    return 0;
337:                }
338:                Rectangle upperRect = state.getUpperTrackBounds();
339:                Rectangle lowerRect = state.getLowerTrackBounds();
340:
341:                if (lowerRect.contains(pt)) {
342:                    highlight = ScrollbarState.INCREASE_HIGHLIGHT;
343:                    return 1;
344:                } else if (upperRect.contains(pt)) {
345:                    highlight = ScrollbarState.DECREASE_HIGHLIGHT;
346:                    return -1;
347:                } else {
348:                    highlight = ScrollbarState.NO_HIGHLIGHT;
349:                    type = AdjustmentEvent.TRACK;
350:                    repaint(state.getTrackBounds());
351:                }
352:                return 0;
353:            }
354:
355:            public void mouseReleased(MouseEvent me) {
356:                if (me.getButton() != MouseEvent.BUTTON1) {
357:                    return;
358:                }
359:                Point pt = getPoint(me);
360:                boolean incrReleased = incr.mouseReleased(pt);
361:                boolean decrReleased = decr.mouseReleased(pt);
362:                slider.mouseReleased(pt);
363:                if (!(decrReleased || incrReleased)) {
364:                    pressed = false;
365:                    type = -1;
366:                    highlight = ScrollbarState.NO_HIGHLIGHT;
367:                    repaint();
368:                }
369:                // stop timer
370:                blockTask.getTimer().stop();
371:                unitTask.getTimer().stop();
372:
373:            }
374:
375:            public void mouseDragged(MouseEvent e) {
376:                Point pt = getPoint(e);
377:                switchTimerOnDrag(pt, incr, 1);
378:                switchTimerOnDrag(pt, decr, -1);
379:                slider.mouseDragged(pt);
380:            }
381:
382:            /**
383:             * Translates component coordinates into
384:             * scrollbar coordinates
385:             * @param e coordinates of this mouse event are translated
386:             * @return point in scrollbar coordinates
387:             */
388:            private Point getPoint(MouseEvent e) {
389:                Point pt = e.getPoint().getLocation();
390:                Point loc = state.getLocation();
391:                pt.translate(-loc.x, -loc.y);
392:                return pt;
393:            }
394:
395:            /**
396:             * Starts/stops unit scrolling on mouse drag
397:             * in/out of arrow button
398:             * @param pt current mouse position
399:             * @param b arrow button
400:             * @param dir scroll direction
401:             */
402:            void switchTimerOnDrag(Point pt, SimpleButton b, int dir) {
403:                boolean wasPressed = b.isPressed();
404:                b.mouseDragged(pt);
405:                boolean isPressed = b.isPressed();
406:                if (isPressed != wasPressed) {
407:                    if (isPressed) {
408:                        unitTask.start(dir, 0l);
409:                    } else {
410:                        unitTask.getTimer().stop();
411:                    }
412:                }
413:            }
414:
415:            protected abstract void repaint(Rectangle r);
416:
417:            protected abstract void repaint();
418:
419:            protected abstract void requestFocus();
420:
421:            public void mouseMoved(MouseEvent e) {
422:                // ignored
423:
424:            }
425:
426:            public void focusGained(FocusEvent e) {
427:                focused = true;
428:                repaint();
429:
430:            }
431:
432:            public void focusLost(FocusEvent e) {
433:                focused = false;
434:                repaint();
435:            }
436:
437:            public void keyPressed(KeyEvent e) {
438:                // awt.54=Key event for unfocused component
439:                assert focused : Messages.getString("awt.54"); //$NON-NLS-1$
440:                int keyCode = e.getKeyCode();
441:                switch (keyCode) {
442:                case KeyEvent.VK_UP:
443:                case KeyEvent.VK_LEFT:
444:                    scrollByUnit(-1);
445:                    break;
446:                case KeyEvent.VK_DOWN:
447:                case KeyEvent.VK_RIGHT:
448:                    scrollByUnit(1);
449:                    break;
450:                case KeyEvent.VK_PAGE_UP:
451:                    scrollByBlock(-1);
452:                    break;
453:                case KeyEvent.VK_PAGE_DOWN:
454:                    scrollByBlock(1);
455:                    break;
456:                case KeyEvent.VK_HOME:
457:                    setAdjMinMaxValue(false);
458:                    break;
459:                case KeyEvent.VK_END:
460:                    setAdjMinMaxValue(true);
461:                    break;
462:
463:                }
464:            }
465:
466:            public void keyReleased(KeyEvent e) {
467:                // ignored
468:            }
469:
470:            public void keyTyped(KeyEvent e) {
471:                // ignored
472:            }
473:
474:            public void componentHidden(ComponentEvent e) {
475:                // ignored
476:
477:            }
478:
479:            public void componentMoved(ComponentEvent e) {
480:                // ignored
481:
482:            }
483:
484:            public void componentResized(ComponentEvent e) {
485:                // call repaint() to calculate internal layout
486:                repaint();
487:            }
488:
489:            public void componentShown(ComponentEvent e) {
490:                // ignored
491:
492:            }
493:
494:            public boolean isIncreasePressed() {
495:                return incr.isPressed();
496:            }
497:
498:            public boolean isDecreasePressed() {
499:                return decr.isPressed();
500:            }
501:
502:            public boolean isSliderDragged() {
503:                return slider.isDragged();
504:            }
505:
506:            protected abstract void fireEvent();
507:
508:            public final boolean isPressed() {
509:                return pressed;
510:            }
511:
512:            public final int getType() {
513:                return type;
514:            }
515:
516:            /**
517:             * Sets scrollbar value on
518:             * thumb dragging by mouse.
519:             * Repaints scrollbar & fires events
520:             * when necessary.
521:             * @param pt current mouse position
522:             */
523:            public void setValueOnDragging(final Point pt) {
524:
525:                int extent = state.getSliderSize();
526:                int viewSize = state.getScrollSize();
527:                int availableScrollingSize = viewSize - extent;
528:                int thumbSize = getThumbSize();
529:                int availableTrackSize = state.getTrackSize() - thumbSize;
530:                Rectangle trackRect = state.getTrackBounds();
531:                int offset = getOffset(pt, trackRect.x + dragPoint.x,
532:                        trackRect.y + dragPoint.y);
533:
534:                float fVal = 0.0f;
535:                if (availableTrackSize != 0) {
536:                    fVal = (float) offset * availableScrollingSize
537:                            / availableTrackSize;
538:                }
539:                int val = Math.round(fVal);
540:                boolean repaint = false;
541:                if (offset != 0) {
542:
543:                    Rectangle oldRect = (Rectangle) state.getSliderRect()
544:                            .clone();
545:                    Rectangle r = new Rectangle(oldRect);
546:
547:                    if (state.isVertical()) {
548:                        r.y = pt.y - dragPoint.y;
549:                    } else {
550:                        r.x = pt.x - dragPoint.x;
551:                    }
552:                    if (trackRect.contains(r)) {
553:                        state.setSliderRect(r);
554:                        Rectangle paintRect = r.union(oldRect);
555:                        repaint(paintRect);
556:                    } else {
557:                        repaint = true;
558:                    }
559:                }
560:
561:                Adjustable adj = state.getAdjustable();
562:                int oldVal = adj.getValue();
563:                state.setValue(AdjustmentEvent.TRACK, val);
564:                if (oldVal != adj.getValue()) {
565:                    fireEvent();
566:                    if (repaint) {
567:                        repaint();
568:                    }
569:                }
570:
571:            }
572:
573:            /**
574:             * @return width/height of horizontal/vertical
575:             * scrollbar thumb
576:             */
577:            private int getThumbSize() {
578:                Dimension sliderSize = state.getSliderRect().getSize();
579:                return (state.isVertical() ? sliderSize.height
580:                        : sliderSize.width);
581:            }
582:
583:            /**
584:             * Gets distance in points between specified point
585:             * and current mouse position
586:             * @param pt new position coordinates
587:             * @param currentMouseX current mouse x coordinate
588:             * @param currentMouseY current mouse y coordinate
589:             * @return distance in pixels from pt to (currentMouseX, currentMouseY)
590:             */
591:            int getOffset(final Point pt, final int currentMouseX,
592:                    final int currentMouseY) {
593:                boolean vertical = state.isVertical();
594:                int newPos = vertical ? pt.y : pt.x;
595:                int oldPos = vertical ? currentMouseY : currentMouseX;
596:                int offset = newPos - oldPos;
597:                if (!vertical
598:                        && !state.getComponentOrientation().isLeftToRight()) {
599:                    offset = -offset;
600:                }
601:                return offset;
602:            }
603:
604:            /**
605:             * Changes scrollbar value on increment.
606:             * Fires adjustment event on value change.
607:             * @param increment change amount
608:             */
609:            private void updateAdjValue(final int increment) {
610:                Adjustable adj = state.getAdjustable();
611:                int oldVal = adj.getValue();
612:                state.setValue(type, oldVal + increment);
613:                if (oldVal != adj.getValue()) {
614:                    fireEvent();
615:                }
616:            }
617:
618:            /**
619:             * Scrolls by block up(left) if dir is &lt; 0
620:             * or down(right) if dir is &gt; 0.
621:             * @param dir direction
622:             */
623:            void scrollByBlock(final int dir) {
624:                type = (dir > 0 ? AdjustmentEvent.BLOCK_INCREMENT
625:                        : AdjustmentEvent.BLOCK_DECREMENT);
626:                updateAdjValue(state.getAdjustable().getBlockIncrement() * dir);
627:            }
628:
629:            /**
630:             * Scrolls by unit up(left) if dir is &lt; 0
631:             * or down(right) if dir is &gt; 0.
632:             * @param dir direction
633:             */
634:            void scrollByUnit(final int dir) {
635:                type = (dir > 0 ? AdjustmentEvent.UNIT_INCREMENT
636:                        : AdjustmentEvent.UNIT_DECREMENT);
637:                updateAdjValue(state.getAdjustable().getUnitIncrement() * dir);
638:            }
639:
640:            /**
641:             * Scrolls to scrollbar maximum or minimum value
642:             * @param max scroll to maximum if true, scroll to minimum
643:             * otherwise
644:             */
645:            void setAdjMinMaxValue(boolean max) {
646:                Adjustable adj = state.getAdjustable();
647:                int newVal = max ? adj.getMaximum() : adj.getMinimum();
648:                int oldVal = adj.getValue();
649:                adj.setValue(newVal);
650:                if (oldVal != newVal) {
651:                    type = AdjustmentEvent.TRACK;
652:                    fireEvent();
653:                }
654:            }
655:
656:            public int getHighlight() {
657:                return highlight;
658:            }
659:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.