Source Code Cross Referenced for XListPeer.java in  » 6.0-JDK-Platform » solaris » sun » awt » X11 » 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 » 6.0 JDK Platform » solaris » sun.awt.X11 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        // Very much based on XListPeer from javaos
0027:        package sun.awt.X11;
0028:
0029:        import java.awt.*;
0030:        import java.awt.event.*;
0031:        import java.awt.peer.*;
0032:        import java.util.Vector;
0033:        import java.awt.geom.*;
0034:        import java.awt.image.*;
0035:        import java.util.logging.*;
0036:
0037:        // TODO: some input actions should do nothing if Shift or Control are down
0038:
0039:        class XListPeer extends XComponentPeer implements  ListPeer,
0040:                XScrollbarClient {
0041:
0042:            private static final Logger log = Logger
0043:                    .getLogger("sun.awt.X11.XListPeer");
0044:
0045:            public final static int MARGIN = 2;
0046:            public final static int SPACE = 1;
0047:            public final static int SCROLLBAR_AREA = 17; // Area reserved for the
0048:            // scrollbar
0049:            public final static int SCROLLBAR_WIDTH = 13; // Actual width of the
0050:            // scrollbar
0051:            public final static int NONE = -1;
0052:            public final static int WINDOW = 0;
0053:            public final static int VERSCROLLBAR = 1;
0054:            public final static int HORSCROLLBAR = 2;
0055:            public final static int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
0056:            public final static int HORIZ_SCROLL_AMT = 10;
0057:
0058:            final static int PAINT_VSCROLL = 2, PAINT_HSCROLL = 4,
0059:                    PAINT_ITEMS = 8, PAINT_FOCUS = 16, PAINT_BACKGROUND = 32,
0060:                    PAINT_HIDEFOCUS = 64, PAINT_ALL = PAINT_VSCROLL
0061:                            | PAINT_HSCROLL | PAINT_ITEMS | PAINT_FOCUS
0062:                            | PAINT_BACKGROUND;
0063:
0064:            XVerticalScrollbar vsb;
0065:            XHorizontalScrollbar hsb;
0066:            ListPainter painter;
0067:
0068:            // TODO: ick - Vector?
0069:            Vector items;
0070:            boolean multipleSelections;
0071:            int active = NONE;
0072:
0073:            // Holds the array of the indexes of the elements which is selected
0074:            // This array should be kept sorted, low to high.
0075:            int selected[];
0076:            int fontHeight;
0077:            int fontAscent;
0078:            int fontLeading;
0079:
0080:            // Holds the index of the item used in the previous operation (selectItem, deselectItem)
0081:            // Adding of an item or clearing of the list sets this index to -1
0082:            // The index is used at the moment of the post of ACTION_PERFORMED event after the mouse double click event.
0083:            int currentIndex = -1;
0084:
0085:            // Used for tracking selection/deselection between mousePress/Release
0086:            // and for ItemEvents
0087:            int eventIndex = -1;
0088:            int eventType = NONE;
0089:
0090:            // Holds the index of the item that receive focus
0091:            // This variable is reasonable only for multiple list
0092:            // since 'focusIndex' and 'selected[0]' are equal for single-selection list
0093:            int focusIndex;
0094:
0095:            int maxLength;
0096:            boolean vsbVis; // visibility of scrollbars
0097:            boolean hsbVis;
0098:            int listWidth; // Width of list portion of List
0099:            int listHeight; // Height of list portion of List
0100:            // (i.e. without scrollbars)
0101:
0102:            private int firstTimeVisibleIndex = 0;
0103:
0104:            // Motif Lists don't seem to inherit the background color from their
0105:            // parent when an app is first started up.  So, we track if the colors have
0106:            // been set.  See getListBackground()/getListForeground().
0107:            boolean bgColorSet;
0108:            boolean fgColorSet;
0109:
0110:            // Holds the true if mouse is dragging outside of the area of the list
0111:            // The flag is used at the moment of the dragging and releasing mouse
0112:            // See 6243382 for more information
0113:            boolean mouseDraggedOutHorizontally = false;
0114:            boolean mouseDraggedOutVertically = false;
0115:
0116:            // Holds the true if a mouse event was originated on the scrollbar
0117:            // See 6300527 for more information
0118:            boolean isScrollBarOriginated = false;
0119:
0120:            // This variable is set to true after the "mouse pressed" event and to false after the "mouse released" event
0121:            // Fixed 6293432: Key events ('SPACE', 'UP', 'DOWN') aren't blocked if mouse is kept in 'PRESSED' state for List, XAWT
0122:            boolean isMousePressed = false;
0123:
0124:            /**
0125:             * Create a list
0126:             */
0127:            XListPeer(List target) {
0128:                super (target);
0129:            }
0130:
0131:            /**
0132:             * Overridden from XWindow
0133:             */
0134:            public void preInit(XCreateWindowParams params) {
0135:                super .preInit(params);
0136:
0137:                // Stuff that must be initialized before layout() is called
0138:                items = new Vector();
0139:                createVerScrollbar();
0140:                createHorScrollbar();
0141:
0142:                painter = new ListPainter();
0143:
0144:                // See 6246467 for more information
0145:                bgColorSet = target.isBackgroundSet();
0146:                fgColorSet = target.isForegroundSet();
0147:            }
0148:
0149:            public void postInit(XCreateWindowParams params) {
0150:                super .postInit(params);
0151:                initFontMetrics();
0152:                // TODO: more efficient way?
0153:                //       do we really want/need a copy of all the items?
0154:                // get all items from target
0155:                List l = (List) target;
0156:                int stop = l.getItemCount();
0157:                for (int i = 0; i < stop; i++) {
0158:                    items.addElement(l.getItem(i));
0159:                }
0160:
0161:                /* make the visible position visible. */
0162:                int index = l.getVisibleIndex();
0163:                if (index >= 0) {
0164:                    // Can't call makeVisible since it check scroll bar,
0165:                    // initialize scroll bar instead
0166:                    vsb.setValues(index, 0, 0, items.size());
0167:                }
0168:
0169:                // NOTE: needs to have target set
0170:                maxLength = maxLength();
0171:
0172:                // get the index containing all indexes to selected items
0173:                int sel[] = l.getSelectedIndexes();
0174:                selected = new int[sel.length];
0175:                // TODO: shouldn't this be arraycopy()?
0176:                for (int i = 0; i < sel.length; i++) {
0177:                    selected[i] = sel[i];
0178:                }
0179:                // The select()ed item should become the focused item, but we don't
0180:                // get the select() call because the peer generally hasn't yet been
0181:                // created during app initialization.
0182:                // TODO: For multi-select lists, it should be the highest selected index
0183:                if (sel.length > 0) {
0184:                    setFocusIndex(sel[sel.length - 1]);
0185:                } else {
0186:                    setFocusIndex(0);
0187:                }
0188:
0189:                multipleSelections = l.isMultipleMode();
0190:            }
0191:
0192:            /**
0193:             * add Vertical Scrollbar
0194:             */
0195:            void createVerScrollbar() {
0196:                vsb = new XVerticalScrollbar(this );
0197:                vsb.setValues(0, 0, 0, 0, 1, 1);
0198:            }
0199:
0200:            /**
0201:             * add Horizontal scrollbar
0202:             */
0203:            void createHorScrollbar() {
0204:                hsb = new XHorizontalScrollbar(this );
0205:                hsb.setValues(0, 0, 0, 0, HORIZ_SCROLL_AMT, HORIZ_SCROLL_AMT);
0206:            }
0207:
0208:            /* New method name for 1.1 */
0209:            public void add(String item, int index) {
0210:                addItem(item, index);
0211:            }
0212:
0213:            /* New method name for 1.1 */
0214:            public void removeAll() {
0215:                clear();
0216:                maxLength = 0;
0217:            }
0218:
0219:            /* New method name for 1.1 */
0220:            public void setMultipleMode(boolean b) {
0221:                setMultipleSelections(b);
0222:            }
0223:
0224:            /* New method name for 1.1 */
0225:            public Dimension getPreferredSize(int rows) {
0226:                return preferredSize(rows);
0227:            }
0228:
0229:            /* New method name for 1.1 */
0230:            public Dimension getMinimumSize(int rows) {
0231:                return minimumSize(rows);
0232:            }
0233:
0234:            /**
0235:             * Minimum size.
0236:             */
0237:            public Dimension minimumSize() {
0238:                return minimumSize(DEFAULT_VISIBLE_ROWS);
0239:            }
0240:
0241:            /**
0242:             * return the preferredSize
0243:             */
0244:            public Dimension preferredSize(int v) {
0245:                return minimumSize(v);
0246:            }
0247:
0248:            /**
0249:             * return the minimumsize
0250:             */
0251:            public Dimension minimumSize(int v) {
0252:                FontMetrics fm = getFontMetrics(getFont());
0253:                initFontMetrics();
0254:                return new Dimension(20 + fm.stringWidth("0123456789abcde"),
0255:                        getItemHeight() * v + (2 * MARGIN));
0256:            }
0257:
0258:            /**
0259:             * Calculate font metrics
0260:             */
0261:            void initFontMetrics() {
0262:                FontMetrics fm = getFontMetrics(getFont());
0263:                fontHeight = fm.getHeight();
0264:                fontAscent = fm.getAscent();
0265:                fontLeading = fm.getLeading();
0266:            }
0267:
0268:            /**
0269:             * return the length of the largest item in the list
0270:             */
0271:            int maxLength() {
0272:                FontMetrics fm = getFontMetrics(getFont());
0273:                int m = 0;
0274:                int end = items.size();
0275:                for (int i = 0; i < end; i++) {
0276:                    int l = fm.stringWidth(((String) items.elementAt(i)));
0277:                    m = Math.max(m, l);
0278:                }
0279:                return m;
0280:            }
0281:
0282:            /** 
0283:             * Calculates the width of item's label
0284:             */
0285:            int getItemWidth(int i) {
0286:                FontMetrics fm = getFontMetrics(getFont());
0287:                return fm.stringWidth((String) items.elementAt(i));
0288:            }
0289:
0290:            /**
0291:             * return the on-screen width of the given string "str"
0292:             */
0293:            int stringLength(String str) {
0294:                FontMetrics fm = getFontMetrics(target.getFont());
0295:                return fm.stringWidth(str);
0296:            }
0297:
0298:            public void setForeground(Color c) {
0299:                fgColorSet = true;
0300:                super .setForeground(c);
0301:            }
0302:
0303:            public void setBackground(Color c) {
0304:                bgColorSet = true;
0305:                super .setBackground(c);
0306:            }
0307:
0308:            /**
0309:             * Returns the color that should be used to paint the background of
0310:             * the list of items.  Note that this is not the same as 
0311:             * target.getBackground() which is the color of the scrollbars, and the
0312:             * lower-right corner of the Component when the scrollbars are displayed.
0313:             */
0314:            private Color getListBackground(Color[] colors) {
0315:                if (bgColorSet) {
0316:                    return colors[BACKGROUND_COLOR];
0317:                } else {
0318:                    return SystemColor.text;
0319:                }
0320:            }
0321:
0322:            /**
0323:             * Returns the color that should be used to paint the list item text.
0324:             */
0325:            private Color getListForeground(Color[] colors) {
0326:                if (fgColorSet) {
0327:                    return colors[FOREGROUND_COLOR];
0328:                } else {
0329:                    return SystemColor.textText;
0330:                }
0331:            }
0332:
0333:            Rectangle getVScrollBarRec() {
0334:                return new Rectangle(width - (SCROLLBAR_WIDTH), 0,
0335:                        SCROLLBAR_WIDTH + 1, height);
0336:            }
0337:
0338:            Rectangle getHScrollBarRec() {
0339:                return new Rectangle(0, height - SCROLLBAR_WIDTH, width,
0340:                        SCROLLBAR_WIDTH);
0341:            }
0342:
0343:            int getFirstVisibleItem() {
0344:                if (vsbVis) {
0345:                    return vsb.getValue();
0346:                } else {
0347:                    return 0;
0348:                }
0349:            }
0350:
0351:            int getLastVisibleItem() {
0352:                if (vsbVis) {
0353:                    return Math.min(items.size() - 1, vsb.getValue()
0354:                            + itemsInWindow() - 1);
0355:                } else {
0356:                    return Math.min(items.size() - 1, itemsInWindow() - 1);
0357:                }
0358:            }
0359:
0360:            Area getItemsArea(int firstItem, int lastItem) {
0361:                firstItem = Math.max(getFirstVisibleItem(), firstItem);
0362:                lastItem = Math.min(lastItem, getLastVisibleItem());
0363:                if (lastItem < getFirstVisibleItem()) {
0364:                    return new Area();
0365:                }
0366:                if (firstItem <= lastItem) {
0367:                    int startY = getItemY(firstItem);
0368:                    int endY = getItemY(lastItem) + getItemHeight();
0369:                    // Account for focus rectangle, instead should be called twice - before change
0370:                    // of focusIndex and after
0371:                    startY -= 2;
0372:                    endY += 2;
0373:                    // x is 0 since we need to account for focus rectangle,
0374:                    // the same with width
0375:                    return new Area(new Rectangle(0, startY,
0376:                            getItemWidth() + 3, endY - startY + 1));
0377:                } else {
0378:                    return new Area();
0379:                }
0380:            }
0381:
0382:            Rectangle getItemRect(int item) {
0383:                return new Rectangle(MARGIN, getItemY(item), getItemWidth(),
0384:                        getItemHeight());
0385:            }
0386:
0387:            Area getItemArea(int item) {
0388:                return new Area(getItemRect(item));
0389:            }
0390:
0391:            public void repaintScrollbarRequest(XScrollbar scrollbar) {
0392:                Graphics g = getGraphics();
0393:                if (scrollbar == hsb) {
0394:                    repaint(PAINT_HSCROLL);
0395:                } else if (scrollbar == vsb) {
0396:                    repaint(PAINT_VSCROLL);
0397:                }
0398:            }
0399:
0400:            /**
0401:             * Overridden for performance
0402:             */
0403:            public void repaint() {
0404:                repaint(getFirstVisibleItem(), getLastVisibleItem(), PAINT_ALL);
0405:            }
0406:
0407:            public void repaint(int options) {
0408:                repaint(getFirstVisibleItem(), getLastVisibleItem(), options);
0409:            }
0410:
0411:            public void repaint(int firstItem, int lastItem, int options) {
0412:                Graphics g = getGraphics();
0413:                try {
0414:                    painter.paint(g, firstItem, lastItem, options);
0415:                } finally {
0416:                    g.dispose();
0417:                }
0418:            }
0419:
0420:            public void paint(Graphics g) {
0421:                painter.paint(g, getFirstVisibleItem(), getLastVisibleItem(),
0422:                        PAINT_ALL);
0423:            }
0424:
0425:            public boolean isFocusable() {
0426:                return true;
0427:            }
0428:
0429:            // TODO: share/promote the Focus methods?
0430:            public void focusGained(FocusEvent e) {
0431:                super .focusGained(e);
0432:                repaint(PAINT_FOCUS);
0433:            }
0434:
0435:            public void focusLost(FocusEvent e) {
0436:                super .focusLost(e);
0437:                repaint(PAINT_FOCUS);
0438:            }
0439:
0440:            /**
0441:             * Layout the sub-components of the List - that is, the scrollbars and the
0442:             * list of items.
0443:             */
0444:            public void layout() {
0445:                int vis, maximum;
0446:                boolean vsbWasVisible;
0447:                int origVSBVal;
0448:                assert (target != null);
0449:
0450:                // Start with assumption there is not a horizontal scrollbar,
0451:                // see if we need a vertical scrollbar
0452:
0453:                // Bug: If the list DOES have a horiz scrollbar and the value is set to
0454:                // the very bottom value, value is reset in setValues() because it isn't
0455:                // a valid value for cases when the list DOESN'T have a horiz scrollbar.
0456:                // This is currently worked-around with origVSGVal.
0457:                origVSBVal = vsb.getValue();
0458:                vis = itemsInWindow(false);
0459:                maximum = items.size() < vis ? vis : items.size();
0460:                vsb.setValues(vsb.getValue(), vis, vsb.getMinimum(), maximum);
0461:                vsbVis = vsbWasVisible = vsbIsVisible(false);
0462:                listHeight = height;
0463:
0464:                // now see if we need a horizontal scrollbar
0465:                listWidth = getListWidth();
0466:                vis = listWidth - ((2 * SPACE) + (2 * MARGIN));
0467:                maximum = maxLength < vis ? vis : maxLength;
0468:                hsb.setValues(hsb.getValue(), vis, hsb.getMinimum(), maximum);
0469:                hsbVis = hsbIsVisible(vsbVis);
0470:
0471:                if (hsbVis) {
0472:                    // do need a horizontal scrollbar, so recalculate height of
0473:                    // vertical s crollbar
0474:                    listHeight = height - SCROLLBAR_AREA;
0475:                    vis = itemsInWindow(true);
0476:                    maximum = items.size() < vis ? vis : items.size();
0477:                    vsb.setValues(origVSBVal, vis, vsb.getMinimum(), maximum);
0478:                    vsbVis = vsbIsVisible(true);
0479:                }
0480:
0481:                // now check to make sure we haven't changed need for vertical
0482:                // scrollbar - if we have, we need to
0483:                // recalculate horizontal scrollbar width - then we're done...
0484:                if (vsbWasVisible != vsbVis) {
0485:                    listWidth = getListWidth();
0486:                    vis = listWidth - ((2 * SPACE) + (2 * MARGIN));
0487:                    maximum = maxLength < vis ? 0 : maxLength;
0488:                    hsb.setValues(hsb.getValue(), vis, hsb.getMinimum(),
0489:                            maximum);
0490:                    hsbVis = hsbIsVisible(vsbVis);
0491:                }
0492:
0493:                vsb.setSize(SCROLLBAR_WIDTH, listHeight);
0494:                hsb.setSize(listWidth, SCROLLBAR_WIDTH);
0495:
0496:                vsb.setBlockIncrement(itemsInWindow());
0497:                hsb
0498:                        .setBlockIncrement(width
0499:                                - ((2 * SPACE) + (2 * MARGIN) + (vsbVis ? SCROLLBAR_AREA
0500:                                        : 0)));
0501:            }
0502:
0503:            int getItemWidth() {
0504:                return width - ((2 * MARGIN) + (vsbVis ? SCROLLBAR_AREA : 0));
0505:            }
0506:
0507:            /* Returns height of an item in the list */
0508:            int getItemHeight() {
0509:                return (fontHeight - fontLeading) + (2 * SPACE);
0510:            }
0511:
0512:            int getItemX() {
0513:                return MARGIN + SPACE;
0514:            }
0515:
0516:            int getItemY(int item) {
0517:                return index2y(item);
0518:            }
0519:
0520:            int getFocusIndex() {
0521:                return focusIndex;
0522:            }
0523:
0524:            void setFocusIndex(int value) {
0525:                focusIndex = value;
0526:            }
0527:
0528:            /**
0529:             * Update and return the focus rectangle.
0530:             * Focus is around the focused item, if it is visible, or
0531:             * around the border of the list if the focused item is scrolled off the top
0532:             * or bottom of the list.
0533:             */
0534:            Rectangle getFocusRect() {
0535:                Rectangle focusRect = new Rectangle();
0536:                // width is always only based on presence of vert sb
0537:                focusRect.x = 1;
0538:                focusRect.width = getListWidth() - 3;
0539:                // if focused item is not currently displayed in the list,  paint
0540:                // focus around entire list (not including scrollbars)
0541:                if (isIndexDisplayed(getFocusIndex())) {
0542:                    // focus rect is around the item
0543:                    focusRect.y = index2y(getFocusIndex()) - 2;
0544:                    focusRect.height = getItemHeight() + 1;
0545:                } else {
0546:                    // focus rect is around the list
0547:                    focusRect.y = 1;
0548:                    focusRect.height = hsbVis ? height - SCROLLBAR_AREA
0549:                            : height;
0550:                    focusRect.height -= 3;
0551:                }
0552:                return focusRect;
0553:            }
0554:
0555:            public void handleConfigureNotifyEvent(XEvent xev) {
0556:                super .handleConfigureNotifyEvent(xev);
0557:
0558:                // Update buffer
0559:                painter.invalidate();
0560:            }
0561:
0562:            public boolean handlesWheelScrolling() {
0563:                return true;
0564:            }
0565:
0566:            // FIXME: need to support MouseWheel scrolling, too
0567:            void handleJavaMouseEvent(MouseEvent e) {
0568:                super .handleJavaMouseEvent(e);
0569:                int i = e.getID();
0570:                switch (i) {
0571:                case MouseEvent.MOUSE_PRESSED:
0572:                    mousePressed(e);
0573:                    break;
0574:                case MouseEvent.MOUSE_RELEASED:
0575:                    mouseReleased(e);
0576:                    break;
0577:                case MouseEvent.MOUSE_DRAGGED:
0578:                    mouseDragged(e);
0579:                    break;
0580:                }
0581:            }
0582:
0583:            void handleJavaMouseWheelEvent(MouseWheelEvent e) {
0584:                if (ListHelper.doWheelScroll(vsbVis ? vsb : null, hsbVis ? hsb
0585:                        : null, e)) {
0586:                    repaint();
0587:                }
0588:            }
0589:
0590:            void mousePressed(MouseEvent mouseEvent) {
0591:                if (log.isLoggable(Level.FINER))
0592:                    log.finer(mouseEvent.toString() + ", hsb " + hsbVis
0593:                            + ", vsb " + vsbVis);
0594:                if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
0595:                    if (inWindow(mouseEvent.getX(), mouseEvent.getY())) {
0596:                        if (log.isLoggable(Level.FINE))
0597:                            log.fine("Mouse press in items area");
0598:                        active = WINDOW;
0599:                        int i = y2index(mouseEvent.getY());
0600:                        if (i >= 0) {
0601:                            if (multipleSelections) {
0602:                                if (isSelected(i)) {
0603:                                    // See 6243382 for more information
0604:                                    deselectItem(i);
0605:                                    eventIndex = i;
0606:                                    eventType = ItemEvent.DESELECTED;
0607:                                } else {
0608:                                    selectItem(i);
0609:                                    eventIndex = i;
0610:                                    eventType = ItemEvent.SELECTED;
0611:                                }
0612:                            }
0613:                            // Backward-compatible bug: even if a single-select
0614:                            // item is already selected, we send an ITEM_STATE_CHANGED/
0615:                            // SELECTED event.  Engineer's Toolbox appears to rely on
0616:                            // this.
0617:                            //else if (!isSelected(i)) {
0618:                            else {
0619:                                selectItem(i);
0620:                                eventIndex = i;
0621:                                eventType = ItemEvent.SELECTED;
0622:                            }
0623:                            // Restoring Windows behaviour
0624:                            // We should update focus index after "mouse pressed" event
0625:                            setFocusIndex(i);
0626:                            repaint(PAINT_FOCUS);
0627:                        } else {
0628:                            // 6426186: reset variable to prevent action event
0629:                            // if user clicks on unoccupied area of list
0630:                            currentIndex = -1;
0631:                        }
0632:                    } else if (inVerticalScrollbar(mouseEvent.getX(),
0633:                            mouseEvent.getY())) {
0634:                        if (log.isLoggable(Level.FINE))
0635:                            log.fine("Mouse press in vertical scrollbar");
0636:                        active = VERSCROLLBAR;
0637:                        vsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0638:                                .getModifiers(), mouseEvent.getX()
0639:                                - (width - SCROLLBAR_WIDTH), mouseEvent.getY());
0640:                    } else if (inHorizontalScrollbar(mouseEvent.getX(),
0641:                            mouseEvent.getY())) {
0642:                        if (log.isLoggable(Level.FINE))
0643:                            log.fine("Mouse press in horizontal scrollbar");
0644:                        active = HORSCROLLBAR;
0645:                        hsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0646:                                .getModifiers(), mouseEvent.getX(), mouseEvent
0647:                                .getY()
0648:                                - (height - SCROLLBAR_WIDTH));
0649:
0650:                    }
0651:                    isMousePressed = true;
0652:                }
0653:            }
0654:
0655:            void mouseReleased(MouseEvent mouseEvent) {
0656:                if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
0657:                    //winReleaseCursorFocus();
0658:                    int clickCount = mouseEvent.getClickCount();
0659:                    if (active == VERSCROLLBAR) {
0660:                        vsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0661:                                .getModifiers(), mouseEvent.getX()
0662:                                - (width - SCROLLBAR_WIDTH), mouseEvent.getY());
0663:                    } else if (active == HORSCROLLBAR) {
0664:                        hsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0665:                                .getModifiers(), mouseEvent.getX(), mouseEvent
0666:                                .getY()
0667:                                - (height - SCROLLBAR_WIDTH));
0668:                    } else if ((currentIndex >= 0) && (clickCount >= 2)
0669:                            && (clickCount % 2 == 0)) {
0670:                        postEvent(new ActionEvent(target,
0671:                                ActionEvent.ACTION_PERFORMED, (String) items
0672:                                        .elementAt(currentIndex), mouseEvent
0673:                                        .getWhen(), mouseEvent.getModifiers())); // No ext mods
0674:                    } else if (active == WINDOW) {
0675:                        // See 6243382 for more information
0676:                        trackMouseReleasedScroll();
0677:
0678:                        if (eventType == ItemEvent.DESELECTED) {
0679:                            assert multipleSelections : "Shouldn't get a deselect for a single-select List";
0680:                            // Paint deselection the release
0681:                            deselectItem(eventIndex);
0682:                        }
0683:                        if (eventType != NONE) {
0684:                            postEvent(new ItemEvent((List) target,
0685:                                    ItemEvent.ITEM_STATE_CHANGED, Integer
0686:                                            .valueOf(eventIndex), eventType));
0687:                        }
0688:                    }
0689:                    active = NONE;
0690:                    eventIndex = -1;
0691:                    eventType = NONE;
0692:                    isMousePressed = false;
0693:                }
0694:            }
0695:
0696:            void mouseDragged(MouseEvent mouseEvent) {
0697:                // TODO: can you drag w/ any other buttons?  what about multiple buttons?
0698:                if (isEnabled()
0699:                        && (mouseEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
0700:                    if ((active == VERSCROLLBAR)) {
0701:                        vsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0702:                                .getModifiers(), mouseEvent.getX()
0703:                                - (width - SCROLLBAR_WIDTH), mouseEvent.getY());
0704:                    } else if ((active == HORSCROLLBAR)) {
0705:                        hsb.handleMouseEvent(mouseEvent.getID(), mouseEvent
0706:                                .getModifiers(), mouseEvent.getX(), mouseEvent
0707:                                .getY()
0708:                                - (height - SCROLLBAR_WIDTH));
0709:                    } else if (active == WINDOW) {
0710:                        int i = y2index(mouseEvent.getY());
0711:                        if (multipleSelections) {
0712:                            // Multi-select only:
0713:                            // If a selected item was pressed on and then dragged off
0714:                            // of, cancel the pending deselect.
0715:                            if (eventType == ItemEvent.DESELECTED) {
0716:                                if (i != eventIndex) {
0717:                                    eventType = NONE;
0718:                                    eventIndex = -1;
0719:                                }
0720:                            }
0721:                        } else if (eventType == ItemEvent.SELECTED) {
0722:                            // Single-select only:
0723:                            // If an unselected item was pressed on, track the drag
0724:                            // and select the item under the mouse
0725:
0726:                            // See 6243382 for more information
0727:                            trackMouseDraggedScroll(mouseEvent);
0728:
0729:                            if (i >= 0 && !isSelected(i)) {
0730:                                int oldSel = eventIndex;
0731:                                selectItem(i);
0732:                                eventIndex = i;
0733:                                repaint(oldSel, eventIndex, PAINT_ITEMS);
0734:                            }
0735:                        }
0736:                        // Restoring Windows behaviour
0737:                        // We should update focus index after "mouse dragged" event
0738:                        if (i >= 0) {
0739:                            setFocusIndex(i);
0740:                            repaint(PAINT_FOCUS);
0741:                        }
0742:                    }
0743:                }
0744:            }
0745:
0746:            /*
0747:             * Helper method for XListPeer with integrated vertical scrollbar.
0748:             * Start or stop vertical scrolling when mouse dragged in / out the area of the list if it's required
0749:             * Restoring Motif behavior
0750:             * See 6243382 for more information
0751:             */
0752:            void trackMouseDraggedScroll(MouseEvent mouseEvent) {
0753:
0754:                if (vsb.beforeThumb(mouseEvent.getX(), mouseEvent.getY())) {
0755:                    vsb.setMode(AdjustmentEvent.UNIT_DECREMENT);
0756:                } else {
0757:                    vsb.setMode(AdjustmentEvent.UNIT_INCREMENT);
0758:                }
0759:
0760:                if (mouseEvent.getY() < 0 || mouseEvent.getY() >= listHeight) {
0761:                    if (!mouseDraggedOutVertically) {
0762:                        mouseDraggedOutVertically = true;
0763:                        vsb.startScrollingInstance();
0764:                    }
0765:                } else {
0766:                    if (mouseDraggedOutVertically) {
0767:                        mouseDraggedOutVertically = false;
0768:                        vsb.stopScrollingInstance();
0769:                    }
0770:                }
0771:
0772:                if (hsb.beforeThumb(mouseEvent.getX(), mouseEvent.getY())) {
0773:                    hsb.setMode(AdjustmentEvent.UNIT_DECREMENT);
0774:                } else {
0775:                    hsb.setMode(AdjustmentEvent.UNIT_INCREMENT);
0776:                }
0777:
0778:                if (mouseEvent.getX() < 0 || mouseEvent.getX() >= listWidth) {
0779:                    if (!mouseDraggedOutHorizontally) {
0780:                        mouseDraggedOutHorizontally = true;
0781:                        hsb.startScrollingInstance();
0782:                    }
0783:                } else {
0784:                    if (mouseDraggedOutHorizontally) {
0785:                        mouseDraggedOutHorizontally = false;
0786:                        hsb.stopScrollingInstance();
0787:                    }
0788:                }
0789:            }
0790:
0791:            /*
0792:             * Helper method for XListPeer with integrated vertical scrollbar.
0793:             * Stop vertical scrolling when mouse released in / out the area of the list if it's required
0794:             * Restoring Motif behavior
0795:             * see 6243382 for more information
0796:             */
0797:            void trackMouseReleasedScroll() {
0798:
0799:                if (mouseDraggedOutVertically) {
0800:                    mouseDraggedOutVertically = false;
0801:                    vsb.stopScrollingInstance();
0802:                }
0803:
0804:                if (mouseDraggedOutHorizontally) {
0805:                    mouseDraggedOutHorizontally = false;
0806:                    hsb.stopScrollingInstance();
0807:                }
0808:            }
0809:
0810:            void handleJavaKeyEvent(KeyEvent e) {
0811:                switch (e.getID()) {
0812:                case KeyEvent.KEY_PRESSED:
0813:                    if (!isMousePressed) {
0814:                        keyPressed(e);
0815:                    }
0816:                    break;
0817:                }
0818:            }
0819:
0820:            void keyPressed(KeyEvent e) {
0821:                int keyCode = e.getKeyCode();
0822:                if (log.isLoggable(Level.FINE))
0823:                    log.fine(e.toString());
0824:                switch (keyCode) {
0825:                case KeyEvent.VK_UP:
0826:                case KeyEvent.VK_KP_UP: // TODO: I assume we also want this, too
0827:                    if (getFocusIndex() > 0) {
0828:                        setFocusIndex(getFocusIndex() - 1);
0829:                        repaint(PAINT_HIDEFOCUS);
0830:                        // If single-select, select the item
0831:                        if (!multipleSelections) {
0832:                            selectItem(getFocusIndex());
0833:                            postEvent(new ItemEvent((List) target,
0834:                                    ItemEvent.ITEM_STATE_CHANGED, Integer
0835:                                            .valueOf(getFocusIndex()),
0836:                                    ItemEvent.SELECTED));
0837:                        }
0838:                        if (isItemHidden(getFocusIndex())) {
0839:                            makeVisible(getFocusIndex());
0840:                        } else {
0841:                            repaint(PAINT_FOCUS);
0842:                        }
0843:                    }
0844:                    break;
0845:                case KeyEvent.VK_DOWN:
0846:                case KeyEvent.VK_KP_DOWN: // TODO: I assume we also want this, too
0847:                    if (getFocusIndex() < items.size() - 1) {
0848:                        setFocusIndex(getFocusIndex() + 1);
0849:                        repaint(PAINT_HIDEFOCUS);
0850:                        // If single-select, select the item
0851:                        if (!multipleSelections) {
0852:                            selectItem(getFocusIndex());
0853:                            postEvent(new ItemEvent((List) target,
0854:                                    ItemEvent.ITEM_STATE_CHANGED, Integer
0855:                                            .valueOf(getFocusIndex()),
0856:                                    ItemEvent.SELECTED));
0857:                        }
0858:                        if (isItemHidden(getFocusIndex())) {
0859:                            makeVisible(getFocusIndex());
0860:                        } else {
0861:                            repaint(PAINT_FOCUS);
0862:                        }
0863:                    }
0864:                    break;
0865:                case KeyEvent.VK_PAGE_UP: {
0866:                    // Assumes that scrollbar does its own bounds-checking
0867:                    int previousValue = vsb.getValue();
0868:                    vsb.setValue(vsb.getValue() - vsb.getBlockIncrement());
0869:                    int currentValue = vsb.getValue();
0870:                    // 6190768 pressing pg-up on AWT multiple selection lists the items but no item event is triggered, on XToolkit 
0871:                    // Restoring Motif behavior
0872:                    if (previousValue != currentValue) {
0873:                        setFocusIndex(Math.max(getFocusIndex()
0874:                                - itemsInWindow(), 0));
0875:                        if (!multipleSelections) {
0876:                            selectItem(getFocusIndex());
0877:                            postEvent(new ItemEvent((List) target,
0878:                                    ItemEvent.ITEM_STATE_CHANGED, Integer
0879:                                            .valueOf(getFocusIndex()),
0880:                                    ItemEvent.SELECTED));
0881:                        }
0882:                    }
0883:                    repaint();
0884:                    break;
0885:                }
0886:                case KeyEvent.VK_PAGE_DOWN: {
0887:                    // Assumes that scrollbar does its own bounds-checking
0888:                    int previousValue = vsb.getValue();
0889:                    vsb.setValue(vsb.getValue() + vsb.getBlockIncrement());
0890:                    int currentValue = vsb.getValue();
0891:                    // 6190768 pressing pg-down on AWT multiple selection list selects the items but no item event is triggered, on XToolkit 
0892:                    // Restoring Motif behavior
0893:                    if (previousValue != currentValue) {
0894:                        setFocusIndex(Math.min(getFocusIndex()
0895:                                + itemsInWindow(), items.size() - 1));
0896:                        if (!multipleSelections) {
0897:                            selectItem(getFocusIndex());
0898:                            postEvent(new ItemEvent((List) target,
0899:                                    ItemEvent.ITEM_STATE_CHANGED, Integer
0900:                                            .valueOf(getFocusIndex()),
0901:                                    ItemEvent.SELECTED));
0902:                        }
0903:                    }
0904:                    repaint();
0905:                    break;
0906:                }
0907:                case KeyEvent.VK_LEFT:
0908:                case KeyEvent.VK_KP_LEFT:
0909:                    if (hsbVis & hsb.getValue() > 0) {
0910:                        hsb.setValue(hsb.getValue() - HORIZ_SCROLL_AMT);
0911:                        repaint();
0912:                    }
0913:                    break;
0914:                case KeyEvent.VK_RIGHT:
0915:                case KeyEvent.VK_KP_RIGHT:
0916:                    if (hsbVis) { // Should check if already at end
0917:                        hsb.setValue(hsb.getValue() + HORIZ_SCROLL_AMT);
0918:                        repaint();
0919:                    }
0920:                    break;
0921:                // 6190778 CTRL + HOME, CTRL + END keys do not work properly for list on XToolkit
0922:                // Restoring Motif behavior
0923:                case KeyEvent.VK_HOME:
0924:                    if (!e.isControlDown()
0925:                            || ((List) target).getItemCount() <= 0)
0926:                        break;
0927:                    if (vsbVis) {
0928:                        vsb.setValue(vsb.getMinimum());
0929:                    }
0930:                    setFocusIndex(0);
0931:                    if (!multipleSelections) {
0932:                        selectItem(getFocusIndex());
0933:                        postEvent(new ItemEvent((List) target,
0934:                                ItemEvent.ITEM_STATE_CHANGED, Integer
0935:                                        .valueOf(getFocusIndex()),
0936:                                ItemEvent.SELECTED));
0937:                    }
0938:                    repaint();
0939:                    break;
0940:                case KeyEvent.VK_END:
0941:                    if (!e.isControlDown()
0942:                            || ((List) target).getItemCount() <= 0)
0943:                        break;
0944:                    if (vsbVis) {
0945:                        vsb.setValue(vsb.getMaximum());
0946:                    }
0947:                    setFocusIndex(items.size() - 1);
0948:                    if (!multipleSelections) {
0949:                        selectItem(getFocusIndex());
0950:                        postEvent(new ItemEvent((List) target,
0951:                                ItemEvent.ITEM_STATE_CHANGED, Integer
0952:                                        .valueOf(getFocusIndex()),
0953:                                ItemEvent.SELECTED));
0954:                    }
0955:                    repaint();
0956:                    break;
0957:                case KeyEvent.VK_SPACE:
0958:                    // Fixed 6299853: XToolkit: Pressing space triggers ItemStateChanged event after List.removeAll called
0959:                    // If getFocusIndex() is less than 0, the event will not be triggered when space pressed
0960:                    if (getFocusIndex() < 0
0961:                            || ((List) target).getItemCount() <= 0) {
0962:                        break;
0963:                    }
0964:
0965:                    boolean isSelected = isSelected(getFocusIndex());
0966:
0967:                    // Spacebar only deselects for multi-select Lists
0968:                    if (multipleSelections && isSelected) {
0969:                        deselectItem(getFocusIndex());
0970:                        postEvent(new ItemEvent((List) target,
0971:                                ItemEvent.ITEM_STATE_CHANGED, Integer
0972:                                        .valueOf(getFocusIndex()),
0973:                                ItemEvent.DESELECTED));
0974:                    } else if (!isSelected) { // Note: this changes the Solaris/Linux
0975:                        // behavior to match that of win32.
0976:                        // That is, pressing space bar on a 
0977:                        // single-select list when the focused
0978:                        // item is already selected does NOT
0979:                        // send an ItemEvent.SELECTED event.
0980:                        selectItem(getFocusIndex());
0981:                        postEvent(new ItemEvent((List) target,
0982:                                ItemEvent.ITEM_STATE_CHANGED, Integer
0983:                                        .valueOf(getFocusIndex()),
0984:                                ItemEvent.SELECTED));
0985:                    }
0986:                    break;
0987:                case KeyEvent.VK_ENTER:
0988:                    // It looks to me like there are bugs as well as inconsistencies
0989:                    // in the way the Enter key is handled by both Solaris and Windows.
0990:                    // So for now in XAWT, I'm going to simply go by what the List docs
0991:                    // say: "AWT also generates an action event when the user presses
0992:                    // the return key while an item in the list is selected."
0993:                    if (selected.length > 0) {
0994:                        postEvent(new ActionEvent((List) target,
0995:                                ActionEvent.ACTION_PERFORMED, (String) items
0996:                                        .elementAt(getFocusIndex()), e
0997:                                        .getWhen(), e.getModifiers())); // ActionEvent doesn't have
0998:                        // extended modifiers.
0999:                    }
1000:                    break;
1001:                }
1002:            }
1003:
1004:            /**
1005:             * return value from the scrollbar
1006:             */
1007:            public void notifyValue(XScrollbar obj, int type, int v,
1008:                    boolean isAdjusting) {
1009:
1010:                if (log.isLoggable(Level.FINE))
1011:                    log.fine("Notify value changed on " + obj + " to " + v);
1012:                int value = obj.getValue();
1013:                if (obj == vsb) {
1014:                    scrollVertical(v - value);
1015:
1016:                    // See 6243382 for more information
1017:                    int oldSel = eventIndex;
1018:                    int newSel = eventIndex + v - value;
1019:                    if (mouseDraggedOutVertically && !isSelected(newSel)) {
1020:                        selectItem(newSel);
1021:                        eventIndex = newSel;
1022:                        repaint(oldSel, eventIndex, PAINT_ITEMS);
1023:                        // Scrolling select() should also set the focus index
1024:                        // Otherwise, the updating of the 'focusIndex' variable will be incorrect
1025:                        // if user drag mouse out of the area of the list
1026:                        setFocusIndex(newSel);
1027:                        repaint(PAINT_FOCUS);
1028:                    }
1029:
1030:                } else if ((XHorizontalScrollbar) obj == hsb) {
1031:                    scrollHorizontal(v - value);
1032:                }
1033:
1034:            }
1035:
1036:            /**
1037:             * deselect all items in List
1038:             */
1039:            private void deselectAllItems() {
1040:                selected = new int[0];
1041:                repaint(PAINT_ITEMS);
1042:            }
1043:
1044:            /** 
1045:             * set multiple selections
1046:             */
1047:            public void setMultipleSelections(boolean v) {
1048:                if (multipleSelections != v) {
1049:                    if (!v) {
1050:                        int selPos = (isSelected(focusIndex)) ? focusIndex : -1;
1051:                        deselectAllItems();
1052:                        if (selPos != -1) {
1053:                            selectItem(selPos);
1054:                        }
1055:                    }
1056:                    multipleSelections = v;
1057:                }
1058:            }
1059:
1060:            /**
1061:             * add an item
1062:             * if the index of the item is < 0 or >= than items.size() 
1063:             * then add the item to the end of the list
1064:             */
1065:            public void addItem(String item, int i) {
1066:                int oldMaxLength = maxLength;
1067:                boolean hsbWasVis = hsbVis;
1068:                boolean vsbWasVis = vsbVis;
1069:
1070:                int addedIndex = 0; // Index where the new item ended up
1071:                if (i < 0 || i >= items.size()) {
1072:                    i = -1;
1073:                }
1074:
1075:                // Why we set this variable to -1 in spite of the fact that selected[] is changed in other way?
1076:                // It's not clear how to reproduce incorrect behaviour based on this assignment
1077:                // since before using this variable (mouseReleased) we certainly update it to correct value
1078:                // So we don't modify this behaviour now
1079:                currentIndex = -1;
1080:
1081:                if (i == -1) {
1082:                    items.addElement(item);
1083:                    i = 0; // fix the math for the paintItems test
1084:                    addedIndex = items.size() - 1;
1085:                } else {
1086:                    items.insertElementAt(item, i);
1087:                    addedIndex = i;
1088:                    for (int j = 0; j < selected.length; j++) {
1089:                        if (selected[j] >= i) {
1090:                            selected[j] += 1;
1091:                        }
1092:                    }
1093:                }
1094:                if (log.isLoggable(Level.FINER))
1095:                    log.finer("Adding item '" + item + "' to " + addedIndex);
1096:
1097:                // Update maxLength
1098:                boolean repaintItems = !isItemHidden(addedIndex);
1099:                maxLength = Math.max(maxLength, getItemWidth(addedIndex));
1100:                layout();
1101:
1102:                int options = 0;
1103:                if (vsbVis != vsbWasVis || hsbVis != hsbWasVis) {
1104:                    // Scrollbars are being added or removed, so we must repaint all
1105:                    options = PAINT_ALL;
1106:                } else {
1107:                    options = (repaintItems ? (PAINT_ITEMS) : 0)
1108:                            | ((maxLength != oldMaxLength || (hsbWasVis ^ hsbVis)) ? (PAINT_HSCROLL)
1109:                                    : 0)
1110:                            | ((vsb.needsRepaint()) ? (PAINT_VSCROLL) : 0);
1111:
1112:                }
1113:                if (log.isLoggable(Level.FINEST))
1114:                    log.finest("Last visible: " + getLastVisibleItem()
1115:                            + ", hsb changed : " + (hsbWasVis ^ hsbVis)
1116:                            + ", items changed " + repaintItems);
1117:                repaint(addedIndex, getLastVisibleItem(), options);
1118:            }
1119:
1120:            /** 
1121:             * delete items starting with s (start position) to e (end position) including s and e
1122:             * if s < 0 then s = 0
1123:             * if e >= items.size() then e = items.size() - 1 
1124:             */
1125:            public void delItems(int s, int e) {
1126:                // save the current state of the scrollbars
1127:                boolean hsbWasVisible = hsbVis;
1128:                boolean vsbWasVisible = vsbVis;
1129:                int oldLastDisplayed = lastItemDisplayed();
1130:
1131:                if (log.isLoggable(Level.FINE))
1132:                    log.fine("Deleting from " + s + " to " + e);
1133:
1134:                if (log.isLoggable(Level.FINEST))
1135:                    log.finest("Last displayed item: " + oldLastDisplayed
1136:                            + ", items in window " + itemsInWindow()
1137:                            + ", size " + items.size());
1138:
1139:                if (items.size() == 0) {
1140:                    return;
1141:                }
1142:
1143:                // if user passed in flipped args, reverse them
1144:                if (s > e) {
1145:                    int tmp = s;
1146:                    s = e;
1147:                    e = tmp;
1148:                }
1149:
1150:                // check for starting point less than zero
1151:                if (s < 0) {
1152:                    s = 0;
1153:                }
1154:
1155:                // check for end point greater than the size of the list
1156:                if (e >= items.size()) {
1157:                    e = items.size() - 1;
1158:                }
1159:
1160:                // determine whether we're going to delete any visible elements
1161:                // repaint must also be done if scrollbars appear/disappear, which
1162:                // can happen from removing a non-showing list item
1163:                /*
1164:                  boolean repaintNeeded = 
1165:                  ((s <= lastItemDisplayed()) && (e >= vsb.getValue()));
1166:                 */
1167:                boolean repaintNeeded = (s >= getFirstVisibleItem() && s <= getLastVisibleItem());
1168:
1169:                // delete the items out of the items list and out of the selected list
1170:                for (int i = s; i <= e; i++) {
1171:                    items.removeElementAt(s);
1172:                    int j = posInSel(i);
1173:                    if (j != -1) {
1174:                        int newsel[] = new int[selected.length - 1];
1175:                        System.arraycopy(selected, 0, newsel, 0, j);
1176:                        System.arraycopy(selected, j + 1, newsel, j,
1177:                                selected.length - (j + 1));
1178:                        selected = newsel;
1179:                    }
1180:
1181:                }
1182:
1183:                // update the indexes in the selected array
1184:                int diff = (e - s) + 1;
1185:                for (int i = 0; i < selected.length; i++) {
1186:                    if (selected[i] > e) {
1187:                        selected[i] -= diff;
1188:                    }
1189:                }
1190:
1191:                int options = PAINT_VSCROLL;
1192:                // focusedIndex updating according to native (Window, Motif) behaviour
1193:                if (getFocusIndex() > e) {
1194:                    setFocusIndex(getFocusIndex() - (e - s + 1));
1195:                    options |= PAINT_FOCUS;
1196:                } else if (getFocusIndex() >= s && getFocusIndex() <= e) {
1197:                    // Fixed 6299858: PIT. Focused border not shown on List if selected item is removed, XToolkit
1198:                    // We should set focus to new first item if the current first item was removed 
1199:                    // except if the list is empty
1200:                    int focusBound = (items.size() > 0) ? 0 : -1;
1201:                    setFocusIndex(Math.max(s - 1, focusBound));
1202:                    options |= PAINT_FOCUS;
1203:                }
1204:
1205:                if (log.isLoggable(Level.FINEST))
1206:                    log.finest("Multiple selections: " + multipleSelections);
1207:
1208:                // update vsb.val
1209:                if (vsb.getValue() >= s) {
1210:                    if (vsb.getValue() <= e) {
1211:                        vsb.setValue(e + 1 - diff);
1212:                    } else {
1213:                        vsb.setValue(vsb.getValue() - diff);
1214:                    }
1215:                }
1216:
1217:                int oldMaxLength = maxLength;
1218:                maxLength = maxLength();
1219:                if (maxLength != oldMaxLength) {
1220:                    // Width of the items changed affecting the range of
1221:                    // horizontal scrollbar
1222:                    options |= PAINT_HSCROLL;
1223:                }
1224:                layout();
1225:                repaintNeeded |= (vsbWasVisible ^ vsbVis)
1226:                        || (hsbWasVisible ^ hsbVis); // If scrollbars visibility changed
1227:                if (repaintNeeded) {
1228:                    options |= PAINT_ALL;
1229:                }
1230:                repaint(s, oldLastDisplayed, options);
1231:            }
1232:
1233:            /**
1234:             * ListPeer method
1235:             */
1236:            public void select(int index) {
1237:                // Programmatic select() should also set the focus index
1238:                setFocusIndex(index);
1239:                repaint(PAINT_FOCUS);
1240:                selectItem(index);
1241:            }
1242:
1243:            /**
1244:             * select the index
1245:             * redraw the list to the screen
1246:             */
1247:            void selectItem(int index) {
1248:                // NOTE: instead of recalculating and the calling repaint(), painting
1249:                // is done immediately
1250:
1251:                // 6190746 List does not trigger ActionEvent when double clicking a programmatically selected item, XToolkit
1252:                // If we invoke select(int) before setVisible(boolean), then variable currentIndex will equals -1. At the same time isSelected may be true.
1253:                // Restoring Motif behavior
1254:                currentIndex = index;
1255:
1256:                if (isSelected(index)) {
1257:                    return;
1258:                }
1259:                if (!multipleSelections) {
1260:                    if (selected.length == 0) { // No current selection
1261:                        selected = new int[1];
1262:                        selected[0] = index;
1263:                    } else {
1264:                        int oldSel = selected[0];
1265:                        selected[0] = index;
1266:                        if (!isItemHidden(oldSel)) {
1267:                            // Only bother painting if item is visible (4895367)
1268:                            repaint(oldSel, oldSel, PAINT_ITEMS);
1269:                        }
1270:                    }
1271:                } else {
1272:                    // insert "index" into the selection array
1273:                    int newsel[] = new int[selected.length + 1];
1274:                    int i = 0;
1275:                    while (i < selected.length && index > selected[i]) {
1276:                        newsel[i] = selected[i];
1277:                        i++;
1278:                    }
1279:                    newsel[i] = index;
1280:                    System.arraycopy(selected, i, newsel, i + 1,
1281:                            selected.length - i);
1282:                    selected = newsel;
1283:                }
1284:                if (!isItemHidden(index)) {
1285:                    // Only bother painting if item is visible (4895367)
1286:                    repaint(index, index, PAINT_ITEMS);
1287:                }
1288:            }
1289:
1290:            /**
1291:             * ListPeer method
1292:             * focusedIndex isn't updated according to native (Window, Motif) behaviour
1293:             */
1294:            public void deselect(int index) {
1295:                deselectItem(index);
1296:            }
1297:
1298:            /**
1299:             * deselect the index
1300:             * redraw the list to the screen
1301:             */
1302:            void deselectItem(int index) {
1303:                if (!isSelected(index)) {
1304:                    return;
1305:                }
1306:                if (!multipleSelections) {
1307:                    // TODO: keep an int[0] and int[1] around and just use them instead
1308:                    // creating new ones all the time
1309:                    selected = new int[0];
1310:                } else {
1311:                    int i = posInSel(index);
1312:                    int newsel[] = new int[selected.length - 1];
1313:                    System.arraycopy(selected, 0, newsel, 0, i);
1314:                    System.arraycopy(selected, i + 1, newsel, i,
1315:                            selected.length - (i + 1));
1316:                    selected = newsel;
1317:                }
1318:                currentIndex = index;
1319:                if (!isItemHidden(index)) {
1320:                    // Only bother repainting if item is visible
1321:                    repaint(index, index, PAINT_ITEMS);
1322:                }
1323:            }
1324:
1325:            /**
1326:             * ensure that the given index is visible, scrolling the List
1327:             * if necessary, or doing nothing if the item is already visible.
1328:             * The List must be repainted for changes to be visible.
1329:             */
1330:            public void makeVisible(int index) {
1331:                if (index < 0 || index >= items.size()) {
1332:                    return;
1333:                }
1334:                if (isItemHidden(index)) { // Do I really need to call this?
1335:                    // If index is above the top, scroll up
1336:                    if (index < vsb.getValue()) {
1337:                        scrollVertical(index - vsb.getValue());
1338:                    }
1339:                    // If index is below the bottom, scroll down
1340:                    else if (index > lastItemDisplayed()) {
1341:                        int val = index - lastItemDisplayed();
1342:                        scrollVertical(val);
1343:                    }
1344:                }
1345:            }
1346:
1347:            /**
1348:             * clear 
1349:             */
1350:            public void clear() {
1351:                selected = new int[0];
1352:                items = new Vector();
1353:                currentIndex = -1;
1354:                // Fixed 6291736: ITEM_STATE_CHANGED triggered after List.removeAll(), XToolkit
1355:                // We should update 'focusIndex' variable more carefully
1356:                setFocusIndex(-1);
1357:                vsb.setValue(0);
1358:                maxLength = 0;
1359:                layout();
1360:                repaint();
1361:            }
1362:
1363:            /**
1364:             * return the selected indexes
1365:             */
1366:            public int[] getSelectedIndexes() {
1367:                return selected;
1368:            }
1369:
1370:            /**
1371:             * return the y value of the given index "i".
1372:             * the y value represents the top of the text
1373:             * NOTE: index can be larger than items.size as long
1374:             * as it can fit the window
1375:             */
1376:            int index2y(int index) {
1377:                int h = getItemHeight();
1378:
1379:                //if (index < vsb.getValue() || index > vsb.getValue() + itemsInWindow()) {
1380:                return MARGIN + ((index - vsb.getValue()) * h) + SPACE;
1381:            }
1382:
1383:            /* return true if the y is a valid y coordinate for
1384:             *  a VISIBLE list item, otherwise returns false
1385:             */
1386:            boolean validY(int y) {
1387:
1388:                int shown = itemsDisplayed();
1389:                int lastY = shown * getItemHeight() + MARGIN;
1390:
1391:                if (shown == itemsInWindow()) {
1392:                    lastY += MARGIN;
1393:                }
1394:
1395:                if (y < 0 || y >= lastY) {
1396:                    return false;
1397:                }
1398:
1399:                return true;
1400:            }
1401:
1402:            /**
1403:             * return the position of the index in the selected array
1404:             * if the index isn't in the array selected return -1;
1405:             */
1406:            int posInSel(int index) {
1407:                for (int i = 0; i < selected.length; i++) {
1408:                    if (index == selected[i]) {
1409:                        return i;
1410:                    }
1411:                }
1412:                return -1;
1413:            }
1414:
1415:            boolean isIndexDisplayed(int idx) {
1416:                int lastDisplayed = lastItemDisplayed();
1417:
1418:                return idx <= lastDisplayed
1419:                        && idx >= Math.max(0, lastDisplayed - itemsInWindow()
1420:                                + 1);
1421:            }
1422:
1423:            /**
1424:             * returns index of last item displayed in the List
1425:             */
1426:            int lastItemDisplayed() {
1427:                int n = itemsInWindow();
1428:                return (Math.min(items.size() - 1, (vsb.getValue() + n) - 1));
1429:            }
1430:
1431:            /**
1432:             * returns whether the given index is currently scrolled off the top or
1433:             * bottom of the List.
1434:             */
1435:            boolean isItemHidden(int index) {
1436:                return index < vsb.getValue()
1437:                        || index >= vsb.getValue() + itemsInWindow();
1438:            }
1439:
1440:            /**
1441:             * returns the width of the list portion of the component (accounts for
1442:             * presence of vertical scrollbar)
1443:             */
1444:            int getListWidth() {
1445:                return vsbVis ? width - SCROLLBAR_AREA : width;
1446:            }
1447:
1448:            /**
1449:             * returns number of  items actually displayed in the List
1450:             */
1451:            int itemsDisplayed() {
1452:
1453:                return (Math
1454:                        .min(items.size() - vsb.getValue(), itemsInWindow()));
1455:
1456:            }
1457:
1458:            /**
1459:             * scrollVertical
1460:             * y is the number of items to scroll
1461:             */
1462:            void scrollVertical(int y) {
1463:                if (log.isLoggable(Level.FINE))
1464:                    log.fine("Scrolling vertically by " + y);
1465:                int itemsInWin = itemsInWindow();
1466:                int h = getItemHeight();
1467:                int pixelsToScroll = y * h;
1468:
1469:                if (vsb.getValue() < -y) {
1470:                    y = -vsb.getValue();
1471:                }
1472:                vsb.setValue(vsb.getValue() + y);
1473:
1474:                if (y > 0) {
1475:                    // Fixed 6308295: XAWTduplicate list item is displayed
1476:                    // Window resizing leads to the buffer flushing
1477:                    // That's why the repainting with the PAINT_HIDEFOCUS option is the repainting with PAINT_ALL option
1478:                    // So we should do only the repainting instead of the copy area
1479:                    if (y < itemsInWin && painter.isBuffer()) {
1480:                        if (log.isLoggable(Level.FINEST)) {
1481:                            log.finest("Copying " + "" + MARGIN + ","
1482:                                    + (MARGIN + pixelsToScroll) + ","
1483:                                    + (width - SCROLLBAR_AREA) + ","
1484:                                    + (h * (itemsInWin - y) - 1) + "," + 0
1485:                                    + "," + (-pixelsToScroll));
1486:                        }
1487:                        // Unpaint focus before copying
1488:                        repaint(PAINT_HIDEFOCUS);
1489:                        painter.copyArea(MARGIN, MARGIN + pixelsToScroll, width
1490:                                - SCROLLBAR_AREA, h * (itemsInWin - y - 1) - 1,
1491:                                0, -pixelsToScroll);
1492:                    }
1493:                    repaint(vsb.getValue() + (itemsInWin - y) - 1, (vsb
1494:                            .getValue() + itemsInWin) - 1, PAINT_ITEMS
1495:                            | PAINT_VSCROLL | PAINT_FOCUS);
1496:                } else if (y < 0 && painter.isBuffer()) {
1497:                    if (y + itemsInWindow() > 0) {
1498:                        if (log.isLoggable(Level.FINEST)) {
1499:                            log.finest("Copying " + MARGIN + "," + MARGIN + ","
1500:                                    + (width - SCROLLBAR_AREA) + ","
1501:                                    + (h * (itemsInWin + y)) + "," + "0" + ","
1502:                                    + (-pixelsToScroll));
1503:                        }
1504:                        repaint(PAINT_HIDEFOCUS);
1505:                        painter.copyArea(MARGIN, MARGIN,
1506:                                width - SCROLLBAR_AREA, h * (itemsInWin + y),
1507:                                0, -pixelsToScroll);
1508:                    }
1509:                    int e = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
1510:                    repaint(vsb.getValue(), e, PAINT_ITEMS | PAINT_VSCROLL
1511:                            | PAINT_FOCUS);
1512:                }
1513:            }
1514:
1515:            /**
1516:             * scrollHorizontal
1517:             * x is the number of pixels to scroll
1518:             */
1519:            void scrollHorizontal(int x) {
1520:                if (log.isLoggable(Level.FINE))
1521:                    log.fine("Scrolling horizontally by " + y);
1522:                int w = getListWidth();
1523:                w -= ((2 * SPACE) + (2 * MARGIN));
1524:                int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
1525:                hsb.setValue(hsb.getValue() + x);
1526:
1527:                if (x < 0 && painter.isBuffer()) {
1528:                    painter.copyArea(MARGIN + SPACE, MARGIN, w + x, h, -x, 0);
1529:                } else if (x > 0 && painter.isBuffer()) {
1530:                    painter.copyArea(MARGIN + SPACE + x, MARGIN, w - x, h, -x,
1531:                            0);
1532:                }
1533:                repaint(vsb.getValue(), lastItemDisplayed(), PAINT_ITEMS
1534:                        | PAINT_HSCROLL);
1535:            }
1536:
1537:            /**
1538:             * return the index 
1539:             */
1540:            int y2index(int y) {
1541:                if (!validY(y)) {
1542:                    return -1;
1543:                }
1544:
1545:                int i = (y - MARGIN) / getItemHeight() + vsb.getValue();
1546:                int last = lastItemDisplayed();
1547:
1548:                if (i > last) {
1549:                    i = last;
1550:                }
1551:
1552:                return i;
1553:
1554:            }
1555:
1556:            /**
1557:             * is the index "index" selected
1558:             */
1559:            boolean isSelected(int index) {
1560:                if (eventType == ItemEvent.SELECTED && index == eventIndex) {
1561:                    return true;
1562:                }
1563:                for (int i = 0; i < selected.length; i++) {
1564:                    if (selected[i] == index) {
1565:                        return true;
1566:                    }
1567:                }
1568:                return false;
1569:            }
1570:
1571:            /**
1572:             * return the number of items that can fit 
1573:             * in the current window
1574:             */
1575:            int itemsInWindow(boolean scrollbarVisible) {
1576:                int h;
1577:                if (scrollbarVisible) {
1578:                    h = height - ((2 * MARGIN) + SCROLLBAR_AREA);
1579:                } else {
1580:                    h = height - 2 * MARGIN;
1581:                }
1582:                return (h / getItemHeight());
1583:            }
1584:
1585:            int itemsInWindow() {
1586:                return itemsInWindow(hsbVis);
1587:            }
1588:
1589:            /**
1590:             * return true if the x and y position is in the horizontal scrollbar
1591:             */
1592:            boolean inHorizontalScrollbar(int x, int y) {
1593:                int w = getListWidth();
1594:                int h = height - SCROLLBAR_WIDTH;
1595:                return (hsbVis && (x >= 0) && (x <= w) && (y > h));
1596:            }
1597:
1598:            /**
1599:             * return true if the x and y position is in the verticalscrollbar
1600:             */
1601:            boolean inVerticalScrollbar(int x, int y) {
1602:                int w = width - SCROLLBAR_WIDTH;
1603:                int h = hsbVis ? height - SCROLLBAR_AREA : height;
1604:                return (vsbVis && (x > w) && (y >= 0) && (y <= h));
1605:            }
1606:
1607:            /**
1608:             * return true if the x and y position is in the window
1609:             */
1610:            boolean inWindow(int x, int y) {
1611:                int w = getListWidth();
1612:                int h = hsbVis ? height - SCROLLBAR_AREA : height;
1613:                return ((x >= 0) && (x <= w)) && ((y >= 0) && (y <= h));
1614:            }
1615:
1616:            /**
1617:             * return true if vertical scrollbar is visible and false otherwise;
1618:             * hsbVisible is the visibility of the horizontal scrollbar
1619:             */
1620:            boolean vsbIsVisible(boolean hsbVisible) {
1621:                return (items.size() > itemsInWindow(hsbVisible));
1622:            }
1623:
1624:            /**
1625:             * return true if horizontal scrollbar is visible and false otherwise;
1626:             * vsbVisible is the visibility of the vertical scrollbar
1627:             */
1628:            boolean hsbIsVisible(boolean vsbVisible) {
1629:                int w = width
1630:                        - ((2 * SPACE) + (2 * MARGIN) + (vsbVisible ? SCROLLBAR_AREA
1631:                                : 0));
1632:                return (maxLength > w);
1633:            }
1634:
1635:            /*
1636:             * Returns true if the event has been handled and should not be
1637:             * posted to Java
1638:             */
1639:            boolean prePostEvent(final AWTEvent e) {
1640:                if (e instanceof  MouseEvent) {
1641:                    return prePostMouseEvent((MouseEvent) e);
1642:                }
1643:                return super .prePostEvent(e);
1644:            }
1645:
1646:            /*
1647:             * Fixed 6240151: XToolkit: Dragging the List scrollbar initiates DnD
1648:             * To be compatible with Motif, MouseEvent originated on the scrollbar
1649:             * should be sent into Java in this way:
1650:             * - post: MOUSE_ENTERED, MOUSE_EXITED, MOUSE_MOVED
1651:             * - don't post: MOUSE_PRESSED, MOUSE_RELEASED, MOUSE_CLICKED, MOUSE_DRAGGED
1652:             */
1653:            boolean prePostMouseEvent(final MouseEvent me) {
1654:                if (getToplevelXWindow().isModalBlocked()) {
1655:                    return false;
1656:                }
1657:
1658:                int eventId = me.getID();
1659:
1660:                if (eventId == MouseEvent.MOUSE_MOVED) {
1661:                    // only for performance improvement 
1662:                } else if ((eventId == MouseEvent.MOUSE_DRAGGED || eventId == MouseEvent.MOUSE_RELEASED)
1663:                        && isScrollBarOriginated) {
1664:                    if (eventId == MouseEvent.MOUSE_RELEASED) {
1665:                        isScrollBarOriginated = false;
1666:                    }
1667:                    handleJavaMouseEventOnEDT(me);
1668:                    return true;
1669:                } else if ((eventId == MouseEvent.MOUSE_PRESSED || eventId == MouseEvent.MOUSE_CLICKED)
1670:                        && (inVerticalScrollbar(me.getX(), me.getY()) || inHorizontalScrollbar(
1671:                                me.getX(), me.getY()))) {
1672:                    if (eventId == MouseEvent.MOUSE_PRESSED) {
1673:                        isScrollBarOriginated = true;
1674:                    }
1675:                    handleJavaMouseEventOnEDT(me);
1676:                    return true;
1677:                }
1678:                return false;
1679:            }
1680:
1681:            /*
1682:             * Do handleJavaMouseEvent on EDT
1683:             */
1684:            void handleJavaMouseEventOnEDT(final MouseEvent me) {
1685:                EventQueue.invokeLater(new Runnable() {
1686:                    public void run() {
1687:                        handleJavaMouseEvent(me);
1688:                    }
1689:                });
1690:            }
1691:
1692:            /*
1693:             * Fixed 5010944: List's rows overlap one another
1694:             * The bug is due to incorrent caching of the list item size
1695:             * So we should recalculate font metrics on setFont
1696:             */
1697:            public void setFont(Font f) {
1698:                super .setFont(f);
1699:                initFontMetrics();
1700:                layout();
1701:                repaint();
1702:            }
1703:
1704:            /**
1705:             * Sometimes painter is called on Toolkit thread, so the lock sequence is:
1706:             *     awtLock -> Painter -> awtLock
1707:             * Sometimes it is called on other threads:
1708:             *     Painter -> awtLock
1709:             * Since we can't guarantee the sequence, use awtLock.
1710:             */
1711:            class ListPainter {
1712:                // TODO: use VolatileImage
1713:                VolatileImage buffer;
1714:                Color[] colors;
1715:
1716:                private Color getListForeground() {
1717:                    if (fgColorSet) {
1718:                        return colors[FOREGROUND_COLOR];
1719:                    } else {
1720:                        return SystemColor.textText;
1721:                    }
1722:                }
1723:
1724:                private Color getListBackground() {
1725:                    if (bgColorSet) {
1726:                        return colors[BACKGROUND_COLOR];
1727:                    } else {
1728:                        return SystemColor.text;
1729:                    }
1730:                }
1731:
1732:                private Color getDisabledColor() {
1733:                    Color backgroundColor = getListBackground();
1734:                    Color foregroundColor = getListForeground();
1735:                    return (backgroundColor.equals(Color.BLACK)) ? foregroundColor
1736:                            .darker()
1737:                            : backgroundColor.darker();
1738:                }
1739:
1740:                private boolean createBuffer() {
1741:                    VolatileImage localBuffer = null;
1742:                    XToolkit.awtLock();
1743:                    try {
1744:                        localBuffer = buffer;
1745:                    } finally {
1746:                        XToolkit.awtUnlock();
1747:                    }
1748:
1749:                    if (localBuffer == null) {
1750:                        if (log.isLoggable(Level.FINE))
1751:                            log.fine("Creating buffer " + width + "x" + height);
1752:                        // use GraphicsConfig.cCVI() instead of Component.cVI(),
1753:                        // because the latter may cause a deadlock with the tree lock
1754:                        localBuffer = graphicsConfig
1755:                                .createCompatibleVolatileImage(width + 1,
1756:                                        height + 1);
1757:                    }
1758:                    XToolkit.awtLock();
1759:                    try {
1760:                        if (buffer == null) {
1761:                            buffer = localBuffer;
1762:                            return true;
1763:                        }
1764:                    } finally {
1765:                        XToolkit.awtUnlock();
1766:                    }
1767:                    return false;
1768:                }
1769:
1770:                public void invalidate() {
1771:                    XToolkit.awtLock();
1772:                    try {
1773:                        if (buffer != null) {
1774:                            buffer.flush();
1775:                        }
1776:                        buffer = null;
1777:                    } finally {
1778:                        XToolkit.awtUnlock();
1779:                    }
1780:                }
1781:
1782:                private void paint(Graphics listG, int firstItem, int lastItem,
1783:                        int options) {
1784:                    if (log.isLoggable(Level.FINER))
1785:                        log.finer("Repaint from " + firstItem + " to "
1786:                                + lastItem + " options " + options);
1787:                    if (firstItem > lastItem) {
1788:                        int t = lastItem;
1789:                        lastItem = firstItem;
1790:                        firstItem = t;
1791:                    }
1792:                    if (firstItem < 0) {
1793:                        firstItem = 0;
1794:                    }
1795:                    colors = getGUIcolors();
1796:                    VolatileImage localBuffer = null;
1797:                    do {
1798:                        XToolkit.awtLock();
1799:                        try {
1800:                            if (createBuffer()) {
1801:                                // First time created buffer should be painted over at full.
1802:                                options = PAINT_ALL;
1803:                            }
1804:                            localBuffer = buffer;
1805:                        } finally {
1806:                            XToolkit.awtUnlock();
1807:                        }
1808:                        switch (localBuffer
1809:                                .validate(getGraphicsConfiguration())) {
1810:                        case VolatileImage.IMAGE_INCOMPATIBLE:
1811:                            invalidate();
1812:                            options = PAINT_ALL;
1813:                            continue;
1814:                        }
1815:                        Graphics g = localBuffer.createGraphics();
1816:
1817:                        try {
1818:                            g.setFont(getFont());
1819:                            if ((options & PAINT_BACKGROUND) != 0) {
1820:                                g.setColor(SystemColor.window);
1821:                                g.fillRect(0, 0, width, height);
1822:                                g.setColor(getListBackground());
1823:                                g.fillRect(0, 0, listWidth, listHeight);
1824:                                draw3DRect(g, getSystemColors(), 0, 0,
1825:                                        listWidth - 1, listHeight - 1, false);
1826:                                // Since we made full erase update items
1827:                                firstItem = getFirstVisibleItem();
1828:                                lastItem = getLastVisibleItem();
1829:                            }
1830:                            if ((options & PAINT_ITEMS) != 0) {
1831:                                paintItems(g, firstItem, lastItem, options);
1832:                            }
1833:                            if ((options & PAINT_VSCROLL) != 0 && vsbVis) {
1834:                                g.setClip(getVScrollBarRec());
1835:                                paintVerScrollbar(g, true);
1836:                            }
1837:                            if ((options & PAINT_HSCROLL) != 0 && hsbVis) {
1838:                                g.setClip(getHScrollBarRec());
1839:                                paintHorScrollbar(g, true);
1840:                            }
1841:                            if ((options & (PAINT_FOCUS | PAINT_HIDEFOCUS)) != 0) {
1842:                                paintFocus(g, options);
1843:                            }
1844:                        } finally {
1845:                            g.dispose();
1846:                        }
1847:                    } while (localBuffer.contentsLost());
1848:                    listG.drawImage(localBuffer, 0, 0, null);
1849:                }
1850:
1851:                private void paintItems(Graphics g, int firstItem,
1852:                        int lastItem, int options) {
1853:                    if (log.isLoggable(Level.FINER))
1854:                        log.finer("Painting items from " + firstItem + " to "
1855:                                + lastItem + ", focused " + focusIndex
1856:                                + ", first " + getFirstVisibleItem()
1857:                                + ", last " + getLastVisibleItem());
1858:
1859:                    firstItem = Math.max(getFirstVisibleItem(), firstItem);
1860:                    if (firstItem > lastItem) {
1861:                        int t = lastItem;
1862:                        lastItem = firstItem;
1863:                        firstItem = t;
1864:                    }
1865:                    firstItem = Math.max(getFirstVisibleItem(), firstItem);
1866:                    lastItem = Math.min(lastItem, items.size() - 1);
1867:
1868:                    if (log.isLoggable(Level.FINER))
1869:                        log.finer("Actually painting items from " + firstItem
1870:                                + " to " + lastItem + ", items in window "
1871:                                + itemsInWindow());
1872:                    for (int i = firstItem; i <= lastItem; i++) {
1873:                        paintItem(g, i);
1874:                    }
1875:                }
1876:
1877:                private void paintItem(Graphics g, int index) {
1878:                    if (log.isLoggable(Level.FINEST))
1879:                        log.finest("Painting item " + index);
1880:                    // 4895367 - only paint items which are visible
1881:                    if (!isItemHidden(index)) {
1882:                        Shape clip = g.getClip();
1883:                        int w = getItemWidth();
1884:                        int h = getItemHeight();
1885:                        int y = getItemY(index);
1886:                        int x = getItemX();
1887:                        if (log.isLoggable(Level.FINEST))
1888:                            log.finest("Setting clip "
1889:                                    + new Rectangle(x, y, w - (SPACE * 2), h
1890:                                            - (SPACE * 2)));
1891:                        g.setClip(x, y, w - (SPACE * 2), h - (SPACE * 2));
1892:
1893:                        // Always paint the background so that focus is unpainted in
1894:                        // multiselect mode
1895:                        if (isSelected(index)) {
1896:                            if (log.isLoggable(Level.FINEST))
1897:                                log.finest("Painted item is selected");
1898:                            g.setColor(getListForeground());
1899:                        } else {
1900:                            g.setColor(getListBackground());
1901:                        }
1902:                        if (log.isLoggable(Level.FINEST))
1903:                            log.finest("Filling " + new Rectangle(x, y, w, h));
1904:                        g.fillRect(x, y, w, h);
1905:
1906:                        if (index <= getLastVisibleItem()
1907:                                && index < items.size()) {
1908:                            if (!isEnabled()) {
1909:                                g.setColor(getDisabledColor());
1910:                            } else if (isSelected(index)) {
1911:                                g.setColor(getListBackground());
1912:                            } else {
1913:                                g.setColor(getListForeground());
1914:                            }
1915:                            String str = (String) items.elementAt(index);
1916:                            g.drawString(str, x - hsb.getValue(), y
1917:                                    + fontAscent);
1918:                        } else {
1919:                            // Clear the remaining area around the item - focus area and the rest of border
1920:                            g.setClip(x, y, listWidth, h);
1921:                            g.setColor(getListBackground());
1922:                            g.fillRect(x, y, listWidth, h);
1923:                        }
1924:                        g.setClip(clip);
1925:                    }
1926:                }
1927:
1928:                void paintScrollBar(XScrollbar scr, Graphics g, int x, int y,
1929:                        int width, int height, boolean paintAll) {
1930:                    if (log.isLoggable(Level.FINEST))
1931:                        log.finest("Painting scrollbar " + scr + " width "
1932:                                + width + " height " + height + ", paintAll "
1933:                                + paintAll);
1934:                    g.translate(x, y);
1935:                    scr.paint(g, getSystemColors(), paintAll);
1936:                    g.translate(-x, -y);
1937:                }
1938:
1939:                /**
1940:                 * Paint the horizontal scrollbar to the screen
1941:                 *
1942:                 * @param g the graphics context to draw into
1943:                 * @param colors the colors used to draw the scrollbar
1944:                 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1945:                 */
1946:                void paintHorScrollbar(Graphics g, boolean paintAll) {
1947:                    int w = getListWidth();
1948:                    paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w,
1949:                            SCROLLBAR_WIDTH, paintAll);
1950:                }
1951:
1952:                /**
1953:                 * Paint the vertical scrollbar to the screen
1954:                 *
1955:                 * @param g the graphics context to draw into
1956:                 * @param colors the colors used to draw the scrollbar
1957:                 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1958:                 */
1959:                void paintVerScrollbar(Graphics g, boolean paintAll) {
1960:                    int h = height - (hsbVis ? (SCROLLBAR_AREA - 2) : 0);
1961:                    paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0,
1962:                            SCROLLBAR_WIDTH - 2, h, paintAll);
1963:                }
1964:
1965:                private Rectangle prevFocusRect;
1966:
1967:                private void paintFocus(Graphics g, int options) {
1968:                    boolean paintFocus = (options & PAINT_FOCUS) != 0;
1969:                    if (paintFocus && !hasFocus()) {
1970:                        paintFocus = false;
1971:                    }
1972:                    if (log.isLoggable(Level.FINE))
1973:                        log
1974:                                .fine("Painting focus, focus index "
1975:                                        + getFocusIndex()
1976:                                        + ", focus is "
1977:                                        + (isItemHidden(getFocusIndex()) ? ("invisible")
1978:                                                : ("visible"))
1979:                                        + ", paint focus is " + paintFocus);
1980:                    Shape clip = g.getClip();
1981:                    g.setClip(0, 0, listWidth, listHeight);
1982:                    if (log.isLoggable(Level.FINEST))
1983:                        log.finest("Setting focus clip "
1984:                                + new Rectangle(0, 0, listWidth, listHeight));
1985:                    Rectangle rect = getFocusRect();
1986:                    if (prevFocusRect != null) {
1987:                        // Erase focus rect
1988:                        if (log.isLoggable(Level.FINEST))
1989:                            log.finest("Erasing previous focus rect "
1990:                                    + prevFocusRect);
1991:                        g.setColor(getListBackground());
1992:                        g.drawRect(prevFocusRect.x, prevFocusRect.y,
1993:                                prevFocusRect.width, prevFocusRect.height);
1994:                        prevFocusRect = null;
1995:                    }
1996:                    if (paintFocus) {
1997:                        // Paint new
1998:                        if (log.isLoggable(Level.FINEST))
1999:                            log.finest("Painting focus rect " + rect);
2000:                        g.setColor(getListForeground()); // Focus color is always black on Linux
2001:                        g.drawRect(rect.x, rect.y, rect.width, rect.height);
2002:                        prevFocusRect = rect;
2003:                    }
2004:                    g.setClip(clip);
2005:                }
2006:
2007:                public void copyArea(int x, int y, int width, int height,
2008:                        int dx, int dy) {
2009:                    if (log.isLoggable(Level.FINER))
2010:                        log.finer("Copying area " + x + ", " + y + " " + width
2011:                                + "x" + height + ", (" + dx + "," + dy + ")");
2012:                    VolatileImage localBuffer = null;
2013:                    do {
2014:                        XToolkit.awtLock();
2015:                        try {
2016:                            if (createBuffer()) {
2017:                                // Newly created buffer should be painted over at full
2018:                                repaint(PAINT_ALL);
2019:                                return;
2020:                            }
2021:                            localBuffer = buffer;
2022:                        } finally {
2023:                            XToolkit.awtUnlock();
2024:                        }
2025:                        switch (localBuffer
2026:                                .validate(getGraphicsConfiguration())) {
2027:                        case VolatileImage.IMAGE_INCOMPATIBLE:
2028:                            invalidate();
2029:                        case VolatileImage.IMAGE_RESTORED:
2030:                            // Since we've lost the content we can't just scroll - we should paint again
2031:                            repaint(PAINT_ALL);
2032:                            return;
2033:                        }
2034:                        Graphics g = localBuffer.createGraphics();
2035:                        try {
2036:                            g.copyArea(x, y, width, height, dx, dy);
2037:                        } finally {
2038:                            g.dispose();
2039:                        }
2040:                    } while (localBuffer.contentsLost());
2041:                    Graphics listG = getGraphics();
2042:                    listG.setClip(x, y, width, height);
2043:                    listG.drawImage(localBuffer, 0, 0, null);
2044:                    listG.dispose();
2045:                }
2046:
2047:                public boolean isBuffer() {
2048:                    boolean isBuffer;
2049:                    XToolkit.awtLock();
2050:                    try {
2051:                        isBuffer = (buffer != null);
2052:                    } finally {
2053:                        XToolkit.awtUnlock();
2054:                    }
2055:                    return isBuffer;
2056:                }
2057:            }
2058:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.